Custom Shellcode Encoders
- Introduction
We all used Metasploit shellcode encoders like XORmencoder,shikata_ga_nai, and many others,these encoders are targets for most antiviruses to fingerprint as they used by most attackers, so what about writing your own encoders?.
In this article we will see how easy it is to write custom encoders,however writing an encoder which is not easily fingerprinted by antiviruses is the hard part.
2. Shellcode and Encoders
Shellcode is the piece used as the payload in the exploitation of software vulnerabilities for examplem spawning a shell, nearly all metasploitshellcodesmare fingerprinted by most antiviruses therefore we use encoders to encode the shellcode and try to obfuscate(hide) it from antiviruses. So instead of using for example the shellcode used for spawning a shell “/bins/sh” , the new shellcodewill be the [encodedshellcode+ a decoder stub] that decodes the encoded shellcode at runtime.
In this article we will write from scratch the both the encoder in python and then the decoder in assembly language. So the plan is
1.we will get ashellcode of “/bin/sh”
2.Encode the shellcode using any custom technique
3.Write a decoder stub that will take the encoded shellcode and decodes it at runtime
4.Generate the new shellcode (shellcode of decoder program)
3. Writing Encoder
In this article I have chosen an Encoder which is simple and can be illustrated in the article which is the Swap Encoder the encoder takes every two bytes of the shellcode and swaps them together which at last gives some rubbish values of hex which don’t mean anything so imagine we have a shell code like this / xA2/xAA/xBF/xC3/x44/x1A/…….. , what will do is will swap each two bytes together.
We will develop the Encoding using a Python script , the code will be self-explanatory.in the below example our original “/bin/sh” code is 28 bytes “\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\ x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80\x31\ xc0\x40\xcd\x80”
The output of the below script and our encoded shellcode is as below \xc0\x31\x68\x50\x2f\x2f\x68\x73\x2f\x68\x69\x62\x89\x6e\x89\xe3\x89\xc1\xb0\xc2\xcd\x0b\x31\x80\ x40\xc0\x80\xcd
4. Jmp Call Pop Trick
After writing the Encoder we have to write an assembly program which will take the encoded shell code as an input and add a decoder stub to decode it at run time, the shellcode of this assembly program is going to be the new shellcode that we are going to use. so the steps we are going to do is
- Hardcode the encoded shellcode inside the an assembly script
- Get the address of the encoded shellcode
- Decode the encoded shellcode
- Pass control to the decoded shellcode
First we need to consider that the address of the encoded shellcode will be hardcoded inside the program as we don’t know where the address will be located in memory and it may differ with different computers
So to solve this problem there is a technique called “jmp call pop” , the idea behind this trick is when a call instruction is excuted the address of the next instruction is pushed on the stack, if we defined our encoded shellcode to be the next instruction after the call instruction we can easily obtain it’s location by doing a pop operation on the stack, so let’s see this technique in action
The program skeleton will look like below
if you want to visualize this better you can run gdb ,set a break point at pop esi instruction and examine the memory location where esi points to.
x/28xb $esi is gdb command which examine 28 bytes at the memory location pointed by esi. As in the figure it points to our encoded shellcode /xc0/x31/x68 ……
Finally now we can write our decoder.
5. Writing decoder
To test the shellcode there is a very famous and useful C program which create a pointer to a function that executes the shellcode, below is the code snippet.
Compile the program with the fno stack protector option, this option will make our stack executable for the purpose of this Demo . run the binary and here you are will get a shell /bin/sh
One thing to notice is the increase of the shellcode length
From 28 to 61, this is due to the addition of the decoder stub
6. Conclusion
Finally we saw how easy it’s to write encoders , it only requires some basic skills in assembly Language, it really all summarize to your imagination of creating the idea of the encoders so it will be hard for antiviruses to fingerprint,
Another idea exists is to Chain Encoders together, so we can actually take the shellcode we generated from the swap decoder and it will be the input for a XOR Encoder and the output of the XOR decoder can be the input to another type of encoders and so on.
About The Author
Khaled Sakr, Information Security Engineer at Security-Meter