In-Memory PE Execution

Badger can run any unmanaged executables compiled in Clang or MingW GCC/G++ within its own memory. This helps to avoid process creation events or creating new process as a whole. This feature of running executables instead of reflective DLLs in-memory was first introduced in release v1.1 and before that in a blog that I posted quite a while back Executing Shellcode from Object Files/PE. However, implementing this feature without making changes to msvcrt.dll’s function was a bit of a challenge. Some executables call ExitProcess when they return, and the entrypoint of executables are usually mainCRTStartup from msvcrt.dll instead of ‘int main()’ or ‘void main()’. This meant that the badger should be capable of handling the Exits and it should not exit itself when the in-memory executable process returns. One way to pass commandline argument to the in-memory process’s mainCRTStartup was patching a few functions from msvcrt.dll, but that boat is long passed for Brute Ratel as we don’t like patching things in memory in order to avoid getting caught. All of this is now possible with badger with the introduction of the memexec command.

The memexec command can run any console executable in memory and return the output of the executable using a custom in-proc-console-reader. Below are the screenshots of running mimikatz and a few other sysinternals tool:

Executing mimikatz.exe coffee command in memory:

Executing handle64.exe executable from sysinternal toolkit to list open lsass handles:

Executing accesschk64.exe executable from sysinternal toolkit to check object access:

These are just simple examples to run various executables in memory and brings us a full round circle with all types of reflection in Brute Ratel.