我有这样一段运行 shell 的代码:
BITS 64
global _start
_start:
mov rax, 59
jmp short file
c1:
pop rdi
jmp short argv
c2:
pop rsi
mov rdx, 0
syscall
file:
call c1
db '/bin/sh',0
argv:
call c2
dq arg, 0
arg:
db 'sh',0
以这种方式构建时,它会起作用:
nasm -f elf64 shcode.asm
ld shcode.o -o shcode
虽然,当我将其转换为二进制形式时:
nasm -f bin shcode.asm
将其粘贴到以下 C++ 代码中:
int main(void)
{
char kod[]="\xB8\x3B\x00\x00\x00\xEB\x0B\x5F\xEB\x15\x5E\xBA\x00\x00\x00\x00\x0F\x05\xE8\xF0\xFF\xFF\xFF\x2F\x62\x69\x6E\x2F\x73\x68\x00\xE8\xE6\xFF\xFF\xFF\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x73\x68\x00";
reinterpret_cast<void(*)()>(kod)();
return 0;
}
使用 clang++ texp.cpp -o texp.e -Wl,-z,execstack 并执行,shell 没有运行。
运行之后
strace ./texp.e
我看到了类似的东西(我用 ^C 停止了这个过程):
syscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960) = -1 ENOSYS (Nie zaimplementowana funkcja)
syscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960) = -1 ENOSYS (Nie zaimplementowana funkcja)
.
.
.
syscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960) = -1 ENOSYS (Nie zaimplementowana funkcja)
^Csyscall_0xffffffffffffffda(0x7ffc23e0a297, 0x7ffc23e0a2a4, 0, 0x4a0, 0x7fe1ff3039b0, 0x7fe1ff69b960strace: Process 2806 detached
<detached ...>
Nie zaimplementowana funkcja - 功能未实现
所以程序(又名 shellcode)可能正在运行不正确的系统调用。
最佳答案
在您的 C++ shellcode 调用程序中,strace
显示您的 execve
系统调用是
execve("/bin/sh", [0x34], NULL) = -1 EFAULT (Bad address)
后面的 syscall_0xffffffffffffffda(...) = -1 ENOSYS
来自无限循环 RAX = -EFAULT
而不是 59,然后来自 RAX =- ENOSYS
(同样不是有效的电话号码)。此循环由您的 call/pop
创建。
可能是因为您从未链接的 .o
或 PIE 可执行文件中 hexdump 了 arg
的绝对地址,这就是您如何获得 0x34
作为绝对地址。
显然,如果要从随机堆栈地址运行且没有重定位修复,那么在 shellcode 中嵌入绝对地址的整个方法将不起作用。 dq arg, 0
与位置无关。
您至少需要使用指针自己构造argv
数组(通常使用push
)。您还可以使用 push imm32
来构造 arg
本身。例如push 'shsh'
/lea rax, [rsp+2]
.
或者最常见的技巧是利用 Linux 特定的“功能”:您可以使用 xor esi 传递
.argv=NULL
(而不是指向 NULL 指针的指针) ,esi
(使用 mov reg,0
完全违背了 jmp/call/pop 技巧避免零字节的目的。如果允许零字节,您还不如使用普通的 RIP 相关 LEA . 但如果没有,您可以向前跳过数据,然后使用具有负位移的 RIP 相关 LEA。)
关于c++ - shellcode 在单独运行时调用不同的系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57285839/