feat: add is full export browsing data option

pull/200/head
moonD4rk 2 years ago
parent fbe61a2cf4
commit 84ab4005f9
No known key found for this signature in database
GPG Key ID: 5AB6217E08D39ABA
  1. 2
      browingdata/bookmark/bookmark.go
  2. 10
      browingdata/browsingdata.go
  3. 12
      browingdata/outputter.go
  4. 2
      browingdata/outputter_test.go
  5. 19
      browser/browser.go
  6. 24
      browser/chromium/chromium.go
  7. 25
      browser/chromium/chromium_darwin.go
  8. 23
      browser/chromium/chromium_linux.go
  9. 13
      browser/chromium/chromium_windows.go
  10. 11
      browser/firefox/firefox.go
  11. 14
      crypto/crypto.go
  12. 4
      crypto/crypto_darwin.go
  13. 6
      crypto/crypto_linux.go
  14. 6
      crypto/crypto_windows.go
  15. 27
      item/item.go

@ -40,7 +40,7 @@ func (c *ChromiumBookmark) Parse(masterKey []byte) error {
return true return true
}) })
} }
// TODO: refactor with go generics
sort.Slice(*c, func(i, j int) bool { sort.Slice(*c, func(i, j int) bool {
return (*c)[i].DateAdded.After((*c)[j].DateAdded) return (*c)[i].DateAdded.After((*c)[j].DateAdded)
}) })

