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;
}