Last month at the initial REcon Security Conference in Brussels, I gave a talk on ‘Teaching Old Shellcode New Tricks’ or breathing new life into existing MetaSploit Framework (MSF) Windows exploit payloads. During the talk, I released Fido, a tool that enables penetration testers to bypass EMET EAF/Caller protections and various antivirus provider detections by modifying existing MSF payloads on the fly.
The talk is a result of research that led to a surprising conclusion:
A stable EMET EAF and Caller bypass has existed since Windows 7 through Windows 10 OS.
This bypass is enabled by MinWin, - an implementation to break out Windows APIs into smaller, more portable DLLs that are then imported into the regular DLLs that developers normally interact with - particularly with the api-ms-win-core-libraryloader-*.dll. This DLL is imported into kernel32.dll and includes GetProcAddress (GPA), which is in the import table for kernel32.dll. To bypass EAF (Export Address Filtering), we parse the import table of kernel32.dll to find GPA. From there, we use GPA find LoadLibraryA (LLA), and we have access to the entire windows API. This method is stable from Windows 7 through Windows 10. To bypass the caller check, we call into GPA/LLA vs using a ret or a jmp as the current MSF payload invokes.
As a result, Fido, a python script, was released that expanded on research presented in a blog post from last summer to take MSF Windows x86 single-stage payloads and modify them for bypassing EMET EAF/Caller checks automatically. This was accomplished by stripping Stephen Fewer’s Hash API (Hash API) stub and replacing it with one of four different Import Address Table parsing x86 assembly stubs, bridging it with an offset table assembly stub that abstracts out the four byte hash WinAPI representation and calls the windows API. You are not limited to using the method I mentioned above. Fido will pick a method for you based on your target executable and target Windows operating system version.
Many MSF windows x86/x64 payloads have two parts, the Hash API stub and the actual payload logic that calls the Hash API stub. Each windows API that is used is calculated via a 13 bit assembly rotate algorithm in the form of a four byte hash. Since we’re replacing the Hash API with an offset table, the original four byte hashes no longer hold value after enumerating what APIs are being used. Fido supports mangling these hashes to random values, thereby breaking AV signatures in the process.
There is more to do, specifically for Windows x64 MSF payloads and how to incorporate these techniques into MSF staged payloads.