mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-07-06 21:37:47 +02:00
feat: add is full export browsing data option
This commit is contained in:
@@ -28,7 +28,7 @@ func New(name, storage, profilePath string, items []item.Item) ([]*Chromium, err
|
||||
profilePath: profilePath,
|
||||
items: items,
|
||||
}
|
||||
multiItemPaths, err := c.getMultiItemPath(c.profilePath, c.items)
|
||||
multiItemPaths, err := c.userItemPaths(c.profilePath, c.items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -48,8 +48,13 @@ func (c *Chromium) Name() string {
|
||||
return c.name
|
||||
}
|
||||
|
||||
func (c *Chromium) BrowsingData() (*browingdata.Data, error) {
|
||||
b := browingdata.New(c.items)
|
||||
func (c *Chromium) BrowsingData(isFullExport bool) (*browingdata.Data, error) {
|
||||
items := c.items
|
||||
if !isFullExport {
|
||||
items = item.FilterSensitiveItems(c.items)
|
||||
}
|
||||
|
||||
data := browingdata.New(items)
|
||||
|
||||
if err := c.copyItemToLocal(); err != nil {
|
||||
return nil, err
|
||||
@@ -61,10 +66,10 @@ func (c *Chromium) BrowsingData() (*browingdata.Data, error) {
|
||||
}
|
||||
|
||||
c.masterKey = masterKey
|
||||
if err := b.Recovery(c.masterKey); err != nil {
|
||||
if err := data.Recovery(c.masterKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return b, nil
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (c *Chromium) copyItemToLocal() error {
|
||||
@@ -72,7 +77,7 @@ func (c *Chromium) copyItemToLocal() error {
|
||||
filename := i.String()
|
||||
var err error
|
||||
switch {
|
||||
case fileutil.FolderExists(path):
|
||||
case fileutil.IsDirExists(path):
|
||||
if i == item.ChromiumLocalStorage {
|
||||
err = fileutil.CopyDir(path, filename, "lock")
|
||||
}
|
||||
@@ -89,8 +94,8 @@ func (c *Chromium) copyItemToLocal() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Chromium) getMultiItemPath(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) {
|
||||
// multiItemPaths is a map of user to item path, map[profile 1][item's name & path key pair]
|
||||
// userItemPaths return 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)
|
||||
parentDir := fileutil.ParentDir(profilePath)
|
||||
err := filepath.Walk(parentDir, chromiumWalkFunc(items, multiItemPaths))
|
||||
@@ -120,6 +125,7 @@ func (c *Chromium) getMultiItemPath(profilePath string, items []item.Item) (map[
|
||||
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 {
|
||||
return func(path string, info fs.FileInfo, err error) error {
|
||||
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) {
|
||||
if p, ok := itemPaths[item.ChromiumHistory]; ok {
|
||||
lsp := filepath.Join(filepath.Dir(p), storage.FileName())
|
||||
if fileutil.FolderExists(lsp) {
|
||||
if fileutil.IsDirExists(lsp) {
|
||||
itemPaths[item.ChromiumLocalStorage] = lsp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
@@ -22,34 +23,34 @@ var (
|
||||
)
|
||||
|
||||
func (c *Chromium) GetMasterKey() ([]byte, error) {
|
||||
var (
|
||||
cmd *exec.Cmd
|
||||
stdout, stderr bytes.Buffer
|
||||
)
|
||||
// don't need chromium key file for macOS
|
||||
defer os.Remove(item.TempChromiumKey)
|
||||
// Get the master key from the keychain
|
||||
// $ 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.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err := cmd.Run(); err != nil {
|
||||
return nil, fmt.Errorf("run security command failed: %w, message %s", err, stderr.String())
|
||||
}
|
||||
|
||||
if stderr.Len() > 0 {
|
||||
if strings.Contains(stderr.String(), "could not be found") {
|
||||
return nil, errCouldNotFindInKeychain
|
||||
}
|
||||
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
|
||||
}
|
||||
chromeSalt := []byte("saltysalt")
|
||||
salt := []byte("saltysalt")
|
||||
// @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 {
|
||||
return nil, errWrongSecurityCommand
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ package chromium
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
@@ -17,12 +17,13 @@ import (
|
||||
|
||||
func (c *Chromium) GetMasterKey() ([]byte, error) {
|
||||
// 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()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Remove(item.TempChromiumKey)
|
||||
svc, err := keyring.GetSecretService(conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -40,6 +41,7 @@ func (c *Chromium) GetMasterKey() ([]byte, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var secret []byte
|
||||
for _, col := range collections {
|
||||
items, err := col.GetAllItems()
|
||||
if err != nil {
|
||||
@@ -54,19 +56,20 @@ func (c *Chromium) GetMasterKey() ([]byte, error) {
|
||||
if label == c.storage {
|
||||
se, err := i.GetSecret(session.Path())
|
||||
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
|
||||
chromiumSecret = []byte("peanuts")
|
||||
|
||||
if len(secret) == 0 {
|
||||
// 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
|
||||
key := pbkdf2.Key(chromiumSecret, chromiumSalt, 1, 16, sha1.New)
|
||||
key := pbkdf2.Key(secret, salt, 1, 16, sha1.New)
|
||||
c.masterKey = key
|
||||
log.Infof("%s initialized master key success", c.name)
|
||||
return key, nil
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/moond4rk/HackBrowserData/crypto"
|
||||
"github.com/moond4rk/HackBrowserData/item"
|
||||
"github.com/moond4rk/HackBrowserData/log"
|
||||
"github.com/moond4rk/HackBrowserData/utils/fileutil"
|
||||
@@ -17,20 +18,22 @@ import (
|
||||
var errDecodeMasterKeyFailed = errors.New("decode master key failed")
|
||||
|
||||
func (c *Chromium) GetMasterKey() ([]byte, error) {
|
||||
keyFile, err := fileutil.ReadFile(item.TempChromiumKey)
|
||||
b, err := fileutil.ReadFile(item.TempChromiumKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Remove(keyFile)
|
||||
encryptedKey := gjson.Get(keyFile, "os_crypt.encrypted_key")
|
||||
defer os.Remove(item.TempChromiumKey)
|
||||
|
||||
encryptedKey := gjson.Get(b, "os_crypt.encrypted_key")
|
||||
if !encryptedKey.Exists() {
|
||||
return nil, nil
|
||||
}
|
||||
pureKey, err := base64.StdEncoding.DecodeString(encryptedKey.String())
|
||||
|
||||
key, err := base64.StdEncoding.DecodeString(encryptedKey.String())
|
||||
if err != nil {
|
||||
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)
|
||||
return c.masterKey, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user