gpt4 book ai didi

c - 使用堆溢出写入任意数据

转载 作者:太空狗 更新时间:2023-10-29 16:26:13 26 4
gpt4 key购买 nike

我一直在努力学习堆溢出攻击的基础知识。我最感兴趣的是使用 block 元数据的损坏或修改作为攻击的基础,但我也愿意接受其他建议。我知道我的漏洞利用目标应该是用 challenge() 函数指针覆盖 printf() 函数指针,但我似乎无法理解出如何实现那个写。我有以下要利用的代码,它使用 glibc 2.11.2 中的 malloc :

void challenge()
{
puts("you win\n");
}

int main(int argc, char **argv)
{
char *inputA, *inputB, *inputC;

inputA = malloc(32);
inputB = malloc(32);
inputC = malloc(32);

strcpy(inputA, argv[1]);
strcpy(inputB, argv[2]);
strcpy(inputC, argv[3]);

free(inputC);
free(inputB);
free(inputA);

printf("execute challenge to win\n");
}

显然,实现对已分配 block 的元数据的实际覆盖是微不足道的。但是,我一直无法找到使用任何标准技术来利用此代码的方法。我已阅读并尝试实现以下技术:

  • 论文:w00w00 Heap Overflows
    • 虽然这篇论文很清楚,但是 unlink 技术已经过时了一段时间。
  • Malloc Maleficarum.txt
    • 本文扩展了 w00w00 时代的漏洞利用技术,并说明了 glibc 的较新版本。但是,我没有发现鉴于论文中详述的 5 种技术,上面的代码符合这些技术的任何先决条件。
  • Understanding the Heap By Breaking it(pdf)
    • 该 pdf 很好地回顾了堆的工作原理,但侧重于双重释放技术。

我最初试图通过操纵 inputC block 的大小值来利用此代码,以便它指向 inputC block 的头部。当这不起作用时,我尝试进一步指向 inputB block 。那时我才意识到新的 glibc 对大小值执行完整性检查。

假设用户有能力将分配的 block 的元数据编辑为任意值,并使用它来覆盖 GOT 中的值或写入任何其他任意地址,用户如何才能利用免费的漏洞利用?

注意:当我写“任意地址”时,我理解内存页可能是只读的或 protected ,我的意思是我可以假设我可以写入的地址。

最佳答案

注:回答前声明,纯学术回答,不用于恶意目的。我知道 OP 正在进行的练习,它们是开源的,无意鼓励任何用户在未经批准的情况下使用这些技术。

我将在下面详细介绍该技术,但为了您的引用,我会看一下 Vudo malloc 技巧(在上面的一个链接中引用了它),因为我的概述将是一个简短的:http://www.phrack.com/issues.html?issue=57&id=8

它详细说明了 malloc 如何处理创建内存块、从列表中提取内存以及其他事情。特别是取消链接攻击对这种攻击很感兴趣(注意:你是正确的,glibc 现在出于这个特殊原因对大小执行健全性检查,但你应该使用较旧的 libc 来进行此练习......遗留兄弟)。

从论文中可以看出,分配 block 和空闲 block 使用相同的数据结构,但对数据的处理方式不同。看这里:

chunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| prev_size: size of the previous chunk, in bytes (used |
| by dlmalloc only if this previous chunk is free) |
+---------------------------------------------------------+
| size: size of the chunk (the number of bytes between |
| "chunk" and "nextchunk") and 2 bits status information |
mem -> +---------------------------------------------------------+
| fd: not used by dlmalloc because "chunk" is allocated |
| (user data therefore starts here) |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| bk: not used by dlmalloc because "chunk" is allocated |
| (there may be user data here) |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| |
| |
| user data (may be 0 bytes long) |
| |
| |
next -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| prev_size: not used by dlmalloc because "chunk" is |
| allocated (may hold user data, to decrease wastage) |
+---------------------------------------------------------+

分配的 block 不使用 fd 或 bk 指针,但自由 block 会。这在以后很重要。您应该了解足够多的编程知识,以了解 Doug Lea 的 malloc 中的“ block ”被组织成一个双向链表;有一个用于空闲 block 的列表,另一个用于分配的 block (从技术上讲,根据大小有几个免费列表,但它在这里无关紧要,因为代码分配了相同大小的 block )。所以当你释放一个特定的 block 时,你必须修复指针以保持列表的完整性。

例如假设您要从下面的列表中释放 block y:

x <-> y <-> z

请注意,在上图中,bk 和 fd 的位置包含沿列表迭代所需的指针。当 malloc 想要从列表中取出 block p 时,它会调用一个宏来修复列表:

#define unlink( y, BK, FD ) {            
BK = P->bk;
FD = P->fd;
FD->bk = BK;
BK->fd = FD;
}

宏本身并不难理解,但在旧版本的 libc 中需要注意的重要一点是它不会对大小或写入的指针执行健全性检查。在您的情况下,这意味着在没有任何类型的地址随机化的情况下,您可以可预测且可靠地确定堆的状态,并通过以特定方式溢出堆(通过此处的 strncopy)将任意指针重定向到您选择的地址.

要使攻击生效,需要做一些事情:

  • 您的 block 的 fd 指针指向您要覆盖的减去 12 个字节的地址。偏移量与 malloc 在修改列表时清理对齐有关
  • 你的 block 的 bk 指针指向你的 shellcode
  • 大小需要为 -4。这完成了一些事情,即它设置了 block 中的状态位

因此,您必须在特定示例中使用偏移量,但您尝试在此处使用 strcpy 传递的一般恶意格式的格式为:

|垃圾填满合法缓冲区| -4 | -4 |您要覆盖的地址 -12 (0x0C) | addr 你想调用

注意负数将 prev_size 字段设置为 -4,这使得自由路由认为 prev_size block 实际上从您控制/正在损坏的当前 block 开始。

是的,如果不提及这种攻击不适用于当前版本的 glibc,那么正确的解释是不完整的;大小已完成健全性检查,取消链接方法将不起作用。这与地址随机化等缓解措施相结合,使得这种攻击在遗留系统以外的任何地方都不可行。但是这里描述的方法是我如何完成挑战的;)

关于c - 使用堆溢出写入任意数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9646608/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com