在启用了NX(DEP)和ASLR的x86-64上利用基于字符串的溢出

时间:2013-07-11 09:35:17

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

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

#include <string.h>

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

    return 0;
}

在启用了NX和ASLR的运行Linux的IA-32(x86,32位)上,我将使用GOT覆盖技术来利用它,它基本上包括以下步骤:

  1. 溢出缓冲区直到RIP
  2. 使用strcpy@plt
  3. 的地址覆盖RIP
  4. 使用.text中的干净小工具,例如pop edi ; pop ebp ; ret,作为strcpy
  5. 的返回地址
  6. strcpy撰写论据:&bss - 使用/bin/sh作为目的地的地址和.text的一个字节
  7. 重复步骤2-4,直到/bin/sh完全写入&bss
  8. strcpy覆盖system的GOT条目(使用偏移量,需要了解Libc的使用版本 - 让我们忽略这一点)
  9. 在堆栈上写strcpy@plt,然后是一些4字节的块,最后是&bss的地址,指向/bin/sh
  10. 利润
  11. 我希望在x86-64上利用此功能,同时启用相同的缓解措施。但这更像想象的那样困难。基本上由于以下原因:

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

      |0x00000000|        (most significant bytes)
      |0x00deadbe| <- RIP (least significant bytes)
      |0x41414141|
      |0x41414141| <- SFP
      |   ...    | 
      
    3. 这些是我在启用NX和ASLR的x86-64上利用该程序时遇到的主要问题。有没有解决这些问题的技术?或者x86-64真的阻止了一个可行的,开壳的漏洞吗?

1 个答案:

答案 0 :(得分:0)

x86-64不会阻止这些类型的攻击。请参阅此tutorial