shadow1ng/fscan · error
invalid RDP random length: client=%d server=%d
Error message
invalid RDP random length: client=%d server=%d
What it means
generateKeys derives the RDP session encryption keys from the client and server randoms, which must each be at least 32 bytes. If either random is shorter (garbled or truncated server/client random data from the GCC conference create response), the library refuses to derive keys with this error.
Source
Thrown at libs/grdp/protocol/sec/sec.go:619
@summary: Generate master secret
@param secret: secret
@param clientRandom : client random
@param serverRandom : server random
*/
func sessionKeyBlob(secret, random1, random2 []byte) []byte {
sh1 := saltedHash([]byte("X"), secret, random1, random2)
sh2 := saltedHash([]byte("YY"), secret, random1, random2)
sh3 := saltedHash([]byte("ZZZ"), secret, random1, random2)
ms := bytes.NewBuffer(nil)
ms.Write(sh1)
ms.Write(sh2)
ms.Write(sh3)
return ms.Bytes()
}
func generateKeys(clientRandom, serverRandom []byte, method uint32) ([]byte, []byte, []byte, error) {
if len(clientRandom) < 32 || len(serverRandom) < 32 {
return nil, nil, nil, fmt.Errorf("invalid RDP random length: client=%d server=%d", len(clientRandom), len(serverRandom))
}
b := &bytes.Buffer{}
b.Write(clientRandom[:24])
b.Write(serverRandom[:24])
preMasterHash := b.Bytes()
glog.Debug("preMasterHash:", hex.EncodeToString(preMasterHash))
masterHash := masterSecret(preMasterHash, clientRandom, serverRandom)
glog.Debug("masterHash:", hex.EncodeToString(masterHash))
sessionKey := sessionKeyBlob(masterHash, clientRandom, serverRandom)
glog.Debug("sessionKey:", hex.EncodeToString(sessionKey))
macKey128 := sessionKey[:16]
initialFirstKey128 := finalHash(sessionKey[16:32], clientRandom, serverRandom)
initialSecondKey128 := finalHash(sessionKey[32:48], clientRandom, serverRandom)
View on GitHub (pinned to 95cc12e753)
Solutions
- Dump the clientRandom/serverRandom lengths at the call site to see which side is short.
- Verify the GCC Conference Create Response parser handles all server variants (per MS-RDPBCGR 2.2.1.4).
- Update the grdp library — fixes for nonstandard server randoms may exist upstream.
- If the server truly sends short randoms, the connection cannot use standard RDP encryption; require NLA/TLS mode instead.
Defensive patterns
Strategy: validation
Validate before calling
func randomsValid(clientRandom, serverRandom []byte) bool {
return len(clientRandom) >= 32 && len(serverRandom) >= 32
}
if !randomsValid(cr, sr) { return errors.New("short RDP randoms; refusing key derivation") } Type guard
func hasFullRandoms(cr, sr []byte) bool { return len(cr) >= 32 && len(sr) >= 32 } Try / catch
m1, m2, k, err := generateKeys(clientRandom, serverRandom, method)
if err != nil && strings.HasPrefix(err.Error(), "invalid RDP random length") {
return fmt.Errorf("server sent malformed/random data; aborting standard-security handshake: %w", err)
} Prevention
- Prefer NLA/TLS mode, which avoids the standard-security random exchange path.
- Validate GCC parsing when connecting to non-Windows RDP servers.
- Keep grdp updated for embedded/appliance RDP server quirks.
- Log random lengths when debugging appliance connections.
When it happens
Trigger: The parsed ClientRandom/ServerRandom arrays from the GCC data are shorter than 32 bytes — usually caused by malformed or incorrectly parsed server GCC response, or by a nonstandard RDP server sending abbreviated randoms.
Common situations: Connecting to non-Windows or embedded RDP servers (thin clients, appliances) with protocol quirks; corrupted TLS-decrypted handshake data; a parser bug mis-slicing the GCC fields.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- unsupported Capability type 0x%04x
- Unknown data pdu type2 0x%02x
- Unsupport slow update type 0x%x
- invalid length in Auto-Reconnect packet
- unsupported version of Auto-Reconnect packet
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/36739d127941d458.
Report an issue: GitHub.