C bufbomb堆栈溢出失败

C bufbomb堆栈溢出失败,c,gcc,buffer-overflow,C,Gcc,Buffer Overflow,我正在使用bufbomb.c进行一些缓冲区溢出攻击实验 我成功地使用了gdb来调试代码。然而;当我直接运行程序时,当我输入字符尝试攻击时,我会得到一个“分段错误(内核转储)” 我使用了gcc(Ubuntu/Linaro4.8.1-10ubuntu9)4.8.1。要构建以下内容 //bufbomb.c /* Bomb program that is solved using a buffer overflow attack */ #include <stdio.h> #in

我正在使用
bufbomb.c
进行一些
缓冲区溢出攻击
实验

我成功地使用了
gdb
来调试代码。然而;当我直接运行程序时,当我输入字符尝试攻击时,我会得到一个
“分段错误(内核转储)”

我使用了gcc(Ubuntu/Linaro4.8.1-10ubuntu9)4.8.1。要构建以下内容

//bufbomb.c  
/* Bomb program that is solved using a buffer overflow attack */ 

#include <stdio.h>  
#include <stdlib.h>  
#include <ctype.h>  

/* Like gets, except that characters are typed as pairs of hex digits. 
   Nondigit characters are ignored.  Stops when encounters newline */ 
char *getxs(char *dest) 
{ 
    int c; 
    int even =1; /* Have read even number of digits */ 
    int otherd =0; /* Other hex digit of pair */ 
    char*sp = dest; 
    while ((c = getchar()) != EOF && c !='\n') { 
        if (isxdigit(c)) {
            int val; 
            if ('0'<= c && c <='9') 
                val = c -'0'; 
            else if ('A'<= c && c <='F') 
                val = c -'A'+10; 
            else 
                val = c -'a'+10; 
            if (even) { 
                otherd = val; 
                even =0; 
            } 
            else { 
                *sp++= otherd *16+ val; 
                even =1; 
            } 
        } 
    } 
    *sp++='\0'; 
    return dest; 
} 

/* $begin getbuf-c */ 
int getbuf() 
{ 
    char buf[12]; 
    getxs(buf); 
    return 1; 
} 

void test() 
{ 
    int val; 
    printf("Type Hex string:"); 
    val = getbuf(); 
    printf("getbuf returned 0x%x\n", val); 
} 
/* $end getbuf-c */ 

int main() 
{ 
    int buf[16]; 
    /* This little hack is an attempt to get the stack to be in a 
       stable position 
    */ 
    int offset = (((int) buf) &0xFFF); 
    int*space = (int*) alloca(offset); 
    *space =0; /* So that don't get complaint of unused variable */ 
    test(); 
    return 0; 
}
然后没有gdb::

./bufbomb 
Type Hex string:30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 d8 bf ff ff 9f 85 04 08 b0 86 04 08 30 31 32 33 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 ef be ad de
Segmentation fault (core dumped)

我正在寻找一些帮助来解决seg故障

您正在访问进程不“拥有”的内存

当您运行gdb时,编译器会添加一些东西(比如额外的调试信息)

在尝试缓冲区溢出之前,可以通过扩展堆栈绕过分段错误:

int expand_stack(int n_bytes) 
{
  char buf[n_bytes];
  return buf[n_bytes-1]; // access the memory to make sure the optimiser doesn't remove buf.
}
main
中,在调用
test
之前,添加对
expand\u stack
的调用:

int main() 
{ 
    int buf[16]; 
    /* This little hack is an attempt to get the stack to be in a 
       stable position 
    */ 
    int offset = (((int) buf) &0xFFF); 
    int*space = (int*) alloca(offset); 
    *space = expand_stack(200); 

    test(); 
    return 0; 
}
请注意,您的代码仍然调用未定义的行为


注2:如果您的编译器不支持可变长度数组,只需使用固定数组,
buf[200]
在gdb下使用更大的缓冲区运行它,查看它试图访问的地址,以猜测
getbuf()
使用的返回地址的堆栈偏移量

为了承受因使用gdb而产生的内存偏移量的微小差异,请使用NOP底座。您的攻击缓冲区应如下所示:

|RET地址x 30 | NOPS(
0x90
)x 1000 |外壳代码|

返回地址应指向NOP底座的中间


如果执行跳转到底座中的任何位置,它将滑到外壳代码。

我使用以下命令编译:gcc-o bufbomb-fno stack protector-m32-g bufbomb.cbe缓冲区溢出条件下的程序行为未定义。它可能会崩溃,也可能不会。你到底想实现什么?仅供参考:我在Linux(SUSE SLES11)上编译了问题代码,使用:“gcc-o bufbomb-fno stack protector-m32-g bufbomb.c”。无论是否在gdb下运行代码,都会产生segfault。我同意@dmitri;还要问,这个项目的预期行为是什么?请编辑问题并澄清。抱歉,我没有清楚解释我的意图,函数getbuf()return 1和函数test()将打印“getbuf returned 1”,我想打印“getbuf returned 0xdeadbeef”。重点不是扩展当前函数的堆栈帧,而是覆盖帧后存储的返回地址。一旦覆盖了返回地址,你就不在乎是否破坏了堆栈,因为你的代码正在运行。你是说堆栈已经足够大了,他正在用垃圾覆盖返回地址,导致返回跳转跳转到“未知区域”?没错。利用漏洞的目的是用不只是垃圾的东西覆盖地址,即用户控制的地址。如果用户选择了正确的地址,执行将跳转到用户控制的代码。感谢您的回答。我想知道正常运行的进程堆栈帧大小是否与gdb中运行的进程相同。如果相同,为什么我使用-fno stack protector选项进行编译,但结果不同。我认为gcc没有为bufbomb.c提供任何堆栈保护。操作系统是否提供保护?补充一下,我希望在不修改源文件的情况下尝试缓冲区溢出。哦,谢谢你的回答。实际上我刚刚开始学习缓冲区溢出,我对外壳代码了解不多。你能给我更多关于外壳代码的建议或教程吗
int main() 
{ 
    int buf[16]; 
    /* This little hack is an attempt to get the stack to be in a 
       stable position 
    */ 
    int offset = (((int) buf) &0xFFF); 
    int*space = (int*) alloca(offset); 
    *space = expand_stack(200); 

    test(); 
    return 0; 
}