From efd1e71d9d29f9d5e238c5b2b6104c62bfbf64d6 Mon Sep 17 00:00:00 2001 From: ZacharyZcR Date: Sat, 9 May 2026 10:19:03 +0800 Subject: [PATCH] fix rdp invalid random panic --- mylib/grdp/login/screen.go | 8 +++++- mylib/grdp/protocol/sec/sec.go | 32 +++++++++++++++++------- mylib/grdp/protocol/sec/sec_test.go | 38 +++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 10 deletions(-) create mode 100644 mylib/grdp/protocol/sec/sec_test.go diff --git a/mylib/grdp/login/screen.go b/mylib/grdp/login/screen.go index 910b4f0..8babaec 100644 --- a/mylib/grdp/login/screen.go +++ b/mylib/grdp/login/screen.go @@ -173,7 +173,7 @@ func (g *Client) NlaAuthOnly(domain, user, pwd string, timeout int64) (bool, err func (g *Client) ProbeOSInfo(host, domain, user, pwd string, timeout int64, rdpProtocol uint32) (info map[string]any) { start := time.Now() - exitFlag := make(chan bool) + exitFlag := make(chan bool, 1) info = make(map[string]any) targetSlice := strings.Split(g.Host, ":") @@ -200,6 +200,12 @@ func (g *Client) ProbeOSInfo(host, domain, user, pwd string, timeout int64, rdpP g.pdu.SetFastPathSender(g.tpkt) g.sec.SetChannelSender(g.mcs) + g.sec.On("error", func(e error) { + err = e + glog.Error("sec error", e) + g.pdu.Emit("done") + }) + g.tpkt.On("os_info", func(infoMap map[string]any) { glog.Debug("[+] callback, get os info ........................") for k, v := range infoMap { diff --git a/mylib/grdp/protocol/sec/sec.go b/mylib/grdp/protocol/sec/sec.go index eba25d2..d4aac11 100644 --- a/mylib/grdp/protocol/sec/sec.go +++ b/mylib/grdp/protocol/sec/sec.go @@ -9,6 +9,7 @@ import ( "crypto/sha1" "encoding/hex" "errors" + "fmt" "io" "unicode/utf16" @@ -495,7 +496,9 @@ func (c *Client) connect(clientData []interface{}, serverData []interface{}, use c.enableEncryption = c.ClientCoreData().ServerSelectedProtocol == 0 if c.enableEncryption { - c.sendClientRandom() + if !c.sendClientRandom() { + return + } } c.sendInfoPkt() @@ -611,7 +614,11 @@ func sessionKeyBlob(secret, random1, random2 []byte) []byte { return ms.Bytes() } -func generateKeys(clientRandom, serverRandom []byte, method uint32) ([]byte, []byte, []byte) { +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]) @@ -633,12 +640,12 @@ func generateKeys(clientRandom, serverRandom []byte, method uint32) ([]byte, []b glog.Debug("SecondKey128:", hex.EncodeToString(initialSecondKey128)) //generate valid key if method == gcc.ENCRYPTION_FLAG_40BIT { - return gen40bits(macKey128), gen40bits(initialFirstKey128), gen40bits(initialSecondKey128) + return gen40bits(macKey128), gen40bits(initialFirstKey128), gen40bits(initialSecondKey128), nil } else if method == gcc.ENCRYPTION_FLAG_56BIT { - return gen56bits(macKey128), gen56bits(initialFirstKey128), gen56bits(initialSecondKey128) + return gen56bits(macKey128), gen56bits(initialFirstKey128), gen56bits(initialSecondKey128), nil } // method == gcc.ENCRYPTION_FLAG_128BIT - return macKey128, initialFirstKey128, initialSecondKey128 + return macKey128, initialFirstKey128, initialSecondKey128, nil } @@ -656,7 +663,7 @@ func (e *ClientSecurityExchangePDU) serialize() []byte { return buff.Bytes() } -func (c *Client) sendClientRandom() { +func (c *Client) sendClientRandom() bool { glog.Debug("send Client Random") clientRandom := core.Random(32) @@ -665,8 +672,14 @@ func (c *Client) sendClientRandom() { serverRandom := c.ServerSecurityData().ServerRandom glog.Debug("ServerRandom:", hex.EncodeToString(serverRandom)) - c.macKey, c.initialDecrytKey, c.initialEncryptKey = generateKeys(clientRandom, + var err error + c.macKey, c.initialDecrytKey, c.initialEncryptKey, err = generateKeys(clientRandom, serverRandom, c.ServerSecurityData().EncryptionMethod) + if err != nil { + glog.Error("generateKeys failed:", err) + c.Emit("error", err) + return false + } //initialize keys c.currentDecrytKey = c.initialDecrytKey @@ -681,13 +694,13 @@ func (c *Client) sendClientRandom() { if err != nil || serverPubKey == nil { glog.Error("GetPublicKey failed:", err) c.Emit("error", errors.New("failed to get server public key")) - return + return false } ret, err := rsa.EncryptPKCS1v15(rand.Reader, serverPubKey, core.Reverse(clientRandom)) if err != nil { glog.Error("EncryptPKCS1v15 err:", err) c.Emit("error", err) - return + return false } message := ClientSecurityExchangePDU{} message.EncryptedClientRandom = core.Reverse(ret) @@ -697,6 +710,7 @@ func (c *Client) sendClientRandom() { glog.Debug("message:", message) c.sendFlagged(EXCHANGE_PKT, message.serialize()) + return true } func (c *Client) sendInfoPkt() { var secFlag uint16 = INFO_PKT diff --git a/mylib/grdp/protocol/sec/sec_test.go b/mylib/grdp/protocol/sec/sec_test.go new file mode 100644 index 0000000..7906688 --- /dev/null +++ b/mylib/grdp/protocol/sec/sec_test.go @@ -0,0 +1,38 @@ +package sec + +import ( + "testing" + + "github.com/shadow1ng/fscan/mylib/grdp/glog" + "github.com/shadow1ng/fscan/mylib/grdp/protocol/t125/gcc" +) + +func TestGenerateKeysRejectsShortRandoms(t *testing.T) { + glog.SetLevel(glog.NONE) + + clientRandom := make([]byte, 32) + serverRandom := make([]byte, 32) + + if _, _, _, err := generateKeys(clientRandom, nil, gcc.ENCRYPTION_FLAG_128BIT); err == nil { + t.Fatal("expected error for empty server random") + } + + if _, _, _, err := generateKeys(nil, serverRandom, gcc.ENCRYPTION_FLAG_128BIT); err == nil { + t.Fatal("expected error for empty client random") + } +} + +func TestGenerateKeysAcceptsValidRandoms(t *testing.T) { + glog.SetLevel(glog.NONE) + + clientRandom := make([]byte, 32) + serverRandom := make([]byte, 32) + + macKey, decryptKey, encryptKey, err := generateKeys(clientRandom, serverRandom, gcc.ENCRYPTION_FLAG_128BIT) + if err != nil { + t.Fatalf("generateKeys returned error for valid randoms: %v", err) + } + if len(macKey) != 16 || len(decryptKey) != 16 || len(encryptKey) != 16 { + t.Fatalf("unexpected key lengths: mac=%d decrypt=%d encrypt=%d", len(macKey), len(decryptKey), len(encryptKey)) + } +}