assembly - 我如何解释以下 shellcode 漏洞利用的行为?

标签 assembly x86 buffer-overflow exploit shellcode

这是一个利用缓冲区溢出漏洞的shellcode。它设置了 setuid(0)并使用 execve() 生成一个 shell .以下是我解释它的方式:

xor    %ebx,%ebx       ; Xoring to make ebx value 0
lea    0x17(%ebx),%eax ; adds 23 to 0 and loads effective addr to eax. for setuid()
int    $0x80           ; interrupt
push   %ebx            ; push ebx
push   $0x68732f6e     ; push address // why this address only????
push   $0x69622f2f     ; push address // same question
mov    %esp,%ebx
push   %eax
push   %ebx
mov    %esp,%ecx
cltd                   ; mov execve sys call into al
mov    $0xb,%al
int    $0x80           ; interrupt

任何人都可以清楚地解释整个步骤吗?

最佳答案

int是触发软件中断的操作码。软件中断被编号(从 0 到 255)并由内核处理。在 Linux 系统上,中断 128 (0x80) 是系统调用的常规入口点。内核需要寄存器中的系统调用参数;特别是 %eax 寄存器标识了我们正在谈论的系统调用。

  • 将 %ebx 设置为 0
  • 计算 %ebx+23 并将结果存储在 %eax 中(操作码是 lea 作为“加载有效地址”但不涉及内存访问;这只是进行加法的一种迂回方式)。
  • 系统调用。 %eax 包含 23,表示系统调用是 setuid .该系统调用使用一个参数(目标 UID),可以在 %ebx 中找到,在那个点它很方便地包含 0(它在第一条指令中设置)。注意:返回时,寄存器不会被修改,除了 %eax 包含系统调用的返回值,通常为 0(如果调用成功)。
  • 将 %ebx 压入堆栈(仍为 0)。
  • 将 $0x68732f6e 压入堆栈。
  • 将 $0x69622f2f 压入堆栈。由于堆栈“向下”增长并且 x86 处理器使用小端编码,因此指令 4 到 6 的效果是 %esp(堆栈指针)现在指向 12 个字节的序列,值为 2f 2f 62 69 6e 2f 73 68 00 00 00 00(十六进制)。这就是“//bin/sh”字符串的编码(有一个终止零,后面还有三个额外的零)。
  • 将 %esp 移动到 %ebx。现在 %ebx 包含一个指向上面构建的“//bin/sh”字符串的指针。
  • 将 %eax 压入堆栈(此时 %eax 为 0,这是从 setuid 返回的状态)。
  • 将 %ebx 压入堆栈(指向“//bin/sh”的指针)。指令 8 和 9 在堆栈上构建了一个由两个指针组成的数组,第一个是指向“//bin/sh”的指针,第二个是 NULL 指针。那个数组就是 execve系统调用将用作第二个参数。
  • 将 %esp 移动到 %ecx。现在 %ecx 指向使用指令 8 和 9 构建的数组。
  • 将 %eax 符号扩展为 %edx:%eax。 cltd是英特尔文档所称的 AT&T 语法 cdq .由于 %eax 在这一点上为零,这也将 %edx 设置为零。
  • 将 %al(%eax 的最低有效字节)设置为 11。由于 %eax 为零,因此 %eax 的整个值现在是 11。
  • 系统调用。 %eax (11) 的值将系统调用标识为 execve . execve期望三个参数,在 %ebx(指向命名要执行的文件的字符串的指针)、%ecx(指向字符串指针数组的指针,这些指针是程序参数,第一个是程序名称的副本)被调用的程序本身使用)和 %edx(指向字符串指针数组的指针,它们是环境变量;对于空环境,Linux 允许该值为 NULL)。

  • 所以代码首先调用setuid(0) ,然后调用 execve("//bin/sh", x, 0)哪里x指向一个由两个指针组成的数组,第一个是指向“//bin/sh”的指针,而另一个是NULL。

    这段代码非常复杂,因为它想要避免零:当组装成二进制操作码时,指令序列仅使用非零字节。例如,如果第 12 条指令是 movl $0xb,%eax (将整个 %eax 设置为 11),那么该操作码的二进制表示将包含三个值为 0 的字节。缺少零使得该序列可用作以零结尾的 C 字符串的内容。这当然是为了通过缓冲区溢出来攻击有缺陷的程序。

    关于assembly - 我如何解释以下 shellcode 漏洞利用的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4126599/

    相关文章:

    c - 请更正缓冲区溢出

    python - 如何使用标准 Linux 工具修复死锁脚本?

    c++ - C++ 中的怪异性能(VC 2010)

    assembly - 在长模式下使用 64/32 位寄存器是否会受到任何惩罚?

    c++ - 写入 [ds :0x0]? 后添加 ud2 有什么意义

    c - 有助于理解 C 和 C++ 中#define、const 和 enum 在汇编级别上的差异

    c++ - 分配给 int 类型缓冲区的大内存大小

    assembly - MIPS 指令 J 格式

    c - 获取函数的地址

    x86调用栈保存一个字节