Assignment 6 – Polymorphing Shellcodes from Shell-Storm
This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification:
Student ID: SLAE-1112
This is the sixth from seven assignments in order to complete the SLAE (32bit) certification.
In this Assignment the objective is to create polymorphic versions from three Shellcodes from Shell-Storm.
In short, Polymorphism is the process of producing different code versions that operates with the same functionality. This helps bypassing signature-based systems.
The only rule for this Assignment is that the Polymorphed implementation cannot be 150% bigger than the original one.
In this post I wont go into much detail about the code since the objective here is to produce polymorphed versions and most of the code herein have already been explained in previous Assignments.
The three Shellcodes to be polymorphed are:
- Linux/x86 Shellcode execve (“/bin/sh”) – 21 Bytes
- Linux/x86 file reader – 65 Bytes + path
- Shell Reverse TCP Shellcode – 74 Bytes
1) linux/x86 Shellcode execve (“/bin/sh”)
The first Shellcode that I chose is an execve (“bin/sh”) with 21 bytes. In the following image I present the original code and my adaptation:
The final result is a Shellcode with 25 bytes (~19% bigger).
2) Linux/x86 file reader
The second Shellcode is a File reader with 65 bytes plus the filepath bytes. Trying to use the Shellcode to read /etc/passwd (11 bytes) would make a total size of 76 bytes.
My implementation ended up having 62 bytes including the number of bytes from the filepath. That is a reduction of 14 bytes (~18,4%).
3) Shell Reverse TCP Shellcode – 74 bytes
The last Shellcode is a Reverse TCP Shellcode with 74 bytes.
The polymorphed implementation ended up being 5 bytes bigger (~6,76%) .
Bypassing signature-based systems
Before wrapping up this Assignment I thought it would be fun to make a little demonstration of how these polymorphic versions would bypass signature-based systems.
For a quick demonstration I’ll be using YARA. A brief description from the website:
YARA is a tool aimed at (but not limited to) helping malware researchers to identify and classify malware samples. With YARA you can create descriptions of malware families (or whatever you want to describe) based on textual or binary patterns. Each description, a.k.a rule, consists of a set of strings and a boolean expression which determine its logic.
Alright, lets take the first Shellcode as an example:
Looking at the code, we see that the easier thing to do is to fingerprint the push instructions because this push pattern is seen in most variations of this Shellcode, for instance:
- Linux/x86 – execve(/bin/sh) Shellcode (19 bytes) – exploit-db
- Linux/x86 – execve(/bin/sh) Shellcode (24 bytes) – exploit-db
- Linux/x86 execve /bin/sh shellcode 23 bytes – shell-storm
- Linux x86 execve(“/bin/sh”) – 28 bytes – shell-storm
So a simple YARA rule would be:
In order to make a test I will use the following Shellcodes:
- Original Shellcode (execve_orig)
- Shellcode from exploit-db (exploitdb_40131)
- Polymorphed implementation (execve_poly)
As we can see in the following image, running the YARA rule against the binaries returns two matches (exploitdb_40131 and execve_orig) because both possess the fingerprint pattern:
On the other hand, running it with the “-n” option, in order to negate the results, YARA returns execve_poly, meaning that the Polymorphed implementation would bypass this simple YARA rule:
It’s obvious that in this case it would be easy to bypass the rule because the code is small and the rule was really simple. However, it was a good example on how it is possible to produce new versions of the Shellcode that bypass signature-based systems even though the Shellcode functionality remains the same
YARA is a great tool to help Malware researchers to identify and classify malware samples and I definitely recommend taking a look into it:
That’s all for this Assignment. As always, the full code can be found in my SLAE Github repository. See you in the next one!