首页 > 解决方案 > 这个 shellcode 中使用的堆栈指针是什么?

问题描述

https://www.exploit-db.com/exploits/46907

global _start
section .text
_start:
    xor rsi,rsi
    push rsi
    mov rdi,0x68732f2f6e69622f
    push rdi
    push rsp
    pop rdi
    push 59
    pop rax
    cdq
    syscall

一条指令是push %rsp,然后将其弹出rdi。我很困惑。根据文档,rdi系统execve调用中应该包含可执行文件的路径名。和这里有什么关系rsp?其他 shellcode 不会操纵rsp.

标签: assemblyx86-64nasmshellcode

解决方案


在堆栈上构造数据,然后将堆栈指针复制到另一个 reg,是完全正常的。许多 shellcode 操纵 RSP。

push rsp/pop rdi只是 2 字节的版本mov rdi, rsp,它是在推送 0 和 8 字节的 ASCII 数据之后出现的。(在 NASM 语法中可以更清楚地写为mov rdi, '/bin//sh')。

使用调试器单步执行 asm,并在执行时查看 RDI 指向的内存syscall,然后向后工作以了解您是如何到达那里的。


奇怪的是,他们mov rdi,rsp使用 push/pop 将其缩小到 2 个字节,但在 xor-zeroing 指令上使用了 REX 前缀。 xor esi,esi是等价的。NASM 会将该源优化为xor esi,esi.,但您的链接显示了反汇编。

此外,push 59/pop rax是在寄存器中构造小常量( ) 的标准 3 字节方式,__NR_execve而不依赖于任何其他寄存器值。他们本可以做到lea eax, [rsi+59]这也是 3 个字节,也可以避免任何0字节。(5 字节mov eax, 59将包括一个带有三个零字节的 imm32,这就是为什么大多数 shellcode 必须避免它。)

cdq只需设置 RDX=0 ( envp=NULL),因为此时 EAX 为正数。另一种节省字节与xor edx,edx. 在这种情况下,他们显然知道在编写 32 位 reg (EDX) 时要利用完整 64 位 reg 的隐式归零,所以更奇怪的是,他们对 RSI 使用了 64 位异或归零。也许他们对 x86-64 了解不多,甚至没有意识到它cqo会显式使用 64 位操作数大小,将 RAX 符号扩展为 RDX:RAX,并打算在任何地方都使用 64 位,因为他们认为需要。


推荐阅读