问答
发起
提问
文章
攻防
活动
Toggle navigation
首页
(current)
问答
商城
实战攻防技术
漏洞分析与复现
NEW
活动
摸鱼办
搜索
登录
注册
域渗透自动化模块一-域信息收集
安全工具
下图是域渗透自动化工具的整体架构。目前每个模块的内容已确定,并且模块具体内容也已确定。接下来就是用代码实现,这里主要采用C#来编写。招募队友,会C#,并且对域渗透自动化感兴趣的小伙伴联系我(有一定筛选,但门槛不高,详见GitHub),我们一起搞事情。
收集信息项 ----- 开发一个类似SharpHound的域信息收集工具时,需要考虑收集以下关键信息。这些信息有助于分析和理解Active Directory(AD)域的结构、权限和潜在安全漏洞。 1. 域控制器:收集所有域控制器的详细信息,包括名称、IP地址、操作系统版本等。 2. 用户信息:收集域内所有用户的信息,如用户名、全名、邮箱、电话、部门、职务、最后登录时间等。 3. 计算机信息:收集域内所有计算机的信息,包括名称、IP地址、操作系统版本、补丁状态等。 4. 组信息:收集域内所有组的信息,包括组名称、组类型(如安全组或分发组)和组成员(用户和计算机)等。 5. 组织单位(OU):收集域内所有组织单位的信息,包括OU名称、层级结构和关联的用户、计算机和组等。 6. 权限和访问控制:收集与用户、计算机、组和OU相关的访问控制列表(ACL),包括读、写、删除、管理等权限。 7. 委派权限:收集与用户、计算机和服务账户相关的Kerberos委派权限。 8. 账户策略:收集域内的账户策略,如密码策略(长度、复杂性、过期时间等)和账户锁定策略等。 9. 服务主体名称(SPN):收集与服务账户关联的服务主体名称,以检查潜在的Kerberos服务票据攻击。 10. GPO(组策略对象):收集域内所有GPO的信息,包括名称、设置、关联的OU和权限等。 11. 域信任关系:收集域与其他域和森林之间的信任关系,包括双向、单向和跨森林信任等。 12. 登录事件和审计:收集域控制器上的登录事件和审计日志,以检查潜在的异常登录行为。 在开发这个工具时,可以参考现有的域信息收集工具,如BloodHound、ADRecon等,了解如何收集、存储和分析这些信息。 确定收集代码框架 -------- ### 确定代码语言 在开始之前,先要确定采用哪种语言来开发。主要考虑运行速度、开发难易度、运行依赖等等。 | 语言 | 优点 | 缺点 | |---|---|---| | C++ | - 性能高,运行速度快 - 跨平台 - 支持面向对象和泛型编程 | - 语法繁琐 - 内存管理较复杂 - 编译时间较长 | | C# | - 语法清晰,易于学习 - 面向对象 - .NET 生态丰富 | - 主要限于 Windows 平台 - 性能略逊于 C++ | | Python | - 语法简单,易于阅读和编写 - 社区庞大,丰富的第三方库 - 跨平台 | - 运行速度较慢 - 高并发需求可能不是最佳选择 | | Go | - 简洁的语法,易于学习 - 原生支持并发 - 运行速度快 | - 社区相对较小 - 第三方库较少 - 错误处理方式可能较为不同 | | Java | - 跨平台 - 性能较高 - 成熟的生态系统和丰富的库 | - 语法相对繁琐 - 开发效率较低 - 资源消耗较大 | 综合考虑,保证性能的情况先,选择一个编写简单的语言,最终选择C#。 ### 确定收集方式 以上这些信息项通过ldap应该都可以收集,初步想法是写一个类,这个类主要通过LDAP向域进行信息收集。 在C#中通过LDAP协议进行域信息查询,大致有以下两种类型的函数。System.DirectoryServices 和 System.DirectoryServices.Protocols 都可以用于在 C# 中进行 LDAP 查询。这两个命名空间有一些区别,主要表现在易用性和灵活性方面。 **System.DirectoryServices:** - 提供了更高级别的抽象,易于使用,适用于快速开发。 - 主要针对 Microsoft Active Directory 设计,但也可用于其他 LDAP 服务器。 - 性能较低,因为在内部使用 ADSI (Active Directory Service Interfaces) 进行操作。 - 需要添加对 System.DirectoryServices.dll 的引用。 **System.DirectoryServices.Protocols:** - 提供了更底层的 LDAP 访问,更为灵活。 - 与各种 LDAP 服务器(包括非 Microsoft 服务器)兼容性更好。 - 性能较高,因为直接使用 LDAP 协议进行操作。 - 需要添加对 System.DirectoryServices.Protocols.dll 的引用。 这里选择使用前者,适用于快速开发。 ### LDAP查询过程 既然确定了使用LDAP协议来收集,那么就先需要知道LDAP方法查询的整个过程原理。大致可以分为:连接、查询条件、查询结果三部分。 连接 ```php // 设置 LDAP 服务器地址和端口 string ldapServer \= "Your\_LDAP\_Server\_Address"; int ldapPort \= 389; // 创建 LdapConnection 对象并连接到 LDAP 服务器 DirectoryEntry entry \= new DirectoryEntry($"LDAP://{ldapServer}:{ldapPort}",null,null,AuthenticationTypes.Secure); DirectorySearcher search \= new DirectorySearcher(entry); ``` 查询条件 ```php // 设置搜索过滤器以查找域控制器对象 search.Filter \= "(&(objectClass=user)(sAMAccountName=\*example\*))"; // 执行搜索并获取结果 var searchResults \= search.FindAll(); ``` 处理结果 ```php foreach (SearchResult result in searchResults) { DirectoryEntry serverEntry \= result.GetDirectoryEntry(); Console.WriteLine($"Xxx: {serverEntry.xxx}"); Console.WriteLine($"YYY: {serverEntry.YYY}"); Console.WriteLine($"Zzzz: {serverEntry.Properties\["Zzzz"\].Value.ToString()}"); Console.WriteLine("-------------------------------------------"); } ``` LDAP方式收集编写 ---------- ### 域控制器信息收集 先把信息收集项的第一条“域控制器”的信息收集完成。 根据前边的分析,查询不同的对象信息,只需要改变查询条件即可。 查询域控制器的条件 ```php search.Filter \= "(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))" ``` 这里回去域控的名称、IP地址、操作系统版本: ```php foreach (SearchResult result in searchResults) { DirectoryEntry serverEntry \= result.GetDirectoryEntry(); string Name \= serverEntry.Name; string dnshostname \= serverEntry.dnshostname string os \= serverEntry.Attributes\["operatingSystem"\]\[0\].ToString(); string osVersion \= serverEntry.Attributes\["operatingSystemVersion"\]\[0\].ToString(); Console.WriteLine("-------------------------------------------"); } ``` 这里只能从域中获取域控主机的域名,还需要查询dns来获取IP地址 ```php IPAddress\[\] ipAddresses \= Dns.GetHostAddresses(dnsHostName); IPAddress ipAddress \= ipAddresses\[0\]; ``` 运行演示 ![image-9b783cc27368e0d2b02db39d5160cf04af3f1c44.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-9b783cc27368e0d2b02db39d5160cf04af3f1c44.png) 还可以直接获取部分属性,向 DirectorySearcher 的 PropertiesToLoad 集合中添加两个属性:dnshostname 和 Ipv4address。PropertiesToLoad 集合包含在执行 LDAP 查询时应检索的属性名称。这样可以提高查询性能,因为只会返回指定的属性而不是对象的所有属性。 ```php search.PropertiesToLoad.AddRange(new string\[\] { "dnshostname", "Ipv4address" }); ``` 在这个示例中,查询结果将仅包含两个属性: - dnshostname:此属性包含计算机或其他网络设备的 DNS 主机名。 - Ipv4address:此属性包含计算机或其他网络设备的 IPv4 地址。 在执行查询后,可以通过访问 SearchResult.Properties 集合来获取这些属性的值。 当然,这只是部分信息。并且还需要进一步保存,下边把这些信息转化成json格式,保存到文件。 需要用到库`Newtonsoft.Json`把结果转化成json格式 结果文件如下 ![image-20230331103319666.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-e3febde3b7cef19d7055be1e5c2498f42ec32ea2.png) 这样,无论是后续使用,还是保存,都很方便。 ### 用户信息收集 其实也是类似,只不过是把查询条件换一下即可 ```php search.Filter \= "(&(objectCategory=person)(objectClass=user))"; ``` 运行演示 ![image-20230331102447782.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-8f19dafee43e5b4d9ba997666f8616f593831b9d.png) ### 计算机信息 获取计算机信息的查询条件 ```php search.Filter \= "(objectCategory=computer)"; ``` 运行演示 ![image-20230331103917738.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-9bcdc100b3a516a71d969509137a51fd0d716ed2.png) ### 组信息 获取组信息的查询条件 ```php search.Filter \= "(objectCategory=group)"; ``` 运行演示:这里信息太多,只打印组路径列表 ![image-20230331104829399.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-22c1cbec1c961af44d060100d0e9570ca53829b0.png) ### 组织单位 获取组织单位信息的查询条件 ```php search.Filter \= "(objectCategory=organizationalUnit)"; ``` 运行演示 ![image-20230331104937279.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-78e9b5ca5acd6b2f4eda84cb22c4e91c4f813a73.png) ### 服务主体名称(SPN) 收集服务主体名称信息的查询条件 ```php search.Filter \= "(&(objectClass=user)(servicePrincipalName=\*))"; ``` 运行演示 ![image-20230331105100291.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-a36cc38448d265f932078a5b77ecc49057f206ca.png) ### 组策略 获取组策略信息的查询条件 ```php search.Filter \= "(objectCategory=groupPolicyContainer)"; ``` 运行演示 ![image-20230331105157054.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-42e304817e44a40bf027ce5f67688d94586eec91.png) ### 委派权限 查找具有 "允许委派给服务" 权限的用户的查询条件。 此查询过滤器会查找所有具有 userAccountControl 属性值包含 524288(即 TRUSTED\_FOR\_DELEGATION 标志)的用户对象。这意味着这些用户对象已被授予无约束委派权限。这种类型的委派允许服务在用户的名义下向任何其他服务请求服务票证。 ```php search.Filter \= "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=524288))" ``` 查找具有 "不需要预身份验证" 权限的用户的查询条件 ```php search.Filter \= "(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=16777216))" ``` 获取约束委派(KCD)权限信息的查询条件。 这意味着这些用户对象已被授予约束委派权限。与无约束委派不同,约束委派仅允许服务在用户的名义下请求在 msDS-AllowedToDelegateTo 属性中列出的服务的服务票证。 ```php search.Filter \= "(&(objectCategory=user)(msDS-AllowedToDelegateTo=\*))"; ``` 资源属性基于约束委派(RBCD) ```php search.Filter \= "(&(objectCategory=computer)(msDS-AllowedToActOnBehalfOfOtherIdentity=\*))" ``` 接口查询 ---- ### 域信任关系 域信任关系有直接的接口可以直接获取 ```php // 获取当前计算机所属的域 Domain currentDomain \= Domain.GetCurrentDomain(); // 获取与当前域的信任关系 TrustRelationshipInformationCollection trustRelationships \= currentDomain.GetAllTrustRelationships(); ``` 运行演示 ![image-20230328165429996.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-08982e44cf3e909e4244c892c32f43ab5a2b5640.png) ### 访问控制列表 获取访问控制列表的查询条件 您需要将 ldapPath 变量替换为您要查询的 Active Directory 对象的 LDAP 路径。该示例将打印出对象的访问控制列表信息,包括授权的身份(Identity)、权限(Rights)和访问控制类型(Access Type)。 ```php // 将 LDAP 路径替换为您要查询的 Active Directory 对象的路径 // string ldapPath = "LDAP://la0gke.local:389/CN=krbtgt,CN=Users,DC=la0gke,DC=local"; DirectoryEntry directoryEntry \= new DirectoryEntry(ldapPath); ActiveDirectorySecurity adsSecurity \= directoryEntry.ObjectSecurity; // 获取授权规则集合 AuthorizationRuleCollection authorizationRules \= adsSecurity.GetAccessRules(true, true, typeof(NTAccount)); ``` 运行演示 ![image-20230329101317540.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-83db8b5355ff1991f5b2bedb48ddddf9fba485bd.png) 其他 -- ### 无需密码的账户 LDAP 查询条件 userAccountControl:1.2.840.113556.1.4.803:=65536 用于查找具有 PASSWD\_NOTREQD 标志的用户对象。这意味着这些用户账户可以创建时不需要密码。 ```php search.Filter \= "(userAccountControl:1.2.840.113556.1.4.803:=65536)" ``` ### 判断是否在域内 这里采用直接获取当前域名的方式来判断。获取成功说明在域内,报错则说明不在域内。 ```php var currentDomain = Domain.GetCurrentDomain(); ``` ### 获取域内指定组的成员列表 通过`PrincipalContext`类来查询。 ```php // 获取域上下文 PrincipalContext ctx \= new PrincipalContext(ContextType.Domain, domainName); // 获取组上下文 GroupPrincipal group \= GroupPrincipal.FindByIdentity(ctx, groupName); // 遍历组成员 foreach (Principal member in group.Members) { Console.WriteLine($"Name: {member.Name}, SAM Account Name: {member.SamAccountName}"); } ``` 运行演示 ![image-20230329111359164.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-12e3017d0aee164dcc9eef4d782c9ebf9ae4cff4.png) 模块一成品 ----- 最终运行效果: ![image-20230331101421492.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-c1a25843e28aad1dc239801b62328a404b1424df.png) 这里没有对收集的信息细化,主要是考虑到后续和其他模块的融合,一开始不适合固定细化。当然,收集的这些域信息也不足以完全支撑整个域渗透过程。后续会根据具体需求,再适当增减。 重点来了 ---- 下图是域渗透自动化工具的整体架构。目前每个模块的内容已确定,并且模块具体内容也已确定。接下来就是用代码实现,这里主要采用C#来编写。招募队友,会C#,并且对域渗透自动化感兴趣的小伙伴联系我(有一定筛选,但门槛不高,详见GitHub),我们一起搞事情。 GitHub地址:<https://github.com/la00gke/DomainAuto-one> ![image-20230331091825832.png](https://shs3.b.qianxin.com/attack_forum/2023/03/attach-3e8178aa575ec2c7a5070016c5fef1d70f19cc72.png) 另:筛选的同时,我也需要展示一下我的作品,见如下公众号: - \[ \] **闲聊知识铺**
发表于 2023-04-06 09:00:02
阅读 ( 7149 )
分类:
安全开发
0 推荐
收藏
0 条评论
请先
登录
后评论
Harper Scott
9 篇文章
×
发送私信
请先
登录
后发送私信
×
举报此文章
垃圾广告信息:
广告、推广、测试等内容
违规内容:
色情、暴力、血腥、敏感信息等内容
不友善内容:
人身攻击、挑衅辱骂、恶意行为
其他原因:
请补充说明
举报原因:
×
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!