{"record":{"id":"bb2926491bff27a5","repo":"shadow1ng/fscan","slug":"ms17010-tree-response-incomplete","errorCode":null,"errorMessage":"ms17010_tree_response_incomplete","messagePattern":"ms17010_tree_response_incomplete","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/ms17010.go","lineNumber":365,"sourceCode":"\t\t}\n\t}\n\n\t// 树连接请求\n\tuserID := reply[32:34]\n\ttreeConnect := append([]byte(nil), treeConnectRequest...)\n\ttreeConnect[32] = userID[0]\n\ttreeConnect[33] = userID[1]\n\n\tif _, err = conn.Write(treeConnect); err != nil {\n\t\treturn false, osVersion, false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"ms17010_send_tree_error\"), err)\n\t}\n\n\tn, readErr = conn.Read(reply)\n\tif readErr != nil || n < 36 {\n\t\tif readErr != nil {\n\t\t\treturn false, osVersion, false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"ms17010_read_tree_error\"), readErr)\n\t\t}\n\t\treturn false, osVersion, false, fmt.Errorf(\"%s\", i18n.GetText(\"ms17010_tree_response_incomplete\"))\n\t}\n\n\t// 命名管道请求\n\ttreeID := reply[28:30]\n\ttransNamedPipe := append([]byte(nil), transNamedPipeRequest...)\n\ttransNamedPipe[28] = treeID[0]\n\ttransNamedPipe[29] = treeID[1]\n\ttransNamedPipe[32] = userID[0]\n\ttransNamedPipe[33] = userID[1]\n\n\tif _, err = conn.Write(transNamedPipe); err != nil {\n\t\treturn false, osVersion, false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"ms17010_send_pipe_error\"), err)\n\t}\n\n\tn, readErr = conn.Read(reply)\n\tif readErr != nil || n < 36 {\n\t\tif readErr != nil {\n\t\t\treturn false, osVersion, false, fmt.Errorf(\"%s: %w\", i18n.GetText(\"ms17010_read_pipe_error\"), readErr)","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/ms17010.go#L347-L383","documentation":"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.","triggerScenarios":"checkMS17010VulnerabilityAt returns this when conn.Read(reply) after the tree-connect write succeeds with readErr == nil but n < 36.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"n, readErr := conn.Read(reply)\nif readErr == nil && n < 36 {\n    // short clean reply: verify device actually speaks SMB before probing\n}\n// pre-check: nmap --script smb-protocols host","typeGuard":"func isValidSMBHeader(n int, reply []byte) bool {\n    return n >= 36 && string(reply[4:8]) == \"\\xffSMB\"\n}","tryCatchPattern":"if readErr == nil && n < 36 {\n    return fmt.Errorf(\"tree connect response incomplete (%d bytes)\", n) // retry or mark host non-SMB\n}","preventionTips":["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."],"tags":["smb","network","ms17-10","truncated-response"],"backgroundTag":"empty-response-body","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}