shadow1ng/fscan · error
Invalid AV_PAIR list
Error message
Invalid AV_PAIR list
What it means
After reading each AV_PAIR in the NTLM CHALLENGE TargetInfo list, recvChallenge advances currIdx and expects another AV_PAIR header to still fit inside the TargetInfo block. This error means the AV_PAIR walk ran past the declared TargetInfo end — the list is not terminated/aligned as the NTLM spec requires, so the library refuses to continue parsing rather than reading garbage.
Source
Thrown at libs/grdp/protocol/tpkt/tpkt.go:257
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", "")
}
info[field] = value
}
currIdx += avPairLen + int(avPair.AvLen)
if currIdx+avPairLen > startIdx+targetInfoLen {
return fmt.Errorf("Invalid AV_PAIR list")
}
avPairBuf = bytes.NewBuffer(response[currIdx : currIdx+avPairLen])
err = binary.Read(avPairBuf, binary.LittleEndian, &avPair)
if err != nil {
return err
}
}
}
glog.Info("get os info by NLA done !")
glog.Info("=======================================")
for key, value := range info {
glog.Info(key, ":", value)
}
glog.Info("=======================================")
//判断是否存在windows域
if netBiosDomainName, exists := info["NetBIOSDomainName"]; exists {
if netBiosComputerName, exists := info["NetBIOSComputerName"]; exists {View on GitHub (pinned to 95cc12e753)
Solutions
- Ensure the full NTLM CHALLENGE packet is read before parsing (buffer/reassemble instead of a single 1024-byte Read)
- Check that avPair.AvLen is parsed from the correct offset so currIdx advances by exactly avPairLen+AvLen
- Test against a known-good Windows RDP host to isolate server-side nonconformance
- Log startIdx, targetInfoLen, and currIdx at failure to confirm whether the server data or the parser is at fault
Example fix
// before
currIdx += avPairLen + int(avPair.AvLen)
if currIdx+avPairLen > startIdx+targetInfoLen {
return fmt.Errorf("Invalid AV_PAIR list")
}
// after
currIdx += avPairLen + int(avPair.AvLen)
if currIdx == startIdx+targetInfoLen {
break // reached end of TargetInfo normally
}
if currIdx+avPairLen > startIdx+targetInfoLen {
return fmt.Errorf("Invalid AV_PAIR list")
} Defensive patterns
Strategy: validation
Validate before calling
func avPairsWellFormed(targetInfo []byte) bool {
i := 0
for i+4 <= len(targetInfo) {
avLen := int(binary.LittleEndian.Uint16(targetInfo[i+2 : i+4]))
i += 4 + avLen
if i == len(targetInfo) { return true }
if i+4 > len(targetInfo) { return false }
}
return false
} Try / catch
if err := client.Login(host, user, pass); err != nil {
if strings.Contains(err.Error(), "Invalid AV_PAIR") {
return fmt.Errorf("server sent malformed NTLM TargetInfo; try TLS-only security level: %w", err)
}
return err
} Prevention
- Validate against a known-good Windows host before blaming credentials
- Ensure the full challenge message is buffered before NTLM parsing
- Watch for AV_PAIR parsing bugs when modifying grdp internals
- Treat non-Windows RDP servers as suspects for nonconformant TargetInfo
When it happens
Trigger: StartNLA → recvChallenge against a server whose TargetInfo AV_PAIR chain has an AvLen that pushes iteration beyond startIdx+targetInfoLen, or whose TargetInfo bytes were truncated/misparsed so the terminator AV_PAIR (MsvAvEOL) is never reached in bounds.
Common situations: Servers with unusual AV_PAIR sets (e.g. Linux rdesktop-style servers, tight gateways); a prior parsing bug shifting currIdx by a few bytes; truncated network reads delivering partial TargetInfo.
Related errors
- Invalid TargetInfoLen value
- NLA auth failed: empty PubKeyAuth
- unsupported Capability type 0x%04x
- Unknown data pdu type2 0x%02x
- Unsupport slow update type 0x%x
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/30372e21f7a2c88d.
Report an issue: GitHub.