projectdiscovery/nuclei · error

DsGetNCChanges: %w

Error message

DsGetNCChanges: %w

What it means

DsGetNCChanges is the core DCSync replication call that returns the secret material for the resolved DN. A wrapped failure here almost always means the DC refused replication — the classic cause is the missing 'Replicating Directory Changes' / '... All' extended right on the domain head. Other causes are an invalid DN pair or replication being administratively blocked.

Source

Thrown at pkg/js/libs/secretsdump/secretsdump.go:164

		return nil, fmt.Errorf("ds domain dn: %w", err)
	}

	// Resolve target -> DN if it doesn't already look like one.
	userDN := target
	if len(target) < 3 || (target[:3] != "CN=" && target[:3] != "cn=") {
		cracked, err := gpdrs.DsCrackNames(rpc, bind.Handle, 7 /* DS_NT4_ACCOUNT_NAME */, 1 /* DS_FQDN_1779_NAME */, []string{c.Domain + "\\" + target})
		if err != nil || len(cracked) == 0 || cracked[0].Name == "" {
			cracked, err = gpdrs.DsCrackNames(rpc, bind.Handle, 11 /* DS_UNIQUE_ID_NAME (SID) */, 1, []string{target})
			if err != nil || len(cracked) == 0 || cracked[0].Name == "" {
				return nil, fmt.Errorf("could not resolve %q to a DN", target)
			}
		}
		userDN = cracked[0].Name
	}

	res, err := gpdrs.DsGetNCChanges(rpc, bind.Handle, domainDN, userDN, dcInfo.NtdsDsaObjectGuid, rpc.GetSessionKey())
	if err != nil {
		return nil, fmt.Errorf("DsGetNCChanges: %w", err)
	}
	if len(res.Objects) == 0 {
		return nil, fmt.Errorf("DsGetNCChanges returned no objects")
	}
	o := res.Objects[0]
	out := &Secret{
		SAMAccountName:     o.SAMAccountName,
		DistinguishedName:  o.DN,
		RID:                o.RID,
		NTHash:             hex.EncodeToString(o.NTHash),
		LMHash:             hex.EncodeToString(o.LMHash),
		UserAccountControl: o.UserAccountControl,
		PwdLastSet:         o.PwdLastSet,
	}
	for _, h := range o.NTHashHistory {
		out.NTHashHistory = append(out.NTHashHistory, hex.EncodeToString(h))
	}
	for _, h := range o.LMHashHistory {

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Use Domain Admin (or SYSTEM on a DC) credentials
  2. Grant the ACE to the account: dsacls 'DC=acme,DC=local' /G acme\\user:CA;'Replicating Directory Changes All';
  3. Double-check the target DN from the crack-names result instead of hand-crafting it
  4. Inspect the wrapped RPC fault text for access-denied versus invalid-DN hints
Defensive patterns

Strategy: try-catch

Try / catch

secret, err := c.DCSync(target)
if err != nil && strings.Contains(err.Error(), "DsGetNCChanges:") {
    // replication denied: verify/obtain 'Replicating Directory Changes (All)' rights
    return err
}

Prevention

When it happens

Trigger: Syncing any principal with a plain domain user (no replication ACE); syncing sensitive principals like krbtgt where 'Replicating Directory Changes All' is required; passing a hand-built DN that does not exist under the domain NC.

Common situations: Testing with a non-privileged account captured during a engagement; permissions revoked between recon and exploitation; templates assuming Domain Admin rights on a delegated account.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/cea1396533046e9b. Report an issue: GitHub.