{"record":{"id":"9598794cda1e131f","repo":"shadow1ng/fscan","slug":"failed-to-connect-target-s","errorCode":null,"errorMessage":"failed to connect target: %s","messagePattern":"failed to connect target: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/ms17010_exp.go","lineNumber":922,"sourceCode":"\nfunc smb2Grooms(address string, grooms int) ([]net.Conn, error) {\n\theader := makeSMB2Header()\n\tvar (\n\t\tconns []net.Conn\n\t\tok    bool\n\t)\n\tdefer func() {\n\t\tif ok {\n\t\t\treturn\n\t\t}\n\t\tfor i := 0; i < len(conns); i++ {\n\t\t\t_ = conns[i].Close()\n\t\t}\n\t}()\n\tfor i := 0; i < grooms; i++ {\n\t\tconn, err := net.Dial(\"tcp\", address)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to connect target: %s\", err)\n\t\t}\n\t\t_, err = conn.Write(header)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to send SMB2 header: %s\", err)\n\t\t}\n\t\tconns = append(conns, conn)\n\t}\n\tok = true\n\treturn conns, nil\n}\n\nfunc makeSMB2Header() []byte {\n\tbuf := bytes.Buffer{}\n\tbuf.Write([]byte{0x00, 0x00, 0xFF, 0xF7, 0xFE})\n\tbuf.WriteString(\"SMB\")\n\tbuf.Write(makeZero(124))\n\treturn buf.Bytes()\n}","sourceCodeStart":904,"sourceCodeEnd":940,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/ms17010_exp.go#L904-L940","documentation":"smb2Grooms opens `grooms` parallel TCP connections to the target to spray SMB2 groom packets. The first net.Dial that fails aborts the whole loop, closes already-open connections, and returns 'failed to connect target'. This is the SMB2 stage's TCP connect failure.","triggerScenarios":"exploit → smb2Grooms(address, grooms, header) → net.Dial fails on iteration i: connection refused, host unreachable, or the target's backlog is exhausted by the groom flood itself (too many grooms).","commonSituations":"Setting grooms too high exhausts the target's connection backlog or triggers rate limiting; firewall blocks subsequent connections; target drops connections under load.","solutions":["Reduce the grooms count (default is tuned; excessive values trigger failures)","Verify port 445 reachability with a single connect test first","Check firewall/rate-limiting on the target and intermediate devices","Add backoff/retry on individual dial failures instead of aborting"],"exampleFix":"// before\nconn, err := net.Dial(\"tcp\", address)\nif err != nil { return nil, fmt.Errorf(\"failed to connect target: %s\", err) }\n// after\nconn, err := net.Dial(\"tcp\", address)\nif err != nil {\n    time.Sleep(100 * time.Millisecond)\n    conn, err = net.Dial(\"tcp\", address)\n    if err != nil { return nil, fmt.Errorf(\"failed to connect target: %s\", err) }\n}","handlingStrategy":"validation","validationCode":"// before grooms, verify a single dial succeeds and tune the count\nif err := canConnect(address); err != nil {\n    return fmt.Errorf(\"target unreachable, skipping grooms: %w\", err)\n}\nconst maxReasonableGrooms = 100\nif grooms > maxReasonableGrooms { grooms = maxReasonableGrooms }","typeGuard":null,"tryCatchPattern":"conns, err := smb2Grooms(address, grooms, header)\nif err != nil {\n    var derr *net.OpError\n    if errors.As(err, &derr) && isRefused(derr.Err) {\n        // back off and retry with fewer grooms\n    }\n    return err\n}","preventionTips":["Keep the grooms count within the target's connection backlog capacity","Pre-test connectivity with one dial before the loop","Add per-iteration backoff instead of aborting on the first failure","Check rate limiting on firewalls between scanner and target"],"tags":["network","tcp","smb2","go"],"backgroundTag":"connection-refused","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}