From e0a3fd3ca2880cd27024a5f49c449ff8edff9885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=B4=8D=E1=B4=8F=E1=B4=8F=C9=B4D4=CA=80=E1=B4=8B?= Date: Mon, 11 Apr 2022 20:53:50 +0800 Subject: [PATCH] feat: add firefox decrypt --- internal/browingdata/bookmark.go | 2 +- internal/browingdata/cookie.go | 1 + internal/browingdata/history.go | 2 + internal/browingdata/password.go | 2 + internal/browser/browser.go | 19 +-- internal/browser/firefox/firefox.go | 237 +++++++++++++++------------- internal/item/item.go | 2 +- 7 files changed, 140 insertions(+), 125 deletions(-) diff --git a/internal/browingdata/bookmark.go b/internal/browingdata/bookmark.go index 723bf3b..2fe2a95 100644 --- a/internal/browingdata/bookmark.go +++ b/internal/browingdata/bookmark.go @@ -92,7 +92,7 @@ func (f *FirefoxBookmark) Parse(masterKey []byte) error { if err != nil { return err } - defer os.RemoveAll(item.TempFirefoxBookmark) + defer os.Remove(item.TempFirefoxBookmark) defer keyDB.Close() _, err = keyDB.Exec(closeJournalMode) diff --git a/internal/browingdata/cookie.go b/internal/browingdata/cookie.go index 775b1a3..96f04e5 100644 --- a/internal/browingdata/cookie.go +++ b/internal/browingdata/cookie.go @@ -84,6 +84,7 @@ func (f *FirefoxCookie) Parse(masterKey []byte) error { if err != nil { return err } + defer os.Remove(item.TempFirefoxCookie) defer cookieDB.Close() rows, err := cookieDB.Query(queryFirefoxCookie) if err != nil { diff --git a/internal/browingdata/history.go b/internal/browingdata/history.go index ed60ad8..e6f3bb8 100644 --- a/internal/browingdata/history.go +++ b/internal/browingdata/history.go @@ -66,6 +66,8 @@ func (f *FirefoxHistory) Parse(masterKey []byte) error { if err != nil { return err } + defer os.Remove(item.TempFirefoxHistory) + defer keyDB.Close() _, err = keyDB.Exec(closeJournalMode) if err != nil { return err diff --git a/internal/browingdata/password.go b/internal/browingdata/password.go index 63fc473..51bbb45 100644 --- a/internal/browingdata/password.go +++ b/internal/browingdata/password.go @@ -156,6 +156,7 @@ func getFirefoxDecryptKey(key4file string) (item1, item2, a11, a102 []byte, err if err != nil { return nil, nil, nil, nil, err } + defer os.Remove(key4file) defer keyDB.Close() if err = keyDB.QueryRow(queryMetaData).Scan(&item1, &item2); err != nil { @@ -173,6 +174,7 @@ func getFirefoxLoginData(loginJson string) (l []loginData, err error) { if err != nil { return nil, err } + defer os.Remove(loginJson) h := gjson.GetBytes(s, "logins") if h.Exists() { for _, v := range h.Array() { diff --git a/internal/browser/browser.go b/internal/browser/browser.go index 9eee6c1..9625d7f 100644 --- a/internal/browser/browser.go +++ b/internal/browser/browser.go @@ -7,6 +7,7 @@ import ( "hack-browser-data/internal/browingdata" "hack-browser-data/internal/browser/chromium" + "hack-browser-data/internal/browser/firefox" ) type Browser interface { @@ -69,15 +70,15 @@ func pickFirefox(name string) []Browser { var browsers []Browser name = strings.ToLower(name) if name == "all" || name == "firefox" { - // for _, f := range firefoxList { - // multiFirefox, err := firefox(f.browserInfo, f.items) - // if err != nil { - // panic(err) - // } - // for _, browser := range multiFirefox { - // browsers = append(browsers, browser) - // } - // } + for _, v := range firefoxList { + multiFirefox, err := firefox.New(v.name, v.storage, v.profilePath, v.items) + if err != nil { + panic(err) + } + for _, browser := range multiFirefox { + browsers = append(browsers, browser) + } + } return browsers } return nil diff --git a/internal/browser/firefox/firefox.go b/internal/browser/firefox/firefox.go index 171d8d5..c4ebacf 100644 --- a/internal/browser/firefox/firefox.go +++ b/internal/browser/firefox/firefox.go @@ -1,116 +1,125 @@ package firefox -// type firefox struct { -// name string -// storage string -// profilePath string -// masterKey []byte -// items []item.Item -// itemPaths map[item.Item]string -// multiItemPaths map[string]map[item.Item]string -// } -// -// // New -// func New(info *browserInfo, items []item.Item) ([]*firefox, error) { -// f := &firefox{ -// browserInfo: info, -// items: items, -// } -// multiItemPaths, err := getFirefoxItemAbsPath(f.browserInfo.profilePath, f.items) -// if err != nil { -// if strings.Contains(err.Error(), "profile path is not exist") { -// fmt.Println(err) -// return nil, nil -// } -// panic(err) -// } -// var firefoxList []*firefox -// for name, value := range multiItemPaths { -// firefoxList = append(firefoxList, &firefox{ -// browserInfo: &browserInfo{ -// name: name, -// masterKey: nil, -// }, -// items: items, -// itemPaths: value, -// }) -// } -// return firefoxList, nil -// } -// -// 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) { -// return nil, fmt.Errorf("%s profile path is not exist", absProfilePath) -// } -// err := filepath.Walk(absProfilePath, firefoxWalkFunc(items, multiItemPaths)) -// return multiItemPaths, err -// } -// -// func (f *firefox) CopyItemFileToLocal() error { -// for item, sourcePath := range f.itemPaths { -// var dstFilename = item.TempName() -// 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 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.FileName() { -// parentDir := getParentDir(path) -// if _, exist := multiItemPaths[parentDir]; exist { -// multiItemPaths[parentDir][v] = path -// } else { -// multiItemPaths[parentDir] = map[item.Item]string{v: path} -// } -// } -// } -// return err -// } -// } -// -// func getParentDir(absPath string) string { -// return filepath.Base(filepath.Dir(absPath)) -// } -// -// func (f *firefox) GetMasterKey() ([]byte, error) { -// return f.masterKey, nil -// } -// -// func (f *firefox) Name() string { -// return f.name -// } -// -// func (f *firefox) GetBrowsingData() []browingdata.Source { -// var browsingData []browingdata.Source -// for item := range f.itemPaths { -// d := item.NewBrowsingData() -// if d != nil { -// browsingData = append(browsingData, d) -// } -// } -// return browsingData -// } +import ( + "fmt" + "io/fs" + "io/ioutil" + "path/filepath" + "strings" + + "hack-browser-data/internal/browingdata" + "hack-browser-data/internal/item" + "hack-browser-data/internal/utils/fileutil" + "hack-browser-data/internal/utils/typeutil" +) + +type firefox struct { + name string + storage string + profilePath string + masterKey []byte + items []item.Item + itemPaths map[item.Item]string +} + +// New returns a new firefox instance. +func New(name, storage, profilePath string, items []item.Item) ([]*firefox, error) { + f := &firefox{ + name: name, + storage: storage, + profilePath: profilePath, + items: items, + } + if !fileutil.FolderExists(profilePath) { + return nil, fmt.Errorf("%s profile path is not exist: %s", name, profilePath) + } + + multiItemPaths, err := f.getMultiItemPath(f.profilePath, f.items) + if err != nil { + if strings.Contains(err.Error(), "profile path is not exist") { + fmt.Println(err) + return nil, nil + } + return nil, err + } + var firefoxList []*firefox + for name, itemPaths := range multiItemPaths { + firefoxList = append(firefoxList, &firefox{ + name: name, + items: typeutil.Keys(itemPaths), + itemPaths: itemPaths, + }) + } + return firefoxList, nil +} + +func (f *firefox) getMultiItemPath(profilePath string, items []item.Item) (map[string]map[item.Item]string, error) { + var multiItemPaths = make(map[string]map[item.Item]string) + + err := filepath.Walk(profilePath, firefoxWalkFunc(items, multiItemPaths)) + return multiItemPaths, err +} + +func (f *firefox) copyItemToLocal() error { + for i, path := range f.itemPaths { + // var dstFilename = item.TempName() + var filename = i.String() + // TODO: Handle read file error + d, err := ioutil.ReadFile(path) + if err != nil { + fmt.Println(err.Error()) + } + err = ioutil.WriteFile(filename, d, 0777) + if err != nil { + return err + } + } + return nil +} + +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.FileName() { + parentDir := getParentDir(path) + if _, exist := multiItemPaths[parentDir]; exist { + multiItemPaths[parentDir][v] = path + } else { + multiItemPaths[parentDir] = map[item.Item]string{v: path} + } + } + } + return err + } +} + +func getParentDir(absPath string) string { + return filepath.Base(filepath.Dir(absPath)) +} + +func (f *firefox) GetMasterKey() ([]byte, error) { + return f.masterKey, nil +} + +func (f *firefox) Name() string { + return f.name +} + +func (f *firefox) GetBrowsingData() (*browingdata.Data, error) { + b := browingdata.New(f.items) + + if err := f.copyItemToLocal(); err != nil { + return nil, err + } + + masterKey, err := f.GetMasterKey() + if err != nil { + return nil, err + } + + f.masterKey = masterKey + if err := b.Recovery(f.masterKey); err != nil { + return nil, err + } + return b, nil +} diff --git a/internal/item/item.go b/internal/item/item.go index 33dddba..c2fb49a 100644 --- a/internal/item/item.go +++ b/internal/item/item.go @@ -103,7 +103,7 @@ func (i Item) String() string { case FirefoxPassword: return TempFirefoxPassword case FirefoxCookie: - return TempFirefoxPassword + return TempFirefoxCookie case FirefoxBookmark: return TempFirefoxBookmark case FirefoxDownload: