feat: add firefox for windows decrypt Closes #11

pull/83/head
ᴍᴏᴏɴD4ʀᴋ 4 years ago
parent 8e56250880
commit 1b7edcbe6c
  1. 37
      core/common.go
  2. 16
      utils/utils.go
  3. 53
      utils/utils_darwin.go
  4. 75
      utils/utils_windows.go

@ -2,8 +2,6 @@ package core
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"database/sql"
"encoding/base64"
"encoding/hex"
@ -445,7 +443,7 @@ func parseFirefoxKey4() {
return
}
var masterPwd []byte
m, err := checkPassword(globalSalt, masterPwd, pbe)
m, err := utils.CheckPassword(globalSalt, masterPwd, pbe)
if err != nil {
log.Error("decrypt firefox failed", err)
return
@ -460,7 +458,7 @@ func parseFirefoxKey4() {
return
}
log.Debugf("decrypt asn1 pbe success")
finallyKey, err := checkPassword(globalSalt, masterPwd, pbe2)
finallyKey, err := utils.CheckPassword(globalSalt, masterPwd, pbe2)
finallyKey = finallyKey[:24]
if err != nil {
log.Error(err)
@ -545,37 +543,6 @@ func parseFirefoxCookie() {
}
func checkPassword(globalSalt, masterPwd []byte, pbe utils.MetaPBE) ([]byte, error) {
//byte[] GLMP; // GlobalSalt + MasterPassword
//byte[] HP; // SHA1(GLMP)
//byte[] HPES; // HP + EntrySalt
//byte[] CHP; // SHA1(HPES)
//byte[] PES; // EntrySalt completed to 20 bytes by zero
//byte[] PESES; // PES + EntrySalt
//byte[] k1;
//byte[] tk;
//byte[] k2;
//byte[] k; // final value conytaining key and iv
glmp := append(globalSalt, masterPwd...)
hp := sha1.Sum(glmp)
s := append(hp[:], pbe.EntrySalt...)
chp := sha1.Sum(s)
pes := utils.PaddingZero(pbe.EntrySalt, 20)
tk := hmac.New(sha1.New, chp[:])
tk.Write(pes)
pes = append(pes, pbe.EntrySalt...)
k1 := hmac.New(sha1.New, chp[:])
k1.Write(pes)
tkPlus := append(tk.Sum(nil), pbe.EntrySalt...)
k2 := hmac.New(sha1.New, chp[:])
k2.Write(tkPlus)
k := append(k1.Sum(nil), k2.Sum(nil)...)
iv := k[len(k)-8:]
key := k[:24]
log.Warn("key=", hex.EncodeToString(key), "iv=", hex.EncodeToString(iv))
return utils.Des3Decrypt(key, iv, pbe.Encrypted)
}
func GetLoginData() (l []loginData) {
s, err := ioutil.ReadFile(utils.FirefoxLoginData)
if err != nil {

@ -1,6 +1,7 @@
package utils
import (
"crypto/aes"
"crypto/cipher"
"crypto/des"
"encoding/asn1"
@ -224,3 +225,18 @@ func DecodeLogin(decodeItem []byte) (pbe LoginPBE, err error) {
}
return pbe, nil
}
func aes128CBCDecrypt(key, iv, encryptPass []byte) ([]byte, error) {
if len(chromeKey) == 0 {
return []byte{}, nil
}
block, err := aes.NewCipher(key)
if err != nil {
return []byte{}, err
}
dst := make([]byte, len(encryptPass))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(dst, encryptPass)
dst = PKCS5UnPadding(dst)
return dst, nil
}

@ -2,10 +2,10 @@ package utils
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/sha1"
"encoding/asn1"
"encoding/hex"
"errors"
"hack-browser-data/log"
"os/exec"
@ -88,7 +88,8 @@ func decryptChromeKey(chromePass []byte) {
func DecryptChromePass(encryptPass []byte) (string, error) {
if len(encryptPass) > 3 {
return aes128CBCDecrypt(encryptPass[3:])
m, err := aes128CBCDecrypt(chromeKey, iv, encryptPass[3:])
return string(m), err
} else {
return "", &DecryptError{
err: passwordIsEmpty,
@ -96,21 +97,6 @@ func DecryptChromePass(encryptPass []byte) (string, error) {
}
}
func aes128CBCDecrypt(encryptPass []byte) (string, error) {
if len(chromeKey) == 0 {
return "", nil
}
block, err := aes.NewCipher(chromeKey)
if err != nil {
return "", err
}
dst := make([]byte, len(encryptPass))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(dst, encryptPass)
dst = PKCS5UnPadding(dst)
return string(dst), nil
}
/*
SEQUENCE (2 elem)
SEQUENCE (2 elem)
@ -144,3 +130,34 @@ func DecodeMeta(decodeItem []byte) (pbe MetaPBE, err error) {
}
return
}
func CheckPassword(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) {
//byte[] GLMP; // GlobalSalt + MasterPassword
//byte[] HP; // SHA1(GLMP)
//byte[] HPES; // HP + EntrySalt
//byte[] CHP; // SHA1(HPES)
//byte[] PES; // EntrySalt completed to 20 bytes by zero
//byte[] PESES; // PES + EntrySalt
//byte[] k1;
//byte[] tk;
//byte[] k2;
//byte[] k; // final value conytaining key and iv
glmp := append(globalSalt, masterPwd...)
hp := sha1.Sum(glmp)
s := append(hp[:], pbe.EntrySalt...)
chp := sha1.Sum(s)
pes := PaddingZero(pbe.EntrySalt, 20)
tk := hmac.New(sha1.New, chp[:])
tk.Write(pes)
pes = append(pes, pbe.EntrySalt...)
k1 := hmac.New(sha1.New, chp[:])
k1.Write(pes)
tkPlus := append(tk.Sum(nil), pbe.EntrySalt...)
k2 := hmac.New(sha1.New, chp[:])
k2.Write(tkPlus)
k := append(k1.Sum(nil), k2.Sum(nil)...)
iv := k[len(k)-8:]
key := k[:24]
log.Warn("key=", hex.EncodeToString(key), "iv=", hex.EncodeToString(iv))
return Des3Decrypt(key, iv, pbe.Encrypted)
}

@ -3,14 +3,20 @@ package utils
import (
"crypto/aes"
"crypto/cipher"
"crypto/sha1"
"crypto/sha256"
"encoding/asn1"
"encoding/base64"
"encoding/hex"
"errors"
"hack-browser-data/log"
"os"
"strings"
"syscall"
"unsafe"
"github.com/tidwall/gjson"
"golang.org/x/crypto/pbkdf2"
)
const (
@ -22,6 +28,8 @@ const (
speed360KeyPath = ""
qqBrowserProfilePath = "/AppData/Local/Tencent/QQBrowser/User Data/*/"
qqBrowserKeyPath = ""
firefoxProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles/*.default-release/"
firefoxKeyPath = ""
)
var (
@ -47,6 +55,10 @@ var (
qqBrowserProfilePath,
qqBrowserKeyPath,
},
"firefox": {
firefoxProfilePath,
"",
},
}
)
@ -161,3 +173,66 @@ func DecryptStringWithDPAPI(data []byte) (string, error) {
defer procLocalFree.Call(uintptr(unsafe.Pointer(outBlob.pbData)))
return string(outBlob.ToByteArray()), nil
}
type MetaPBE struct {
SequenceA
CipherText []byte
}
type SequenceA struct {
PKCS5PBES2 asn1.ObjectIdentifier
SequenceB
}
type SequenceB struct {
SequenceC
SequenceD
}
type SequenceC struct {
PKCS5PBKDF2 asn1.ObjectIdentifier
SequenceE
}
type SequenceD struct {
AES256CBC asn1.ObjectIdentifier
IV []byte
}
type SequenceE struct {
EntrySalt []byte
IterationCount int
KeySize int
SequenceF
}
type SequenceF struct {
HMACWithSHA256 asn1.ObjectIdentifier
}
func CheckPassword(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) {
sha1.New()
k := sha1.Sum(globalSalt)
log.Println(hex.EncodeToString(k[:]))
key := pbkdf2.Key(k[:], pbe.EntrySalt, pbe.IterationCount, pbe.KeySize, sha256.New)
log.Println(hex.EncodeToString(key))
i, err := hex.DecodeString("040e")
if err != nil {
log.Println(err)
}
// @https://hg.mozilla.org/projects/nss/rev/fc636973ad06392d11597620b602779b4af312f6#l6.49
iv := append(i, pbe.IV...)
dst, err := aes128CBCDecrypt(key, iv, pbe.CipherText)
if err != nil {
log.Println(err)
}
return dst, err
}
func DecodeMeta(decodeItem []byte) (pbe MetaPBE, err error) {
_, err = asn1.Unmarshal(decodeItem, &pbe)
if err != nil {
log.Error(err)
return
}
return
}

Loading…
Cancel
Save