So, finally I got some time to write a blog post about Security and pentesting. I thought to myself, it would be really cool to implement some of the functionalities that cheat developers use into malware/pentest scenarios. In many aspects, game cheat development is leaps and bounds more advanced than the current techniques we are using as pentester. In memory execution? Powershell? Reflective DLL Injection? Heh. To combat kernel level Anti-Cheat like EAC and BE, game cheat developers has been done with memory execution and reflective dll loading and moved into manualmapping, kernel driver, and some even gone as far as bootkit/hypervisor mode. However, today let’s focus on some of the more easily understandable aspect of this, and it is DLL Injection. More specifically, Mimikatz dll injection.
Everyone is well aware of the most well-known lsass password dumping tool called Mimikatz. I won’t go too deep into it, but you can read more about it here on github. It reads lsass’ memory, looks for patterns and dump creds. Most well known tool, most well detected tool on any environment.
I am more shocked that something you compiled yourself can have a higher detection rate but neither is wanted.
Here, at my consulting company – we modified Mimikatz ourselves and dubbed it PANDA and it achieved great results. The obfuscated mimikatz dubbed PANDA have gone on for a long time without any detection, until recently. And as obfuscation goes, it can only go so far… therefore I wanted to make it a bit of a challenge to see if we can make Mimikatz undetected, without obfuscation. My first thought, DLL Injection.
To compile Mimikatz as an dll, there is a few things we must modify. First, a setting to tell the compiler to compiles as an DLL as well as a different entrypoint. DLL entrypoint is default at DllMain() instead of main() or wmain() in this case due to wide-character setting. Dll also does not have its own console so we would have to AllocConsole() and uses freopen_s() to redirect the console output to the new console. Lastly, we can no longer pass arguments like we used to from command line using argv/argc, so we must use a different method for that such as std::wcin or C equivalence. For this demonstration, let’s just hardcode our commands.

After that is done, we can now compile our mimikatz.dll and use it as we wish. Let’s check our detection rate right now.

Down by 2, not a surprise given we did not modify much in term of how the binary is running. There is no difference beside a few instructions and a new entrypoint. However, that is good enough as a starter.
Next up, how are we going to make this execute? You surely won’t push this dll which is a 17/25 and an injector onto disk and execute it…will you? While it will work, it is kinda far from our goal of 0/25. Also, using an injector to inject Mimikatz manually is kind of a joke… so my next idea is to make a binary that is an injector, but also have Mimikatz’ bytecode in it so that it can injects the bytecode itself without requiring Mimikatz.dll to be on disk as its own file. For this to work, I will use an injector source code that I been using for quite some time and quite familiar with, that is also well documented – GuidedHacking Injector.
To be more specific, I will use its manualmapping functionality to get our dll to execute. For those who does not know what manualmapping is, it is basically doing everything LoadLibraryA does, manually, without actually using LoadLibraryA. This mean, write the bytecode to target process, inject the loader shellcode, relocate, fix imports, execute tls callbacks, and finally call DllMain. All of which are done usually by LoadLibraryA but because that is a very suspicious WINAPI functionality to call, we will avoid using it at all cost. There are much better writeup on manualmapping injection technique so I won’t go too deep into that.
https://pastebin.com/eN7KPX3x for the source code of GH Injector.
I also made a video on how to embed the dll (mimikatz.dll) as a resource and compile it with the injector. You can watch it here.
Let’s skip all of that because I already covered it in the video, but what we will end up with is this:

I will use notepad.exe right now as an example but it would be fairly easy to change that into some other executable file. There are a few system processes that we can use (not lsass because lsass does not have its own windows). Or better, loop through every single processes and look for one that have a windows, same architecture as the compiled mimikatz (x86 can only inject into x86, and same for x64 > x64, there is no Heaven’s Gate implementation) and is running as with system/admin privilege. I dubbed this KittenClaw because, while claws does not inject – it does scratches you pretty well.
Here is KittenClaw in action:
It runs, manualmap Mimikatz into notepad.exe and does the 3 commands that I hardcoded. Let’s check its detection right now.

4/25, I expected better but then I realizes there is absolutely no obfuscation and all the strings that the binary comes with (mimikatz, gentilkiwi, etc) probably causes some of these detections. On top of that, it is a Heuristic detection for 2/4 so maybe we can go into some more on a later date. Overall, I think this is good progress for a few hours of work and we can totally work out this another time.