Updating Mimikatz in Metasploit
Mimikatz integrated in the current Metasploit Framework is a little bit outdated. If you want to use the recent features (like plaintext RDP credential dumping), the Mimikatz Extension (called Kiwi) should be manually updated and compiled into the current framework. Here is how to do it.
The Kiwi Extension
The (in)famous Meterpreter shell payload of the Metasploit Framework allows an attacker to load extensions. Extension loading is implemented by in-memory DLL injections without spawning new processes. If the Meterpreter shell bypasses the AV/EDR solutions, there is a high chance that the extensions are also remaining stealthy.
The great Mimikatz post-exploitation tool by Gentilkiwi is available as a Meterpreter extension called Kiwi. Once we have a Meterpreter session (what is already bypassed the AV/EDR solutions), it is very comfortable to load the Kiwi extension and launch various Mimikatz modules in a post-exploitation task.
The only issue about this is that the Mimikatz module integrated in the current Metasploit Framework (v6.0.46 as of writing this article) is a little bit outdated. The Mimikatz fork used in this Meterpreter release is from the late 2019, and it lacks some awesome current features (my favorite is the latest RDP plaintext credential dump).
The solution for getting the recent features is updating the Kiwi extension by recompiling it using the current Mimikatz master branch.
Preparing the source tree
The Kiwi extension can be compiled altogether with the C Windows Meterpreter shell hosted in the Rapid7 metasploit-payloads github repository.
First, on a Windows machine (with Visual Studio, preferably VS2019) clone the repo:
git clone https://github.com/rapid7/metasploit-payloads
cd metasploit-payloads
For Visual Studio dependencies, see the “Building — Windows on Windows” section of the Windows C Meterpreter building README.
Next, instead of following the README, replace the c\meterpreter\source\extensions\kiwi\mimikatz
submodule originally refering to the Rapid7 mimikatz fork (https://github.com/rapid7/mimikatz) with the master branch of the official mimikatz repo by Benjamin Delpy (gentilkiwi) (https://github.com/gentilkiwi/mimikatz/).
Set the new url for mimikatz submodule in the kiwi extension folder:
git submodule set-url c\meterpreter\source\extensions\kiwi\mimikatz https://github.com/gentilkiwi/mimikatz
If submodule set-url is not supported (in older git versions), edit .gitmodules directly and change the rapid7 mimikatz github URL in the c/meterpreter/source/extensions/kiwi/mimikatz submodule section to the gentilkiwi one:
url = https://github.com/gentilkiwi/mimikatz
Next step is init and update (fetch) the submodules:
git submodule init
git submodule update
Now the gentilkiwi mimikatz branch is in the project, but it is not at the latest commit. Check it out to the latest update:
git submodule update --remote
The source tree is almost ready, but the appropriate c\meterpreter\workspace\ext_server_kiwi\ext_server_kiwi.vcxproj
Visual C++ project file should me modified for the updated mimikatz component before compiling.
Patching the Visual C++ project file
Actually, merging the new header and source file locations existing in the new mimikatz and missing in the old mimikatz version is needed.
Checking (on Linux :) ) which source files should be added to c\meterpreter\workspace\ext_server_kiwi\ext_server_kiwi.vcxproj
as the ClCompile
Include
attributes:
diff <(cat c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj | grep '<ClCompile Include' | sort) <(cat c/meterpreter/source/extensions/kiwi/mimikatz/mimikatz/mimikatz.vcxproj | grep '<ClCompile Include' | sed -e 's/Include="/Include="..\\..\\source\\extensions\\kiwi\\mimikatz\\mimikatz\\/' -e 's/\\mimikatz\\\.\.//' | sort) | grep '^>' | sed -e 's/^> //'
The result is (supplemented by the sqlite3.c PrePorcessorDefinitions):
These lines should be added to c\meterpreter\workspace\ext_server_kiwi\ext_server_kiwi.vcxproj
. Note, that sqlite3_omit.c
(with the full element list inside its <ClCompile></ClCompile>
tag) should be removed (because it is replaced by sqlite3.c
in the recent mimikatz).
The same for the header files:
diff <(cat c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj | grep '<ClInclude Include' | sort) <(cat c/meterpreter/source/extensions/kiwi/mimikatz/mimikatz/mimikatz.vcxproj | grep '<ClInclude Include' | sed -e 's/Include="/Include="..\\..\\source\\extensions\\kiwi\\mimikatz\\mimikatz\\/' -e 's/\\mimikatz\\\.\.//' | sort) | grep '^>' | sed -e 's/^> //'
The result is:
These lines should be added to c\meterpreter\workspace\ext_server_kiwi\ext_server_kiwi.vcxproj
. Also note, that sqlite3_omit.h
should be removed (because it is replaced by sqlite3.h
in the recent mimikatz).
Now some more compile options needs to be merged from the mimikatz branch to the meterpreter workspace project.
First, make sure that compiler warnings won’t abort to error, so replace all occurrences of TreatWarningAsError elements from <TreatWarningAsError>true</TreatWarningAsError>
to <TreatWarningAsError>false</TreatWarningAsError>
.
Second, add the new linker dependencies. To see the changes without manually comparing the dependencies one-by-one (on Linux):
diff <(cat c/meterpreter/source/extensions/kiwi/mimikatz/mimikatz/mimikatz.vcxproj | grep AdditionalDependencies | cut -d\> -f2 | cut -d\< -f1 | tr ';' '\n' | sort) <(cat c/meterpreter/workspace/ext_server_kiwi/ext_server_kiwi.vcxproj | grep AdditionalDependencies | head -1 | cut -d\> -f2 | cut -d\< -f1 | tr ';' '\n' | sort)
This shows the new link libs: bcrypt.lib, delayimp.lib, odbc32.lib, wbemuuid.lib. Add these as AdditionalDependencies in the workspace vcxproj file (add after all occurrences of AdditionalDependencies for making sure it is added to all targets):
<AdditionalDependencies>bcrypt.lib;delayimp.lib;odbc32.lib;wbemuuid.lib;%(AdditionalDependencies)</AdditionalDependencies>
Now the source tree is ready for building.
Building and installing
Building the project (including the kiwi extension with the updated mimikatz) is simple: just launch a “Developer Command Prompt for VS 2019" (or for other Visual Studio version, see the README of Windows C Meterpreter), and navigate to the c\meterpreter
folder inside the metasploit-payloads tree and issue make:
cd c\meterpreter
make
This builds the full meterpreter project for Windows x86 and x64 architectures as well (don’t worry about building not just the kiwi extension but the whole meterpreter, the build is super fast).
The compiled kiwi extension (as reflective dlls) should be in the output folder:
output\ext_server_kiwi.x64.dll
output\ext_server_kiwi.x86.dll
For installing, just replace the existing ext_server_kiwi.x??.dll
files in your Metasploit setup at (the root metasploit-framework folder may be at different location than /usr/share depending on your setup):
/usr/share/metasploit-framework/vendor/bundle/ruby/2.7.0/gems/metasploit-payloads-2.0.45/data/meterpreter/ext_server_kiwi.x64.dll
/usr/share/metasploit-framework/vendor/bundle/ruby/2.7.0/gems/metasploit-payloads-2.0.45/data/meterpreter/ext_server_kiwi.x86.dll
For testing, making backups of the original ext_server_kiwi.x??.dll
files in the official Metasploit setup may be useful.
Trying the up-to-date Mimikatz
After triggering a Meterpreter shell and loading the Kiwi extension, the bleeding edge functions (like RDP plaintext credential dumping) in Meterpreter should be available for playing. :)
P.S. The motivation for this project was testing EDR evasion techniques (by reflective DLL injection) which is not covered in this short article.