我有以下程序(在C中):
char shellcode[] = "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80";
void run_shellcode() {
int* ret;
ret = (int*)(&ret) + 2;
*ret = (int)shellcode;
}
int main() {
run_shellcode();
}
基础是这里有关网络安全的讲座的一个例子:
https://hhunetsec.de/2015/02-BufferOverflows.pdf
该计划的作用如下。 int* ret
是函数run_shellcode
的堆栈上的指针变量。从变量中获取自己的地址,添加两个(指针算术)并写入地址本身。结果地址是ret
原始地址之上的两个地址,并且是函数的返回地址。然后取消引用该变量,并且该字符串的地址将覆盖该函数的返回地址。通过这种方式,代码应该在shellcode
中执行机器代码。
我试图重现这个例子,但是因为分段错误而不断失败。字符串中的机器代码只是对退出系统调用的调用(尽管名称为" shellcode")并且在反汇编程序中看起来相当不错:
(gdb) disass /r shellcode
Dump of assembler code for function shellcode:
0x080495ec <shellcode+0>: b8 01 00 00 00 mov $0x1,%eax
0x080495f1 <shellcode+5>: bb 00 00 00 00 mov $0x0,%ebx
0x080495f6 <shellcode+10>: cd 80 int $0x80
0x080495f8 <shellcode+12>: 00 00 add %al,(%eax)
它按以下方式编译:
gcc -g -m32 -fno-stack-protector -o hello_5 hello_5.c
调试器还显示它实际跳转到shellcode
,但随后会出现分段错误。我尝试了不同的机器代码实际上工作,但在这个例子中总是失败。
我想有一些防止执行的保护机制?我在某个地方犯了错误吗?我可以以某种方式运行吗?
我不是那个讲座来自大学的学生,所以我无法在那里寻求帮助。