shadow1ng/fscan · error

read %s

Error message

read %s

What it means

In the tpkt layer's NLA (CredSSP) flow, StartNLA reads the server's NTLM CHALLENGE response from the socket with a single Conn.Read into a 1024-byte buffer. If the read fails (connection reset, timeout, closed socket), the error is wrapped as 'read %s'. The failed network read means the CredSSP handshake could not continue.

Source

Thrown at libs/grdp/protocol/tpkt/tpkt.go:124

}

func (t *TPKT) StartNLA() error {
	err := t.StartTLS()
	if err != nil {
		glog.Info("start tls failed", err)
		return err
	}
	req := nla.EncodeDERTRequest([]nla.Message{t.ntlm.GetNegotiateMessage()}, nil, nil)
	_, err = t.Conn.Write(req)
	if err != nil {
		glog.Info("send NegotiateMessage", err)
		return err
	}

	resp := make([]byte, 1024)
	n, err := t.Conn.Read(resp)
	if err != nil {
		return fmt.Errorf("read %s", err)
	} else {
		glog.Debug("StartNLA Read success")
	}
	return t.recvChallenge(resp[:n])
}

func (t *TPKT) recvChallenge(data []byte) error {
	//own add
	glog.Debug("start recv challenge......")
	info := make(map[string]any)
	type NTLMChallenge struct {
		Signature              [8]byte
		MessageType            uint32
		TargetNameLen          uint16
		TargetNameMaxLen       uint16
		TargetNameBufferOffset uint32
		NegotiateFlags         uint32
		ServerChallenge        uint64

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Inspect the wrapped error: 'connection reset by peer' usually means the server rejected the NEGOTIATE message or credentials.
  2. Verify NLA is enabled and compatible (NTLMv2) on the target host.
  3. Add/retry with a longer socket timeout on the underlying connection.
  4. Retest connectivity (dial + banner) to rule out transient network failure before rerunning StartNLA.
Defensive patterns

Strategy: retry

Validate before calling

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

Try / catch

err := tpktLayer.StartNLA(user, pwd, domain)
if err != nil && strings.HasPrefix(err.Error(), "read ") {
	if errors.Is(err, io.EOF) || strings.Contains(err.Error(), "reset") {
		// server dropped us mid-CredSSP: check credentials/policy, then retry with backoff
	}
	return retryWithBackoff(...)
}

Prevention

When it happens

Trigger: Calling StartNLA and the TCP read of the challenge message fails: server closes the connection abruptly, network interruption mid-handshake, TLS/Negotiate mismatch causing the server to drop the client, or read timeout.

Common situations: Servers rejecting credentials and closing the socket during CredSSP; RST from firewalls/IDS mid-handshake; target host rebooting; slow networks exceeding socket deadlines.

Related errors


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