Skip to content

[review only] Kerberos relay stack + ESC8 (CVE-2026-20929) - #1

Closed
Pushpenderrathore wants to merge 9 commits into
masterfrom
feature/kerberos-relay-esc8
Closed

[review only] Kerberos relay stack + ESC8 (CVE-2026-20929)#1
Pushpenderrathore wants to merge 9 commits into
masterfrom
feature/kerberos-relay-esc8

Conversation

@Pushpenderrathore

@Pushpenderrathore Pushpenderrathore commented Jul 26, 2026

Copy link
Copy Markdown
Owner

Self-review copy of rapid7#21709, opened in this fork so Copilot and coderabbitai can review it without touching upstream.

Scope: native Kerberos relay stack plus an ESC8 (AD CS Web Enrollment) target. 16 new files, no deletions, specs included.

Not for merge. This PR exists purely to collect an automated review pass.

Foundation for native Kerberos relay support. Introduces the
Msf::Exploit::Remote::Relay::Kerberos namespace mirroring the NTLM relay
stack, with an ApReqExtractor mixin that pulls a captured AP-REQ out of a
client's GSS-API token (SPNEGO NegTokenInit or bare GSS Kerberos) as
opaque DER, ready to forward to a relay target unchanged.

The AP-REQ is carried, never interpreted: the client identity lives in
its encrypted ticket/authenticator which only the real target decrypts,
and ApReq#decode is not implemented. RelayResult struct added for the
target-reply contract. Covered by rspec (round-trip plus NTLM/malformed
rejection).
Rename the AP-REQ extractor mixin to GssApReq to reflect that it now
handles both directions of the relay: extract_ap_req captures a client's
AP-REQ (relay server side), and the new build_spnego_ap_req re-wraps that
captured AP-REQ into a fresh GSS-SPNEGO blob to send to the real service
(relay target side).

build_spnego_ap_req is the inverse of extract_ap_req and takes raw AP-REQ
DER rather than an ApReq model object, since the relay only holds the
captured bytes. Round-trip specs assert extract -> build -> extract yields
the original AP-REQ unchanged.
Adds Relay::Kerberos::Target::HTTP::Client, which replays a captured
AP-REQ to a real HTTP service (e.g. AD CS Web Enrollment for ESC8) over a
SPNEGO Negotiate exchange. Unlike NTLM there is no challenge/response
round-trip: the AP-REQ is a complete credential sent in a single request,
and on success the connection is left open for the calling module to
issue authenticated follow-up requests.

Moves RelayResult under the Target namespace to satisfy Zeitwerk (a
target.rb file must define Target); mirrors the NTLM target layout.
Verified by rspec (network mocked: Negotiate header contents and
success/failure status mapping) and the zeitwerk_compliance spec.
Adds Relay::Kerberos::RelayHandler, the Kerberos counterpart to the NTLM
server client's relay_ntlmssp. Given an incoming client GSS token it
dispatches on mechanism (Kerberos vs NTLM), extracts the AP-REQ, relays
it to the target client, and fires the module's on_relay_success /
on_relay_failure and on_relay_end callbacks.

The flow is one-shot: a captured AP-REQ is a complete credential, so there
is no challenge/response and no per-identity target selection. The AP-REQ
is cryptographically bound to the SPN the attacker coerced, so it can only
be relayed to the matching service. Non-Kerberos tokens return nil so a
shared relay server falls through to its NTLM path.

Protocol-agnostic (the RubySMB/HTTP server plumbing lives in the including
class); verified by rspec with the target and callbacks mocked.
Adds Target.create_client, the single dispatch point mapping a relay
target's protocol to its per-protocol client (HTTP today). Mirrors the
NTLM server client's create_relay_client and gives the relay server one
call to build a target, with a clear extension point for future protocols
(e.g. LDAP). Verified by rspec.
Adds SMB::Relay::Kerberos::ServerClient, the Kerberos counterpart to the
NTLM SMB relay server client. A coerced host authenticates over SMB; its
SMB2 SessionSetup carries a SPNEGO-wrapped Kerberos AP-REQ. The one-shot
flow (no NTLM-style challenge) captures that AP-REQ, dispatches on
kerberos_ap_req?, selects the SPN-matching target, builds its client via
Target.create_client, and relays through relay_kerberos.

The relay decision (target selection + relay) is split into
relay_captured_ap_req and unit-tested; the SMB status mapping is tested
too. The exact SMB2 SessionSetup response shape is noted as pending live
validation against a coerced client. Validated on real lab data: the
capture->extract->rebuild->Negotiate->CA(200) forward path was confirmed
end-to-end against the live AD CS server.
Adds SMB::Relay::Kerberos::Server, the Kerberos counterpart to the NTLM
SMB relay server. Accepts incoming SMB connections from coerced hosts and
services each with a Kerberos ServerClient on its own thread, completing
the capture side of the relay. Mirrors the NTLM server's dialect set,
accept loop, and shutdown; closed?/close behaviour is unit-tested.
Wire the Kerberos relay stack (CVE-2026-20929) through to AD CS ESC8
certificate enrollment:

- Make Relay::Kerberos::Target::HTTP::Client drivable as an HTTP client
  (request_raw/request_cgi/send_recv delegators) so WebEnrollment can
  reuse the Kerberos-authenticated connection after a successful relay.
- Add SMB::Relay::Kerberos::RelayServer, a reusable module-level mixin
  mirroring SMB::RelayServer that runs the Kerberos SMB relay server and
  keeps the relay server decoupled from the target action.
- Add auxiliary/server/relay/esc8_kerberos, which relays a captured
  AP-REQ to AD CS Web Enrollment and requests a certificate. Identity is
  supplied via RELAY_IDENTITY since the AP-REQ carries it encrypted.
@github-actions

Copy link
Copy Markdown

Thanks for your pull request! As part of our landing process, we manually verify that all modules work as expected.

We've added the additional-testing-required label to indicate that additional testing is required before this pull request can be merged.
For maintainers, this means visiting here.

coderabbitai[bot]

This comment was marked as outdated.

Repository owner deleted a comment from coderabbitai Bot Jul 26, 2026
Repository owner deleted a comment from coderabbitai Bot Jul 26, 2026
Repository owner deleted a comment from coderabbitai Bot Jul 26, 2026
@Pushpenderrathore

Copy link
Copy Markdown
Owner Author

Closing: opened only to collect an automated review pass, which is not available here.

Pushpenderrathore pushed a commit that referenced this pull request Aug 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant