Add bruteforce fallback for out-of-sync crypto

This commit is contained in:
Andrew Gutekanst
2020-02-22 11:20:52 -05:00
parent fe786617d4
commit fff92b16ed

View File

@@ -1,6 +1,7 @@
package network package network
import ( import (
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
@@ -16,6 +17,7 @@ type CryptConn struct {
readKeyRot uint32 readKeyRot uint32
sendKeyRot uint32 sendKeyRot uint32
sentPackets int32 sentPackets int32
prevRecvPacketCombinedCheck uint16
prevSendPacketCombinedCheck uint16 prevSendPacketCombinedCheck uint16
} }
@@ -25,8 +27,6 @@ func NewCryptConn(conn net.Conn) *CryptConn {
conn: conn, conn: conn,
readKeyRot: 995117, readKeyRot: 995117,
sendKeyRot: 995117, sendKeyRot: 995117,
sentPackets: 0,
prevSendPacketCombinedCheck: 0,
} }
return cc return cc
} }
@@ -41,8 +41,6 @@ func (cc *CryptConn) ReadPacket() ([]byte, error) {
return nil, err return nil, err
} }
//fmt.Printf("Header: %s\n", hex.Dump(headerData))
// Parse the data into a usable struct. // Parse the data into a usable struct.
cph, err := NewCryptPacketHeader(headerData) cph, err := NewCryptPacketHeader(headerData)
if err != nil { if err != nil {
@@ -65,10 +63,29 @@ func (cc *CryptConn) ReadPacket() ([]byte, error) {
if cph.Check0 != check0 || cph.Check1 != check1 || cph.Check2 != check2 { if cph.Check0 != check0 || cph.Check1 != check1 || cph.Check2 != check2 {
fmt.Printf("got c0 %X, c1 %X, c2 %X\n", check0, check1, check2) fmt.Printf("got c0 %X, c1 %X, c2 %X\n", check0, check1, check2)
fmt.Printf("want c0 %X, c1 %X, c2 %X\n", cph.Check0, cph.Check1, cph.Check2) fmt.Printf("want c0 %X, c1 %X, c2 %X\n", cph.Check0, cph.Check1, cph.Check2)
fmt.Printf("headerData:\n%s\n", hex.Dump(headerData))
fmt.Printf("encryptedPacketBody:\n%s\n", hex.Dump(encryptedPacketBody))
// Attempt to bruteforce it.
fmt.Println("Crypto out of sync? Attempting bruteforce")
for key := byte(0); key < 255; key++ {
out, combinedCheck, check0, check1, check2 = crypto.Decrypt(encryptedPacketBody, 0, &key)
//fmt.Printf("Key: 0x%X\n%s\n", key, hex.Dump(out))
if cph.Check0 == check0 && cph.Check1 == check1 && cph.Check2 == check2 {
fmt.Printf("Bruceforce successful, override key: 0x%X\n", key)
// Try to fix key for subsequent packets?
//cc.readKeyRot = (uint32(key) << 1) + 999983
cc.prevRecvPacketCombinedCheck = combinedCheck
return out, nil
}
}
return nil, errors.New("decrypted data checksum doesn't match header") return nil, errors.New("decrypted data checksum doesn't match header")
} }
_ = combinedCheck cc.prevRecvPacketCombinedCheck = combinedCheck
return out, nil return out, nil
} }