You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

msfvenom生成的execve shellcode如何执行sh -c ls命令?

解析msfvenom linux/x64/exec payload执行ls的原理

该payload由命令 msfvenom -p linux/x64/exec CMD='ls' 生成,对应的汇编代码如下:

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

核心执行逻辑拆解

你已经了解execve系统调用和/bin/sh -c的参数逻辑,这里重点讲这段汇编如何把ls传入并执行:

  1. 构造/bin/sh路径与execve第一个参数

    • MOV RAX, 0x68732f6e69622f:小端序存储/bin/sh的ASCII值(高字节补0,自动形成字符串终止符\0)
    • CDQ:将RAX的符号位扩展到RDX,因RAX为正数,RDX被置0
    • PUSH RAX:把/bin/sh\0压入栈
    • PUSH RSP; POP RDI:将栈顶的/bin/sh地址存入RDI,作为execve的第一个参数(程序路径)
  2. 构造-c参数与临时存储

    • PUSH RDX:压入0,作为argv数组的末尾NULL
    • PUSH 0x632d:小端序存储-c的ASCII值(高字节补0形成-c\0)
    • PUSH RSP; POP RSI:将-c的地址存入RSI临时保存
  3. 关键:利用指令机器码作为ls字符串

    • PUSH RDX:再次压入0(辅助后续字符串终止逻辑)
    • CALL FUN_0000001e:调用函数时,会将下一条指令(INSB的地址)压入栈——这个地址就是ls字符串的来源:
      • INSB的机器码是0x6c,对应ASCII字符'l'
      • 下一条JNC的机器码是0x73,对应ASCII字符's'
      • 这两个字节刚好组成字符串"ls"
  4. 构造完整argv数组并执行execve
    进入FUN_0000001e后:

    • PUSH RSI; PUSH RDI:将-c的地址、/bin/sh的地址依次压栈
    • PUSH RSP; POP RSI:将当前栈顶地址存入RSI,此时RSI指向的栈结构就是完整的argv数组:["/bin/sh", "-c", 0x6c73指令的地址, NULL]
    • PUSH 0x3b; POP RAX:将execve的系统调用号0x3b存入RAX
    • SYSCALL:执行execve系统调用,启动/bin/sh -c ls
  5. 后续指令无影响的原因
    execve系统调用成功后,当前进程的代码段会被替换为/bin/sh的代码,后续的INSB和JNC指令根本不会被执行,完全不影响ls命令的执行。

内容的提问来源于stack exchange,提问作者Ricket

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 02:49:52