It has been known for some time that an executable payload generated with msfvenom can leverage an alternative template EXE file, and be encoded to better evade endpoint defenses. Having said that, what is the standard process for producing an EXE format without using an alternative template file? If, like many of us, you are using the KALI penetration testing distribution, the template files used for EXE generation are included with the Metasploit software. They are located in the directory “/usr/share/metasploit-framework/data/templates” on the current KALI distribution (as of the date of this article).
If you generate a 32-bit EXE format for Windows, the template file “template_x86_windows.exe” is used, and if you generate a 64-bit EXE format for Windows, the template file “template_x64_windows.exe” is used.
A few years back, the Metasploit framework required that a template EXE file had a buffer (usually 4096 bytes in length) with the fixed string of “PAYLOAD:” contained at the beginning of said buffer. The template EXE files were written such that they used “VirtualAlloc”, then a “MemCpy()” (memory copy), and then called the shellcode directly after it had been copied into an executable section of memory. This technique is still present in the DLL payloads but is no longer present for EXE payload generation. Interestingly, the 64-bit payload template still has this buffer allocation contained within it, even though the function of that EXE file is now irrelevant.
Today, Metasploit (msfvenom) generates payloads in EXE format by placing the shellcode either directly in the “.text” section of the PE/COFF file, or creating a new random executable section name and playing the shellcode into that new section. Then the code entry point address is modified to point at the new code, and the EXE file is saved. Thus, by using this technique, almost any executable file can actually be used as a template.
There is an interesting additional command line flag to “msfvenom” to change the format to “exe-only” rather than “exe”. This flag has the effect of either creating a new section header, or modifying the existing “.text” section in the case of 64-bit binaries. In the case of 32-bit binaries, the shellcode ends up in the “.text” section regardless, however, the characteristics flags differ and some extra assembly code are introduced in the “exe-only” version.
What does this all mean? Well frankly, this gives us additional mechanisms and possibilities to evade endpoint defenses as we leverage the idea of both modifying the PE/COFF section headers and using a well-known binary (such as write.exe or notepad.exe) for the template. I took a deeper look at the 64-bit case as it seems that endpoint defenses are not quite as adept at firing signatures on Metasploit 64-bit binaries.
To examine the differences, I used a program called “PEInsider” which allows us to view the structure of the PECOFF file. These are the two different “msfvenom” commands I used to generate the binary files. Notice the “-f exe” versus “-f exe-only” flags.
In both cases above, we use the Windows file of “write.exe” as the template rather than Metasploit’s standard template file. Taking a look with the PEInsider program, we can see that in the first case (EXE), a new section header is added with a random name, and the code entry point adjusted to hex 6000. In the second case (EXE-ONLY) the existing “.text” section is modified. Also, in both cases the section containing the shellcode is marked as “writeable” in addition to the standard flags of “executable”, “readable”, and “contains code”.
64-bit Payload Using the “-f exe” Flag
64-bit Payload Using the “-f exe-only” Flag
Why is this interesting? Well, it appears that in the past, folks in the penetration testing community have been overly focused on using shellcode encoding as a potential detection evasion technique. This is a bit of a fallacy as the standard Metasploit template itself is a dead giveaway regardless of the shellcode contained within, and more to the point, encoding shellcode was historically more about fitting the payload to the environmental conditions rather than evasion. (ie: what if an input buffer cannot accept a specific character?)
Secondly, it has been my experience that the endpoint defense vendors do a pretty good job of picking up 32-bit payloads, but have fallen somewhat short with respect to 64-bit payloads. Not surprisingly, most environments are solidly running 64-bit systems today which means we all should not ignore the 64-bit attack surface, and defence requirements.
Using either a unique template EXE, or something that is a legitimate O/S binary along with potentially leveraging different PE/COFF output formats yields opportunities for evasion. In addition, defenders should be cognizant of the fact that multiple 64-bit binary formats are possible. In particular, some carefully crafted YARA rules could assist in finding unusual payloads, especially those with E0000020 as the characteristics flags on the “.text” section, indicating that the “writable” flag is set, versus 60000020,which is a more normal setting for flags set on the “.text” section.
While it is tempting to always use the new sexy PowerShell goodness, what is old can be new again and result in a very effective and successful evasion technique. In fact, the new PowerShell techniques are where the attention and focus on endpoint defenses now lie. It is important to keep a diverse set of tricks, and deep grab bag of tools that you just might need.