Search code examples
cgccassemblynasmshellcode

Injected 64 bit shellcode wont execute syscall


I am currently trying to inject code that will print helloworld into a vulnerable program. I have succeeded in injecting the code by storing it in one of the environment variables and overwriting the rip register to point to that code. Here is my assembly and op codes:

 0000000000000000 <_start>:
   0:   eb 17                   jmp    19 <stack_setup>

0000000000000002 <execute>:
   2:   48 31 c0                xor    %rax,%rax
   5:   b0 01                   mov    $0x1,%al
   7:   48 31 ff                xor    %rdi,%rdi
   a:   48 ff c7                inc    %rdi
   d:   5e                      pop    %rsi
   e:   b2 0f                   mov    $0xf,%dl
  10:   0f 05                   syscall 
  12:   b0 3c                   mov    $0x3c,%al
  14:   48 ff cf                dec    %rdi
  17:   0f 05                   syscall 

0000000000000019 <stack_setup>:
  19:   e8 e4 ff ff ff          callq  2 <execute>
  1e:   48                      rex.W
  1f:   65                      gs
  20:   6c                      insb   (%dx),%es:(%rdi)
  21:   6c                      insb   (%dx),%es:(%rdi)
  22:   6f                      outsl  %ds:(%rsi),(%dx)
  23:   2c 20                   sub    $0x20,%al
  25:   77 6f                   ja     96 <stack_setup+0x7d>
  27:   72 6c                   jb     95 <stack_setup+0x7c>
  29:   64 21 0a                and    %ecx,%fs:(%rdx)
  2c:   0d                      .byte 0xd

The opcodes after line 19 are for the instruction db "Hello, world!", 0x0a, 0x0d. After examining the execution of the instructions in lines x2-x10 with gdb, I have noticed that it properly prepared the arguments to print the string Hello, World. However, upon executing the syscall statement, nothing happens. Same is to be said for the instructions from line x12 - x17.

I have also tried to compile and link the assembly code to execute it independently and it works properly. In addition to that, I have compiled the vulnerable program with the options

  -fno-stack-protector -z execstack

So that I can run code located in the stack. I have also disabled randomizing_va_space. I want to ask if there is something I did not do to allow me to successfully execute the code I injected?


Solution

  • The reason might be that the write syscall returns an error code. It could be for many reasons, but maybe rdx is not all zeros, so you should xor %rdx, %rdx before loading 15 there (actually you should load 14 only, for "Hello, World!\n").

    Anyway, the error from write would be returned in rax, and be a negative number (-errno), thus when you do

    mov    $0x3c,%al
    dec    %rdi
    syscall 
    

    That will be an invalid syscall, and errno 38 for ENOSYS will be returned.

    The exit I got to work anyway by doing

    xor    %rax, %rax 
    mov    $0x3c,%al
    syscall
    

    I recommend that you run the program with strace and see from its output why exactly the write is failing.


    Here's a version of shell code that works for me:

    0000000000000000 <main>:
       0:   eb 1d                   jmp    1f <stack_setup>
    
    0000000000000002 <execute>:
       2:   48 31 c0                xor    %rax,%rax
       5:   b0 01                   mov    $0x1,%al
       7:   48 31 ff                xor    %rdi,%rdi
       a:   48 ff c7                inc    %rdi
       d:   5e                      pop    %rsi
       e:   48 31 d2                xor    %rdx,%rdx
      11:   b2 0e                   mov    $0xe,%dl
      13:   0f 05                   syscall 
      15:   48 31 c0                xor    %rax,%rax
      18:   b0 3c                   mov    $0x3c,%al
      1a:   48 ff cf                dec    %rdi
      1d:   0f 05                   syscall 
    
    000000000000001f <stack_setup>:
      1f:   e8 de ff ff ff          callq  2 <execute>
      24:   48                      rex.W
      25:   65 6c                   gs insb (%dx),%es:(%rdi)
      27:   6c                      insb   (%dx),%es:(%rdi)
      28:   6f                      outsl  %ds:(%rsi),(%dx)
      29:   2c 20                   sub    $0x20,%al
      2b:   57                      push   %rdi
      2c:   6f                      outsl  %ds:(%rsi),(%dx)
      2d:   72 6c                   jb     9b <stack_setup+0x7c>
      2f:   64 21 0a                and    %ecx,%fs:(%rdx)