shadow1ng/fscan · warning

netbios_smb_session_read_failed: %w

Error message

netbios_smb_session_read_failed: %w

What it means

This error occurs in queryNetBIOSSession when reading the SMB Session Setup response (response2) from the TCP 139 connection fails. The library wraps the net.Conn.Read error with the i18n message 'netbios_smb_session_read_failed'. The session-setup request was sent, but no reply arrived before the connection died or the deadline expired.

Source

Thrown at plugins/services/netbios.go:255

		0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00, 0x72, 0x00,
		0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00, 0x33, 0x00,
		0x20, 0x00, 0x33, 0x00, 0x37, 0x00, 0x39, 0x00, 0x30, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00,
		0x72, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x20, 0x00, 0x50, 0x00, 0x61, 0x00,
		0x63, 0x00, 0x6B, 0x00, 0x20, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x00, 0x69, 0x00,
		0x6E, 0x00, 0x64, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x73, 0x00, 0x20, 0x00, 0x53, 0x00, 0x65, 0x00,
		0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 0x20, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00,
		0x33, 0x00, 0x20, 0x00, 0x35, 0x00, 0x2E, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
	}

	_, err = conn.Write(smbSessionSetup)
	if err != nil {
		return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_session_send_failed"), err)
	}

	response2 := make([]byte, 2048)
	n, err := conn.Read(response2)
	if err != nil {
		return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_session_read_failed"), err)
	}

	return p.parseNetBIOSSession(response2[:n])
}

// parseNetBIOSNames 解析NetBIOS名称查询响应
func (p *NetBIOSPlugin) parseNetBIOSNames(data []byte) (*NetBIOSInfo, error) {
	info := &NetBIOSInfo{Valid: false}

	if len(data) < 57 {
		return info, fmt.Errorf("%s", i18n.GetText("netbios_response_too_short"))
	}

	// 获取名称记录数量
	numNames := int(data[56])
	if numNames == 0 {
		return info, fmt.Errorf("%s", i18n.GetText("netbios_no_name_records"))
	}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Increase config.ModuleTimeout() to give the host time to respond to session setup.
  2. Treat EOF/reset after session setup as an auth-policy rejection and record the host as 'SMB present but session refused'.
  3. Prefer probing SMB2/3 on port 445 for hosts that don't complete legacy NetBIOS session setup.
  4. Inspect the wrapped error with errors.As(net.Error) to classify timeout vs connection reset.

Example fix

// before
response2 := make([]byte, 2048)
n, err := conn.Read(response2)
if err != nil {
    return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_session_read_failed"), err)
}

// after
response2 := make([]byte, 2048)
n, err := conn.Read(response2)
if err != nil {
    var nerr net.Error
    if errors.As(err, &nerr) && nerr.Timeout() {
        return nil, fmt.Errorf("%s: session setup response timeout for %s", i18n.GetText("netbios_smb_session_read_failed"), host)
    }
    return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_session_read_failed"), err)
}
Defensive patterns

Strategy: fallback

Validate before calling

// only read if the write succeeded and the deadline still has headroom
if time.Until(deadline) <= 0 {
    return fmt.Errorf("deadline already expired before reading session setup response")
}

Type guard

func classifySessionReadErr(err error) string {
    var nerr net.Error
    switch {
    case errors.As(err, &nerr) && nerr.Timeout():
        return "timeout"
    case errors.Is(err, io.EOF), errors.Is(err, syscall.ECONNRESET):
        return "closed-by-peer"
    default:
        return "other"
    }
}

Try / catch

response2 := make([]byte, 2048)
n, err := conn.Read(response2)
if err != nil {
    if classifySessionReadErr(err) != "other" {
        // fall back to names-only info gathered via UDP 137
        return p.queryNetBIOSNames(host, session.Config, session.State)
    }
    return nil, fmt.Errorf("%s: %w", i18n.GetText("netbios_smb_session_read_failed"), err)
}

Prevention

When it happens

Trigger: Scan -> queryNetBIOSSession sends smbSessionSetup successfully, then conn.Read(response2) errors: EOF/reset because the server rejected the NTLM session setup and closed, or i/o timeout because SetDeadline(ModuleTimeout) elapsed without a response.

Common situations: Hosts requiring NTLMv2 or SMB signing that silently drop the NTLMSSP negotiate; auth-hardened Windows hosts closing the connection on anonymous session setup; packet loss on congested networks with a short ModuleTimeout; honeypots that accept writes but never respond.

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/f33e566bd3c1432c. Report an issue: GitHub.