fix rdp invalid random panic

This commit is contained in:
ZacharyZcR
2026-05-09 10:19:03 +08:00
parent 22039d3d21
commit efd1e71d9d
3 changed files with 68 additions and 10 deletions
+7 -1
View File
@@ -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) { func (g *Client) ProbeOSInfo(host, domain, user, pwd string, timeout int64, rdpProtocol uint32) (info map[string]any) {
start := time.Now() start := time.Now()
exitFlag := make(chan bool) exitFlag := make(chan bool, 1)
info = make(map[string]any) info = make(map[string]any)
targetSlice := strings.Split(g.Host, ":") 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.pdu.SetFastPathSender(g.tpkt)
g.sec.SetChannelSender(g.mcs) 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) { g.tpkt.On("os_info", func(infoMap map[string]any) {
glog.Debug("[+] callback, get os info ........................") glog.Debug("[+] callback, get os info ........................")
for k, v := range infoMap { for k, v := range infoMap {
+23 -9
View File
@@ -9,6 +9,7 @@ import (
"crypto/sha1" "crypto/sha1"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
"io" "io"
"unicode/utf16" "unicode/utf16"
@@ -495,7 +496,9 @@ func (c *Client) connect(clientData []interface{}, serverData []interface{}, use
c.enableEncryption = c.ClientCoreData().ServerSelectedProtocol == 0 c.enableEncryption = c.ClientCoreData().ServerSelectedProtocol == 0
if c.enableEncryption { if c.enableEncryption {
c.sendClientRandom() if !c.sendClientRandom() {
return
}
} }
c.sendInfoPkt() c.sendInfoPkt()
@@ -611,7 +614,11 @@ func sessionKeyBlob(secret, random1, random2 []byte) []byte {
return ms.Bytes() 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 := &bytes.Buffer{}
b.Write(clientRandom[:24]) b.Write(clientRandom[:24])
b.Write(serverRandom[:24]) b.Write(serverRandom[:24])
@@ -633,12 +640,12 @@ func generateKeys(clientRandom, serverRandom []byte, method uint32) ([]byte, []b
glog.Debug("SecondKey128:", hex.EncodeToString(initialSecondKey128)) glog.Debug("SecondKey128:", hex.EncodeToString(initialSecondKey128))
//generate valid key //generate valid key
if method == gcc.ENCRYPTION_FLAG_40BIT { 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 { } 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 // 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() return buff.Bytes()
} }
func (c *Client) sendClientRandom() { func (c *Client) sendClientRandom() bool {
glog.Debug("send Client Random") glog.Debug("send Client Random")
clientRandom := core.Random(32) clientRandom := core.Random(32)
@@ -665,8 +672,14 @@ func (c *Client) sendClientRandom() {
serverRandom := c.ServerSecurityData().ServerRandom serverRandom := c.ServerSecurityData().ServerRandom
glog.Debug("ServerRandom:", hex.EncodeToString(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) serverRandom, c.ServerSecurityData().EncryptionMethod)
if err != nil {
glog.Error("generateKeys failed:", err)
c.Emit("error", err)
return false
}
//initialize keys //initialize keys
c.currentDecrytKey = c.initialDecrytKey c.currentDecrytKey = c.initialDecrytKey
@@ -681,13 +694,13 @@ func (c *Client) sendClientRandom() {
if err != nil || serverPubKey == nil { if err != nil || serverPubKey == nil {
glog.Error("GetPublicKey failed:", err) glog.Error("GetPublicKey failed:", err)
c.Emit("error", errors.New("failed to get server public key")) c.Emit("error", errors.New("failed to get server public key"))
return return false
} }
ret, err := rsa.EncryptPKCS1v15(rand.Reader, serverPubKey, core.Reverse(clientRandom)) ret, err := rsa.EncryptPKCS1v15(rand.Reader, serverPubKey, core.Reverse(clientRandom))
if err != nil { if err != nil {
glog.Error("EncryptPKCS1v15 err:", err) glog.Error("EncryptPKCS1v15 err:", err)
c.Emit("error", err) c.Emit("error", err)
return return false
} }
message := ClientSecurityExchangePDU{} message := ClientSecurityExchangePDU{}
message.EncryptedClientRandom = core.Reverse(ret) message.EncryptedClientRandom = core.Reverse(ret)
@@ -697,6 +710,7 @@ func (c *Client) sendClientRandom() {
glog.Debug("message:", message) glog.Debug("message:", message)
c.sendFlagged(EXCHANGE_PKT, message.serialize()) c.sendFlagged(EXCHANGE_PKT, message.serialize())
return true
} }
func (c *Client) sendInfoPkt() { func (c *Client) sendInfoPkt() {
var secFlag uint16 = INFO_PKT var secFlag uint16 = INFO_PKT
+38
View File
@@ -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))
}
}