📶 [WIP] RouterOS WinBox bruteforce
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
mtbf/crypt.go

105 lines
2.4 KiB

package main
// crypt.go: various cryptographical operations
import (
"crypto/hmac"
cryptoRand "crypto/rand"
"crypto/sha1"
"crypto/sha256"
mathRand "math/rand"
"strings"
)
func init() {
registerSwitch("crypt-predictable-rng", "disable secure rng and use a pseudorandom preseeded rng")
mathRand.Seed(300)
}
func getSHA1Digest(data []byte) []byte {
array := sha1.Sum(data)
return array[:]
}
func getSHA2Digest(data []byte) []byte {
array := sha256.Sum256(data)
return array[:]
}
func HKDF(data []byte) []byte {
h := hmac.New(sha1.New, []byte(strings.Repeat("\x00", 64)))
h.Write(data)
h1 := h.Sum(nil)
h2 := make([]byte, 0)
res := make([]byte, 0)
for i := 0; i < 2; i++ {
h = hmac.New(sha1.New, h1)
h.Write(h2)
h.Write([]byte{byte(i) + 1})
h2 = h.Sum(nil)
res = append(res, h2...)
}
return res[:0x24]
}
func genStreamKeys(server bool, data []byte) (sendAESKey, sendHMACKey, receiveAESKey, receiveHMACKey []byte) {
const magic2 = "On the client side, this is the send key; on the server side, it is the receive key."
const magic3 = "On the client side, this is the receive key; on the server side, it is the send key."
var txEnc, rxEnc []byte
txEnc = append(data, []byte(strings.Repeat("\x00", 40))...)
rxEnc = append(data, []byte(strings.Repeat("\x00", 40))...)
if server {
txEnc = append(txEnc, magic3...)
rxEnc = append(rxEnc, magic2...)
} else {
txEnc = append(txEnc, magic2...)
rxEnc = append(rxEnc, magic3...)
}
txEnc = append(txEnc, []byte(strings.Repeat("\xF2", 40))...)
rxEnc = append(rxEnc, []byte(strings.Repeat("\xF2", 40))...)
txEnc = getSHA1Digest(txEnc)[:16]
rxEnc = getSHA1Digest(rxEnc)[:16]
sendKey := HKDF(txEnc)
sendAESKey = sendKey[:16]
sendHMACKey = sendKey[16:]
receiveKey := HKDF(rxEnc)
receiveAESKey = receiveKey[:16]
receiveHMACKey = receiveKey[16:]
return sendAESKey, sendHMACKey, receiveAESKey, receiveHMACKey
}
func genPasswordValidatorPriv(username, password string, salt []byte) []byte {
if len(salt) != 16 {
panic("salt must be 16 bytes")
}
hash := getSHA2Digest([]byte(username + ":" + password))
return getSHA2Digest(append(salt, hash...))
}
func genRandomBytes(n int) ([]byte, error) {
b := make([]byte, n)
var err error
if getParamSwitch("crypt-predictable-rng") {
_, err = mathRand.Read(b)
} else {
_, err = cryptoRand.Read(b)
}
if err != nil {
return nil, err
}
return b, nil
}