SLAE: linux_x86_exec Shellcode Analysis


This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

Student ID: SLAE-924

The task is to:

  • Take up at least 3 shellcode samples created using MSFpayload for linux/x86
  • Use gdb_ndisasm_libemu to dissect the functionality of the shellcode
  • present your analysis

The first shellcode we will examine is linux/x86/exec.

msfvenom -p linux/x86/exec --payload-options

Basic option is CMD.

Let’s generate our shellcode:

msfvenom -p linux/x86/exec CMD=whoami -f c

That’s it

msfvenom -p linux/x86/exec CMD=whoami -f c
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 42 bytes
Final size of c file: 201 bytes
unsigned char buf[] =

Let’s put it into c template file and compile it:

 gcc shellcode.c -z execstack

It works and whoami command executes. Sample image

Analyzing shellcode in gdb

Now let’s see how it works in gdb. I recommend also to install peda which is available here.

pagliacci@pagliacci-ubuntu:~$ gdb -q ./a.out
Reading symbols from /home/pagliacci/a.out...(no debugging symbols found)...done.
gdb-peda$ set disassembly-flavor intel
gdb-peda$ print /x &code
$1 = 0x804a040
gdb-peda$  break *0x804a040
Breakpoint 1 at 0x804a040
gdb-peda$ run
Shellcode Length:  15

Sample image

To move to the next instruction you can use stepi.

That’s what we’ve get:

0x804a040 <code>:	push   0xb                
0x804a042 <code+2>:	pop    eax            ;0xb to eax
0x804a043 <code+3>:	cdq                   ;zero out edx
0x804a044 <code+4>:	push   edx            ;push zero byte to the stack
0x804a045 <code+5>:	pushw  0x632d         ;pushing -c to the stack
0x804a049 <code+9>:	mov    edi,esp        ;now edi points to the stack with -c, terminated by the zero
0x804a04b <code+11>:	push   0x68732f     ;pushing ('hs/') to the stack
0x804a050 <code+16>:	push   0x6e69622f   ;pushing ('nib/') to the stack (now it contains /bin/sh)
0x804a055 <code+21>:	mov    ebx,esp      ;now ebx points to /bin/sh
0x804a057 <code+23>:	push   edx          ;push zero to the stack
0x804a058 <code+24>:	call   0x804a064    ;address of "whoami" is pushed to the stack through call
0x804a064 <code+36>:	push   edi          ;push pointer to -c
0x804a065 <code+37>:	push   ebx          ;push pointer to /bin/sh

Now we’ve put all necessary values for the execve system call to the stack. Now stack looks like this:

0000| 0xbffff67e --> 0xbffff68e ("/bin/sh")
0004| 0xbffff682 --> 0xbffff696 --> 0x632d ('-c')
0008| 0xbffff686 --> 0x804a05d ("whoami")

After that we will move the value of the esp register to the ecx. So now:

  • eax is set to 0xb, which is the syscall number for execve
  • ebx points to /bin/sh
  • ecx points to argv[] which is { “_bin_sh”, “-c”, “whoami” } And now we can call interrupt.
0x804a066 <code+38>:	mov    ecx,esp       ;ecx now points to the top of the stack: where:

0x804a068 <code+40>:	int    0x80          ;call execve

And finally we get it: Sample image

That’s how it works!