{"record":{"id":"7e13ac8e59d5d437","repo":"shadow1ng/fscan","slug":"ms17010-read-tree-error-w","errorCode":null,"errorMessage":"ms17010_read_tree_error: %w","messagePattern":"ms17010_read_tree_error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/services/ms17010.go","lineNumber":363,"sourceCode":"\t\t\t\t}\n\t\t\t}\n\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 {","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/plugins/services/ms17010.go#L345-L381","documentation":"The Tree Connect request was sent but the checker's read of the tree-connect response failed or returned fewer than 36 bytes. Unlike the truncated-error sibling, this variant wraps the underlying read error (%w), preserving the cause (timeout, reset, EOF).","triggerScenarios":"checkMS17010VulnerabilityAt returns this when conn.Read(reply) after the tree-connect write returns a non-nil readErr (regardless of byte count).","commonSituations":"Read deadline expired while the server deliberates on the tree connect; server RST the connection due to policy on IPC$; packet loss on WAN links; Samba crashed handling the request.","solutions":["Increase the socket read deadline and retry once — transient latency is the most common cause.","Unwrap the cause: io.EOF/RESET means the peer closed (see tree_response_incomplete path for short-but-clean reads); timeout means raise the deadline or mark inconclusive.","Confirm IPC$ share is reachable with `net use \\\\host\\IPC$` from a Windows client to validate server behavior independently.","Fall back to a non-SMB verification (patch level via WMI with credentials, or vulnerability scanner) when SMB probing keeps failing."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"conn.SetReadDeadline(time.Now().Add(readTimeout))\nn, readErr := conn.Read(reply)\nif readErr != nil { /* retry probe; inspect errors.Is(readErr, os.ErrDeadlineExceeded) */ }","typeGuard":null,"tryCatchPattern":"n, readErr := conn.Read(reply)\nif readErr != nil {\n    if errors.Is(readErr, os.ErrDeadlineExceeded) {\n        return ErrTimeoutRetry // raise timeout or retry\n    }\n    return fmt.Errorf(\"tree connect read failed: %w\", readErr)\n}","preventionTips":["Distinguish timeout vs reset via errors.Is on the wrapped cause.","Increase read deadlines for WAN scans.","Validate IPC$ reachability with an independent client before blaming the probe.","Fall back to credentialed or external verification when SMB reads keep failing."],"tags":["smb","network","timeout","ms17-10"],"backgroundTag":"network-request-failed","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"}