问题
I've such a code that run's 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
It works when it's built in this way:
nasm -f elf64 shcode.asm
ld shcode.o -o shcode
Althougt, when I bring it into binary form with:
nasm -f bin shcode.asm
paste it into following C++ code:
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;
}
make it with clang++ texp.cpp -o texp.e -Wl,-z,execstack and execute, shell isn't running.
After running it with
strace ./texp.e
I see something like this (I stopped this process with ^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 - Function not implemented
So the program ( aka shellcode ) is propably running improper syscall.
回答1:
In your C++ shellcode caller, strace
shows your execve
system call was
execve("/bin/sh", [0x34], NULL) = -1 EFAULT (Bad address)
The later syscall_0xffffffffffffffda(...) = -1 ENOSYS
are from an infinite loop with RAX = -EFAULT
instead of 59, and then from RAX=- ENOSYS
(again not a valid call number). This loop is created by your call/pop
.
Presumably because you hexdumped an absolute address for arg
from an unlinked .o
or from a PIE executable, which is how you got 0x34
as the absolute address.
Obviously the whole approach of embedding an absolute address in your shellcode doesn't work if it's going to run from a randomized stack address, with no relocation fixup. dq arg, 0
is not position-independent.
You need to construct at least the argv
array yourself (usually with push
) using pointers. You could also use a push imm32
to construct arg
itself. e.g. push 'shsh'
/ lea rax, [rsp+2]
.
Or the most common trick is to take advantage of a Linux-specific "feature": you can pass argv=NULL
(instead of a pointer to a NULL pointer) with xor esi,esi
.
(Using mov reg,0
completely defeats the purpose of the jmp/call/pop trick for avoiding zero bytes. You might as well just use a normal RIP-relative LEA if zero bytes are allowed. But if not, you can jump forward over data then use RIP-relative LEA with a negative displacement.)
来源:https://stackoverflow.com/questions/57285839/shellcode-calls-different-syscall-while-runing-alone-as-individiual-code-and-whi