shadow1ng/fscan · error

[dial err] %v

Error message

[dial err] %v

What it means

NlaAuthOnly wraps the TCP dial error when opening a raw connection to the RDP host for NLA (CredSSP/NTLMv2) credential verification. The library could not establish the initial TCP socket within the given timeout; the underlying OS/net error is interpolated into the message. No RDP protocol negotiation has happened yet, so the failure is purely at the network layer.

Source

Thrown at libs/grdp/login/screen.go:130

		password, _ := u.User.Password()
		auth.Password = password
		dailer, err = proxy.SOCKS5("tcp", address, &auth, forward)
	} else {
		dailer, err = proxy.SOCKS5("tcp", address, nil, forward)
	}

	if err != nil {
		return nil, err
	}
	return dailer, nil
}

// NlaAuthOnly 仅进行NLA认证验证凭据,不建立RDP会话
// 这样不会挤掉已登录的用户
func (g *Client) NlaAuthOnly(domain, user, pwd string, timeout int64) (bool, error) {
	conn, err := WrapperTcpWithTimeout("tcp", g.Host, time.Duration(timeout)*time.Second)
	if err != nil {
		return false, fmt.Errorf("[dial err] %v", err)
	}
	defer conn.Close()

	g.tpkt = tpkt.New(core.NewSocketLayer(conn), nla.NewNTLMv2(domain, user, pwd))
	g.x224 = x224.New(g.tpkt)

	// 设置NLA仅验证模式
	g.tpkt.SetNLAAuthOnly(true)

	// 使用 PROTOCOL_HYBRID (NLA) 协议
	g.x224.SetRequestedProtocol(x224.PROTOCOL_HYBRID)

	// 用于接收结果的通道
	resultChan := make(chan error, 1)

	// 监听错误事件(包括 ErrNLAAuthSuccess)
	g.x224.On("error", func(err error) {
		resultChan <- err

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify the host is reachable: run `nc -vz <host> 3389` (or the configured port) from the same machine.
  2. Check the wrapped error text after '[dial err]' — 'connection refused' means RDP not listening; 'i/o timeout' means firewall/latency; 'no such host' means DNS.
  3. Increase the timeout parameter passed to NlaAuthOnly.
  4. Confirm the Host field is formatted as 'host:port' and points at the RDP service.

Example fix

// before
g.Host = "192.168.1.10" // no port, or service on nonstandard port
// after
g.Host = "192.168.1.10:3389"
Defensive patterns

Strategy: retry

Validate before calling

func hostReachable(host string) error {
	conn, err := net.DialTimeout("tcp", host, 5*time.Second)
	if err != nil { return err }
	conn.Close()
	return nil
}

Try / catch

ok, err := client.NlaAuthOnly(domain, user, pwd, timeout)
if err != nil && strings.Contains(err.Error(), "[dial err]") {
	// network-layer failure: backoff and retry, don't count as bad credentials
	return retryWithBackoff(...)
}

Prevention

When it happens

Trigger: Calling Client.NlaAuthOnly (directly or via NlaAuth) with an unreachable g.Host, a closed port (typically 3389), a firewall dropping packets, DNS resolution failure, or a timeout shorter than the network RTT.

Common situations: Scanning hosts that are offline or not running RDP; wrong port in the host string (e.g. missing ':3389' or custom port); the target blocks the scanner IP; timeout value too small for slow WAN links.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06). Data as JSON: /api/errors/bc01fc992d8b35e0. Report an issue: GitHub.