shadow1ng/fscan · error

SMB1 response too short: %d bytes

Error message

SMB1 response too short: %d bytes

What it means

This error is returned by smb1GetResponse when the length field of the NetBIOS header decodes to a value smaller than the 32-byte SMB header (smbHeaderSize) (plugins/services/ms17010_exp.go:203). Such a frame cannot contain a valid SMB message, and proceeding would cause an out-of-range slice when parsing buf[:smbHeaderSize]. The library throws it as a guard against malformed/hostile responses.

Source

Thrown at plugins/services/ms17010_exp.go:203

func smb1GetResponse(conn net.Conn) ([]byte, *smbHeader, error) {
	// net BIOS
	buf := make([]byte, 4)
	_, err := io.ReadFull(conn, buf)
	if err != nil {
		const format = "failed to get SMB1 response about NetBIOS session service: %s"
		return nil, nil, fmt.Errorf(format, err)
	}
	typ := buf[0]
	if typ != 0x00 {
		const format = "invalid message type 0x%02X in SMB1 response"
		return nil, nil, fmt.Errorf(format, typ)
	}
	sizeBuf := make([]byte, 4)
	copy(sizeBuf[1:], buf[1:])
	size := int(binary.BigEndian.Uint32(sizeBuf))
	// 畸形响应(size < SMB 头长度)会导致后续 buf[:smbHeaderSize] 越界 panic
	if size < smbHeaderSize {
		return nil, nil, fmt.Errorf("SMB1 response too short: %d bytes", size)
	}
	// SMB
	buf = make([]byte, size)
	_, err = io.ReadFull(conn, buf)
	if err != nil {
		const format = "failed to get SMB1 response about header: %s"
		return nil, nil, fmt.Errorf(format, err)
	}
	smbHeader := smbHeader{}
	reader := bytes.NewReader(buf[:smbHeaderSize])
	err = binary.Read(reader, binary.LittleEndian, &smbHeader)
	if err != nil {
		const format = "failed to parse SMB1 response header: %s"
		return nil, nil, fmt.Errorf(format, err)
	}
	return buf, &smbHeader, nil
}

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Treat the target as speaking broken/non-SMB protocol and skip it or flag for manual inspection
  2. Reconnect and retry once — a desynced stream is unrecoverable but a fresh one may work
  3. Log the declared size alongside the raw 4 NetBIOS bytes to diagnose the offending responder
  4. Keep the guard in place: never remove the size check, it prevents a slice-bounds panic

Example fix

// before
if size < smbHeaderSize {
    return nil, nil, fmt.Errorf("SMB1 response too short: %d bytes", size)
}
// after
if size < smbHeaderSize {
    return nil, nil, fmt.Errorf("SMB1 response too short: %d bytes (NetBIOS header: % x)", size, buf)
}
Defensive patterns

Strategy: validation

Validate before calling

// Callers can pre-validate framing assumptions only by reading; guard downstream instead
func safeParseSMBResponse(raw []byte) (*smbHeader, bool) {
    if len(raw) < smbHeaderSize { return nil, false }
    h := &smbHeader{}
    if err := binary.Read(bytes.NewReader(raw[:smbHeaderSize]), binary.LittleEndian, h); err != nil {
        return nil, false
    }
    return h, true
}

Type guard

func isMalformedFrameErr(err error) bool {
    return strings.Contains(err.Error(), "SMB1 response too short")
}

Try / catch

_, _, err := smb1GetResponse(conn)
if err != nil {
    if isMalformedFrameErr(err) {
        return markHostSuspicious() // broken or hostile SMB responder
    }
    return err
}

Prevention

When it happens

Trigger: The 3-byte NetBIOS length yields size < 32 — a truncated, corrupt, or deliberately crafted response from the peer, or reading from a desynchronized stream where arbitrary bytes form a tiny length.

Common situations: Honeypots or fuzzers sending junk frames; responses from non-SMB protocols that happen to start with 0x00; partially flushed responses captured mid-write; scanning misbehaving embedded devices.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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