{"record":{"id":"36739d127941d458","repo":"shadow1ng/fscan","slug":"invalid-rdp-random-length-client-d-server-d","errorCode":null,"errorMessage":"invalid RDP random length: client=%d server=%d","messagePattern":"invalid RDP random length: client=(.+?) server=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"libs/grdp/protocol/sec/sec.go","lineNumber":619,"sourceCode":"@summary: Generate master secret\n@param secret: secret\n@param clientRandom : client random\n@param serverRandom : server random\n*/\nfunc sessionKeyBlob(secret, random1, random2 []byte) []byte {\n\tsh1 := saltedHash([]byte(\"X\"), secret, random1, random2)\n\tsh2 := saltedHash([]byte(\"YY\"), secret, random1, random2)\n\tsh3 := saltedHash([]byte(\"ZZZ\"), secret, random1, random2)\n\tms := bytes.NewBuffer(nil)\n\tms.Write(sh1)\n\tms.Write(sh2)\n\tms.Write(sh3)\n\treturn ms.Bytes()\n\n}\nfunc generateKeys(clientRandom, serverRandom []byte, method uint32) ([]byte, []byte, []byte, error) {\n\tif len(clientRandom) < 32 || len(serverRandom) < 32 {\n\t\treturn nil, nil, nil, fmt.Errorf(\"invalid RDP random length: client=%d server=%d\", len(clientRandom), len(serverRandom))\n\t}\n\n\tb := &bytes.Buffer{}\n\tb.Write(clientRandom[:24])\n\tb.Write(serverRandom[:24])\n\tpreMasterHash := b.Bytes()\n\tglog.Debug(\"preMasterHash:\", hex.EncodeToString(preMasterHash))\n\n\tmasterHash := masterSecret(preMasterHash, clientRandom, serverRandom)\n\tglog.Debug(\"masterHash:\", hex.EncodeToString(masterHash))\n\n\tsessionKey := sessionKeyBlob(masterHash, clientRandom, serverRandom)\n\tglog.Debug(\"sessionKey:\", hex.EncodeToString(sessionKey))\n\n\tmacKey128 := sessionKey[:16]\n\tinitialFirstKey128 := finalHash(sessionKey[16:32], clientRandom, serverRandom)\n\tinitialSecondKey128 := finalHash(sessionKey[32:48], clientRandom, serverRandom)\n","sourceCodeStart":601,"sourceCodeEnd":637,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/libs/grdp/protocol/sec/sec.go#L601-L637","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func randomsValid(clientRandom, serverRandom []byte) bool {\n\treturn len(clientRandom) >= 32 && len(serverRandom) >= 32\n}\nif !randomsValid(cr, sr) { return errors.New(\"short RDP randoms; refusing key derivation\") }","typeGuard":"func hasFullRandoms(cr, sr []byte) bool { return len(cr) >= 32 && len(sr) >= 32 }","tryCatchPattern":"m1, m2, k, err := generateKeys(clientRandom, serverRandom, method)\nif err != nil && strings.HasPrefix(err.Error(), \"invalid RDP random length\") {\n\treturn fmt.Errorf(\"server sent malformed/random data; aborting standard-security handshake: %w\", err)\n}","preventionTips":["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."],"tags":["rdp","crypto","key-derivation","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}