。Nana told me that buffer overflow is one of the most common software vulnerability.
Is that true?
Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c
Running at : nc pwnable.kr 9000
将 bof 文件下载下来,用 file 命令查看一下,可以看到是一个32位的 ELF 可执行文件,拖到 Ubuntu 中进行调试。
简单运行发现程序需要我们输入一些字符串,根据提示可以知道此题需要进行溢出。直接抄起 gdb 调试之。尝试直接使用 b main 在主函数处设置断点。
r 开始运行,程序断在了主函数入口处,使用 n 进行单步跟踪,当走到 0x8000069a 处时,程序 call 0x8000062c 调用了 0x8000062c 处的函数,直接 s 单步进入继续跟。
当走到 0x8000064c 程序将寄存器 eax 的值 0xbffff55c 压入栈,随后进行 call 0xb7e78cd0 <_IO_gets>,此处为 c 语言中的 gets() 函数调用,最终 0xbffff55c 会指向用户输入的字符串。这里使用peda中的 pattern create 64 创建一个64字节的测试 payload 将其输入到程序中,方便后续调试。
输入完字符串后,程序停在了 0x80000654 进行了一个简单的比较操作 cmp DWORD PTR [ebp+0x8],0xcafebabe,比较 DWORD PTR [ebp+0x8] 处的值是否等于 0xcafebabe,而此时的 DWORD PTR [ebp+0x8] 地址为 0xbffff590,回顾一下刚刚指向用户输入字符串的地址 0xbffff55c。输入的字符串地址处在一个低地址上,如果输入足够长的字符串,就能够覆盖到后面 0xbffff590 处的值。
当比较成功时,程序不会发生跳转,调用 call 0xb7e54190 <__libc_system>,而其参数为 /bin/sh,如下图。
理清过程后,剩下的就只需要找到输入字符串指针距离 0xbffff590 的偏移即可。由于之前使用了特殊的 payload,这时候我们查看一下输入字符串周围的堆栈情况。
可以看到刚才输入的 payload 已经覆盖到了 0xbffff590 处的值,但是并不是程序需要的 0xcafebabe,使用 pattern offset 来计算偏移。
可以看到,0xbffff590 距离字符串开头的偏移为52个字节,因此为了成功地使程序跳转执行system(“/bin/sh”),我们构造的输入字符串就应该为:
"A" * 52 + "\xbe\xba\xfe\xca"
此时,直接使用命令行远程打 payload:
(python -c 'print "A" * 52 + "\xbe\xba\xfe\xca"'; cat -) | nc pwnable.kr 9000