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;
}
PDOMAIN_CONTROLLER_INFO
的信息都在这里:
其中要注意的是,DC的这些API都需要调用NetApi32.lib
,并且包含dsgetdc.h
: