生成简单的shell二进制代码以复制到堆栈以进行堆栈溢出

时间:2015-03-29 05:42:08

标签: c assembly stack-overflow instructions

我正在尝试实现缓冲区溢出攻击,但是我需要生成二进制的指令代码,这样我就可以将它放在堆栈中来执行。我的问题是,我现在得到的指令已跳转到程序的不同部分,这些部分很难放入堆栈。所以我有这段简单的代码(不是要被利用的代码),我想把它放在堆栈上来产生一个新的shell。

#include <stdio.h>

int main( ) {
        char *buf[2];
        buf[0] = "/bin/bash";
        buf[1] = NULL;
        execve(buf[0], buf, NULL);
}

使用带有以下标志的gcc编译代码:

CFLAGS = -Wall -Wextra -g -fno-stack-protector -m32 -z execstack
LDFLAGS = -fno-stack-protector -m32 -z execstack

最后使用objdump -d -S,我得到以下代码(部分内容)的十六进制:

....
....
08048320 <execve@plt>:
 8048320:       ff 25 08 a0 04 08       jmp    *0x804a008
 8048326:       68 10 00 00 00          push   $0x10
 804832b:       e9 c0 ff ff ff          jmp    80482f0 <_init+0x3c>
....
....
int main( ) {
 80483e4:       55                      push   %ebp
 80483e5:       89 e5                   mov    %esp,%ebp
 80483e7:       83 e4 f0                and    $0xfffffff0,%esp
 80483ea:       83 ec 20                sub    $0x20,%esp
        char *buf[2];
        buf[0] = "/bin/bash";
 80483ed:       c7 44 24 18 f0 84 04    movl   $0x80484f0,0x18(%esp)
 80483f4:       08 
        buf[1] = NULL;
 80483f5:       c7 44 24 1c 00 00 00    movl   $0x0,0x1c(%esp)
 80483fc:       00 
        execve(buf[0], buf, NULL);
 80483fd:       8b 44 24 18             mov    0x18(%esp),%eax
 8048401:       c7 44 24 08 00 00 00    movl   $0x0,0x8(%esp)
 8048408:       00 
 8048409:       8d 54 24 18             lea    0x18(%esp),%edx
 804840d:       89 54 24 04             mov    %edx,0x4(%esp)
 8048411:       89 04 24                mov    %eax,(%esp)
 8048414:       e8 07 ff ff ff          call   8048320 <execve@plt>
}
 8048419:       c9                      leave  
 804841a:       c3                      ret    
 804841b:       90                      nop

正如您所看到的,此代码很难复制到堆栈中。 execve跳转到要执行的汇编代码的不同部分。有没有办法很好地获得一个程序,可以在没有太多空间和分支使用的情况下紧凑地放在堆栈上?

2 个答案:

答案 0 :(得分:1)

如果您想要一个干净的汇编代码而无需自己编码,请执行以下操作:

  1. 将您的代码移至单独的功能
  2. 将-O0编译标志传递给gcc以防止优化
  3. 仅编译目标文件 - 使用gcc [input file] -o [output file]
  4. 按照以下步骤操作,并使用objdump生成的汇编代码 请记住,你有execve的外部依赖:
    8048414: e8 07 ff ff ff call 8048320 <execve@plt>
     因此,您必须显式包含其实现并删除调用,或者事先知道要攻击的进程在其地址空间中具有此功能,并修改调用地址以匹配进程执行地址。

答案 1 :(得分:0)

欢迎使用 Stack Overflow (双关语)。

这是一个不寻常的请求。你想被国家安全局雇用吗?

显然,编译器不会以非常友好的形式构建汇编代码。他们的优化思路可能是性能而不是紧凑性。因此,您可以考虑使用汇编程序对其进行手工编码,使用编译器输出作为指导来实现您的目标。

您所拥有的内容可能无法最好地代表编译器在任何情况下都可以通知您的调查。将代码放入main之外的函数中,这样您就可以获得必要的最小堆栈设置和参数处理,并尝试使用所有不同的优化级别对其进行编译,以查看它的作用。

可能获得一些额外的设置开销,因为它是你的程序的主要入口点,并且必须与libc和操作系统接口(只是猜测),并且可能正在为程序的操作上下文进行设置(对于您插入代码的任何可执行文件,您可以假设已经完成了这样做,因此它将是多余的)。