-2

I am almost sure it's suspending because the shellcode is supposed to print a string.Instead the program just hangs

I overwrote the return address in my own application to that of my own shellcode. The jmp 0x7fffffffdbc7 is the first instruction it encounters. After it jumps to 0x7fffffffdbc7 it calls the address right below the first instruction which is supposed decrement the stack, and then push the string located at 0x7fffffffdbcc at the top, before setting control flow to 0x7fffffffdbb2 ( instead of a return address I pushed the address of the string)

(gdb) x/20i $rip
=> 0x7fffffffdbb0:  jmp    0x7fffffffdbc7
   0x7fffffffdbb2:  pop    rcx
   0x7fffffffdbb3:  xor    eax,eax
   0x7fffffffdbb5:  mov    al,0x4
   0x7fffffffdbb7:  xor    ebx,ebx
   0x7fffffffdbb9:  inc    ebx
   0x7fffffffdbbb:  xor    edx,edx
   0x7fffffffdbbd:  mov    dl,0xf
   0x7fffffffdbbf:  int    0x80
   0x7fffffffdbc1:  mov    al,0x1
   0x7fffffffdbc3:  dec    ebx
   0x7fffffffdbc5:  int    0x80
   0x7fffffffdbc7:  call   0x7fffffffdbb2
   0x7fffffffdbcc:  rex.W
   0x7fffffffdbcd:  gs ins BYTE PTR es:[rdi],dx
   0x7fffffffdbcf:  ins    BYTE PTR es:[rdi],dx
   0x7fffffffdbd0:  outs   dx,DWORD PTR ds:[rsi]
   0x7fffffffdbd1:  sub    al,0x1f
   0x7fffffffdbd3:  ja     0x7fffffffdc44
   0x7fffffffdbd5:  jb     0x7fffffffdc43

Here's what happens when i actually run the exploit

(gdb) nexti
0x00007fffffffdbc7 in ?? ()
(gdb) nexti
^C
Program received signal SIGINT, Interrupt.
0x00007fffffffdbc1 in ?? ()

The program hangs and i have to exit out manually before it transfers control to a completely random instruction.

nemequ
  • 16,623
  • 1
  • 43
  • 62
  • Try single stepping through the disassembly (`stepi`)? – a3f Mar 24 '18 at 20:30
  • 1
    `int 0x80` is a 32-bit system call. It can't handle addresses that can't be represented in 32-bits. You end up only passing the lower 32-bit part of RCX (the full address) via ECX to the sys_write and that isn't where your string is at. You need to use the syscall instruction and follow the 64-bit Linux system call ABI. More on that here: http://blog.rchapman.org/posts/Linux_System_Call_Table_for_x86_64/ – Michael Petch Mar 24 '18 at 21:26
  • This was tested on ubuntu as a native os – Gabriel Reyes Mar 24 '18 at 21:35
  • After `write()` returns rax=-EFAULT, you set only the low byte to `1`, so the next `int 0x80` returns -ENOSYS instead of running `sys_exit`, creating an infinite loop. **You're already using a debugger, look at the registers**. (e.g. `info reg`, `print $eax`, or `layout reg`. See the bottom of https://stackoverflow.com/tags/x86/info) – Peter Cordes Mar 24 '18 at 22:01
  • @MichaelPetch: on Win10, `int 0x80` would have faulted, and not with SIGINT. This is an infinite loop, and the GBD output is showing a SIGINT from the OP pressing ^C manually. I was confused by that for a while, too, because RIP was right after an `int 0x80` instruction. – Peter Cordes Mar 24 '18 at 22:08

1 Answers1

1

You need to use 64-bit system calls. The 32-bit system call doesn’t support the 64-bit pointer to the string.

prl
  • 11,716
  • 2
  • 13
  • 31