shellcode calls different syscall while runing alone as individiual code and while running with C++ code

烂漫一生 提交于 2019-12-11 04:48:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!