我想在C程序上尝试缓冲区溢出。我用gcc像这样function rowHighlight() {
$("TR").click(function() {
try {
$(this).parent().prev()[0].tagName;
HighLightTR(this);
} catch (err) {}
});
}
编译了它。如果我在gdb中运行该程序并且缓冲区溢出,则应该说0x41414141,因为我发送了A。但俗话说0x565561f5。对不起,我的英语不好。有人可以帮我吗?
这是源代码:
gcc -fno-stack-protector -m32 buggy_program.c
#include <stdio.h>
int main(int argc, char **argv)
{
char buffer[64];
printf("Type in something: ");
gets(buffer);
}
我想看这个:
Starting program: /root/Downloads/a.out
Type in something: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x565561f5 in main ()
答案 0 :(得分:1)
现代操作系统使用地址空间布局随机化ASLR使得这些东西不太容易工作。
我记得它刚开始时的争议。对于32位进程而言,ASLR并不是一个好主意,因为它对系统施加了其他限制,并且带来了可疑的安全性好处。另一方面,它可以在64位进程上很好地工作,并且现在几乎每个人都使用它。
您不知道代码在哪里。您不知道堆在哪里。您不知道堆栈在哪里。编写漏洞利用代码现在很困难。
此外,您尝试在64位进程上使用32位shellcode和文档。
在阅读更新的问题时:您的代码是使用帧指针编译的(默认设置)。这会导致ret指令本身出错,因为esp已被破坏。 ASLR似乎仍在发挥作用,实际上并不重要。
答案 1 :(得分:1)
查看段错误处理的地址,在反汇编代码中显示相关行:
gdb a.out << EOF
设置登录
r拆卸主 x / i $ eip
p / x $ esp
产生以下输出:
(gdb)启动程序:... / a.out
程序收到信号SIGSEGV,分段错误。 tmp.c:10 10处主(argc =,argv =)中的0x08048482 (gdb)函数main的汇编代码转储:
0x08048436 <+0>: lea 0x4(%esp),%ecx
0x0804843a <+4>:和$ 0xfffffff0,%esp
0x0804843d <+7>:pushl -0x4(%ecx)
0x08048440 <+10>:推送%ebp
0x08048441 <+11>:mov%esp,%ebp
0x08048443 <+13>:推送%ebx
0x08048444 <+14>:推%ecx
0x08048445 <+15>:子$ 0x40,%esp
0x08048448 <+18>:呼叫
0x8048370 <__ x86.get_pc_thunk.bx>
0x0804844d <+23>:添加$ 0x1bb3,%ebx
0x08048453 <+29>:子$ 0xc,%esp
0x08048456 <+32>:lea -0x1af0(%ebx),%eax
0x0804845c <+38>:推送%eax
0x0804845d <+39>:致电0x8048300
0x08048462 <+44>:加$ 0x10,%esp
0x08048465 <+47>:子$ 0xc,%esp
0x08048468 <+50>:lea -0x48(%ebp),%eax
0x0804846b <+53>:推送%eax
0x0804846c <+54>:致电0x8048310
0x08048471 <+59>:添加$ 0x10,%esp
0x08048474 <+62>:mov $ 0x0,%eax
0x08048479 <+67>:lea -0x8(%ebp),%esp
0x0804847c <+70>:弹出%ecx
0x0804847d <+71>:弹出%ebx
0x0804847e <+72>:弹出%ebp
0x0804847f <+73>: lea -0x4(%ecx),%esp
=> 0x08048482 <+76>:ret
汇编程序转储结束。
(gdb)=> 0x8048482:ret
(gdb)$ 1 = 0x4141413d
(gdb)退出
失败的语句是ret
末尾的main
。当ret
尝试从堆栈顶部加载返回地址时,程序失败。生成的可执行文件在对齐字边界之前将旧值esp
存储在堆栈中。 main
完成后,程序将尝试从堆栈中恢复esp
,然后读取返回地址。但是,整个堆栈的顶部被破坏了,因此呈现了堆栈指针垃圾($1 = 0x4141413d
)的新值。执行ret
时,它将尝试从地址0x4141413d中读取一个单词,该单词未分配,并产生段错误。
注释
上面的反汇编是使用以下编译器选项从问题中的代码产生的:
-m32 -fno-stack-protector -g -O0
答案 2 :(得分:1)
所以,我找到了解决方案:
只需使用gcc 3.3.4
进行编译
gcc -m32 buggy_program.c