C 使用堆溢出写入任意数据
我一直在努力学习堆溢出攻击的基础知识。我最感兴趣的是使用块元数据的损坏或修改作为攻击的基础,但我也愿意接受其他建议。我知道我的攻击目标应该是用C 使用堆溢出写入任意数据,c,security,heap,exploit,C,Security,Heap,Exploit,我一直在努力学习堆溢出攻击的基础知识。我最感兴趣的是使用块元数据的损坏或修改作为攻击的基础,但我也愿意接受其他建议。我知道我的攻击目标应该是用challenge()函数指针覆盖printf()函数指针,但我似乎不知道如何实现这种写入。 我有一段我想利用的代码,它使用的是glibc2.11.2中的malloc: void challenge() { 卖出(“您赢了”\n); } int main(int argc,字符**argv) { 字符*输入,*输入B,*输入UTC; 输入=malloc(3
challenge()
函数指针覆盖printf()
函数指针,但我似乎不知道如何实现这种写入。
我有一段我想利用的代码,它使用的是glibc2.11.2
中的malloc
:
void challenge()
{
卖出(“您赢了”\n);
}
int main(int argc,字符**argv)
{
字符*输入,*输入B,*输入UTC;
输入=malloc(32);
inputB=malloc(32);
inputt=malloc(32);
strcpy(输入,argv[1]);
strcpy(inputB,argv[2]);
strcpy(inputC,argv[3]);
免费(UTC);
免费(输入b);
免费(输入);
printf(“执行挑战以赢得\n”);
}
显然,实现对已分配块的元数据的实际覆盖是微不足道的。然而,我还没有找到使用任何标准技术来利用这段代码的方法。
我已阅读并尝试实施以下技术:
- 论文编号:w00w00
- 虽然这篇论文非常清楚,但是
技术已经过时一段时间了取消链接
- 虽然这篇论文非常清楚,但是
-
- 本文扩展了w00w00天以来的利用技术,并介绍了较新版本的glibc。然而,我没有发现,考虑到本文中详细介绍的5种技术,上面的代码与这些技术的任何先决条件都不匹配
-
- pdf很好地介绍了堆的工作原理,但重点介绍了双自由技术
注意:当我写“任意地址”时,我知道内存页可能是只读的或受保护的,我指的是一个我可以假设我可以写入的地址。堆溢出很难解决,并且非常依赖堆布局,尽管看起来你是在追求Windows CRT堆,它有很多缓解措施,专门用来阻止这种类型的攻击 如果你真的想做这类事情,你需要高兴地跳进WinDbg,进入free这样的函数,看看free里面到底发生了什么,因此你可以通过前一个值的堆溢出来实现什么样的控制
我不会给你任何比这更具体的帮助,原因很简单,证明堆溢出对于防御安全来说通常就足够了——防御安全专家可以报告堆溢出,而不需要实际充分利用它。真正需要完全利用堆溢出进行远程代码执行的人只有那些攻击性地利用bug的人,如果你想这样做,那就靠你自己。注意,Malloc Malleficarum中介绍的大多数技术现在都得到了保护。glibc大大改进了所有的双自由场景 如果你想提高你对Malloc Malleficarum技术的了解,请阅读blackngel撰写的Malloc Des Malleficarum和《知识之家:重新载入》。你可以在phrack中找到这些文本 我也在研究它,我可以对你们说,例如,心灵之家不再是可利用的,至少,正如文本中所解释的。尽管可以绕过添加到代码中的新限制。 另外,执行代码的最简单方法是覆盖.dtors地址,因此,一旦程序完成,代码将始终执行 如果您下载glibc代码并研究malloc的评论区等,您将发现前面提到的文档中没有记录的代码检查。这些支票是用来阻止双重自由派对的 另一方面,为了理解所有堆机制,您可以在youtube(BlackHat 2007)上找到Justin N.Ferguson(通过打破堆来理解堆)的演示非常完美,但我必须承认,所展示的技术远不可靠,但至少他为堆利用开辟了一个新领域
不管怎样,我也在努力,所以如果你想联系我,我们可以分享我们的进展。您可以在OverflowdMinds.net域中以newlog(自己构建邮件地址^^^)的形式与我联系。注意:在回答之前,我会说,这纯粹是一个学术性的回答,无意用于恶意目的。我知道OP正在做的练习,它们是开源的,不打算鼓励任何用户在未经批准的情况下使用这些技术 我将在下面详细介绍这项技术,但为了供您参考,我会看一看Vudo malloc技巧(上面的一个链接中引用了它),因为我的概述将是一个简短的概述: 它详细介绍了malloc如何处理创建内存块、从列表中提取内存以及其他事情。此攻击特别关注取消链接攻击(注意:glibc现在基于此特定原因对大小执行健全性检查是正确的,但在本练习中,您应该使用较旧的libc…legacy bro) 根据本文,分配块和空闲块使用相同的数据
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) |
+---------------------------------------------------------+
x <-> y <-> z
#define unlink( y, BK, FD ) {
BK = P->bk;
FD = P->fd;
FD->bk = BK;
BK->fd = FD;
}