shadow1ng/fscan · error
ms17010_tree_response_incomplete
Error message
ms17010_tree_response_incomplete
What it means
The tree-connect response read returned cleanly (no error) but fewer than 36 bytes — not even a full SMB header. The library throws this to distinguish 'short/clean reply' from an actual read error, signaling an incomplete or malformed tree-connect response.
Source
Thrown at plugins/services/ms17010.go:365
}
}
// 树连接请求
userID := reply[32:34]
treeConnect := append([]byte(nil), treeConnectRequest...)
treeConnect[32] = userID[0]
treeConnect[33] = userID[1]
if _, err = conn.Write(treeConnect); err != nil {
return false, osVersion, false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_send_tree_error"), err)
}
n, readErr = conn.Read(reply)
if readErr != nil || n < 36 {
if readErr != nil {
return false, osVersion, false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_read_tree_error"), readErr)
}
return false, osVersion, false, fmt.Errorf("%s", i18n.GetText("ms17010_tree_response_incomplete"))
}
// 命名管道请求
treeID := reply[28:30]
transNamedPipe := append([]byte(nil), transNamedPipeRequest...)
transNamedPipe[28] = treeID[0]
transNamedPipe[29] = treeID[1]
transNamedPipe[32] = userID[0]
transNamedPipe[33] = userID[1]
if _, err = conn.Write(transNamedPipe); err != nil {
return false, osVersion, false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_send_pipe_error"), err)
}
n, readErr = conn.Read(reply)
if readErr != nil || n < 36 {
if readErr != nil {
return false, osVersion, false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_read_pipe_error"), readErr)View on GitHub (pinned to 95cc12e753)
Solutions
- Retry the probe; a single short read can result from network segmentation race — the checker does a single Read, so retrying rebuilds the full exchange.
- If reproducible, the device on 445 is not speaking SMB correctly — verify with `nmap -sV -p445` or smb-protocols script and exclude it from SMB-based checks.
- Treat as inconclusive for MS17-10 rather than vulnerable.
- Check MTU/fragmentation issues on the path that could clip the response.
Defensive patterns
Strategy: retry
Validate before calling
n, readErr := conn.Read(reply)
if readErr == nil && n < 36 {
// short clean reply: verify device actually speaks SMB before probing
}
// pre-check: nmap --script smb-protocols host Type guard
func isValidSMBHeader(n int, reply []byte) bool {
return n >= 36 && string(reply[4:8]) == "\xffSMB"
} Try / catch
if readErr == nil && n < 36 {
return fmt.Errorf("tree connect response incomplete (%d bytes)", n) // retry or mark host non-SMB
} Prevention
- Validate the '\xffSMB' magic before parsing header fields.
- Exclude non-SMB devices listening on 445 from SMB checks.
- Investigate MTU/fragmentation clipping responses on the scan path.
- Retry once; a single short read is often a segmentation race.
When it happens
Trigger: checkMS17010VulnerabilityAt returns this when conn.Read(reply) after the tree-connect write succeeds with readErr == nil but n < 36.
Common situations: Server sends a partial packet then closes (aggressive policy or buggy SMB implementation); TCP segmentation plus an early close; non-standard devices on 445 that answer with tiny payloads; middleware that echoes a minimal banner.
Related errors
- ms17010_smbv1_unsupported
- ms17010_send_session_error: %w
- ms17010_session_failed
- ms17010_send_tree_error: %w
- ms17010_read_tree_error: %w
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/bb2926491bff27a5.
Report an issue: GitHub.