msfvenom shellcode 实际上是如何工作的

问题描述 投票:0回答:1
MOV    RAX, 0x68732f6e69622f
CDQ
PUSH   RAX
PUSH   RSP
POP    RDI
PUSH   RDX
PUSH   0x632d
PUSH   RSP
POP    RSI
PUSH   RDX
CALL   FUN_0000001e
INSB   RDI, DX
JNC    FUN_0000001e

FUN_0000001e:
PUSH   RSI
PUSH   RDI
PUSH   RSP
POP    RSI
PUSH   0x3b
POP    RAX
SYSCALL

这些是 msfvenom 有效负载的汇编指令:

msfvenom -p linux/x64/exec CMD='ls'

我了解 execve 系统调用是如何准备的,以及 /bin/sh -c 作为参数传递的。但是这段代码是如何执行 ls 命令的呢?

我尝试使用 c 函数指针执行此 shellcode,它按预期执行了 ls。

linux assembly x86-64 reverse-engineering shellcode
1个回答
1
投票

在调试器中单步执行并观察堆栈上的值变化。

0x68732f6e69622f
/bin/sh

push rsp
/
pop rdi
是一种 2 字节的方式来实现
mov rdi, rsp

insb
/
jnc
实际上并没有运行,这些只是数据。
insb
的机器码就是
0x6c
;这是一个“字符串”指令,隐式使用
[rdi]
后递增。我不知道这是什么 asm 语法,但它不是 NASM。为了让 NASM 组装它,我只是删除了操作数,所以它很简单
insb

如果你组装它并查看机器代码,你可以看到字节:

...
  401017:       e8 03 00 00 00          call   40101f <FUN_0000001e>
  40101c:       6c                      ins    BYTE PTR es:[rdi],dx
  40101d:       73 00                   jae    40101f <FUN_0000001e>

000000000040101f <FUN_0000001e>:
  40101f:       56                      push   rsi
 ...

ASCII

63 73 00
"ls"
以零结尾。这就是
call
推送地址的字符串。

普通人会将其写为

db 0x6c, 0x73, 0
db "ls", 0
,而不是将这些字节“分解”为指令助记符。


请注意,此“shellcode”并非不受

0
字节的影响:前向
call
将在
rel32
的高 3 个字节中包含零(推送的“返回”地址是 ASCII 字节的地址)跟着它)。此外,
push 0x632d
是符号扩展 imm32 的 qword 推送,其高 2 个字节为 0,因为没有
push word
大小覆盖。

并且 rel8=0 的

jae
当然有一个零字节。

© www.soinside.com 2019 - 2024. All rights reserved.