Skip to content

Commit

Permalink
DPAPI oe starting
Browse files Browse the repository at this point in the history
  • Loading branch information
gentilkiwi committed Jun 21, 2015
1 parent 81b9af7 commit 5766e29
Show file tree
Hide file tree
Showing 11 changed files with 887 additions and 125 deletions.
4 changes: 4 additions & 0 deletions mimikatz/mimikatz.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@
<ClCompile Include="..\modules\kull_m_token.c" />
<ClCompile Include="mimikatz.c" />
<ClCompile Include="modules\dpapi\kuhl_m_dpapi.c" />
<ClCompile Include="modules\dpapi\kuhl_m_dpapi_oe.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_creds.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_keys.c" />
<ClCompile Include="modules\kerberos\kuhl_m_kerberos.c" />
<ClCompile Include="modules\kerberos\kuhl_m_kerberos_ccache.c" />
Expand Down Expand Up @@ -167,6 +169,8 @@
<ClInclude Include="..\modules\kull_m_token.h" />
<ClInclude Include="mimikatz.h" />
<ClInclude Include="modules\dpapi\kuhl_m_dpapi.h" />
<ClInclude Include="modules\dpapi\kuhl_m_dpapi_oe.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_creds.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_keys.h" />
<ClInclude Include="modules\kerberos\kuhl_m_kerberos.h" />
<ClInclude Include="modules\kerberos\kuhl_m_kerberos_ccache.h" />
Expand Down
12 changes: 12 additions & 0 deletions mimikatz/mimikatz.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@
<ClCompile Include="..\modules\kull_m_key.c">
<Filter>common modules</Filter>
</ClCompile>
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_creds.c">
<Filter>local modules\dpapi\packages</Filter>
</ClCompile>
<ClCompile Include="modules\dpapi\kuhl_m_dpapi_oe.c">
<Filter>local modules\dpapi</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mimikatz.h" />
Expand Down Expand Up @@ -341,6 +347,12 @@
<ClInclude Include="..\modules\kull_m_key.h">
<Filter>common modules</Filter>
</ClInclude>
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_creds.h">
<Filter>local modules\dpapi\packages</Filter>
</ClInclude>
<ClInclude Include="modules\dpapi\kuhl_m_dpapi_oe.h">
<Filter>local modules\dpapi</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="local modules">
Expand Down
245 changes: 205 additions & 40 deletions mimikatz/modules/dpapi/kuhl_m_dpapi.c

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion mimikatz/modules/dpapi/kuhl_m_dpapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
#include "../modules/kull_m_file.h"
#include "../modules/kull_m_dpapi.h"

#include "kuhl_m_dpapi_oe.h"
#include "packages/kuhl_m_dpapi_keys.h"
#include "packages/kuhl_m_dpapi_creds.h"

const KUHL_M kuhl_m_dpapi;

NTSTATUS kuhl_m_dpapi_blob(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_dpapi_protect(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_dpapi_masterkey(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_dpapi_credhist(int argc, wchar_t * argv[]);

BOOL kuhl_m_dpapi_unprotect_raw_or_blob(LPCVOID pDataIn, DWORD dwDataInLen, LPWSTR *ppszDataDescr, int argc, wchar_t * argv[], LPCVOID pOptionalEntropy, DWORD dwOptionalEntropyLen, LPVOID *pDataOut, DWORD *dwDataOutLen, LPCWSTR pText);
void kuhl_m_dpapi_displayInfosAndFree(PVOID data, DWORD dataLen, PSID sid);
void kuhl_m_dpapi_display_MasterkeyInfosAndFree(LPCGUID guid, PVOID data, DWORD dataLen, PSID sid);
void kuhl_m_dpapi_display_CredHist(PKULL_M_DPAPI_CREDHIST_ENTRY entry, LPCVOID ntlm, LPCVOID sha1);
287 changes: 287 additions & 0 deletions mimikatz/modules/dpapi/kuhl_m_dpapi_oe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,287 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : http://creativecommons.org/licenses/by/3.0/fr/
*/
#include "kuhl_m_dpapi_oe.h"

LIST_ENTRY gDPAPI_Masterkeys = {&gDPAPI_Masterkeys, &gDPAPI_Masterkeys};
LIST_ENTRY gDPAPI_Credentials = {&gDPAPI_Credentials, &gDPAPI_Credentials};
// to do PVK
// to do CREDHIST_encrypted
// to do Masterkey_encrypted

PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY kuhl_m_dpapi_oe_masterkey_get(LPCGUID guid)
{
PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY entry;
for(entry = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) gDPAPI_Masterkeys.Flink; entry != (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) &gDPAPI_Masterkeys; entry = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) entry->navigator.Flink)
if(RtlEqualGuid(guid, &entry->guid))
return entry;
return NULL;
}

BOOL kuhl_m_dpapi_oe_masterkey_add(LPCGUID guid, LPCVOID keyHash, DWORD keyLen)
{
BOOL status = FALSE;
PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY entry;
BYTE digest[SHA_DIGEST_LENGTH];

if(guid && keyHash && keyLen)
{
if(!kuhl_m_dpapi_oe_masterkey_get(guid))
{
if(keyLen != SHA_DIGEST_LENGTH)
kull_m_crypto_hash(CALG_SHA1, keyHash, keyLen, digest, sizeof(digest));

if(entry = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) LocalAlloc(LPTR, sizeof(KUHL_M_DPAPI_OE_MASTERKEY_ENTRY)))
{
RtlCopyMemory(&entry->guid, guid, sizeof(GUID));
RtlCopyMemory(entry->keyHash, (keyLen == SHA_DIGEST_LENGTH) ? keyHash : digest, SHA_DIGEST_LENGTH);

entry->navigator.Blink = gDPAPI_Masterkeys.Blink;
entry->navigator.Flink = &gDPAPI_Masterkeys;
((PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) gDPAPI_Masterkeys.Blink)->navigator.Flink = (PLIST_ENTRY) entry;
gDPAPI_Masterkeys.Blink= (PLIST_ENTRY) entry;
}
}
}
else PRINT_ERROR(L"No GUID or Key Hash?");
return status;
}

void kuhl_m_dpapi_oe_masterkey_delete(PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY entry)
{
if(entry)
{
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Blink)->navigator.Flink = entry->navigator.Flink;
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Flink)->navigator.Blink = entry->navigator.Blink;
LocalFree(entry);
}
}

void kuhl_m_dpapi_oe_masterkey_descr(PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY entry)
{
if(entry)
{
kprintf(L"GUID:");
kull_m_string_displayGUID(&entry->guid);
kprintf(L";");

kprintf(L"KeyHash:");
kull_m_string_wprintf_hex(entry->keyHash, sizeof(entry->keyHash), 0);
kprintf(L"\n");
}
}

void kuhl_m_dpapi_oe_masterkeys_delete()
{
PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY tmp, entry;
for(entry = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) gDPAPI_Masterkeys.Flink; entry != (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) &gDPAPI_Masterkeys; entry = tmp)
{
tmp = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) entry->navigator.Flink;
kuhl_m_dpapi_oe_masterkey_delete(entry);
}
}

void kuhl_m_dpapi_oe_masterkeys_descr()
{
PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY entry;
for(entry = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) gDPAPI_Masterkeys.Flink; entry != (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) &gDPAPI_Masterkeys; entry = (PKUHL_M_DPAPI_OE_MASTERKEY_ENTRY) entry->navigator.Flink)
kuhl_m_dpapi_oe_masterkey_descr(entry);
}

PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY kuhl_m_dpapi_oe_credential_get(LPCWSTR sid, LPCGUID guid)
{
PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry;
BOOL cmpGuid, cmpSid;
for(entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) gDPAPI_Credentials.Flink; entry != (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) &gDPAPI_Credentials; entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Flink)
{
cmpSid = sid && (_wcsicmp(sid, entry->sid) == 0);
cmpGuid = guid && (entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_GUID) && RtlEqualGuid(guid, &entry->guid);

if(sid && guid)
{
if(cmpSid && cmpGuid)
return entry;
}
else if (sid)
{
if(cmpSid && !(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_GUID))
return entry;
}
else if(guid)
{
if(cmpGuid)
return entry;
}
}
return NULL;
}

BOOL kuhl_m_dpapi_oe_credential_copyEntryWithNewGuid(PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry, LPCGUID guid)
{
BOOL status = FALSE;
if(entry && guid && !(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_GUID))
status = kuhl_m_dpapi_oe_credential_add(entry->sid, guid, (entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_MD4) ? entry->md4hash : NULL, (entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_SHA1) ? entry->sha1hash : NULL, (entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_MD4p) ? entry->md4protectedhash : NULL, NULL);
return status;
}


BOOL kuhl_m_dpapi_oe_credential_addtoEntry(PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry, LPCGUID guid, LPCVOID md4hash, LPCVOID sha1hash, LPCVOID md4protectedhash, LPCWSTR password)
{
DWORD SidLen, PasswordLen;
if(entry)
{
SidLen = (DWORD) wcslen(entry->sid) * sizeof(wchar_t);
if(!(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_GUID) && guid)
{
RtlCopyMemory(&entry->guid, guid, sizeof(GUID));
entry->flags |= KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_GUID;
}
if(password)
PasswordLen = (DWORD) wcslen(password) * sizeof(wchar_t);

if(!(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_MD4) && (md4hash || password))
{
if(md4hash)
RtlCopyMemory(entry->md4hash, md4hash, LM_NTLM_HASH_LENGTH);
else
kull_m_crypto_hash(CALG_MD4, password, PasswordLen, entry->md4hash, LM_NTLM_HASH_LENGTH);

if(kull_m_crypto_hmac(CALG_SHA1, entry->md4hash, LM_NTLM_HASH_LENGTH, entry->sid, SidLen + sizeof(wchar_t), entry->md4hashDerived, SHA_DIGEST_LENGTH))
entry->flags |= KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_MD4;
}
if(!(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_SHA1) && (sha1hash || password))
{
if(sha1hash)
RtlCopyMemory(entry->sha1hash, sha1hash, SHA_DIGEST_LENGTH);
else
kull_m_crypto_hash(CALG_SHA1, password, PasswordLen, entry->sha1hash, SHA_DIGEST_LENGTH);

kull_m_crypto_hmac(CALG_SHA1, entry->sha1hash, SHA_DIGEST_LENGTH, entry->sid, SidLen + sizeof(wchar_t), entry->sha1hashDerived, SHA_DIGEST_LENGTH);
entry->flags |= KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_SHA1;
}
//if(!entry->md4protectedhash && (md4protectedhash || entry->md4hash))
//{
// if(md4protectedhash)
// RtlCopyMemory(entry->md4protectedhash, md4protectedhash, LM_NTLM_HASH_LENGTH);
// else
// if(kull_m_crypto_pkcs5_pbkdf2_hmac(CALG_SHA_256, entry->md4hash, LM_NTLM_HASH_LENGTH, sid, SidLen, 10000, sha2, sizeof(sha2), FALSE))
// kull_m_crypto_pkcs5_pbkdf2_hmac(CALG_SHA_256, sha2, sizeof(sha2), sid, SidLen, 1, (PBYTE) entry->md4protectedhash, LM_NTLM_HASH_LENGTH, FALSE);
// kull_m_crypto_hmac(CALG_SHA1, entry->md4protectedhash, LM_NTLM_HASH_LENGTH, sid, SidLen + sizeof(wchar_t), entry->md4protectedhashDerived, SHA_DIGEST_LENGTH);
//}
//kuhl_m_dpapi_oe_credential_descr(entry);
}
return TRUE;
}

