add decrypt for linux

ᴍᴏᴏɴD4ʀᴋ 4 years ago
parent c74b3d43af
commit 46ea323a97
  1. 1
      cmd/cmd.go
  2. 28
      core/common.go
  3. 4
      utils/utils.go
  4. 41
      utils/utils_darwin.go
  5. 200
      utils/utils_linux.go
  6. 56
      utils/utils_windows.go

@ -69,6 +69,7 @@ func Execute() {
} }
} else { } else {
fileList := utils.GetDBPath(browserDir, utils.FirefoxLoginData, utils.FirefoxKey4DB, utils.FirefoxCookie, utils.FirefoxData) fileList := utils.GetDBPath(browserDir, utils.FirefoxLoginData, utils.FirefoxKey4DB, utils.FirefoxCookie, utils.FirefoxData)
log.Error("fileList", fileList)
for _, v := range fileList { for _, v := range fileList {
dst := filepath.Base(v) dst := filepath.Base(v)
err := utils.CopyDB(v, dst) err := utils.CopyDB(v, dst)

@ -378,11 +378,11 @@ func GetDecryptKey() (b [][]byte) {
pwdRows *sql.Rows pwdRows *sql.Rows
nssRows *sql.Rows nssRows *sql.Rows
) )
defer func() { //defer func() {
if err := os.Remove(utils.FirefoxKey4DB); err != nil { // if err := os.Remove(utils.FirefoxKey4DB); err != nil {
log.Error(err) // log.Error(err)
} // }
}() //}()
keyDB, err = sql.Open("sqlite3", utils.FirefoxKey4DB) keyDB, err = sql.Open("sqlite3", utils.FirefoxKey4DB)
defer func() { defer func() {
if err := keyDB.Close(); err != nil { if err := keyDB.Close(); err != nil {
@ -433,32 +433,32 @@ func GetDecryptKey() (b [][]byte) {
func parseFirefoxKey4() { func parseFirefoxKey4() {
h1 := GetDecryptKey() h1 := GetDecryptKey()
globalSalt := h1[0] globalSalt := h1[0]
decodedItem := h1[1] metaBytes := h1[1]
a11 := h1[2] nssA11 := h1[2]
a102 := h1[3] nssA102 := h1[3]
keyLin := []byte{248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} keyLin := []byte{248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
pbe, err := utils.DecodeMeta(decodedItem) meta, err := utils.DecodeMeta(metaBytes)
if err != nil { if err != nil {
log.Error("decrypt meta data failed", err) log.Error("decrypt meta data failed", err)
return return
} }
var masterPwd []byte var masterPwd []byte
m, err := utils.CheckPassword(globalSalt, masterPwd, pbe) m, err := utils.DecryptMeta(globalSalt, masterPwd, meta)
if err != nil { if err != nil {
log.Error("decrypt firefox failed", err) log.Error("decrypt firefox failed", err)
return return
} }
if bytes.Contains(m, []byte("password-check")) { if bytes.Contains(m, []byte("password-check")) {
log.Debugf("password-check success") log.Debugf("password-check success")
m := bytes.Compare(a102, keyLin) m := bytes.Compare(nssA102, keyLin)
if m == 0 { if m == 0 {
pbe2, err := utils.DecodeMeta(a11) nss, err := utils.DecodeNss(nssA11)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return return
} }
log.Debugf("decrypt asn1 pbe success") log.Debugf("decrypt asn1 pbe success")
finallyKey, err := utils.CheckPassword(globalSalt, masterPwd, pbe2) finallyKey, err := utils.DecryptNss(globalSalt, masterPwd, nss)
finallyKey = finallyKey[:24] finallyKey = finallyKey[:24]
if err != nil { if err != nil {
log.Error(err) log.Error(err)
@ -548,7 +548,7 @@ func GetLoginData() (l []loginData) {
if err != nil { if err != nil {
log.Warn(err) log.Warn(err)
} }
defer os.Remove(utils.FirefoxLoginData) //defer os.Remove(utils.FirefoxLoginData)
h := gjson.GetBytes(s, "logins") h := gjson.GetBytes(s, "logins")
if h.Exists() { if h.Exists() {
for _, v := range h.Array() { for _, v := range h.Array() {

@ -53,6 +53,10 @@ const (
FirefoxKey3DB = "key3.db" FirefoxKey3DB = "key3.db"
) )
func InitKey(string) error {
return nil
}
func ListBrowser() []string { func ListBrowser() []string {
var l []string var l []string
for k := range browserList { for k := range browserList {

@ -110,6 +110,11 @@ SEQUENCE (2 elem)
OCTET STRING (16 byte) OCTET STRING (16 byte)
*/ */
type NssPBE struct {
SequenceA
Encrypted []byte
}
type MetaPBE struct { type MetaPBE struct {
SequenceA SequenceA
Encrypted []byte Encrypted []byte
@ -125,8 +130,19 @@ type SequenceB struct {
Len int Len int
} }
func DecodeMeta(decodeItem []byte) (pbe MetaPBE, err error) { func DecodeMeta(metaBytes []byte) (pbe MetaPBE, err error) {
_, err = asn1.Unmarshal(decodeItem, &pbe) log.Debug(hex.EncodeToString(metaBytes))
_, err = asn1.Unmarshal(metaBytes, &pbe)
if err != nil {
log.Error(err)
return
}
return
}
func DecodeNss(nssA11Bytes []byte) (pbe NssPBE, err error) {
log.Debug(hex.EncodeToString(nssA11Bytes))
_, err = asn1.Unmarshal(nssA11Bytes, &pbe)
if err != nil { if err != nil {
log.Error(err) log.Error(err)
return return
@ -134,7 +150,14 @@ func DecodeMeta(decodeItem []byte) (pbe MetaPBE, err error) {
return return
} }
func CheckPassword(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) { func DecryptMeta(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) {
return decryptPBE(globalSalt, masterPwd, pbe.EntrySalt, pbe.Encrypted)}
func DecryptNss(globalSalt, masterPwd []byte, pbe NssPBE) ([]byte, error) {
return decryptPBE(globalSalt, masterPwd, pbe.EntrySalt, pbe.Encrypted)
}
func decryptPBE(globalSalt, masterPwd, entrySalt, encrypted []byte) ([]byte, error) {
//byte[] GLMP; // GlobalSalt + MasterPassword //byte[] GLMP; // GlobalSalt + MasterPassword
//byte[] HP; // SHA1(GLMP) //byte[] HP; // SHA1(GLMP)
//byte[] HPES; // HP + EntrySalt //byte[] HPES; // HP + EntrySalt
@ -147,20 +170,20 @@ func CheckPassword(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) {
//byte[] k; // final value conytaining key and iv //byte[] k; // final value conytaining key and iv
glmp := append(globalSalt, masterPwd...) glmp := append(globalSalt, masterPwd...)
hp := sha1.Sum(glmp) hp := sha1.Sum(glmp)
s := append(hp[:], pbe.EntrySalt...) s := append(hp[:], entrySalt...)
chp := sha1.Sum(s) chp := sha1.Sum(s)
pes := PaddingZero(pbe.EntrySalt, 20) pes := PaddingZero(entrySalt, 20)
tk := hmac.New(sha1.New, chp[:]) tk := hmac.New(sha1.New, chp[:])
tk.Write(pes) tk.Write(pes)
pes = append(pes, pbe.EntrySalt...) pes = append(pes, entrySalt...)
k1 := hmac.New(sha1.New, chp[:]) k1 := hmac.New(sha1.New, chp[:])
k1.Write(pes) k1.Write(pes)
tkPlus := append(tk.Sum(nil), pbe.EntrySalt...) tkPlus := append(tk.Sum(nil), entrySalt...)
k2 := hmac.New(sha1.New, chp[:]) k2 := hmac.New(sha1.New, chp[:])
k2.Write(tkPlus) k2.Write(tkPlus)
k := append(k1.Sum(nil), k2.Sum(nil)...) k := append(k1.Sum(nil), k2.Sum(nil)...)
iv := k[len(k)-8:] iv := k[len(k)-8:]
key := k[:24] key := k[:24]
log.Warn("key=", hex.EncodeToString(key), "iv=", hex.EncodeToString(iv)) log.Warnf("key=%s iv=%s", hex.EncodeToString(key), hex.EncodeToString(iv))
return Des3Decrypt(key, iv, pbe.Encrypted) return Des3Decrypt(key, iv, encrypted)
} }

@ -0,0 +1,200 @@
package utils
import (
"crypto/hmac"
"crypto/sha1"
"crypto/sha256"
"encoding/asn1"
"encoding/hex"
"hack-browser-data/log"
"strings"
"golang.org/x/crypto/pbkdf2"
)
const (
fireFoxProfilePath = "/Users/*/Library/Application Support/Firefox/Profiles/*.default-release/"
fireFoxCommand = ""
)
var (
iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
command = []string{"security", "find-generic-password", "-wa"}
chromeSalt = []byte("saltysalt")
chromeKey []byte
browserList = map[string]struct {
ProfilePath string
Command string
}{
"firefox": {
fireFoxProfilePath,
fireFoxCommand,
},
}
)
func DecryptStringWithDPAPI(data []byte) (string, error) {
return string(data), nil
}
func PickBrowser(name string) (browserDir, command string, err error) {
name = strings.ToLower(name)
if choice, ok := browserList[name]; ok {
return choice.ProfilePath, choice.Command, err
}
return "", "", errBrowserNotSupported
}
func decryptChromeKey(chromePass []byte) {
chromeKey = pbkdf2.Key(chromePass, chromeSalt, 1003, 16, sha1.New)
}
func DecryptChromePass(encryptPass []byte) (string, error) {
if len(encryptPass) > 3 {
if len(chromeKey) == 0 {
return "", errKeyIsEmpty
}
m, err := aes128CBCDecrypt(chromeKey, iv, encryptPass[3:])
return string(m), err
} else {
return "", &DecryptError{
err: errPasswordIsEmpty,
}
}
}
/*
SEQUENCE (2 elem)
SEQUENCE (2 elem)
OBJECT IDENTIFIER
SEQUENCE (2 elem)
OCTET STRING (20 byte)
INTEGER 1
OCTET STRING (16 byte)
*/
type MetaPBE struct {
SequenceA
Encrypted []byte
}
type SequenceA struct {
DecryptMethod asn1.ObjectIdentifier
SequenceB
}
type SequenceB struct {
EntrySalt []byte
Len int
}
type NssPBE struct {
SequenceNSSA
Encrypted []byte
}
type SequenceNSSA struct {
PKCS5PBES2 asn1.ObjectIdentifier
SequenceNSSB
}
type SequenceNSSB 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 DecodeMeta(decodeItem []byte) (pbe MetaPBE, err error) {
_, err = asn1.Unmarshal(decodeItem, &pbe)
if err != nil {
log.Error(err)
return
}
return
}
func DecodeNss(nssA11Bytes []byte) (pbe NssPBE, err error) {
log.Debug(hex.EncodeToString(nssA11Bytes))
_, err = asn1.Unmarshal(nssA11Bytes, &pbe)
if err != nil {
log.Error(err)
return
}
return
}
func DecryptMeta(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) {
return decryptMeta(globalSalt, masterPwd, pbe.EntrySalt, pbe.Encrypted)
}
func DecryptNss(globalSalt, masterPwd []byte, pbe NssPBE) ([]byte, error) {
return decryptNss(globalSalt, masterPwd, pbe.IV, pbe.EntrySalt, pbe.Encrypted, pbe.IterationCount, pbe.KeySize)
}
func decryptMeta(globalSalt, masterPwd, entrySalt, encrypted []byte) ([]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[:], entrySalt...)
chp := sha1.Sum(s)
pes := PaddingZero(entrySalt, 20)
tk := hmac.New(sha1.New, chp[:])
tk.Write(pes)
pes = append(pes, entrySalt...)
k1 := hmac.New(sha1.New, chp[:])
k1.Write(pes)
tkPlus := append(tk.Sum(nil), 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.Warnf("key=%s iv=%s", hex.EncodeToString(key), hex.EncodeToString(iv))
return Des3Decrypt(key, iv, encrypted)
}
func decryptNss(globalSalt, masterPwd, nssIv, entrySalt, encrypted []byte, iter, keySize int) ([]byte, error) {
k := sha1.Sum(globalSalt)
log.Println(hex.EncodeToString(k[:]))
key := pbkdf2.Key(k[:], entrySalt, iter, 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, nssIv...)
dst, err := aes128CBCDecrypt(key, iv, encrypted)
if err != nil {
log.Println(err)
}
return dst, err
}

@ -15,8 +15,9 @@ import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/tidwall/gjson"
"golang.org/x/crypto/pbkdf2" "golang.org/x/crypto/pbkdf2"
"github.com/tidwall/gjson"
) )
const ( const (
@ -174,9 +175,14 @@ func DecryptStringWithDPAPI(data []byte) (string, error) {
return string(outBlob.ToByteArray()), nil return string(outBlob.ToByteArray()), nil
} }
type NssPBE struct {
SequenceA
Encrypted []byte
}
type MetaPBE struct { type MetaPBE struct {
SequenceA SequenceA
CipherText []byte Encrypted []byte
} }
type SequenceA struct { type SequenceA struct {
PKCS5PBES2 asn1.ObjectIdentifier PKCS5PBES2 asn1.ObjectIdentifier
@ -208,31 +214,47 @@ type SequenceF struct {
HMACWithSHA256 asn1.ObjectIdentifier HMACWithSHA256 asn1.ObjectIdentifier
} }
func CheckPassword(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) { func DecodeMeta(decodeItem []byte) (pbe MetaPBE, err error) {
sha1.New() _, err = asn1.Unmarshal(decodeItem, &pbe)
k := sha1.Sum(globalSalt) if err != nil {
log.Error(err)
return
}
return
}
func DecodeNss(nssA11Bytes []byte) (pbe NssPBE, err error) {
log.Debug(hex.EncodeToString(nssA11Bytes))
_, err = asn1.Unmarshal(nssA11Bytes, &pbe)
if err != nil {
log.Error(err)
return
}
return
}
func DecryptMeta(globalSalt, masterPwd []byte, pbe MetaPBE) ([]byte, error) {
return decryptMeta(globalSalt, masterPwd, pbe.IV, pbe.EntrySalt, pbe.Encrypted, pbe.IterationCount, pbe.KeySize)
}
func DecryptNss(globalSalt, masterPwd []byte, pbe NssPBE) ([]byte, error) {
return decryptMeta(globalSalt, masterPwd, pbe.IV, pbe.EntrySalt, pbe.Encrypted, pbe.IterationCount, pbe.KeySize)
}
func decryptMeta(globalSalt, masterPwd, nssIv, entrySalt, encrypted []byte, iter, keySize int) ([]byte, error) {
k := sha1.Sum(globalSalt)
log.Println(hex.EncodeToString(k[:])) log.Println(hex.EncodeToString(k[:]))
key := pbkdf2.Key(k[:], pbe.EntrySalt, pbe.IterationCount, pbe.KeySize, sha256.New) key := pbkdf2.Key(k[:], entrySalt, iter, keySize, sha256.New)
log.Println(hex.EncodeToString(key)) log.Println(hex.EncodeToString(key))
i, err := hex.DecodeString("040e") i, err := hex.DecodeString("040e")
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
// @https://hg.mozilla.org/projects/nss/rev/fc636973ad06392d11597620b602779b4af312f6#l6.49 // @https://hg.mozilla.org/projects/nss/rev/fc636973ad06392d11597620b602779b4af312f6#l6.49
iv := append(i, pbe.IV...) iv := append(i, nssIv...)
dst, err := aes128CBCDecrypt(key, iv, pbe.CipherText) dst, err := aes128CBCDecrypt(key, iv, encrypted)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
return dst, 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