将字符串转换为函数

时间:2015-08-08 15:36:43

标签: c++ c shellcode

我正在尝试学习从程序中执行shellcode,但我无法获得最基本的代码来运行。以下代码只是在运行时退出终端:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/mman.h>

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80";

int main() {
    int (*func)();
    func = (int (*)())exitcode;
    (int)(*func)();
    return 0;
}

但我得到的只是一个段错误。 GDB说当程序访问exitcode [at(int)(* func)()的内存位置时会发生这种情况。 ],但我不确定为什么这会导致问题。我正在运行64位Linux Mint操作系统。非常感谢任何帮助。

4 个答案:

答案 0 :(得分:6)

现代操作系统使用内存保护。内存页面具有访问权限,就像文件一样:可读,可写,可执行。您的程序的数据段通常位于非可执行页面中,尝试执行它会导致段错误。

如果您想在linux上的程序中执行动态编写的二进制代码,首先必须使用可以写入的mmap()映射页面,然后将代码放在那里,然后将其更改为只读,可执行使用mprotect()。然后你可以跳到那里。

您可以举例说明read this article

编辑:如果这是关于安全漏洞,请注意,现在堆栈通常也是不可执行的......所以这些旧的“黑客教程”将不再起作用。如果您对新技术感兴趣,请阅读面向返回编程

答案 1 :(得分:4)

代码必须标记为可执行代码。一种方法是将这个二进制机器代码复制到可执行缓冲区中。

#include <unistd.h>
#include <sys/mman.h>
#include <string.h>

char exitcode[] = "\xb0\x01\x31\xdb\xcd\x80";

int main(int argc, char **argv)
{   
    void *buf;

  /* copy code to executable buffer */    
  buf = mmap (0,sizeof(exitcode),PROT_READ|PROT_WRITE|PROT_EXEC,
              MAP_PRIVATE|MAP_ANON,-1,0);
  memcpy (buf, exitcode, sizeof(code));

  /* run code */
  int i = ((int (*) (void))buf)();
  printf("OK. returned: %d", i);
return 0;
}

答案 2 :(得分:0)

您的shellcode是:

mov    $0x1,%al
xor    %ebx,%ebx
int    $0x80

有两个问题:

  1. Syscall 0x1是64位的sys_write(但在32位上是sys_exit)
  2. 您应该分配给%rax,而不是%al。 %rax将包含高位残留物。

答案 3 :(得分:0)

我遇到了这个问题并经常搜索以解决它。

您必须使用此代码编译C代码(禁用堆栈保护并使其可执行):

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

在Kali 32/64位测试。不再是段错误了。

祝你好运