The Past two months i was really busy with other work and hence i was not able to spend enough time on the SLAE course. I hope i will be able to complete all the assignments within this month, today i will be doing my 5th assignment which is to analyse any three metasploit linux/x86 payloads . I decided to first analyse linux/x86/exec payload
To get more info about the payload we can use the "S" option which stands for summary
sudo msfpayload -p linux/x86/exec S
Summary of the Payload :-
Name: Linux Execute Command
Module: payload/linux/x86/exec
Version: 0
Platform: Linux
Arch: x86
Needs Admin: No
Total size: 143
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
So from the summary, The above payload requires a command which will be executed remotely, I decided to execute the "ls" command.
sudo msfpayload -p linux/x86/exec CMD=ls S
Summary of the Payload :-
Name: Linux Execute Command
Module: payload/linux/x86/exec
Version: 0
Platform: Linux
Arch: x86
Needs Admin: No
Total size: 150
Rank: Normal
Provided by:
vlad902 <vlad902@gmail.com>
Basic options:
Name Current Setting Required Description
---- --------------- -------- -----------
CMD ls yes The command string to execute
Description:
Execute an arbitrary command
Now our payload is ready, I will first use libemu to analyse the payload
Libemu Analysis
sudo msfpayload -p linux/x86/exec CMD=ls R | ./sctest -vvv -Ss 10000
To get the out put in a nice graphical flow chart format , We use the "-G" option
sudo msfpayload -p linux/x86/exec CMD=ls R |./sctest -vvv -Ss 10000 -G exec.dot
The out put file is stored in .dot format to convert it to .png format, we need to issue the following command
dot exec.dot -Tpng -o exec.png
From the above flow chart we can clearly see that "execve" system call has been used , we can have a look at the man page to get some info on execve
man 2 execve
From the man page, We understand that execve executes a program but it requires three inputs (*filename, *agrv and *envp) .From libemu's output the arguments are not clear to us .
So for further analysis it necessary for us to first test the shellcode in our C template, After which we can use tools such as strace and gdb for analysis . To do this we will first get the payload output in C format by issuing the following command
So for further analysis it necessary for us to first test the shellcode in our C template, After which we can use tools such as strace and gdb for analysis . To do this we will first get the payload output in C format by issuing the following command
sudo msfpayload -p linux/x86/exec CMD=ls C
/* * linux/x86/exec - 38 bytes * http://www.metasploit.com * VERBOSE=false, PrependSetresuid=false, * PrependSetreuid=false, PrependSetuid=false, * PrependSetresgid=false, PrependSetregid=false, * PrependSetgid=false, PrependChrootBreak=false, * AppendExit=false, CMD=ls */ 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\x03\x00\x00\x00\x6c" "\x73\x00\x57\x53\x89\xe1\xcd\x80";
Now, Let's copy the shellcode and use it in our C template (For Testing a shellcode locally)
*/
*#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\x03\x00\x00\x00\x6c"
"\x73\x00\x57\x53\x89\xe1\xcd\x80"
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
gcc -fno-stack-protector -z execstack shellcode.c -o shellcode ./shellcode
as expected the ls command is executed
Now lets find the arguments passed in the execve system call by using Strace
Strace Analysis
We use the "-e" option to filter "execve" system call
strace -e execve ./shellcode
By correlating the output, we find the arguments of execve
- filename :- Contains the path of the binary to be executed which is (/bin/sh)
- agrv [] :- Contains an array of argument strings passed to the new program. By convention, the first of these strings should contain the *file name associated with the file being executed that is ["/bin/sh", "-c", "ls"]
- envp [] :- Is an array of strings, conventionally of the form key=value, which are passed as environment to the new program, this is nothing but a null pointer [/* 0 vars */]
Note:- Both *argv and *envp must be terminated by a NULL pointer
GDB Analysis
Now lets use gdb to step through the program to find out the registers, which have been used and also to analyse the program flow
gdb -q ./shellcode
Now lets set the disassembly to "Intel" format and then set a break point at "code"
(gdb) set disassembly-flavor intel
(gdb) break *&code
Breakpoint 1 at 0x804a040
(gdb) run
Starting program: /home/john/libemu/tools/sctest/shellcode
Shellcode Length: 15
Breakpoint 1, 0x0804a040 in code ()
(gdb) disassemble
Dump of assembler code for function code:
=> 0x0804a040 <+0>: push 0xb
0x0804a042 <+2>: pop eax
0x0804a043 <+3>: cdq
0x0804a044 <+4>: push edx
0x0804a045 <+5>: pushw 0x632d
0x0804a049 <+9>: mov edi,esp
0x0804a04b <+11>: push 0x68732f
0x0804a050 <+16>: push 0x6e69622f
0x0804a055 <+21>: mov ebx,esp
0x0804a057 <+23>: push edx
0x0804a058 <+24>: call 0x804a060
0x0804a05d <+29>: ins BYTE PTR es:[edi],dx
0x0804a05e <+30>: jae 0x804a060
0x0804a060 <+32>: push edi
0x0804a061 <+33>: push ebx
0x0804a062 <+34>: mov ecx,esp
0x0804a064 <+36>: int 0x80
0x0804a066 <+38>: add BYTE PTR [eax],al
End of assembler dump.
Now i will comment on each step, for better understanding and i will also set break points when required
Dump of assembler code for function code: => 0x0804a040 <+0>: push 0xb ; Syscall Number of Execve is pushed on the stack 0x0804a042 <+2>: pop eax ; Syscall Number of Execve is poped into the EAX Register 0x0804a043 <+3>: cdq ; Convert double-word to quad-word 0x0804a044 <+4>: push edx ; EDX is pushed on the stack 0x0804a045 <+5>: pushw 0x632d ; "-C" is pushed on the stack 0x0804a049 <+9>: mov edi,esp ; Address of esp in moved into EDI register which nothing but "-c" 0x0804a04b <+11>: push 0x68732f ; "/sh" is moved on the stack in reverse stack grows from higher memory to lower memory 0x0804a050 <+16>: push 0x6e69622f ; "/bin" is moved on the stack in reverse stack grows from higher memory to lower memory 0x0804a055 <+21>: mov ebx,esp ; Address of esp is moved into EBX register which is a pointer to "/bin/sh" 0x0804a057 <+23>: push edx ; EDX Register is pushed on the stack (Null)
From the above analysis we know the following
- EAX :- Contains the system call number of execve which is 11 (hex - 0xb)
- EBX :- Contains the binary to be executed "/bin/sh"
- EDX :- Contains Nulls for null terminating (argv and envp)
- EDI :- Contains the address of "-c" one of the arguments
Now lets set a break point at 0x0804a058 (Before the Call instruction)
(gdb) break * 0x0804a058
Breakpoint 2 at 0x804a058
(gdb) c
Continuing.
Breakpoint 2, 0x0804a058 in code ()
(gdb) disassemble
Dump of assembler code for function code:
0x0804a040 <+0>: push 0xb
0x0804a042 <+2>: pop eax
0x0804a043 <+3>: cdq
0x0804a044 <+4>: push edx
0x0804a045 <+5>: pushw 0x632d
0x0804a049 <+9>: mov edi,esp
0x0804a04b <+11>: push 0x68732f
0x0804a050 <+16>: push 0x6e69622f
0x0804a055 <+21>: mov ebx,esp
0x0804a057 <+23>: push edx
=> 0x0804a058 <+24>: call 0x804a060
0x0804a05d <+29>: ins BYTE PTR es:[edi],dx
0x0804a05e <+30>: jae 0x804a060
0x0804a060 <+32>: push edi
0x0804a061 <+33>: push ebx
0x0804a062 <+34>: mov ecx,esp
0x0804a064 <+36>: int 0x80
0x0804a066 <+38>: add BYTE PTR [eax],al
End of assembler dump.
Now lets step through and analyse the stack $esp before and after the call instruction
=> 0x0804a058 <+24>: call 0x804a060 0x0804a05d <+29>: ins BYTE PTR es:[edi],dx 0x0804a05e <+30>: jae 0x804a060 0x0804a060 <+32>: push edi 0x0804a061 <+33>: push ebx 0x0804a062 <+34>: mov ecx,esp 0x0804a064 <+36>: int 0x80 0x0804a066 <+38>: add BYTE PTR [eax],al End of assembler dump. (gdb) x/xw $esp 0xbffff2ca: 0x00000000 (gdb) stepi 0x0804a060 in code () ( gdb) x/xw $esp 0xbffff2c6: 0x0804a05d (gdb) x/xs 0x0804a05d 0x804a05d : "ls" (gdb) disassemble Dump of assembler code for function code: 0x0804a040 <+0>: push 0xb 0x0804a042 <+2>: pop eax 0x0804a043 <+3>: cdq 0x0804a044 <+4>: push edx 0x0804a045 <+5>: pushw 0x632d 0x0804a049 <+9>: mov edi,esp 0x0804a04b <+11>: push 0x68732f 0x0804a050 <+16>: push 0x6e69622f 0x0804a055 <+21>: mov ebx,esp 0x0804a057 <+23>: push edx 0x0804a058 <+24>: call 0x804a060 0x0804a05d <+29>: ins BYTE PTR es:[edi],dx 0x0804a05e <+30>: jae 0x804a060 => 0x0804a060 <+32>: push edi 0x0804a061 <+33>: push ebx 0x0804a062 <+34>: mov ecx,esp 0x0804a064 <+36>: int 0x80 0x0804a066 <+38>: add BYTE PTR [eax],al End of assembler dump.
From the above analysis, we confirm that the payload is using "jump call pop" technique . The argument "ls" is now on the stack
Lets continue our analysis
=> 0x0804a060 <+32>: push edi ; Pointer to "-c" 0x0804a061 <+33>: push ebx ; Pointer to "/bin/sh" 0x0804a062 <+34>: mov ecx,esp ; pointer to " /bin/sh -c ls " 0x0804a064 <+36>: int 0x80
Lets set a break point just before interrupt "0x80" and see how the stack and other registers are laid out
(gdb) break *0x0804a064 Breakpoint 3 at 0x804a064 (gdb) c Continuing. Breakpoint 3, 0x0804a064 in code () (gdb) disassemble 0x0804a061 <+33>: push ebx 0x0804a062 <+34>: mov ecx,esp => 0x0804a064 <+36>: int 0x80 0x0804a066 <+38>: add BYTE PTR [eax],al
Now lets analyse the registers
(gdb) info registers eax 0xb 11 ; Execve Sys call number ecx 0xbffff2be -1073745218 ; address of "/bin/sh -c ls" edx 0x0 0 ; Null (envp) ebx 0xbffff2ce -1073745202 ; pointer to "bin/sh" esp 0xbffff2be 0xbffff2be
- EAX :- Contains the system call number of execve which is 11 (hex - 0xb)
- EBX :- Contains the binary to be executed "/bin/sh"
- ECX :- Pointer to "/bin/sh -c ls "
- EDX :- Contains Null (envp)
So from the above analysis we found out that "execve" system call was used and we also found out that the shellcode used "jump call pop technique" to execute the command that we first feed in "ls"







0 comments: