0x00 简介

在内网中的域环境下,获取域控的信息有很多种,但是在此之前都是以经验来判定的。

而MSDN文档的API从未接触过,因此想多扩展一下知识面。

地址:https://docs.microsoft.com/zh-cn/windows/desktop/api/_ad/

0x01 域用户的登录过程

参考:https://blog.csdn.net/jsd2honey/article/details/54340439

  • 1、客户端发起net logon 服务会 运行DsGetDcName这个API。
  • 2、DsGetDcName就会从客户端收集DNS和site的信息。
  • 3、Net logon 会根据IP地址找到相应的DNS服务器,并发送一个 DNS Query的数据包,查询site内所有DC的SRV记录和A记录。
  • 4、DNS 服务器会返回一个 response数据包,里面包含site内所有DC的一张表格。如果DNS服务器不返回这个数据包,那么locate DC就失败了。
  • 5、然后客户端 的netlogon就根据这张表格给每台DC都发送一个 Query 数据包。如果有多台DC都给客户端返回response的数据包,那么客户端以最先返回 response 为准,即客户端成功locate 到这台DC。但是如果没有DC返回响应数据包,那么locate DC也会失败。

0x02 尝试学习API

微软有一个Example:https://docs.microsoft.com/zh-cn/windows/desktop/AD/enumerating-domain-controllers

准备花时间慢慢啃~

第一个API - DsGetDcName

DSGETDCAPI DWORD DsGetDcNameA(
  IN LPCSTR                    ComputerName,
  IN LPCSTR                    DomainName,
  IN GUID                      *DomainGuid,
  IN LPCSTR                    SiteName,
  IN ULONG                     Flags,
  OUT PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo
);

关于参数的介绍都在文档中。

0x03 获取域控信息

我写了一个例子,获取域控的地址、GUID等信息,都保存在DomainControllerInfo

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <DsGetDC.h>
#include <Lm.h>
#pragma  comment(lib, "NetApi32.lib")


int main()
{
	PDOMAIN_CONTROLLER_INFO  dcInfo;
	DWORD ret = DsGetDcName(
		NULL,
		NULL,
		NULL,
		NULL,
		DS_KDC_REQUIRED,
		&dcInfo
	);
	if (ret == ERROR_SUCCESS) {
		GUID * dc_guid = &dcInfo->DomainGuid;
		wprintf(L"DomainControllerName : %s \n ", dcInfo->DomainControllerName);
		wprintf(L"DomainControllerAddress : %s \n ", dcInfo->DomainControllerAddress);
		wprintf(L"DomainGuid : %x-%x-%x-%x \n", dc_guid->Data1, dc_guid->Data2, dc_guid->Data3, dc_guid->Data4);
		NetApiBufferFree(dcInfo);
	}
	else {
		wprintf(L"Error : %d \n ", GetLastError());
	}
	
	system("pause");
    return 0;
}

2019-04-12-23-59-57

PDOMAIN_CONTROLLER_INFO的信息都在这里:

2019-04-13-00-00-52

其中要注意的是,DC的这些API都需要调用NetApi32.lib,并且包含dsgetdc.h

2019-04-13-00-02-54