BOOL kuhl_m_dpapi_oe_credential_add(LPCWSTR sid, LPCGUID guid, LPCVOID md4hash, LPCVOID sha1hash, LPCVOID md4protectedhash, LPCWSTR password)
{
BOOL status = FALSE;
PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry;

if(sid)
{
if(!(entry = kuhl_m_dpapi_oe_credential_get(sid, guid)))
{
if(entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) LocalAlloc(LPTR, sizeof(KUHL_M_DPAPI_OE_CREDENTIAL_ENTRY)))
{
entry->sid = _wcsdup(sid);
entry->navigator.Blink = gDPAPI_Credentials.Blink;
entry->navigator.Flink = &gDPAPI_Credentials;
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) gDPAPI_Credentials.Blink)->navigator.Flink = (PLIST_ENTRY) entry;
gDPAPI_Credentials.Blink= (PLIST_ENTRY) entry;
}
}
if(entry)
kuhl_m_dpapi_oe_credential_addtoEntry(entry, guid, md4hash, sha1hash, md4protectedhash, password);
}
else PRINT_ERROR(L"No SID?");
return status;
}

void kuhl_m_dpapi_oe_credential_delete(PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry)
{
PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entryB = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Blink, entryF = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Flink;

if(entry)
{
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Blink)->navigator.Flink = entry->navigator.Flink;
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Flink)->navigator.Blink = entry->navigator.Blink;
if(entry->sid)
free(entry->sid);
LocalFree(entry);
}
}

void kuhl_m_dpapi_oe_credential_descr(PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry)
{
if(entry)
{
if(entry->sid)
kprintf(L"SID:%s", entry->sid);
kprintf(L";");
if(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_GUID)
{
kprintf(L"GUID:");
kull_m_string_displayGUID(&entry->guid);
}
kprintf(L";");
if(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_MD4)
{
kprintf(L"MD4:");
kull_m_string_wprintf_hex(entry->md4hash, LM_NTLM_HASH_LENGTH, 0);
}
kprintf(L";");
if(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_SHA1)
{
kprintf(L"SHA1:");
kull_m_string_wprintf_hex(entry->sha1hash, SHA_DIGEST_LENGTH, 0);
}
kprintf(L";");
if(entry->flags & KUHL_M_DPAPI_OE_CREDENTIAL_FLAG_MD4p)
{
kprintf(L"MD4p:");
kull_m_string_wprintf_hex(entry->md4protectedhash, LM_NTLM_HASH_LENGTH, 0);
}
kprintf(L"\n");
}
}

void kuhl_m_dpapi_oe_credentials_delete()
{
PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY tmp, entry;
for(entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) gDPAPI_Credentials.Flink; entry != (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) &gDPAPI_Credentials; entry = tmp)
{
tmp = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Flink;
kuhl_m_dpapi_oe_credential_delete(entry);
}
}

void kuhl_m_dpapi_oe_credentials_descr()
{
PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY entry;
for(entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) gDPAPI_Credentials.Flink; entry != (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) &gDPAPI_Credentials; entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) entry->navigator.Flink)
kuhl_m_dpapi_oe_credential_descr(entry);
}

NTSTATUS kuhl_m_dpapi_oe_clean()
{

kuhl_m_dpapi_oe_credentials_delete();

kuhl_m_dpapi_oe_masterkeys_delete();

return STATUS_SUCCESS;
}

NTSTATUS kuhl_m_dpapi_oe_cache(int argc, wchar_t * argv[])
{
kprintf(L"\nCREDENTIALS cache\n=================\n");
kuhl_m_dpapi_oe_credentials_descr();

kprintf(L"\nMASTERKEYS cache\n================\n");
kuhl_m_dpapi_oe_masterkeys_descr();

return STATUS_SUCCESS;
}
Loading

0 comments on commit 5766e29

Please sign in to comment.