{"record":{"id":"cdf37bfd5f46fe98","repo":"shadow1ng/fscan","slug":"nla-auth-timeout","errorCode":null,"errorMessage":"NLA auth timeout","messagePattern":"NLA auth timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/login/screen.go","lineNumber":170,"sourceCode":"\tg.x224.On(\"connect\", func(protocol uint32) {\n\t\tresultChan <- fmt.Errorf(\"unexpected connect in auth-only mode\")\n\t})\n\n\t// 发起连接\n\terr = g.x224.Connect()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\n\t// 等待结果或超时\n\tselect {\n\tcase err := <-resultChan:\n\t\tif err == tpkt.ErrNLAAuthSuccess {\n\t\t\treturn true, nil\n\t\t}\n\t\treturn false, err\n\tcase <-time.After(time.Duration(timeout*3) * time.Second):\n\t\treturn false, fmt.Errorf(\"NLA auth timeout\")\n\t}\n}\n\nfunc (g *Client) ProbeOSInfo(host, domain, user, pwd string, timeout int64, rdpProtocol uint32) (info map[string]any) {\n\tstart := time.Now()\n\texitFlag := make(chan bool, 1)\n\tinfo = make(map[string]any)\n\n\tip := rdpTargetHost(g.Host)\n\tconn, err := WrapperTcpWithTimeout(\"tcp\", g.Host, time.Duration(timeout)*time.Second)\n\tif err != nil {\n\t\treturn\n\t}\n\tdefer conn.Close()\n\tglog.Info(conn.LocalAddr().String())\n\n\tg.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd))\n\tg.x224 = x224.New(g.tpkt)","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/login/screen.go#L152-L188","documentation":"NlaAuthOnly waits on resultChan with a deadline of timeout*3 seconds. If neither the success sentinel (tpkt.ErrNLAAuthSuccess) nor an error arrives before the deadline, it gives up with 'NLA auth timeout'. This guards against servers that accept the TCP connection but stall during CredSSP/NTLMv2 negotiation.","triggerScenarios":"Server accepts the TCP dial but never responds to NTLM NEGOTIATE/CHALLENGE messages; heavily filtered networks that allow SYN but drop payload; overloaded target; overall timeout parameter too small (deadline is 3x the passed value).","commonSituations":"Firewalled/IDS environments that tarpit RDP; slow WAN or VPN scans; Windows hosts under load (e.g. many concurrent RDP probes); credentials being checked against a slow domain controller.","solutions":["Increase the timeout argument (the effective deadline is 3x this value).","Confirm the server responds on port 3389 and NLA is enabled — a silent server often indicates filtering.","Reduce concurrent probes against the same host to avoid load-induced stalls.","Capture a packet trace of the CredSSP exchange to see which NTLM message stalls."],"exampleFix":"// before\nok, err := client.NlaAuthOnly(\"\", \"user\", \"pass\", 5)\n// after\nok, err := client.NlaAuthOnly(\"\", \"user\", \"pass\", 15)","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"ok, err := client.NlaAuthOnly(domain, user, pwd, timeout)\nif err != nil && err.Error() == \"NLA auth timeout\" {\n\t// effective deadline is timeout*3; retry once with a larger timeout\n\treturn client.NlaAuthOnly(domain, user, pwd, timeout*2)\n}","preventionTips":["Budget timeout generously; the internal deadline is 3x your value.","Avoid probing hosts through tarpitting firewalls.","Limit concurrent NLA probes per host.","Distinguish timeouts from credential failures in results."],"tags":["timeout","nla","rdp","network"],"backgroundTag":"request-timeout","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"}