Red team penetration testers very often add tools to their arsenal that borrow techniques originating in malicious software. Shellter is such a tool. It was inspired by the EPO and polymorphic file-infector viruses, became established as a tool for pen testers and then crossed back to being leveraged by cybercriminals. If you are not familiar with these concepts, here are the definitions:
- EPO stands for “entry point obscuring.” The most common types of file infections occur at the entry point, making the infected code easily detectable, so in order to circumvent that, the EPO infection takes place in an arbitrary location in the execution flow of the host application.
- Polymorphic code is code that changes its appearance and instructions from one infection to another but maintains the same functionality.
- File infectors add malicious code to originally benign executables.
Investigation
For the initial investigation, we chose a Shellter-infected version of DebugView. DebugView is a legitimate application made by Microsoft that lets its users monitor system debug output. During the dynamic analysis of the infected version of this application, the executable behaves as expected and functions normally like the original Microsoft version, but it also starts listening for incoming network connections on a non-standard port. Since this behavior does not match any of DebugView’s features, it is a clear indication that we are dealing with a modified version. To see what happens behind the curtain, we fired up a debugger and started to delve into the live code. Examining the entry point revealed that it is a standard one for an application written in the Microsoft Visual C programming language, and therefore the altered part must be hidden somewhere else. After setting a few breakpoints, we were able to pinpoint the infection code. As can be seen, there are a lot of instructions without any real purpose. These are used to obfuscate the code and complicate the analysis. This is an example of the aforementioned EPO technique, which hides its entry point in randomly selected host code paths, as opposed to overwriting the host’s entry point. Soon after in the control flow, a new memory zone is allocated. The malicious code copies its next stage there. Then, it jumps to this zone to execute. The second-stage code uses the same obfuscation technique to complicate the analysis. The sole purpose of this stage is to decrypt the payload and transfer the execution to it. This is what the beginning of the payload looks like: You might already recognize the Meterpreter code. This stage will be almost the same for each infected executable — the only part that can change is the type of the payload. The most popular by far is the reverse shell. By now, we’ve confirmed that the executable is infected by an EPO tool and that it executes a Meterpreter payload. In order to demonstrate the polymorphic abilities, we analyzed another infected file. This one exhibited the same behavior and has the same structure (two stages and payload), but the code differs while maintaining the same functionality.Hunting
Once we knew how Shellter looks and works, we wanted to test our findings by hunting for infected files in the wild. To do so, we developed a YARA rule based on our observations, and we used it with our MalQuery product, which allows complex searches over a vast body of malware samples. Detection of polymorphic code with signature-based scanners is usually difficult, but the flexibility of YARA syntax gave us the possibility to create rules, which yielded a satisfactory grade of accuracy. During our analysis, we found some weaknesses in the polymorphic generation routine that helped the creation of the rule. For example, for eachxor <32bit_reg>, big_constant
instruction, there is a corresponding add <32bit_reg>, big_constant
instruction.
Another sequence of code remains almost the same:
sub
32bit_reg, 4
jnz
address
We also observed that each sample contains a Call $+5
instruction, which actually means “call the next instruction” — it is commonly used along with a POP instruction in order to get the current address of code execution.
The analysis of the infected files’ PE header and structure revealed some new characteristics: The digital signatures of the original samples are always removed, DLL Characteristics and Security Directory are always 0, and only 32-bit applications can be infected.
After putting together all of this information, we came up with the following YARA rule:
import "pe"
rule CrowdStrike_Shellter
{
strings:
// call $+5
$call_EIP = {E800000000}
// not
dword ptr
$not = {F7 (10|11|12|13|16|17)}
// xor
dword ptr , big_constant
$xor = {81 (30|31|32|33|36|37)}
// add
dword ptr , big_constant
$add = {81 (00|01|02|03|06|07)}
// sub
eax|ecx|edx|ebx|esi|edi|esp|ebp, 4
// jnz
decyption_loop
$sub_jnz1 = {83 E8 04 0F 85 ?? F? FF FF}
$sub_jnz2 = {83 E9 04 0F 85 ?? F? FF FF}
$sub_jnz3 = {83 EA 04 0F 85 ?? F? FF FF}
$sub_jnz4 = {83 EB 04 0F 85 ?? F? FF FF}
$sub_jnz5 = {83 EC 04 0F 85 ?? F? FF FF}
$sub_jnz6 = {83 ED 04 0F 85 ?? F? FF FF}
$sub_jnz7 = {83 EE 04 0F 85 ?? F? FF FF}
$sub_jnz8 = {83 EF 04 0F 85 ?? F? FF FF}
condition:
$call_EIP
and $not and $xor and $add
// the not, xor and add instructions to detect should occur at least two times each
and #not >= 2 and #xor >= 2 and #add >= 2
// check that the xor and the add have the same second operand
and (uint32(@xor<1> + 2) == uint32(@add<1> + 2)
or uint32(@xor<1> + 2) == uint32(@add<2> + 2)
or uint32(@xor<2> + 2) == uint32(@add<1> + 2)
or uint32(@xor<2> + 2) == uint32(@add<2> + 2))
// check if any $sub_jnz matches
and any of ($sub_jnz*)
and filesize < 1000KB
// we observed that any byte at offset $sub_jnz + 25 is equal to any byte at the offset $sub_jnz + 53
and for any of ($sub_jnz*)
: (uint8(@ + 25) == uint8(@ + 53))
and pe.number_of_signatures == 0
and pe.dll_characteristics == 0
and pe.machine == pe.MACHINE_I386
and pe.characteristics & pe.EXECUTABLE_IMAGE
}
Here is a screenshot of the YARA rule being used in CrowdStrike Falcon® MalQuery:
Outcome
Part of our motivation was to stop Shellter-based threats not only by using various indicators of attacks (IOAs) but also statically, just by analyzing files on disk. To accomplish these goals, we used the outcome of our research to hunt for Shellter files and added them to our machine learning (ML) training corpus. As a first step, this ensures that ML can learn from these malicious specimens.The next step, after building a collection of infected samples, was to extend our ML feature space by extracting specific Shellter features.
With the new features, our model is able to dramatically increase the coverage of Shellter samples currently in our collection. This ability gives us an additional means of spotting this highly obfuscated attack vector to fortify our defense-in-depth approach.
Conclusion
Even though it was not created for malicious deeds, Shellter is a dangerous tool in the hands of attackers because of its effectiveness in bypassing the detection of antivirus programs. However, due to continuous research work like this combined with a powerful next-generation antivirus, CrowdStrike®solutions are able to detect and prevent such threats. Are you an expert in designing large-scale distributed systems? The CrowdStrike Engineering team wants to hear from you! Check out the openings on our career page.Additional Resources
- Learn more about the CrowdStrike Falcon® platform by visiting the product webpage.
- Learn more about CrowdStrike endpoint detection and response by visiting the Falcon InsightTM webpage.
- Test CrowdStrike next-gen AV for yourself. Start your free trial of Falcon Prevent™ today.