导致缓冲区溢出,段错误

4

我正在尝试在以下非常简单的程序中造成缓冲区溢出:

#include <stdio.h>
#include <stdint.h>

void badf(int n, char c, char* buffer)
{

    char mycode[] = {
0xeb, 0x0f, 0xb8, 0x0b,
0x00, 0x00, 0x00, 0x8b,
0x1c, 0x24, 0x8d, 0x0c,
0x24, 0x31, 0xd2, 0xcd,
0x80, 0xe8, 0xec, 0xff, 
0xff, 0xff, 0x2f, 0x62,
0x69, 0x6e, 0x2f, 0x6c, 
0x73, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00
}; // 37 bytes

// Overwrite Base Pointer
    //mycode[37] = 0x29;
//mycode[38] = 0xf4;
//mycode[39] = 0xff;
//mycode[40] = 0xbf;

    // Overwrite Instruction Pointer
    // Using debugger, found mycode[] to be loaded in: 0xbffff42d
    mycode[41] = 0x2d;
    mycode[42] = 0xf4;
    mycode[43] = 0xff;
    mycode[44] = 0xbf;

}

void f(int n, char c)
{
    char buffer[37];    
    badf(n,c,buffer);
}

void test()
{
    printf("test");
}

int main()
{
    f(37,0x00);
    return 0;
}

我已成功地通过缓冲区溢出执行了test()函数。现在,我正在尝试通过用mycode[]的起始地址覆盖指令指针来执行mycode[]。

这只有一半成功,程序跳转到正确的地址,在调试器中可以看到正确的机器代码,但在执行以下指令之前就会崩溃并显示分段错误(见截图)。

enter image description here

我正在尝试找出在执行“注入”代码之前为什么会崩溃。 我对这种东西相对较新,我理解分段错误意味着我正在尝试访问操作系统不允许我访问的内存?

(PS: 32位Linux机器,使用-fno-stack-protector编译以便进行此类实验)

(如果需要更多信息,我将乐意更新帖子)


你解决了你的问题吗?我也有同样的问题。 - Kennet Celeste
2个回答

3
很遗憾,这种令人兴奋的技巧现在已经不再适用了。要怪罪那些病毒制造者。
数据段被标记为 NX (no execute) 位,这就触发了段错误。CPU看到PC处于不可执行区域。
为什么不尝试覆盖“真实”函数指针的代码(获取现有函数的地址)并查看会发生什么(这可能会失败,因为自修改代码也受到编译器/链接器/操作系统的反感,同样是由于上述提到的病毒制造者)。

好的,谢谢。实际上这是一项学校练习,但我在家里完成它。你认为我可以得出结论,我已经成功地注入了代码并重定向了指令指针,但我的现代Debian发行版正在阻止这种情况发生吗? - Juicy
你只能得出这样的结论:你成功地将一些机器代码注入到一个变量中,但无法执行它。也许如果没有NX保护,它可能会起作用,也可能不会。更新:请参见编辑答案中的建议。 - dan3

3

如果是Linux系统,你可以尝试下载并安装execstack,并按照这里的指示操作。出现“分段错误”可能是由于ELF二进制文件默认设置了nx位导致的,而execstack可以选择性地撤销该设置。如果这样做不起作用,你可能会触发其他保护措施,这些保护措施可能无法禁用。


1
我尝试使用以下命令进行编译:“gcc -z execstack -fno-stack-protector -g -static -o bof bof.c”,这样做应该是一样的,对吗? - Juicy
1
@Juicy:这在我的发行版上不起作用。需要单独下载和安装Execstack,并使用execstack -s <binary name>命令。你偶尔会看到你写的语法被建议使用,但对我来说不起作用。 - gnometorule
虽然这取决于我的发行版,但它在代码库中;因此只需运行 sudo apt-get install execstack 即可完成安装和配置。 - gnometorule
谢谢!我尝试了一下,但仍然出现了段错误。我相信,就像我告诉dan3的那样,我已经做到了我的讲师想要的,它在我的Debian上无法工作,但希望能在我们大学的Ubuntu上工作。 - Juicy
调试器上显示的代码就是我尝试注入的机器码(用于系统调用execv),所以它看起来是正确的代码在正确的地址。 - Juicy
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接