/hunt-ldap
Hunt LDAP Injection and XPath Injection — authentication bypass, blind char-by-char attribute exfiltration, AD user/group enumeration, XML-store XPath bypass. Covers the LDAP special-character set (* ( ) \\ NUL /), search-filter-context vs DN-injection, parenthesis-balancing,
$ npx -y skills add elementalsouls/Claude-BugHunter --skill hunt-ldap --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/hunt-ldap
Context preview
The summary Claude sees to decide when to auto-load this skill.
Hunt LDAP Injection and XPath Injection — authentication bypass, blind char-by-char attribute exfiltration, AD user/group enumeration, XML-store XPath bypass. Covers the LDAP special-character set (* ( ) \\ NUL /), search-filter-context vs DN-injection, parenthesis-balancing,
SKILL.md
hunt-ldap.SKILL.mdname: hunt-ldap
description: "Hunt LDAP Injection and XPath Injection — authentication bypass, blind char-by-char attribute exfiltration, AD user/group enumeration, XML-store XPath bypass. Covers the LDAP special-character set (* ( ) \\ NUL /), search-filter-context vs DN-injection, parenthesis-balancing, AND/OR filter logic, and {SSHA}/{CRYPT} userPassword exfil on non-AD directories. Use when target uses LDAP/AD authentication, corporate SSO with a directory backend, an address-book/people-search API, or XML-based data stores queried with XPath."
sources: hackerone_public, owasp, portswigger
report_count: 0HUNT-LDAP — LDAP Injection & XPath Injection
> Grounding note: LDAP injection is rarely disclosed with verbatim payloads on > public platforms (most live on internal-pentest reports). This skill is > grounded in the **OWASP LDAP Injection Prevention / Testing Guide > (WSTG-INPV-06)**, **PortSwigger Web Security Academy (LDAP injection)**, and > the **RFC 4515** filter grammar — all publicly verifiable references rather > than invented HackerOne IDs. Do not cite a report you cannot link.
Crown Jewel Targets
LDAP injection that bypasses authentication = **Critical**. Blind attribute exfiltration of credentials/secrets = **High**. AD enumeration alone = Medium-High.
**Highest-value chains:**
- **LDAP auth bypass** — close the `uid` filter and append an always-true OR so the
bind/search returns the admin entry without a valid password.
- **Blind attribute exfil** — char-by-char extraction of an attribute value via a
boolean oracle (login success/failure, result count, or response length).
- **userPassword hash exfil (non-AD only)** — on OpenLDAP/389-DS the
`userPassword` attribute can hold `{SSHA}`/`{CRYPT}` hashes that ARE readable by query. See the AD-vs-generic warning below.
- **XPath injection auth bypass** — `' or '1'='1` against XML-backed auth.
---
CRITICAL — Active Directory vs generic LDAP
Do **not** conflate the two. They behave very differently:
| | Generic LDAP (OpenLDAP, 389-DS, ApacheDS) | Active Directory | |---|---|---| | Password attribute | `userPassword` — may hold `{SSHA}`/`{MD5}`/`{CRYPT}` and **is readable** if ACL allows | `unicodePwd` — **write-only**, never returned by any search | | Hash exfil via injection | **Possible** where ACLs leak `userPassword` | **Not possible** — there is no readable hash attribute over LDAP | | Useful enum attrs | `uid`, `cn`, `mail`, `userPassword` | `sAMAccountName`, `userPrincipalName`, `mail`, `memberOf`, `description` (often holds plaintext secrets!) |
**Do not tell a reader that blind LDAP injection yields AD password hashes — it does not.** `unicodePwd` is write-only. Against AD, the win is enumeration (`sAMAccountName`, `memberOf`, `description`/`info` fields that admins misuse to store passwords) and auth bypass — not hash dumping. The hash-exfil technique applies **only** to non-AD directories exposing `userPassword`.
---
Attack Surface Signals
Corporate SSO / intranet login pages (often legacy Java/Spring/PHP)
Windows + IIS + "integrated" directory auth
/api/ldap/* /api/directory/* /people /address-book /search?dir=
"Find a colleague" / org-chart / employee-search features
XML-backed config or auth → XPath injection candidate
Error strings that confirm an LDAP backend:
javax.naming.NameNotFoundException
javax.naming.directory.InvalidSearchFilterException
LDAP: error code 49 - 80090308 (AD invalid creds / bind failure)
com.sun.jndi.ldap.* / System.DirectoryServices / ldap_search():
"Bad search filter" / net.ldap (Go) / python-ldap SERVER_DOWN
---
LDAP filter grammar (RFC 4515) — why injection works
A login filter is typically built by string-concat:
(&(uid=<USERNAME>)(userPassword=<PASSWORD>))
`&` = AND, `|` = OR, `!` = NOT. **Filters are prefix/Polish notation** — the operator comes first and every sub-filter is parenthesised. To inject you must (a) escape the current `(uid=...)` group, (b) inject your own logic, and (c) leave the overall parenthesis count **balanced** or the server throws a filter-syntax error instead of executing.
The special-character set — TEST EACH ONE
These characters are syntactically meaningful and MUST be escaped by a safe app (RFC 4515 §3). If the app reflects an error or behaves differently when you send them raw, the input is unescaped → injectable:
| Char | Filter escape | Why it matters | |------|---------------|----------------| | `*` | `\2a` | wildcard — matches any value | | `(` | `\28` | opens a filter group | | `)` | `\29` | closes a filter group | | `\` | `\5c` | escape char itself | | NUL | `\00` | string terminator — truncates filter in C-backed servers | | `/` | (DN context) | RDN separator — relevant for DN injection |
**Search-filter context vs DN injection** are different bugs:
- **Search-filter injection** (most common): your input lands inside a
`(attr=VALUE)` filter. Payloads use `* ( ) & | !`.
- **DN injection**: your input is concatenated into a Distinguished Name
(`uid=VALUE,ou=people,dc=corp`). Here `,` `=` `+` `"` `\` `<` `>` `;` and `/` matter, and a `*` is NOT a wildcard. Test both — the payloads do not transfer.
---
Step-by-Step Hunting Methodology
Phase 1 — Confirm an LDAP backend (baseline first)
# ALWAYS capture a control response first — you compare everything to this.
BASE=$(curl -s -o /dev/null -w "%{http_code}|%{size_download}|%{time_total}" \
-X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username":"validlookinguser","password":"wrongpass"}')
echo "BASELINE (valid-format, wrong pw): $BASE"
# Send a single unbalanced paren. A SAFE (escaping) app → identical baseline.
# An INJECTABLE app → 500 / filter-syntax error / different size.
curl -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username":"test)","password":"x"}' | grep -iE \
"naming|InvalidSearchFilter|Read more
name: hunt-ldap
description: "Hunt LDAP Injection and XPath Injection — authentication bypass, blind char-by-char attribute exfiltration, AD user/group enumeration, XML-store XPath bypass. Covers the LDAP special-character set (* ( ) \\ NUL /), search-filter-context vs DN-injection, parenthesis-balancing, AND/OR filter logic, and {SSHA}/{CRYPT} userPassword exfil on non-AD directories. Use when target uses LDAP/AD authentication, corporate SSO with a directory backend, an address-book/people-search API, or XML-based data stores queried with XPath."
sources: hackerone_public, owasp, portswigger
report_count: 0HUNT-LDAP — LDAP Injection & XPath Injection
> Grounding note: LDAP injection is rarely disclosed with verbatim payloads on > public platforms (most live on internal-pentest reports). This skill is > grounded in the **OWASP LDAP Injection Prevention / Testing Guide > (WSTG-INPV-06)**, **PortSwigger Web Security Academy (LDAP injection)**, and > the **RFC 4515** filter grammar — all publicly verifiable references rather > than invented HackerOne IDs. Do not cite a report you cannot link.
Crown Jewel Targets
LDAP injection that bypasses authentication = **Critical**. Blind attribute exfiltration of credentials/secrets = **High**. AD enumeration alone = Medium-High.
**Highest-value chains:**
- **LDAP auth bypass** — close the `uid` filter and append an always-true OR so the
bind/search returns the admin entry without a valid password.
- **Blind attribute exfil** — char-by-char extraction of an attribute value via a
boolean oracle (login success/failure, result count, or response length).
- **userPassword hash exfil (non-AD only)** — on OpenLDAP/389-DS the
`userPassword` attribute can hold `{SSHA}`/`{CRYPT}` hashes that ARE readable by query. See the AD-vs-generic warning below.
- **XPath injection auth bypass** — `' or '1'='1` against XML-backed auth.
---
CRITICAL — Active Directory vs generic LDAP
Do **not** conflate the two. They behave very differently:
| | Generic LDAP (OpenLDAP, 389-DS, ApacheDS) | Active Directory | |---|---|---| | Password attribute | `userPassword` — may hold `{SSHA}`/`{MD5}`/`{CRYPT}` and **is readable** if ACL allows | `unicodePwd` — **write-only**, never returned by any search | | Hash exfil via injection | **Possible** where ACLs leak `userPassword` | **Not possible** — there is no readable hash attribute over LDAP | | Useful enum attrs | `uid`, `cn`, `mail`, `userPassword` | `sAMAccountName`, `userPrincipalName`, `mail`, `memberOf`, `description` (often holds plaintext secrets!) |
**Do not tell a reader that blind LDAP injection yields AD password hashes — it does not.** `unicodePwd` is write-only. Against AD, the win is enumeration (`sAMAccountName`, `memberOf`, `description`/`info` fields that admins misuse to store passwords) and auth bypass — not hash dumping. The hash-exfil technique applies **only** to non-AD directories exposing `userPassword`.
---
Attack Surface Signals
Corporate SSO / intranet login pages (often legacy Java/Spring/PHP) Windows + IIS + "integrated" directory auth /api/ldap/* /api/directory/* /people /address-book /search?dir= "Find a colleague" / org-chart / employee-search features XML-backed config or auth → XPath injection candidate Error strings that confirm an LDAP backend: javax.naming.NameNotFoundException javax.naming.directory.InvalidSearchFilterException LDAP: error code 49 - 80090308 (AD invalid creds / bind failure) com.sun.jndi.ldap.* / System.DirectoryServices / ldap_search(): "Bad search filter" / net.ldap (Go) / python-ldap SERVER_DOWN
---
LDAP filter grammar (RFC 4515) — why injection works
A login filter is typically built by string-concat:
(&(uid=<USERNAME>)(userPassword=<PASSWORD>))
`&` = AND, `|` = OR, `!` = NOT. **Filters are prefix/Polish notation** — the operator comes first and every sub-filter is parenthesised. To inject you must (a) escape the current `(uid=...)` group, (b) inject your own logic, and (c) leave the overall parenthesis count **balanced** or the server throws a filter-syntax error instead of executing.
The special-character set — TEST EACH ONE
These characters are syntactically meaningful and MUST be escaped by a safe app (RFC 4515 §3). If the app reflects an error or behaves differently when you send them raw, the input is unescaped → injectable:
| Char | Filter escape | Why it matters | |------|---------------|----------------| | `*` | `\2a` | wildcard — matches any value | | `(` | `\28` | opens a filter group | | `)` | `\29` | closes a filter group | | `\` | `\5c` | escape char itself | | NUL | `\00` | string terminator — truncates filter in C-backed servers | | `/` | (DN context) | RDN separator — relevant for DN injection |
**Search-filter context vs DN injection** are different bugs:
- **Search-filter injection** (most common): your input lands inside a
`(attr=VALUE)` filter. Payloads use `* ( ) & | !`.
- **DN injection**: your input is concatenated into a Distinguished Name
(`uid=VALUE,ou=people,dc=corp`). Here `,` `=` `+` `"` `\` `<` `>` `;` and `/` matter, and a `*` is NOT a wildcard. Test both — the payloads do not transfer.
---
Step-by-Step Hunting Methodology
Phase 1 — Confirm an LDAP backend (baseline first)
# ALWAYS capture a control response first — you compare everything to this.
BASE=$(curl -s -o /dev/null -w "%{http_code}|%{size_download}|%{time_total}" \
-X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username":"validlookinguser","password":"wrongpass"}')
echo "BASELINE (valid-format, wrong pw): $BASE"
# Send a single unbalanced paren. A SAFE (escaping) app → identical baseline.
# An INJECTABLE app → 500 / filter-syntax error / different size.
curl -s -X POST https://$TARGET/api/login \
-H "Content-Type: application/json" \
-d '{"username":"test)","password":"x"}' | grep -iE \
"naming|InvalidSearchFilter|A self-contained Claude skill bundle for bug hunting and external red-team work · 82 skills · 15 slash commands · 681 disclosed-report patterns across 24 core vulnerability classes · enterprise identity + infrastructure attack matrices · engagement-folder
Repo: elementalsouls/Claude-BugHunter
Other skills on claude-bughunter.
- /apk-redteam-pipeline
End-to-end Android APK red-team pipeline — automated APK acquisition (Play Store + apkpure + apkmirror fallback), jadx decompilation, secret/URL/JWT/Firebase grep, pinned-cert extraction, exported-component enumeration, Frida runtime instrumentation templates, intent-injection
Open skill - /bb-local-toolkit
Local-tooling companion to the bug-bounty orchestrator — carries the SAME complete bug-bounty workflow, but reach for THIS variant when you also need to resolve where tools, wordlists, and clones are installed on the local machine (jhaddix, SecLists, trufflehog, ffuf, dalfox,
Open skill - /bb-methodology
Use at the START of any bug bounty hunting session, when switching targets, or when feeling lost about what to do next. Master orchestrator that combines the 5-phase non-linear hunting workflow with the critical thinking framework (developer psychology, anomaly detection,
Open skill - /bug-bounty
Complete bug bounty workflow — recon (subdomain enumeration, asset discovery, fingerprinting, HackerOne scope, source code audit), pre-hunt learning (disclosed reports, tech stack research, mind maps, threat modeling), vulnerability hunting (IDOR, SSRF, XSS, auth bypass, CSRF,
Open skill - /bugcrowd-reporting
Bugcrowd-specific reporting tactics complementing report-writing: VRT category search-and-fallback strategy when no exact match exists, manual severity override when VRT defaults underrate impact, severity-request paragraph as first body section, OOS-clause rebuttal templates
Open skill - /cloud-iam-deep
Cloud IAM red-team attack chain across AWS, Azure, GCP — focused on EXTERNAL exploitation paths and post-credential-discovery privilege analysis. Covers IAM enumeration (aws iam, az role, gcloud iam), STS/AssumeRole chaining, Azure Managed Identity abuse (via SSRF/leak), GCP
Open skill

