【问题标题】:Heap overflow exploit堆溢出漏洞利用
【发布时间】:2025-12-30 11:50:11
【问题描述】:

我了解溢出利用需要三个步骤:

1.向目标进程内存空间注入任意代码(shellcode)。

2.控制eip。

3.设置eip执行任意代码。

我阅读了 ben hawkens 关于堆利用的文章,并了解一些关于如何最终覆盖函数指针以指向我的代码的策略。

换句话说,我理解了第 2 步。

我不明白第 1 步和第 3 步。

  1. 如何将代码注入进程内存空间?

  2. 在第 3 步中,我使用 指向我的 shellcode 的指针,我如何计算\知道什么地址 我注入的代码被注入了吗? (这个问题解决了 在*中使用"jmp esp)。

【问题讨论】:

    标签: memory overflow heap-memory exploit


    【解决方案1】:

    第 1 步需要被攻击代码中的漏洞。 常见的漏洞包括:

    • 缓冲区溢出(常见的 i C 代码,如果程序将任意长字符串读入固定缓冲区,就会发生这种情况)
    • 评估未经处理的数据(常见于 SQL 和脚本语言,但也可能出现在其他语言中)

    第 3 步需要详细了解目标架构。

    【讨论】:

    • 我明白了。可以举个例子,在堆溢出的情况下如何查找shellcode地址?
    • 不,我没有制造病毒的习惯,所以我从来没有费心去做。
    • 网上列出了很多方法。举个例子。有时您无法准确控制 eip 的去向,因此人们使用“nop sleds”来覆盖大量内存(搜索术语),希望当他们随机切换内存时,他们会碰到向下滑动的 nop sled漏洞利用。有时堆利用(不仅仅是溢出)会导致任意写入 4 个字节..(所以如果你知道堆栈地址,你可以覆盖返回的 eip)。与缓冲区溢出相比,堆漏洞利用作为漏洞利用涉及更多。
    【解决方案2】:

    在堆溢出中,假设系统没有激活 ASLR,你会知道你在溢出中使用的内存块(也就是缓冲区)的地址。

    如果您可以控制缓冲区的内容(作为应用程序用户),一个选项是将 shellcode 放置在缓冲区所在的位置。一旦你将 shellcode 字节放入缓冲区,你只需要跳转到那个缓冲区地址。

    执行该跳转的一种方法是,例如,覆盖 .dtors 条目。一旦易受攻击的程序完成,放置在缓冲区中的 shellcode 将被执行。复杂的部分是 .dtors 覆盖。为此,您必须使用已发布的堆利用技术。

    先决条件是禁用 ASLR(在执行易受攻击的程序之前知道缓冲区的地址)并且放置缓冲区的内存区域必须是可执行的。

    在更多的事情上,第 2 步和第 3 步是相同的。如果你控制eip,逻辑上你会将它指向shellcode(任意代码)。

    P.S.:绕过 ASLR 更复杂。

    【讨论】:

      【解决方案3】:
      1. 如何将我的代码注入进程空间?

        这是一个相当的陈述/问题。它需要在所述进程空间中有一个“可利用”的代码区域。例如,Windows 目前正在尽可能将大多数 strcpy() 重写为 strncpy()。我说如果可能的话

        因为并非所有使用 strcpy 的代码区域都可以成功转换为 strncpy。为什么?因为~@这个症结的区别如下所示;

        strcpy($buffer, $copied);
        

        strncpy($buffer, $copied, sizeof($copied));
        

        这就是 strncpy 在现实世界场景中难以实施的原因。大多数strncpy 操作都必须安装一个“幻数”(sizeof() 运算符创建这个幻数)

        作为编码人员,我们被教导使用硬编码值,例如严格遵守 char buffer[1024]; 是非常糟糕的编码实践。

        但是 ~ 相比之下 - 使用 buffer[]="";buffer[1024]=""; 是漏洞利用的核心。但是,例如,如果我们将此代码更改为后者,我们会在系统中引入另一个漏洞...

        char * buffer;
        char * copied;
        
        strcpy(buffer, copied);//overflow this right here...
        

        或者这个:

        int size = 1024;
        
        char buffer[size];
        char copied[size];
        
        strncpy(buffer,copied, size);
        

        这将阻止溢出,但会在 RAM 中引入一个可利用的区域,因为它的大小是可预测的并被结构化为 1024 个代码/数据块。

        因此,例如,在程序的地址空间中寻找 strcpy 的原始发布者,如果存在 strcpy,将使该程序可被利用。

        strcpy 比strncpy 更受程序员青睐的原因有很多。幻数、可变输入/输出数据大小……编程风格……等等……

      2. 我如何在我的代码中找到自己(我的位置)

        查看各种黑客书籍以获取此类示例〜

        但是,试试吧;

        label:
        pop eax
        pop eax
        call pointer
        
        jmp label
        pointer:
        mov esp, eax
        jmp $
        

        这是一个无效的示例,因为我不想为编写下一个莫里斯蠕虫负责!但是,任何体面的程序员都会了解这段代码的要点并立即知道我在说什么。

        我的儿子,我希望你的溢出技术在未来能够奏效!

      【讨论】: