shadow1ng/fscan · error

ms17010_set_timeout_error: %w

Error message

ms17010_set_timeout_error: %w

What it means

Immediately after connecting, checkMS17010VulnerabilityAt calls conn.SetDeadline to bound the whole probe; if SetDeadline itself errors, the failure is wrapped as "ms17010_set_timeout_error". This is rare and only happens when the connection is already dead or the deadline value is invalid.

Source

Thrown at plugins/services/ms17010.go:301

		common.LogError(i18n.Tr("ms17010_pipe_decode_error", err))
		return
	}
}

// checkMS17010Vulnerability 检测MS17-010漏洞 (从原始MS17010.go复制和适配)
func (p *MS17010Plugin) checkMS17010Vulnerability(ctx context.Context, ip string, session *common.ScanSession) (bool, string, bool, error) {
	return p.checkMS17010VulnerabilityAt(ctx, net.JoinHostPort(ip, "445"), session)
}

func (p *MS17010Plugin) checkMS17010VulnerabilityAt(ctx context.Context, address string, session *common.ScanSession) (bool, string, bool, error) {
	conn, err := session.DialTCP(ctx, "tcp", address, session.Config.ModuleTimeout())
	if err != nil {
		return false, "", false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_connection_error"), err)
	}
	defer func() { _ = conn.Close() }()

	if err = conn.SetDeadline(time.Now().Add(session.Config.ModuleTimeout())); err != nil {
		return false, "", false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_set_timeout_error"), err)
	}

	// SMB协议协商
	if _, err = conn.Write(negotiateProtocolRequest); err != nil {
		return false, "", false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_send_protocol_error"), err)
	}

	reply := make([]byte, 1024)
	n, readErr := conn.Read(reply)
	if readErr != nil || n < 36 {
		// 连接被关闭或响应不完整,通常表示目标不支持SMBv1
		return false, "", false, fmt.Errorf("%s", i18n.GetText("ms17010_smbv1_unsupported"))
	}

	if binary.LittleEndian.Uint32(reply[9:13]) != 0 {
		return false, "", false, fmt.Errorf("%s", i18n.GetText("ms17010_smbv1_rejected"))
	}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Inspect the wrapped error; 'use of closed network connection' means the peer or stack killed the conn — retry or treat as connection failure.
  2. Ensure session.Config.ModuleTimeout() returns a positive duration; fix the timeout configuration.
  3. Retry the probe once; an immediate RST race is usually transient.
  4. If it persists, verify no middlebox is resetting connections to port 445.

Example fix

// before
config := loadConfig() // ModuleTimeout possibly 0
// after: guarantee a sane timeout
if session.Config.ModuleTimeout() <= 0 {
    session.Config.SetModuleTimeout(10 * time.Second)
}
Defensive patterns

Strategy: retry

Validate before calling

if session.Config.ModuleTimeout() <= 0 { return fmt.Errorf("ModuleTimeout must be positive") }

Try / catch

if err != nil {
    if strings.Contains(err.Error(), "closed network connection") {
        return retryProbe(ctx, address, session) // transient RST race
    }
    return err
}

Prevention

When it happens

Trigger: conn.SetDeadline(time.Now().Add(timeout)) returns an error because the TCP connection was closed between DialTCP and SetDeadline (e.g. RST race), or the net.Conn implementation doesn't support deadlines (not the case for real TCP conns).

Common situations: Target resets the connection immediately after accept (inline IPS/firewall), extremely aggressive timeouts of zero/negative values from misconfigured ModuleTimeout, or resource exhaustion closing the fd.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/9c89584752959700. Report an issue: GitHub.