projectdiscovery/nuclei · error
smb connect: %w
Error message
smb connect: %w
What it means
Thrown by secretsdump.Client.DCSync when the underlying goimpacket SMB client cannot establish a session to the domain controller on port 445. Connect() covers the TCP dial, SMB negotiation, and NTLM session setup, so an unreachable host, a filtered port, an SMB1-only server, or invalid credentials all surface here. The root cause is wrapped with %w and appears after the colon.
Source
Thrown at pkg/js/libs/secretsdump/secretsdump.go:114
// DCSync replicates secrets for a single principal (DN, sAMAccountName, or
// SID) and returns its NT/LM hashes, hash history and account state.
//
// @example
// ```javascript
// const sd = require('nuclei/secretsdump');
// const c = new sd.Client('dc01', 'acme.local', 'admin', 'P@ss');
// const s = c.DCSync('Administrator');
// log(s.nthash);
// ```
func (c *Client) DCSync(target string) (*Secret, error) {
c.nj.Require(target != "", "target cannot be empty")
if !protocolstate.IsHostAllowed(c.nj.ExecutionId(), c.Host) {
return nil, protocolstate.ErrHostDenied.Msgf(c.Host)
}
smb := gpsmb.NewClient(c.target, c.creds)
if err := smb.Connect(); err != nil {
return nil, fmt.Errorf("smb connect: %w", err)
}
defer smb.Close()
pipe, err := smb.OpenPipe("\\PIPE\\lsass")
if err != nil {
// Fall back to drsuapi-named pipe; both are accepted by the DC.
pipe, err = smb.OpenPipe("lsass")
if err != nil {
return nil, fmt.Errorf("open lsass pipe: %w", err)
}
}
rpc := gprpc.NewClient(pipe)
if err := rpc.BindAuth(gpdrs.UUID, gpdrs.MajorVersion, gpdrs.MinorVersion, c.creds); err != nil {
return nil, fmt.Errorf("drsuapi bind: %w", err)
}
defer func() {
_ = rpc.Transport.Close()
}()View on GitHub (pinned to 265b3a3dec)
Solutions
- Verify reachability: nmap -p445 <dc> or Test-NetConnection <dc> -Port 445
- Verify credentials independently with smbclient //<dc>/IPC$ or crackmapexec smb <dc> -u user -p pass
- Confirm the DC hostname resolves (use the FQDN, e.g. dc01.acme.local)
- Ensure the server supports SMB2/3 — goimpacket does not negotiate SMB1
- For pass-the-hash, call c.SetHash(':<nthash>') instead of a plaintext password
Example fix
// before
const c = new sd.Client('dc01', 'acme.local', 'admin', 'WrongPass');
const s = c.DCSync('krbtgt'); // smb connect: ...session setup failed
// after
const c = new sd.Client('dc01.acme.local', 'acme.local', 'admin', 'P@ss');
const s = c.DCSync('krbtgt'); Defensive patterns
Strategy: retry
Validate before calling
// Verify 445 reachable and credentials valid before DCSync
conn, err := net.DialTimeout("tcp", net.JoinHostPort(dc, "445"), 5*time.Second)
if err != nil { return fmt.Errorf("dc unreachable: %w", err) }
_ = conn.Close() Try / catch
secret, err := c.DCSync(target)
if err != nil {
if strings.Contains(err.Error(), "smb connect:") {
// transport/session failure: check reachability, creds, SMB2 support
log.Printf("dc %s connect/auth failed: %v", c.Host, err)
}
return err
} Prevention
- Pre-verify port 445 reachability with a fast TCP dial before DCSync
- Validate credentials with a cheap SMB session (smbclient/crackmapexec) first
- Use the DC's FQDN, not short names, to avoid DNS ambiguity
- Prefer SetHash(':nthash') for pass-the-hash instead of reconstructing passwords
When it happens
Trigger: Calling new sd.Client('dc01','acme.local','user','pass').DCSync('krbtgt') when dc01 does not resolve, port 445 is firewalled, the password is wrong (session setup fails inside Connect), or the target speaks SMB1 only.
Common situations: Typo in the DC hostname; egress firewall or VPN blocking 445; credentials captured for a different domain; lab DC that only allows Kerberos; account locked out or expired password.
Related errors
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/e52c1a6e86c7c497.
Report an issue: GitHub.