【问题标题】:Exploiting a string-based overflow on x86-64 with NX (DEP) and ASLR enabled在启用 NX (DEP) 和 ASLR 的 x86-64 上利用基于字符串的溢出
【发布时间】:2013-07-09 12:32:33
【问题描述】:

考虑以下易受攻击的代码/程序:

#include <string.h>

int main(int argc, char *argv[]) {
    char buf[16];
    strcpy(buf, argv[1]);

    return 0;
}

在 IA-32(x86,32 位)上运行 Linux 并启用 NX 和 ASLR,我将使用 GOT 覆盖技术来利用这一点,该技术主要包括以下步骤:

  1. 溢出缓冲区直到 RIP
  2. strcpy@plt的地址覆盖RIP
  3. 使用来自.text 的干净小工具,例如pop edi ; pop ebp ; ret,作为strcpy的返回地址
  4. strcpy 写入参数:&amp;bss-address 作为目标地址和/bin/sh 的一个字节,使用.text
  5. 重复步骤 2-4,直到 /bin/sh 完全写入 &amp;bss
  6. system 覆盖 strcpy 的 GOT 条目(使用偏移量,需要了解使用的 Libc 版本 - 我们在此忽略)
  7. 在堆栈上写入strcpy@plt,然后是一些4字节的块,最后是&amp;bss的地址,它指向/bin/sh
  8. 利润

我想在启用相同缓解措施的情况下在 x86-64 上利用它。但这比想象的要困难得多。主要有以下几个原因:

  1. x86-64 基于寄存器的调用约定:函数参数使用寄存器而不是堆栈传递。因此,需要一些额外的 ROP-gadgets 将参数从堆栈传输到适当的寄存器。这是一个小问题,但也会受到以下问题的影响:
  2. 64 位返回地址:x86-64 中的 RIP 指向 .text,它甚至不是 32 位长。因此,必须将 NULL 字节写入堆栈以链接函数调用。基本上,可以使用对strcpy 的链式调用并利用strcpy always 写入的 NULL 终止字符来根据需要写入尽可能多的 NULL 字节。但是一个人只能通过覆盖 RIP 的最低有效字节来调用一次strcpy

    |0x00000000|        (most significant bytes)
    |0x00deadbe| <- RIP (least significant bytes)
    |0x41414141|
    |0x41414141| <- SFP
    |   ...    | 
    

这些是我在启用 NX 和 ASLR 的 x86-64 上利用该程序时遇到的主要问题。有什么技术可以解决这些问题吗?或者 x86-64 真的能阻止一个有效的、打开 shell 的漏洞利用吗?

【问题讨论】:

  • 如果 RIP 应该代表返回地址,您需要 x86-64 的新术语。就像 EAX 扩展为 RAX 一样,EIP(当前指令指针)扩展为 RIP。所以在 x86-64 中,RIP 是一个寄存器名称,并且(本身)不会为 RET 将读取的返回地址命名。

标签: linux x86-64 buffer-overflow aslr dep


【解决方案1】:

x86-64 不会阻止这些类型的漏洞利用。看到这个tutorial

【讨论】:

  • 由于这个问题假设 x86-64 同时启用了 ASLR 和 NX,因此您的链接没有提供解决方案:“我不得不通过关闭 ASLR 来欺骗这个问题。由于在 64 位系统上寻址,空字节成为一个非常大的问题。对于这个特殊的挑战,覆盖 RIP 很容易,但由于空字节,我只能返回单个小工具。"
猜你喜欢
  • 2011-12-25
  • 2014-08-08
  • 2011-03-24
  • 2011-03-11
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多