2

我正在学习计算机安全的基础知识,并且正在尝试执行我编写的一些 shellcode。我按照这里给出的步骤

http://dl.packetstormsecurity.net/papers/shellcode/own-shellcode.pdf

http://webcache.googleusercontent.com/search?q=cache:O3uJcNhsksAJ:dl.packetstormsecurity.net/papers/shellcode/own-shellcode.pdf+own+shellcode&cd=1&hl=nl&ct=clnk&gl=nl

$ cat pause.s
xor %eax,%eax
mov $29,%al     
int $0x80       
$ as -o pause.o pause.s
$ ld -o pause pause.o
ld: warning: cannot find entry symbol _start; defaulting to <<some address here>>
$ ./pause 
^C
$ objdump -d ./pause
pause:     file format elf64-x86_64
Disassembly of section .text:
      08048054 <.text>:
      8048054: 31 c0     xor    %eax,%eax
      8048056: b0 1d     mov    $0x1d,%al
      8048058: cd 80     int    $0x8
$

由于我让暂停程序工作,我只是将 objdump 输出复制到 ac 文件。

测试.c:

int main()
{
    char s[] = "\x31\xc0\xb0\x1d\xcd\x80";
    (*(void(*)())s)();
}

但这会产生段错误。现在,这只能归因于 Arch Linux (?) 的安全措施。那么我怎样才能让它工作呢?

4

2 回答 2

7

所在的页面s未映射执行权限。由于您使用的是 x86_64,因此您肯定在硬件上支持 NX。默认情况下,这些天代码和数据位于非常独立的页面中,数据没有执行权限。

您可以使用mmap()mprotect()分配或更改页面以获取PROT_EXEC权限来解决此问题。

于 2011-09-15T14:35:26.663 回答
0

你也可以使用#define 来定义你的shellcode。这样预处理器会将代码直接插入到 main

  #define SHELLCODE "\x31\xc0\xb0\x1d\xcd\x80"
  int main()
  {
     (*(void(*)())SHELLCODE)();
  }

由于安全措施的原因,旧式的 shellcode 编写方式不适用于新系统。您可能还必须在关闭堆栈保护的情况下进行编译:

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

这是一个使用我在 3.2.0.3 内核 x86_64 上测试过的退出系统调用的完整示例:

 #include<stdio.h>

 #define SHELLCODE "\x48\xc7\xc0\x3c\x00\x00\x00\x48\xc7\xc7\xe7\x03\x00\x00\x0f\05"

  main() 
  {
  int (*function)();

   // cast shellcode as a function
   function = (int(*)())SHELLCODE;

   // execute shellcode function
   (int)(*function)();
   return 0;
   }

shellcode 使用 64 位寄存器,所以它不能在 32 位机器上工作。要验证代码是否有效,您可以使用 strace 对其进行测试:

strace shellcode
execve("./shellcode", ["shellcode"], [/* 38 vars */]) = 0
....
munmap(0x7ffff7fd5000, 144436)          = 0
_exit(999)        <---- we passed 999 to exit, our shellcode works! 
于 2013-01-26T07:04:08.040 回答