shadow1ng/fscan · error

Invalid TargetInfoLen value

Error message

Invalid TargetInfoLen value

What it means

recvChallenge parses the NTLM CHALLENGE message returned by the RDP server during NLA (CredSSP) authentication. TargetInfoLen says how many bytes of AV_PAIR (server version, domain, SPN, etc.) data follow, and the library throws this when TargetInfoBufferOffset + TargetInfoLen runs past the end of the received buffer — i.e. the length/offset fields are inconsistent with the actual packet, so the TargetInfo would be read out of bounds. It guards against malformed or truncated server responses.

Source

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

		2: "NetBIOSDomainName",
		3: "FQDN", // DNS Computer Name
		4: "DNSDomainName",
		5: "DNSTreeName",
		7: "Timestamp",
		9: "MsvAvTargetName",
	}

	type AVPair struct {
		AvID  uint16
		AvLen uint16
		// Value (variable)
	}
	var avPairLen = 4
	targetInfoLen := int(responseData.TargetInfoLen)
	if targetInfoLen > 0 {
		startIdx := int(responseData.TargetInfoBufferOffset)
		if startIdx+targetInfoLen > len(response) {
			return fmt.Errorf("Invalid TargetInfoLen value")
		}
		var avPair AVPair
		avPairBuf := bytes.NewBuffer(response[startIdx : startIdx+avPairLen])
		err = binary.Read(avPairBuf, binary.LittleEndian, &avPair)
		if err != nil {
			return err
		}
		currIdx := startIdx
		for avPair.AvID != 0 {
			if field, exists := AvIDMap[avPair.AvID]; exists {
				var value string
				r := response[currIdx+avPairLen : currIdx+avPairLen+int(avPair.AvLen)]
				if avPair.AvID == 7 {
					unixStamp := binary.LittleEndian.Uint64(r)/10000000 - 11644473600
					tm := time.Unix(int64(unixStamp), 0)
					value = tm.Format("2006-01-02 15:04:05")
				} else {
					value = strings.ReplaceAll(string(r), "\x00", "")

View on GitHub (pinned to 95cc12e753)

Solutions

  1. Verify the target is a genuine Windows RDP endpoint; test with a standard client (mstsc) to confirm the server's NLA handshake is well-formed
  2. Upgrade grdp to a version that reassembles fragmented TPKT packets before parsing NTLM messages
  3. Bypass middleboxes/gateways that rewrite CredSSP traffic, or connect directly to the RDP host
  4. Capture the handshake (Wireshark, CREDSSP/NTLM filters) and compare TargetInfoLen/offset against the real message to identify where parsing diverges

Example fix

// before
if startIdx+targetInfoLen > len(response) {
    return fmt.Errorf("Invalid TargetInfoLen value")
}
// after
if startIdx < 0 || targetInfoLen < 0 || startIdx+targetInfoLen > len(response) {
    return fmt.Errorf("Invalid TargetInfoLen value (offset=%d len=%d pkt=%d)", startIdx, targetInfoLen, len(response))
}
Defensive patterns

Strategy: validation

Validate before calling

if targetInfoLen > 0 {
    off := int(responseData.TargetInfoBufferOffset)
    if off < 0 || off+targetInfoLen > len(response) {
        return fmt.Errorf("truncated TargetInfo: need %d bytes at %d, have %d", targetInfoLen, off, len(response))
    }
}

Type guard

func validTargetInfo(response []byte, offset, length int) bool {
    return offset >= 0 && length >= 0 && offset+length <= len(response)
}

Try / catch

if err := client.Login(host, user, pass); err != nil {
    if strings.Contains(err.Error(), "Invalid TargetInfoLen") {
        // malformed NTLM challenge from server; try non-NLA mode or different endpoint
        return fallbackToNonNLA(host, user, pass)
    }
    return err
}

Prevention

When it happens

Trigger: Calling StartNLA when the server's NTLM CHALLENGE message declares a TargetInfoLen/TargetInfoBufferOffset pair whose range extends beyond the bytes actually captured (truncated read, misparsed negotiate response, or a non-Windows/gateway server sending a nonstandard NTLM message).

Common situations: Connecting to RDP behind gateways/proxies or non-Windows servers that emit shortened or reordered NTLM CHALLENGE fields; packet fragmentation causing response buffer truncation; TLS interception appliances mangling the CredSSP handshake.

Related errors


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