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传入并执行:
构造
/bin/sh路径与execve第一个参数MOV RAX, 0x68732f6e69622f:小端序存储/bin/sh的ASCII值(高字节补0,自动形成字符串终止符\0)CDQ:将RAX的符号位扩展到RDX,因RAX为正数,RDX被置0PUSH RAX:把/bin/sh\0压入栈PUSH RSP; POP RDI:将栈顶的/bin/sh地址存入RDI,作为execve的第一个参数(程序路径)
构造
-c参数与临时存储PUSH RDX:压入0,作为argv数组的末尾NULLPUSH 0x632d:小端序存储-c的ASCII值(高字节补0形成-c\0)PUSH RSP; POP RSI:将-c的地址存入RSI临时保存
关键:利用指令机器码作为
ls字符串PUSH RDX:再次压入0(辅助后续字符串终止逻辑)CALL FUN_0000001e:调用函数时,会将下一条指令(INSB的地址)压入栈——这个地址就是ls字符串的来源:INSB的机器码是0x6c,对应ASCII字符'l'- 下一条
JNC的机器码是0x73,对应ASCII字符's' - 这两个字节刚好组成字符串
"ls"
构造完整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存入RAXSYSCALL:执行execve系统调用,启动/bin/sh -c ls
后续指令无影响的原因
execve系统调用成功后,当前进程的代码段会被替换为/bin/sh的代码,后续的INSB和JNC指令根本不会被执行,完全不影响ls命令的执行。
内容的提问来源于stack exchange,提问作者Ricket
相关产品推荐
相关产品推荐

