-1

Would someone please provide me with assistance disassembling the shell code below (in the comment section) and also explain to me the role of the last line of code?

# include <stdlib .h>
# include <stdio .h>
# include <string .h>
const char code [] =
  "\x31\xc0"       /* Line  1: xorl  %eax, %eax */
  "\x50"           /* Line  2: pushl %eax */
  "\x68""// sh"    /* Line  3: pushl $0x68732f2f */
  "\x68""/bin"     /* Line  4: pushl $0x6e69622f */
  "\x89\xe3"       /* Line  5: movl  %esp, %ebx */
  "\x50"           /* Line  6: pushl %eax */
  "\x53"           /* Line  7: pushl %ebx */
  "\x89\xe1"       /* Line  8: movl  %esp, %ecx */
  "\x99"           /* Line  9: cdq */
  "\xb0\x0b"       /* Line 10: movb  $0x0b, %al */
  "\xcd\x80"       /* Line 11: int   $0x80 */;

  int main (int argc , char ** argv ) {
     char buf [ sizeof ( code )];
     strcpy (buf , code );
     (( void (*)( )) buf )( ); /*I don't understand what this line is for*/
  }

I read a little bit about gdb but I don't know how to use it in this case.

P.S : I am on an x86-32 Ubuntu Linux machine.

David Hoelzer
  • 15,862
  • 4
  • 48
  • 67
sasuke
  • 145
  • 1
  • 10
  • 5
    The last line is a function call to the code in `buf[]`. It might not work if the stack memory segment has the NX bit set for security. – Ian Abbott Nov 19 '15 at 17:46
  • 1
    The last line is a function call: http://cdecl.org/?q=%28+void+%28%2a%29%28+%29%29+buf+. – Kijewski Nov 19 '15 at 17:49
  • 1
    @Ian is right. `(void(*)())` is a cast of `buf` to a pointer to a function of no arguments. You can use `gdb`. Just use the `ni` and `si` commands to step at the instruction level. – Mike Dunlavey Nov 19 '15 at 17:50
  • 1
    Possible duplicate of [What is this buffer function doing?](http://stackoverflow.com/questions/15125393/what-is-this-buffer-function-doing) – stuartd Nov 19 '15 at 17:52
  • Thank you guys for your help. However i still don't understand the behavior of the assembly code in comments' section (this is my main question) – sasuke Nov 19 '15 at 18:00
  • In there `sys_execve` is invoked (syscall=0xb). For the structure that is created with the pushes: http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html#pt_regs – Kijewski Nov 19 '15 at 18:12

5 Answers5

3

The code is most probably making a call to the sys_execve() kernel function

const char code [] =
  "\x31\xc0"       /* Line  1: xorl  %eax, %eax */
  "\x50"           /* Line  2: pushl %eax */
  "\x68""// sh"    /* Line  3: pushl $0x68732f2f */
  "\x68""/bin"     /* Line  4: pushl $0x6e69622f */
  "\x89\xe3"       /* Line  5: movl  %esp, %ebx */
  "\x50"           /* Line  6: pushl %eax */
  "\x53"           /* Line  7: pushl %ebx */
  "\x89\xe1"       /* Line  8: movl  %esp, %ecx */
  "\x99"           /* Line  9: cdq */
  "\xb0\x0b"       /* Line 10: movb  $0x0b, %al */
  "\xcd\x80"       /* Line 11: int   $0x80 */;
  1. Line 1 is setting the eax register to zero and will be used as a null string terminator
  2. Lines 2, 3 and 4 are using the stack as a temporary buffer to store the null terminated ASCII string "/bin/ sh"; since the stack grows in decreasing order, the characters are reversed, that's why the terminator is pushed first.
  3. Line 5 is loading into ebx the current value of the stack pointer, which at this moment points to the address of the first character of the string we formed on the previous steps. Ebx is the register where sys_execve() expects the string with the file to be run.
  4. Line 6, and 7 are again using the stack as a temporary buffer to hold an empty null-terminated ASCII string
  5. Line 8 is loading into ecx the address of this empty string where sys_execve() expects the command line parameters
  6. Line 9, no idea of its purpose
  7. Line 10, loads decimal value 11 to AL register, specifying that the sys_execve() function is the one we wish to call
  8. Line 11 triggers interrput 0x80 - its handler is the code that will actually perform the sys_execve() call for us
BlueStrat
  • 2,202
  • 17
  • 27
2

You already have the diassembly for the inline code, it's in the comments. So that part is a bit confusing.

The final statement casts buf into a function pointer, and calls the code. This is the actual use of the exploit. It's also (as far as I know) undefined behavior, and will not work in environments that protect against executing random areas of memory.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 1
    It might be that the first question is actually in the title. If my interpretation is correct, OP wants to decompile the machine code into C. –  Nov 19 '15 at 17:51
  • @unwind Yes :) but I would love to understand how would the assembly code in comments would look like in C language or at least what's for ? – sasuke Nov 19 '15 at 17:52
1

C can do this, but there's no reverse-compiler that can figure this out, to my knowledge.

This code makes a system call. That's what int $0x80 is. The line before it says it is system call 11. The rest of the instructions set up arguments to it.

xorl  %eax, %eax     ; clear the 32-bit A register to 0
pushl %eax           ; push 32-bit 0 on the stack

pushl $0x68732f2f    ; push two 32-bit constants on the stack
pushl $0x6e69622f

movl  %esp, %ebx     ; copy the stack pointer into the 32-bit B register
pushl %eax           ; push another 0
pushl %ebx           ; push the stack pointer
movl  %esp, %ecx     ; copy the stack pointer into the 32-bit C register
cdq                  ; A already has 0. This also sets D to zero, 32-bit

movb  $0x0b, %al     ; move a constant 11 into the lower 8 bits of the A register
int   $0x80          ; and do the system call

It wouldn't surprise me if this code is designed for some nefarious purpose. It is a way to introduce some unknown code into a program, and get the computer to execute it.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
1

What the assembly does is build an argument list to pass to an operating system call to execute a binary (/bin/sh).

These two lines push /bin/sh onto the stack.

pushl $0x68732f2f
pushl $0x6e69622f

These lines place the pointer to /bin/sh in an argument register according to the calling convention.

movl  %esp, %ebx
pushl %eax
pushl %ebx
movl  %esp, %ecx
cdq

This line places the system call number, 11, in a register as an argument to the interrupt.

movb  $0x0b, %al

The last line calls into the operating system.

int   $0x80

This line in the C code just casts the buffer to a function pointer, and calls the function.

(( void (*)( )) buf )( );

Note, this used to be a common way to exploit software, however a similar method can be used to JIT compile code.

Jason
  • 3,777
  • 14
  • 27
1

I first thought lines 3 and 4 are setting up /bin/sh, but on second thoughts it might be sh /bin/X for some X I can't quite make out. In fact the // sh part looks almost like a comment??

My hunch is that the system call, line 11, is the exec system call, and that the preceding lines are setting up the args for the exec call.

I would hazard a guess that you want to be v careful running this code ;)

You might want to investigate the Hex-Rays disassembler, it can (sort of) convert machine code/assembler (the two are equivalent) into C.

Stuart
  • 37
  • 5