Linux 针对执行 shellcode 的安全措施

发布于 2024-12-05 01:43:19 字数 1070 浏览 1 评论 0原文

我正在学习计算机安全的基础知识,并尝试执行我编写的一些 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 文件中。

test.c:

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

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

I'm learning the basics of computer security and I'm trying to execute some shellcode I've written. I followed the steps given here

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
$

Since I got my pause program to work, I just copied the objdump output to a c file.

test.c:

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

But this produces a segfault. Now, this can only be due to security measures of Arch Linux (?). So how can I get this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

装迷糊 2024-12-12 01:43:19

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

您可以使用 mmap()mprotect() 分配或更改页面以具有 PROT_EXEC< /代码> 权限。

The page s lives in isn't mapped with execute permissions. Since you're on x86_64 you definitely have NX support in hardware. By default these days code and data live in very separate pages, with data not having the execute permission.

You can work around this with either mmap() or mprotect() to allocate or alter pages to have the PROT_EXEC permission.

微凉徒眸意 2024-12-12 01:43:19

您还可以使用 #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! 

You can also use a #define to define your shellcode. This way the pre-processor will insert the code directly into main

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

The older style of writing shellcode doesn't work on newer systems because of security measures.
You will also probably have to compile with stack protection turned off:

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

Here is a fully working example that uses exit system call that I've tested on 3.2.0.3 kernel 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;
   }

The shellcode is using 64 bit registers, so it won't work on 32bit machine.
To verify that the code works, you can test it with strace:

strace shellcode
execve("./shellcode", ["shellcode"], [/* 38 vars */]) = 0
....
munmap(0x7ffff7fd5000, 144436)          = 0
_exit(999)        <---- we passed 999 to exit, our shellcode works! 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文