我一直试图运行Aleph One的示例以获得BOF并打开shell。
这是Aleph One论文:http://insecure.org/stf/smashstack.html
这是简单的C代码(几乎位于论文的一半):
char shellcode[] =
"\xeb\x2a\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00"
"\x00\xb8\x0b\x00\x00\x00\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80"
"\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xe8\xd1\xff\xff"
"\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x89\xec\x5d\xc3";
void main() {
int *ret;
ret = (int *)&ret + 2;
(*ret) = (int)shellcode;
}
现在,我尝试在SSH bash中运行此程序,但没有成功。
由于运行后没有任何反应,我猜测我只是没有写回程地址,所以我使用GDB来查看ret变量和实际返回地址之间的偏移量,并意识到它是7。
为了检查自己,我尝试在3,4,5,6中增加ret,事实上,只有当我将第10行更改为:
ret = (int *)&ret + 7;
我遇到了分段错误。
然而,我不明白为什么没有打开bash而我得到了这个错误。
P.S我正在使用'logic smashthestack'SSH服务器(其中一个挑战是BOF):http://logic.smashthestack.org:88/
感谢帮助者。
答案 0 :(得分:5)
来自http://blog.markloiseau.com/2012/06/64-bit-linux-shellcode/:
此存根是经典shellcode测试存根的更新版本,只有一个关键区别:在新存根中,shellcode在编译时是#defined,因此可以通过gcc的预处理器直接放入主程序中。
这是必要的,因为随着时间的推移,Linux和GCC对可执行文件的哪些部分可以包含可执行代码(与非可执行变量相对)变得更加谨慎。传统版本的程序不适用于较新版本的Linux:
经典的shellcode c stub将在较新的系统上生成段错误 因为shellcode []字符数组存储在显式中 ELF文件的不可执行的.rodata部分。当电脑 将非可执行数组重新编译为函数并尝试运行它, 程序崩溃
。 还要注意编写shellcode的这些更改:
//old way
char[] shellcode ="shellcode..."
//new way
#define SHELLCODE "shellcode
答案 1 :(得分:1)
问题在于shellcode。 shellcode是一个const字符串,因此您无法修改它。如果你看看shellcode的反汇编,那么你可以看到代码试图修改字符串。
您可以尝试分配内存并在那里分配shellcode。可能仍然无法工作,具体取决于操作系统,因为您可能需要修改保护设置以允许在分配的memorxy块中运行代码。
自我修改的原因是执行shell的动作最后需要一个0字节,但这不能包含在字符串中,因此代码必须先修补它才能执行shell。这就是SIGSEGV的原因。
您的问题几乎与此问题相同:Assembly Code keep showing segment fault
shellcode基本相同。不完全,但遵循相同的原则。
<强>更新强>
为了更好地解释这一点,如果BSS段是可写的,该漏洞将起作用。根据C标准,const声明这样的字符串。写入静态字符串是未定义的行为,因此它可以工作或不工作。