第一次缓冲区溢出实验

First experiments with buffer overflow

我已经开始阅读有关缓冲区溢出以及黑客如何使用它来执行自定义代码而不是常规编译代码的信息,现在我正在尝试重现一些基本情况,使用一个可将数据复制到 char 的函数带有不安全 strcpy 的数组。

重点是 当我用程序中定义的函数的汇编指令之一更改 return 地址时,它工作正常,而当我直接以字节形式注入代码时,它returned 段错误。


我使用的是 Kali 发行版 x64 v3.18

我已禁用地址 space 布局随机化 (ASLR):

echo 0 > /proc/sys/kernel/randomize_va_space

并禁用编译器添加的堆栈保护代码:

gcc -g -fno-stack-protector exbof.c -o exbof


代码:

#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv){
    char buffer[500] = {0};
    strcpy(buffer, argv[1]);

    return 0;
}


用法:

./exbof `perl -e 'print "x90"x216;          // nop sled 
                  print CUSTOM_CODE;        // my code  
                  print "xff"x(500 - 216 - CODE_LENGTH);     // fill empty space
                  print "xff"xOFFSET        // distance between the last byte 
                                            // of buffer and the return address 
                  printf("\x%lx", BUFFER_ADDRESS + int(rand(26)) * 8);'`



输出:

Segmentation Fault

在 GDB 中:

Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffxyzt in ?? ()


我已经使用 GDB 对其进行调试,代码将新地址正确写入堆栈。
我正在使用在网上找到的 shellcode exec,但我也尝试从我的程序中以字节为单位注入一段代码,当我检查 GDB 时,注入的汇编代码结果是是有效代码并且与原始代码完全相同。
在我看来,.text 内存段之外的任何地址都不起作用。


建议?

解法:

正如@andars 所建议的,有必要设置将堆栈标记为可执行的标志。


所以,如果你想尝试这个并开始玩缓冲区溢出,你必须:

  • 禁用地址space布局随机化(ASLR):

    echo 0 > /proc/sys/kernel/randomize_va_space

  • 关闭编译器添加的堆栈保护代码:

    gcc -g -fno-stack-protector your_program.c -o your_program

  • 在程序头中设置一个标志以将堆栈标记为可执行:

    execstack -s your_program

    • 或者你可以直接在组装时或link时做:

      gcc -g -fno-stack-protector -z execstack your_program.c -o your_program