执行Shellcode的函数指针

时间:2011-12-13 11:16:00

标签: c security stack-overflow buffer-overflow shellcode

我正在尝试通过覆盖main的返回地址来执行exit(0)调用的这个简单操作码。 问题是我遇到了分段错误。

#include <stdio.h>

char shellcode[]= "/0xbb/0x14/0x00/0x00/0x00"
                  "/0xb8/0x01/0x00/0x00/0x00"
                  "/0xcd/0x80";

void main()
{
      int *ret;

      ret = (int *)&ret + 2; // +2 to get to the return address on the stack

      (*ret) = (int)shellcode;   

}

分段错误中的执行结果。

[user1@fedo BOF]$ gcc -o ExitShellCode ExitShellCode.c

[user1@fedo BOF]$ ./ExitShellCode

Segmentation fault (core dumped)

这是shellcode.a的Objdump

[user1@fedo BOF]$ objdump -d exitShellcodeaAss

exitShellcodeaAss:     file format elf32-i386


Disassembly of section .text:

08048054 <_start>:
 8048054:       bb 14 00 00 00          mov    $0x14,%ebx
 8048059:       b8 01 00 00 00          mov    $0x1,%eax
 804805e:       cd 80                   int    $0x80

系统我正在使用

fedora Linux 3.1.2-1.fc16.i686 
ASLR is disabled.
Debugging with GDB.
gcc version 4.6.2

5 个答案:

答案 0 :(得分:2)

mmm也许是回答这个问题的时间要晚,但它们可能是被动语法错误。似乎shellcode格式不正确,我的意思是:

char shellcode[]= "/0xbb/0x14/0x00/0x00/0x00"
                  "/0xb8/0x01/0x00/0x00/0x00"
                  "/0xcd/0x80";

它不一样:

char shellcode[]= "\xbb\x14\x00\x00\x00"
                  "\xb8\x01\x00\x00\x00"
                  "\xcd\x80";

虽然此修复程序无法帮助您解决此问题,但您是否尝试过禁用某些内核保护机制,例如: NX位堆栈随机化等... ?

答案 1 :(得分:0)

根据另外两个问题,即How to determine return address on stack?C: return address of function (mac),我确信您没有覆盖正确的地址。这主要是由于您的假设,返回地址可以按照您的方式确定。但正如第一个问题(1)所述的答案所述,情况并非如此。

因此:

  1. 检查地址是否真的正确
  2. 如果您不想使用内置GCC功能,请找到确定正确返回地址的方法

答案 2 :(得分:0)

您也可以通过将缓冲区转换为类似

的函数来执行此方案中的shellcode
(*(int(*)()) shellcode)();

答案 3 :(得分:0)

如果你想在堆栈中执行shellcode,你必须在没有NX(堆栈保护器)和正确权限的情况下进行编译。

gcc -fno-stack-protector -z execstack shellcode.c -o shellcode

E.g。

#include <stdio.h>
#include <string.h>

const char code[] ="\xbb\x14\x00\x00\x00"
              "\xb8\x01\x00\x00\x00"
              "\xcd\x80";


int main()
{
    printf("Length: %d bytes\n", strlen(code));
    (*(void(*)()) code)();
    return 0;
}

如果你想用gdb调试它:

[manu@debian /tmp]$ gdb ./shellcode 
GNU gdb (Debian 7.7.1+dfsg-5) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
...
Reading symbols from ./shellcode...(no debugging symbols found)...done.
(gdb) b *&code
Breakpoint 1 at 0x4005c4
(gdb) r
Starting program: /tmp/shellcode 
Length: 2 bytes

Breakpoint 1, 0x00000000004005c4 in code ()
(gdb) disassemble 
Dump of assembler code for function code:
=> 0x00000000004005c4 <+0>: mov    $0x14,%ebx
   0x00000000004005c9 <+5>: mov    $0x1,%eax
   0x00000000004005ce <+10>:    int    $0x80
   0x00000000004005d0 <+12>:    add    %cl,0x6e(%rbp,%riz,2) 
End of assembler dump.

在这个概念证明中,空字节并不重要。但是当你开发shellcode时,你应该记住并删除坏字符。

答案 4 :(得分:-1)

Shellcode上不能有零。删除空字符。