shadow1ng/fscan · warning
ms17010_pipe_response_incomplete
Error message
ms17010_pipe_response_incomplete
What it means
This error is returned by checkMS17010VulnerabilityAt when the SMB named-pipe probe response is shorter than the 36 bytes needed to parse the SMB header (including the fields checked at reply[9..12]). The code only throws it when conn.Read returned no error but delivered fewer than 36 bytes, meaning the target closed or truncated the response mid-conversation. It signals the target did not reply with a well-formed Trans/NamedPipe response, so the MS17-010 (EternalBlue) check cannot proceed.
Source
Thrown at plugins/services/ms17010.go:385
// 命名管道请求
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)
}
return false, osVersion, false, fmt.Errorf("%s", i18n.GetText("ms17010_pipe_response_incomplete"))
}
// 漏洞检测 - 关键检查点
if reply[9] == 0x05 && reply[10] == 0x02 && reply[11] == 0x00 && reply[12] == 0xc0 {
trans2SessionSetup := append([]byte(nil), trans2SessionSetupRequest...)
trans2SessionSetup[28] = treeID[0]
trans2SessionSetup[29] = treeID[1]
trans2SessionSetup[32] = userID[0]
trans2SessionSetup[33] = userID[1]
if _, err = conn.Write(trans2SessionSetup); err != nil {
return true, osVersion, false, nil
}
n, readErr = conn.Read(reply)
if readErr != nil || n < 36 {
return true, osVersion, false, nil
}
View on GitHub (pinned to 95cc12e753)
Solutions
- Retry the check; TCP fragmentation can make a single conn.Read return <36 bytes even from a vulnerable host — add a read loop until 36 bytes accumulate or a timeout expires.
- Verify the target actually exposes SMB on port 445 and is a Windows host worth probing (nmap -sV -p445).
- Confirm no middlebox/IPS is stripping SMB responses between scanner and target.
- If it persists, treat the host as not MS17-010 confirmable and fall back to other detection methods (patch level, os fingerprint).
Example fix
// before
n, readErr = conn.Read(reply)
if readErr != nil || n < 36 {
...
return false, osVersion, false, fmt.Errorf("%s", i18n.GetText("ms17010_pipe_response_incomplete"))
}
// after
for n < 36 {
m, rerr := conn.Read(reply[n:])
if rerr != nil {
return false, osVersion, false, fmt.Errorf("%s: %w", i18n.GetText("ms17010_read_pipe_error"), rerr)
}
if m == 0 {
return false, osVersion, false, fmt.Errorf("%s", i18n.GetText("ms17010_pipe_response_incomplete"))
}
n += m
} Defensive patterns
Strategy: retry
Validate before calling
// before probing
func probeSMB(host string) bool {
conn, err := net.DialTimeout("tcp", host+":445", 3*time.Second)
if err != nil { return false }
defer conn.Close()
_ = conn.SetDeadline(time.Now().Add(3 * time.Second))
return true
} Type guard
func isCompleteSMBReply(n int, err error) bool {
return err == nil && n >= 36
} Try / catch
if err := checkMS17010Vulnerability(host); err != nil {
if strings.Contains(err.Error(), "ms17010_pipe_response_incomplete") {
// transient truncation: retry once with longer deadline, then mark inconclusive
time.Sleep(500 * time.Millisecond)
err = checkMS17010Vulnerability(host)
}
if err != nil { log.Printf("MS17-010 check inconclusive for %s: %v", host, err) }
} Prevention
- Only run the check against confirmed Windows/SMB hosts on port 445.
- Use a read loop until a full SMB header (36 bytes) is received rather than a single conn.Read.
- Set generous connection deadlines for slow or WAN targets.
- Treat inconclusive results as 'unknown', not 'not vulnerable', and re-verify with a second method.
When it happens
Trigger: Calling checkMS17010Vulnerability (which invokes checkMS17010VulnerabilityAt) against a host whose TCP 445 connection accepts the transNamedPipeRequest but returns a partial (<36 byte) reply — e.g. a non-Windows Samba variant, a hardened/patched host dropping the payload, an IDS/resetting middlebox truncating the response, or a slow host whose partial read races with the single conn.Read call.
Common situations: Scanning hardened or patched Windows hosts that RST or close early; probing Linux/Samba servers that respond with malformed or minimal SMB data; scanning through firewalls/NAT devices that mangle SMB traffic; overloaded hosts delivering fragmented responses that the single unlooped conn.Read does not reassemble.
Related errors
- netbios_smb_negotiate_send_failed: %w
- ms17010_connection_error: %w
- ms17010_send_protocol_error: %w
- ms17010_smbv1_unsupported
- ms17010_send_session_error: %w
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/64c5c6e3677a66dc.
Report an issue: GitHub.