@ -28,11 +28,11 @@ type Source interface {
Length() int Length() int
} }
func New(sources []item.Item) *Data { func New(items []item.Item) *Data {
bd := &Data{ bd := &Data{
sources: make(map[item.Item]Source), sources: make(map[item.Item]Source),
} }
bd.addSource(sources) bd.addSources(items)
return bd return bd
} }
@ -46,7 +46,7 @@ func (d *Data) Recovery(masterKey []byte) error {
} }
func (d *Data) Output(dir, browserName, flag string) { func (d *Data) Output(dir, browserName, flag string) {
output := NewOutPutter(flag) output := newOutPutter(flag)
for _, source := range d.sources { for _, source := range d.sources {
if source.Length() == 0 { if source.Length() == 0 {
@ -72,8 +72,8 @@ func (d *Data) Output(dir, browserName, flag string) {
} }
} }
func (d *Data) addSource(Sources []item.Item) { func (d *Data) addSources(items []item.Item) {
for _, source := range Sources { for _, source := range items {
switch source { switch source {
case item.ChromiumPassword: case item.ChromiumPassword:
d.sources[source] = &password.ChromiumPassword{} d.sources[source] = &password.ChromiumPassword{}

@ -13,13 +13,13 @@ import (
"golang.org/x/text/transform" "golang.org/x/text/transform"
) )
type OutPutter struct { type outPutter struct {
json bool json bool
csv bool csv bool
} }
func NewOutPutter(flag string) *OutPutter { func newOutPutter(flag string) *outPutter {
o := &OutPutter{} o := &outPutter{}
if flag == "json" { if flag == "json" {
o.json = true o.json = true
} else { } else {
@ -28,7 +28,7 @@ func NewOutPutter(flag string) *OutPutter {
return o return o
} }
func (o *OutPutter) Write(data Source, writer io.Writer) error { func (o *outPutter) Write(data Source, writer io.Writer) error {
switch o.json { switch o.json {
case true: case true:
encoder := json.NewEncoder(writer) encoder := json.NewEncoder(writer)
@ -45,7 +45,7 @@ func (o *OutPutter) Write(data Source, writer io.Writer) error {
} }
} }
func (o *OutPutter) CreateFile(dir, filename string) (*os.File, error) { func (o *outPutter) CreateFile(dir, filename string) (*os.File, error) {
if filename == "" { if filename == "" {
return nil, errors.New("empty filename") return nil, errors.New("empty filename")
} }
@ -69,7 +69,7 @@ func (o *OutPutter) CreateFile(dir, filename string) (*os.File, error) {
return file, nil return file, nil
} }
func (o *OutPutter) Ext() string { func (o *outPutter) Ext() string {
if o.json { if o.json {
return "json" return "json"
} }

@ -7,7 +7,7 @@ import (
func TestNewOutPutter(t *testing.T) { func TestNewOutPutter(t *testing.T) {
t.Parallel() t.Parallel()
out := NewOutPutter("json") out := newOutPutter("json")
if out == nil { if out == nil {
t.Error("New() returned nil") t.Error("New() returned nil")
} }

@ -17,9 +17,10 @@ type Browser interface {
// Name is browser's name // Name is browser's name
Name() string Name() string
// BrowsingData returns all browsing data in the browser. // BrowsingData returns all browsing data in the browser.
BrowsingData() (*browingdata.Data, error) BrowsingData(isFullExport bool) (*browingdata.Data, error)
} }
// PickBrowsers returns a list of browsers that match the name and profile.
func PickBrowsers(name, profile string) ([]Browser, error) { func PickBrowsers(name, profile string) ([]Browser, error) {
var browsers []Browser var browsers []Browser
clist := pickChromium(name, profile) clist := pickChromium(name, profile)
@ -42,26 +43,26 @@ func pickChromium(name, profile string) []Browser {
name = strings.ToLower(name) name = strings.ToLower(name)
if name == "all" { if name == "all" {
for _, v := range chromiumList { for _, v := range chromiumList {
if !fileutil.FolderExists(filepath.Clean(v.profilePath)) { if !fileutil.IsDirExists(filepath.Clean(v.profilePath)) {
log.Noticef("find browser %s failed, profile folder does not exist", v.name) log.Noticef("find browser %s failed, profile folder does not exist", v.name)
continue continue
} }
if multiChromium, err := chromium.New(v.name, v.storage, v.profilePath, v.items); err == nil { multiChromium, err := chromium.New(v.name, v.storage, v.profilePath, v.items)
log.Noticef("find browser %s success", v.name) if err != nil {
log.Errorf("new chromium error: %v", err)
continue
}
for _, b := range multiChromium { for _, b := range multiChromium {
log.Noticef("find browser %s success", b.Name()) log.Noticef("find browser %s success", b.Name())
browsers = append(browsers, b) browsers = append(browsers, b)
} }
} else {
log.Errorf("new chromium error: %s", err.Error())
}
} }
} }
if c, ok := chromiumList[name]; ok { if c, ok := chromiumList[name]; ok {
if profile == "" { if profile == "" {
profile = c.profilePath profile = c.profilePath
} }
if !fileutil.FolderExists(filepath.Clean(profile)) { if !fileutil.IsDirExists(filepath.Clean(profile)) {
log.Fatalf("find browser %s failed, profile folder does not exist", c.name) log.Fatalf("find browser %s failed, profile folder does not exist", c.name)
} }
chromiumList, err := chromium.New(c.name, c.storage, profile, c.items) chromiumList, err := chromium.New(c.name, c.storage, profile, c.items)
@ -86,7 +87,7 @@ func pickFirefox(name, profile string) []Browser {
} else { } else {
profile = fileutil.ParentDir(profile) profile = fileutil.ParentDir(profile)
} }
if !fileutil.FolderExists(filepath.Clean(profile)) { if !fileutil.IsDirExists(filepath.Clean(profile)) {
log.Noticef("find browser firefox %s failed, profile folder does not exist", v.name) log.Noticef("find browser firefox %s failed, profile folder does not exist", v.name)
continue continue
} }

@ -28,7 +28,7 @@ func New(name, storage, profilePath string, items []item.Item) ([]*Chromium, err
profilePath: profilePath, profilePath: profilePath,
items: items, items: items,
} }
multiItemPaths, err := c.getMultiItemPath(c.profilePath, c.items) multiItemPaths, err := c.userItemPaths(c.profilePath, c.items)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -48,8 +48,13 @@ func (c *Chromium) Name() string {
return c.name return c.name
} }
func (c *Chromium) BrowsingData() (*browingdata.Data, error) { func (c *Chromium) BrowsingData(isFullExport bool) (*browingdata.Data, error) {
b := browingdata.New(c.items) items := c.items
if !isFullExport {
items = item.FilterSensitiveItems(c.items)
}
data := browingdata.New(items)
if err := c.copyItemToLocal(); err != nil { if err := c.copyItemToLocal(); err != nil {
return nil, err return nil, err
@ -61,10 +66,10 @@ func (c *Chromium) BrowsingData() (*browingdata.Data, error) {
} }
c.masterKey = masterKey c.masterKey = masterKey
if err := b.Recovery(c.masterKey); err != nil { if err := data.Recovery(c.masterKey); err != nil {
return nil, err return nil, err
} }
return b, nil return data, nil
} }
func (c *Chromium) copyItemToLocal() error { func (c *Chromium) copyItemToLocal() error {
@ -72,7 +77,7 @@ func (c *Chromium) copyItemToLocal() error {
filename := i.String() filename := i.String()
var err error var err error
switch { switch {
case fileutil.FolderExists(path): case fileutil.IsDirExists(path):
if i == item.ChromiumLocalStorage { if i == item.ChromiumLocalStorage {
err = fileutil.CopyDir(path, filename, "lock") err = fileutil.CopyDir(path, filename, "lock")
} }
@ -89,8 +94,8 @@ func (c *Chromium) copyItemToLocal() error {
return nil return nil
} }
func (c *Chromium) getMultiItemPath(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) { // userItemPaths return a map of user to item path, map[profile 1][item's name & path key pair]
// multiItemPaths is a map of user to item path, map[profile 1][item's name & path key pair] func (c *Chromium) userItemPaths(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) {
multiItemPaths := make(map[string]map[item.Item]string) multiItemPaths := make(map[string]map[item.Item]string)
parentDir := fileutil.ParentDir(profilePath) parentDir := fileutil.ParentDir(profilePath)
err := filepath.Walk(parentDir, chromiumWalkFunc(items, multiItemPaths)) err := filepath.Walk(parentDir, chromiumWalkFunc(items, multiItemPaths))
@ -120,6 +125,7 @@ func (c *Chromium) getMultiItemPath(profilePath string, items []item.Item) (map[
return t, nil return t, nil
} }
// chromiumWalkFunc return a filepath.WalkFunc to find item's path
func chromiumWalkFunc(items []item.Item, multiItemPaths map[string]map[item.Item]string) filepath.WalkFunc { func chromiumWalkFunc(items []item.Item, multiItemPaths map[string]map[item.Item]string) filepath.WalkFunc {
return func(path string, info fs.FileInfo, err error) error { return func(path string, info fs.FileInfo, err error) error {
for _, v := range items { for _, v := range items {
@ -145,7 +151,7 @@ func chromiumWalkFunc(items []item.Item, multiItemPaths map[string]map[item.Item
func fillLocalStoragePath(itemPaths map[item.Item]string, storage item.Item) { func fillLocalStoragePath(itemPaths map[item.Item]string, storage item.Item) {
if p, ok := itemPaths[item.ChromiumHistory]; ok { if p, ok := itemPaths[item.ChromiumHistory]; ok {
lsp := filepath.Join(filepath.Dir(p), storage.FileName()) lsp := filepath.Join(filepath.Dir(p), storage.FileName())
if fileutil.FolderExists(lsp) { if fileutil.IsDirExists(lsp) {
itemPaths[item.ChromiumLocalStorage] = lsp itemPaths[item.ChromiumLocalStorage] = lsp
} }
} }

@ -6,6 +6,7 @@ import (
"bytes" "bytes"
"crypto/sha1" "crypto/sha1"
"errors" "errors"
"fmt"
"os" "os"
"os/exec" "os/exec"
"strings" "strings"
@ -22,34 +23,34 @@ var (
) )
func (c *Chromium) GetMasterKey() ([]byte, error) { func (c *Chromium) GetMasterKey() ([]byte, error) {
var (
cmd *exec.Cmd
stdout, stderr bytes.Buffer
)
// don't need chromium key file for macOS // don't need chromium key file for macOS
defer os.Remove(item.TempChromiumKey) defer os.Remove(item.TempChromiumKey)
// Get the master key from the keychain // Get the master key from the keychain
// $ security find-generic-password -wa 'Chrome' // $ security find-generic-password -wa 'Chrome'
cmd = exec.Command("security", "find-generic-password", "-wa", strings.TrimSpace(c.storage)) //nolint:gosec var (
stdout, stderr bytes.Buffer
)
cmd := exec.Command("security", "find-generic-password", "-wa", strings.TrimSpace(c.storage)) //nolint:gosec
cmd.Stdout = &stdout cmd.Stdout = &stdout
cmd.Stderr = &stderr cmd.Stderr = &stderr
err := cmd.Run() if err := cmd.Run(); err != nil {
if err != nil { return nil, fmt.Errorf("run security command failed: %w, message %s", err, stderr.String())
return nil, err
} }
if stderr.Len() > 0 { if stderr.Len() > 0 {
if strings.Contains(stderr.String(), "could not be found") { if strings.Contains(stderr.String(), "could not be found") {
return nil, errCouldNotFindInKeychain return nil, errCouldNotFindInKeychain
} }
return nil, errors.New(stderr.String()) return nil, errors.New(stderr.String())
} }
chromeSecret := bytes.TrimSpace(stdout.Bytes())
if chromeSecret == nil { secret := bytes.TrimSpace(stdout.Bytes())
if len(secret) == 0 {
return nil, errWrongSecurityCommand return nil, errWrongSecurityCommand
} }
chromeSalt := []byte("saltysalt") salt := []byte("saltysalt")
// @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_mac.mm;l=157 // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_mac.mm;l=157
key := pbkdf2.Key(chromeSecret, chromeSalt, 1003, 16, sha1.New) key := pbkdf2.Key(secret, salt, 1003, 16, sha1.New)
if key == nil { if key == nil {
return nil, errWrongSecurityCommand return nil, errWrongSecurityCommand
} }

@ -4,7 +4,7 @@ package chromium
import ( import (
"crypto/sha1" "crypto/sha1"
"errors" "fmt"
"os" "os"
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
@ -17,12 +17,13 @@ import (
func (c *Chromium) GetMasterKey() ([]byte, error) { func (c *Chromium) GetMasterKey() ([]byte, error) {
// what is d-bus @https://dbus.freedesktop.org/ // what is d-bus @https://dbus.freedesktop.org/
var chromiumSecret []byte // don't need chromium key file for Linux
defer os.Remove(item.TempChromiumKey)
conn, err := dbus.SessionBus() conn, err := dbus.SessionBus()
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer os.Remove(item.TempChromiumKey)
svc, err := keyring.GetSecretService(conn) svc, err := keyring.GetSecretService(conn)
if err != nil { if err != nil {
return nil, err return nil, err
@ -40,6 +41,7 @@ func (c *Chromium) GetMasterKey() ([]byte, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
var secret []byte
for _, col := range collections { for _, col := range collections {
items, err := col.GetAllItems() items, err := col.GetAllItems()
if err != nil { if err != nil {
@ -54,19 +56,20 @@ func (c *Chromium) GetMasterKey() ([]byte, error) {
if label == c.storage { if label == c.storage {
se, err := i.GetSecret(session.Path()) se, err := i.GetSecret(session.Path())
if err != nil { if err != nil {
return nil, errors.New("get storage from dbus error:" + err.Error()) return nil, fmt.Errorf("get storage from dbus error: %v" + err.Error())
} }
chromiumSecret = se.Value secret = se.Value
} }
} }
} }
if chromiumSecret == nil {
// @https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=100 if len(secret) == 0 {
chromiumSecret = []byte("peanuts") // set default secret @https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=100
secret = []byte("peanuts")
} }
chromiumSalt := []byte("saltysalt") salt := []byte("saltysalt")
// @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_linux.cc // @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_linux.cc
key := pbkdf2.Key(chromiumSecret, chromiumSalt, 1, 16, sha1.New) key := pbkdf2.Key(secret, salt, 1, 16, sha1.New)
c.masterKey = key c.masterKey = key
log.Infof("%s initialized master key success", c.name) log.Infof("%s initialized master key success", c.name)
return key, nil return key, nil

@ -9,6 +9,7 @@ import (
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
"github.com/moond4rk/HackBrowserData/crypto"
"github.com/moond4rk/HackBrowserData/item" "github.com/moond4rk/HackBrowserData/item"
"github.com/moond4rk/HackBrowserData/log" "github.com/moond4rk/HackBrowserData/log"
"github.com/moond4rk/HackBrowserData/utils/fileutil" "github.com/moond4rk/HackBrowserData/utils/fileutil"
@ -17,20 +18,22 @@ import (
var errDecodeMasterKeyFailed = errors.New("decode master key failed") var errDecodeMasterKeyFailed = errors.New("decode master key failed")
func (c *Chromium) GetMasterKey() ([]byte, error) { func (c *Chromium) GetMasterKey() ([]byte, error) {
keyFile, err := fileutil.ReadFile(item.TempChromiumKey) b, err := fileutil.ReadFile(item.TempChromiumKey)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer os.Remove(keyFile) defer os.Remove(item.TempChromiumKey)
encryptedKey := gjson.Get(keyFile, "os_crypt.encrypted_key")
encryptedKey := gjson.Get(b, "os_crypt.encrypted_key")
if !encryptedKey.Exists() { if !encryptedKey.Exists() {
return nil, nil return nil, nil
} }
pureKey, err := base64.StdEncoding.DecodeString(encryptedKey.String())
key, err := base64.StdEncoding.DecodeString(encryptedKey.String())
if err != nil { if err != nil {
return nil, errDecodeMasterKeyFailed return nil, errDecodeMasterKeyFailed
} }
c.masterKey, err = crypto.DPAPI(pureKey[5:]) c.masterKey, err = crypto.DPAPI(key[5:])
log.Infof("%s initialized master key success", c.name) log.Infof("%s initialized master key success", c.name)
return c.masterKey, err return c.masterKey, err
} }

@ -39,7 +39,7 @@ func New(name, storage, profilePath string, items []item.Item) ([]*Firefox, erro
firefoxList := make([]*Firefox, 0, len(multiItemPaths)) firefoxList := make([]*Firefox, 0, len(multiItemPaths))
for name, itemPaths := range multiItemPaths { for name, itemPaths := range multiItemPaths {
firefoxList = append(firefoxList, &Firefox{ firefoxList = append(firefoxList, &Firefox{
name: fmt.Sprintf("Firefox-%s", name), name: fmt.Sprintf("firefox-%s", name),
items: typeutil.Keys(itemPaths), items: typeutil.Keys(itemPaths),
itemPaths: itemPaths, itemPaths: itemPaths,
}) })
@ -87,8 +87,13 @@ func (f *Firefox) Name() string {
return f.name return f.name
} }
func (f *Firefox) BrowsingData() (*browingdata.Data, error) { func (f *Firefox) BrowsingData(isFullExport bool) (*browingdata.Data, error) {
b := browingdata.New(f.items) items := f.items
if !isFullExport {
items = item.FilterSensitiveItems(f.items)
}
b := browingdata.New(items)
if err := f.copyItemToLocal(); err != nil { if err := f.copyItemToLocal(); err != nil {
return nil, err return nil, err

@ -63,15 +63,15 @@ type nssPBE struct {
func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) { func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) {
glmp := append(globalSalt, masterPwd...) glmp := append(globalSalt, masterPwd...)
hp := sha1.Sum(glmp) hp := sha1.Sum(glmp)
s := append(hp[:], n.entrySalt()...) s := append(hp[:], n.salt()...)
chp := sha1.Sum(s) chp := sha1.Sum(s)
pes := paddingZero(n.entrySalt(), 20) pes := paddingZero(n.salt(), 20)
tk := hmac.New(sha1.New, chp[:]) tk := hmac.New(sha1.New, chp[:])
tk.Write(pes) tk.Write(pes)
pes = append(pes, n.entrySalt()...) pes = append(pes, n.salt()...)
k1 := hmac.New(sha1.New, chp[:]) k1 := hmac.New(sha1.New, chp[:])
k1.Write(pes) k1.Write(pes)
tkPlus := append(tk.Sum(nil), n.entrySalt()...) tkPlus := append(tk.Sum(nil), n.salt()...)
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)...)
@ -79,7 +79,7 @@ func (n nssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) {
return des3Decrypt(k[:24], iv, n.encrypted()) return des3Decrypt(k[:24], iv, n.encrypted())
} }
func (n nssPBE) entrySalt() []byte { func (n nssPBE) salt() []byte {
return n.AlgoAttr.SaltAttr.EntrySalt return n.AlgoAttr.SaltAttr.EntrySalt
} }
@ -136,12 +136,12 @@ type slatAttr struct {
func (m metaPBE) Decrypt(globalSalt, masterPwd []byte) (key2 []byte, err error) { func (m metaPBE) Decrypt(globalSalt, masterPwd []byte) (key2 []byte, err error) {
k := sha1.Sum(globalSalt) k := sha1.Sum(globalSalt)
key := pbkdf2.Key(k[:], m.entrySalt(), m.iterationCount(), m.keySize(), sha256.New) key := pbkdf2.Key(k[:], m.salt(), m.iterationCount(), m.keySize(), sha256.New)
iv := append([]byte{4, 14}, m.iv()...) iv := append([]byte{4, 14}, m.iv()...)
return aes128CBCDecrypt(key, iv, m.encrypted()) return aes128CBCDecrypt(key, iv, m.encrypted())
} }
func (m metaPBE) entrySalt() []byte { func (m metaPBE) salt() []byte {
return m.AlgoAttr.Data.Data.SlatAttr.EntrySalt return m.AlgoAttr.Data.Data.SlatAttr.EntrySalt
} }

@ -2,12 +2,12 @@
package crypto package crypto
var iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
func Chromium(key, encryptPass []byte) ([]byte, error) { func Chromium(key, encryptPass []byte) ([]byte, error) {
if len(encryptPass) <= 3 { if len(encryptPass) <= 3 {
return nil, errPasswordIsEmpty return nil, errPasswordIsEmpty
} }
iv := []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
return aes128CBCDecrypt(key, iv, encryptPass[3:]) return aes128CBCDecrypt(key, iv, encryptPass[3:])
} }

@ -2,13 +2,13 @@
package crypto package crypto
var iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
func Chromium(key, encryptPass []byte) ([]byte, error) { func Chromium(key, encryptPass []byte) ([]byte, error) {
if len(encryptPass) < 3 { if len(encryptPass) < 3 {
return nil, errPasswordIsEmpty return nil, errPasswordIsEmpty
} }
return aes128CBCDecrypt(key, iv, encryptPass[3:])
chromeIV := []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
return aes128CBCDecrypt(key, chromeIV, encryptPass[3:])
} }
func DPAPI(data []byte) ([]byte, error) { func DPAPI(data []byte) ([]byte, error) {

@ -10,7 +10,7 @@ import (
) )
func Chromium(key, encryptPass []byte) ([]byte, error) { func Chromium(key, encryptPass []byte) ([]byte, error) {
if len(encryptPass) < 3 { if len(encryptPass) < 15 {
return nil, errPasswordIsEmpty return nil, errPasswordIsEmpty
} }
@ -51,7 +51,7 @@ type dataBlob struct {
pbData *byte pbData *byte
} }
func NewBlob(d []byte) *dataBlob { func newBlob(d []byte) *dataBlob {
if len(d) == 0 { if len(d) == 0 {
return &dataBlob{} return &dataBlob{}
} }
@ -78,7 +78,7 @@ func DPAPI(data []byte) ([]byte, error) {
procDecryptData := dllCrypt.NewProc("CryptUnprotectData") procDecryptData := dllCrypt.NewProc("CryptUnprotectData")
procLocalFree := dllKernel.NewProc("LocalFree") procLocalFree := dllKernel.NewProc("LocalFree")
var outBlob dataBlob var outBlob dataBlob
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob))) r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(newBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob)))
if r == 0 { if r == 0 {
return nil, err return nil, err
} }

@ -121,6 +121,31 @@ func (i Item) String() string {
} }
} }
// IsSensitive returns whether the item is sensitive data
// password, cookie, credit card, master key is unlimited
func (i Item) IsSensitive() bool {
switch i {
case ChromiumKey, ChromiumCookie, ChromiumPassword, ChromiumCreditCard,
FirefoxKey4, FirefoxPassword, FirefoxCookie, FirefoxCreditCard,
YandexPassword, YandexCreditCard:
return true
default:
return false
}
}
// FilterSensitiveItems returns the sensitive items
func FilterSensitiveItems(items []Item) []Item {
var filtered []Item
for _, item := range items {
if item.IsSensitive() {
filtered = append(filtered, item)
}
}
return filtered
}
// DefaultFirefox returns the default items for the firefox browser
var DefaultFirefox = []Item{ var DefaultFirefox = []Item{
FirefoxKey4, FirefoxKey4,
FirefoxPassword, FirefoxPassword,
@ -133,6 +158,7 @@ var DefaultFirefox = []Item{
FirefoxExtension, FirefoxExtension,
} }
// DefaultYandex returns the default items for the yandex browser
var DefaultYandex = []Item{ var DefaultYandex = []Item{
ChromiumKey, ChromiumKey,
ChromiumCookie, ChromiumCookie,
@ -145,6 +171,7 @@ var DefaultYandex = []Item{
YandexCreditCard, YandexCreditCard,
} }
// DefaultChromium returns the default items for the chromium browser
var DefaultChromium = []Item{ var DefaultChromium = []Item{
ChromiumKey, ChromiumKey,
ChromiumPassword, ChromiumPassword,

Loading…
Cancel
Save