cnasmsystem-callsexecvestack-smash

exceve syscall is not working via payload


I am writing basic payload for execve syscall. In nasm the payload is:

global _start
  2 section .text
  3    _start:
  4     call payload
  5     db '/bin/sh', 0, 'aaaaaaaa', 0
  6     payload:
  7       mov rax,rsp
  8       mov rax, [rax]
  9       ;mov BYTE  [rax + 0x9], 0x0
 10       mov QWORD  [rax + 0x0a], rax
 11       ;mov BYTE  [rax + 0x12], 0x0
 12       ;mov QWORD  [rax + 0x13], 0x0
 13     mov rdi, rax
 14     lea rsi, [rax + 0x0a]
 15     mov rdx, 0x0
 16     mov rax, 0x0b
 17     int 0x80
 18     mov rax, 0x01
 19     mov rbx, 0x21
 20     int 0x80

The C file is:

char payload[] = "\xe8\x11\x00\x00\x00"
  2                 "\x2f\x62\x69\x6e\x2f\x73\x68\x00"
  3                 "\x61\x61\x61\x61\x61\x61\x61\x61\x00"
  4                 "\x48\x89\xe0"
  5                 "\x48\x8b\x00"
  6                 "\x48\x89\x40\x0a"
  7                 "\x48\x89\xc7"
  8                 "\x48\x8d\x70\x0a"
  9                 "\xba\x00\x00\x00\x00"
 10                 "\xb8\xcb\x00\x00\x00"
 11                 "\xcd\x80"
 12                 "\xb8\x01\x00\x00\x00"
 13                 "\xbb\x21\x00\x00\x00"
 14                 "\xcd\x80";
 15 void main() {
 16   long *pointer;
 17   pointer = (long *)&pointer + 2;
 18   *pointer = (long)payload;

There are 2 syscall first one is execve and second is exit. First one is not executing but the second one is working. This file exits with status code 33. I debugged this code in r2. I put debug point at first int 0x80 The value in registers rdi, rsi and rdx seem correct, let me paste the exact values:

rdi = 0x5580de416045
:> ps @ rdi
/bin/sh
rsi = 0x5580de41604f
px @ rsi
0x5580de41604f  4560 41de 8055 0000
rdx = 0x00000000

So rdi holds the address of /bin/sh, rsi holds an address on which first address is address of /bin/sh, and rdx is null. But I don't think it's working even using strace I don't see this sycall.


Solution

  • Thanks @Nate and @o11c, there were couple of problems:

    1. Instead of int 0x80 I should have used syscall, as I was using registers for 64bit like rdi instead of ebx to pass the first arguement. Changed that but it was still not working.

    2. Initially I was using /bin/bash instead of /bin/sh, so the string length was 7 not 9, so the address of argv is address of string + 8 (7 for length and 1 for null character) not 0a (10 ).

    3. As @o11c pointed out argv should end with NULL address. After argv[0] I just put NULL byte, but this is not sufficient the whole 8 bytes should be NULL because it's an address.

    After this the code is working fine.