From c070323e862be7a682f28598506b6391b644e0e4 Mon Sep 17 00:00:00 2001 From: moonD4rk Date: Sun, 12 Mar 2023 14:23:54 +0800 Subject: [PATCH] refactor: format parse browsing data --- browingdata/bookmark/bookmark.go | 67 +++++++++++------------- browingdata/browsingdata.go | 4 +- browingdata/cookie/cookie.go | 26 +++++---- browingdata/creditcard/creditcard.go | 45 ++++++++-------- browingdata/download/download.go | 33 +++++------- browingdata/extension/extension.go | 10 ++-- browingdata/history/history.go | 33 ++++++------ browingdata/localstorage/localstorage.go | 12 ++--- browingdata/password/password.go | 59 +++++++++++---------- crypto/crypto_darwin.go | 2 +- crypto/crypto_linux.go | 2 +- crypto/crypto_windows.go | 4 +- 12 files changed, 143 insertions(+), 154 deletions(-) diff --git a/browingdata/bookmark/bookmark.go b/browingdata/bookmark/bookmark.go index 89d8283..5bfc7ef 100644 --- a/browingdata/bookmark/bookmark.go +++ b/browingdata/bookmark/bookmark.go @@ -47,23 +47,25 @@ func (c *ChromiumBookmark) Parse(masterKey []byte) error { return nil } +const ( + bookmarkID = "id" + bookmarkAdded = "date_added" + bookmarkURL = "url" + bookmarkName = "name" + bookmarkType = "type" + bookmarkChildren = "children" +) + func getBookmarkChildren(value gjson.Result, w *ChromiumBookmark) (children gjson.Result) { - const ( - bookmarkID = "id" - bookmarkAdded = "date_added" - bookmarkURL = "url" - bookmarkName = "name" - bookmarkType = "type" - bookmarkChildren = "children" - ) nodeType := value.Get(bookmarkType) + children = value.Get(bookmarkChildren) + bm := bookmark{ ID: value.Get(bookmarkID).Int(), Name: value.Get(bookmarkName).String(), URL: value.Get(bookmarkURL).String(), DateAdded: typeutil.TimeEpoch(value.Get(bookmarkAdded).Int()), } - children = value.Get(bookmarkChildren) if nodeType.Exists() { bm.Type = nodeType.String() *w = append(*w, bm) @@ -76,20 +78,11 @@ func getBookmarkChildren(value gjson.Result, w *ChromiumBookmark) (children gjso return children } -func bookmarkType(a int64) string { - switch a { - case 1: - return "url" - default: - return "folder" - } -} - func (c *ChromiumBookmark) Name() string { return "bookmark" } -func (c *ChromiumBookmark) Length() int { +func (c *ChromiumBookmark) Len() int { return len(*c) } @@ -101,38 +94,33 @@ const ( ) func (f *FirefoxBookmark) Parse(masterKey []byte) error { - var ( - err error - keyDB *sql.DB - bookmarkRows *sql.Rows - ) - keyDB, err = sql.Open("sqlite3", item.TempFirefoxBookmark) + db, err := sql.Open("sqlite3", item.TempFirefoxBookmark) if err != nil { return err } defer os.Remove(item.TempFirefoxBookmark) - defer keyDB.Close() - _, err = keyDB.Exec(closeJournalMode) + defer db.Close() + _, err = db.Exec(closeJournalMode) if err != nil { log.Error(err) } - bookmarkRows, err = keyDB.Query(queryFirefoxBookMark) + rows, err := db.Query(queryFirefoxBookMark) if err != nil { return err } - defer bookmarkRows.Close() - for bookmarkRows.Next() { + defer rows.Close() + for rows.Next() { var ( - id, bType, dateAdded int64 - title, url string + id, bt, dateAdded int64 + title, url string ) - if err = bookmarkRows.Scan(&id, &url, &bType, &dateAdded, &title); err != nil { + if err = rows.Scan(&id, &url, &bt, &dateAdded, &title); err != nil { log.Warn(err) } *f = append(*f, bookmark{ ID: id, Name: title, - Type: bookmarkType(bType), + Type: linkType(bt), URL: url, DateAdded: typeutil.TimeStamp(dateAdded / 1000000), }) @@ -147,6 +135,15 @@ func (f *FirefoxBookmark) Name() string { return "bookmark" } -func (f *FirefoxBookmark) Length() int { +func (f *FirefoxBookmark) Len() int { return len(*f) } + +func linkType(a int64) string { + switch a { + case 1: + return "url" + default: + return "folder" + } +} diff --git a/browingdata/browsingdata.go b/browingdata/browsingdata.go index 3bec04d..db63e6c 100644 --- a/browingdata/browsingdata.go +++ b/browingdata/browsingdata.go @@ -25,7 +25,7 @@ type Source interface { Name() string - Length() int + Len() int } func New(items []item.Item) *Data { @@ -49,7 +49,7 @@ func (d *Data) Output(dir, browserName, flag string) { output := newOutPutter(flag) for _, source := range d.sources { - if source.Length() == 0 { + if source.Len() == 0 { // if the length of the export data is 0, then it is not necessary to output continue } diff --git a/browingdata/cookie/cookie.go b/browingdata/cookie/cookie.go index 53aa750..dc5ebbf 100644 --- a/browingdata/cookie/cookie.go +++ b/browingdata/cookie/cookie.go @@ -36,13 +36,13 @@ const ( ) func (c *ChromiumCookie) Parse(masterKey []byte) error { - cookieDB, err := sql.Open("sqlite3", item.TempChromiumCookie) + db, err := sql.Open("sqlite3", item.TempChromiumCookie) if err != nil { return err } defer os.Remove(item.TempChromiumCookie) - defer cookieDB.Close() - rows, err := cookieDB.Query(queryChromiumCookie) + defer db.Close() + rows, err := db.Query(queryChromiumCookie) if err != nil { return err } @@ -71,11 +71,10 @@ func (c *ChromiumCookie) Parse(masterKey []byte) error { ExpireDate: typeutil.TimeEpoch(expireDate), } if len(encryptValue) > 0 { - var err error - if masterKey == nil { + if len(masterKey) == 0 { value, err = crypto.DPAPI(encryptValue) } else { - value, err = crypto.Chromium(masterKey, encryptValue) + value, err = crypto.DecryptPass(masterKey, encryptValue) } if err != nil { log.Error(err) @@ -94,7 +93,7 @@ func (c *ChromiumCookie) Name() string { return "cookie" } -func (c *ChromiumCookie) Length() int { +func (c *ChromiumCookie) Len() int { return len(*c) } @@ -105,13 +104,14 @@ const ( ) func (f *FirefoxCookie) Parse(masterKey []byte) error { - cookieDB, err := sql.Open("sqlite3", item.TempFirefoxCookie) + db, err := sql.Open("sqlite3", item.TempFirefoxCookie) if err != nil { return err } defer os.Remove(item.TempFirefoxCookie) - defer cookieDB.Close() - rows, err := cookieDB.Query(queryFirefoxCookie) + defer db.Close() + + rows, err := db.Query(queryFirefoxCookie) if err != nil { return err } @@ -136,6 +136,10 @@ func (f *FirefoxCookie) Parse(masterKey []byte) error { Value: value, }) } + + sort.Slice(*f, func(i, j int) bool { + return (*f)[i].CreateDate.After((*f)[j].CreateDate) + }) return nil } @@ -143,6 +147,6 @@ func (f *FirefoxCookie) Name() string { return "cookie" } -func (f *FirefoxCookie) Length() int { +func (f *FirefoxCookie) Len() int { return len(*f) } diff --git a/browingdata/creditcard/creditcard.go b/browingdata/creditcard/creditcard.go index 48c9611..45c12e9 100644 --- a/browingdata/creditcard/creditcard.go +++ b/browingdata/creditcard/creditcard.go @@ -29,13 +29,14 @@ const ( ) func (c *ChromiumCreditCard) Parse(masterKey []byte) error { - creditDB, err := sql.Open("sqlite3", item.TempChromiumCreditCard) + db, err := sql.Open("sqlite3", item.TempChromiumCreditCard) if err != nil { return err } defer os.Remove(item.TempChromiumCreditCard) - defer creditDB.Close() - rows, err := creditDB.Query(queryChromiumCredit) + defer db.Close() + + rows, err := db.Query(queryChromiumCredit) if err != nil { return err } @@ -56,17 +57,17 @@ func (c *ChromiumCreditCard) Parse(masterKey []byte) error { Address: address, NickName: nickname, } - if masterKey == nil { - value, err = crypto.DPAPI(encryptValue) - if err != nil { - return err + if len(encryptValue) > 0 { + if len(masterKey) == 0 { + value, err = crypto.DPAPI(encryptValue) + } else { + value, err = crypto.DecryptPass(masterKey, encryptValue) } - } else { - value, err = crypto.Chromium(masterKey, encryptValue) if err != nil { - return err + log.Error(err) } } + ccInfo.CardNumber = string(value) *c = append(*c, ccInfo) } @@ -77,21 +78,20 @@ func (c *ChromiumCreditCard) Name() string { return "creditcard" } -func (c *ChromiumCreditCard) Length() int { +func (c *ChromiumCreditCard) Len() int { return len(*c) } type YandexCreditCard []card func (c *YandexCreditCard) Parse(masterKey []byte) error { - creditDB, err := sql.Open("sqlite3", item.TempYandexCreditCard) + db, err := sql.Open("sqlite3", item.TempYandexCreditCard) if err != nil { return err } defer os.Remove(item.TempYandexCreditCard) - defer creditDB.Close() - defer creditDB.Close() - rows, err := creditDB.Query(queryChromiumCredit) + defer db.Close() + rows, err := db.Query(queryChromiumCredit) if err != nil { return err } @@ -112,15 +112,14 @@ func (c *YandexCreditCard) Parse(masterKey []byte) error { Address: address, NickName: nickname, } - if masterKey == nil { - value, err = crypto.DPAPI(encryptValue) - if err != nil { - return err + if len(encryptValue) > 0 { + if len(masterKey) == 0 { + value, err = crypto.DPAPI(encryptValue) + } else { + value, err = crypto.DecryptPass(masterKey, encryptValue) } - } else { - value, err = crypto.Chromium(masterKey, encryptValue) if err != nil { - return err + log.Error(err) } } ccInfo.CardNumber = string(value) @@ -133,6 +132,6 @@ func (c *YandexCreditCard) Name() string { return "creditcard" } -func (c *YandexCreditCard) Length() int { +func (c *YandexCreditCard) Len() int { return len(*c) } diff --git a/browingdata/download/download.go b/browingdata/download/download.go index 4209677..fc7827a 100644 --- a/browingdata/download/download.go +++ b/browingdata/download/download.go @@ -32,13 +32,13 @@ const ( ) func (c *ChromiumDownload) Parse(masterKey []byte) error { - historyDB, err := sql.Open("sqlite3", item.TempChromiumDownload) + db, err := sql.Open("sqlite3", item.TempChromiumDownload) if err != nil { return err } defer os.Remove(item.TempChromiumDownload) - defer historyDB.Close() - rows, err := historyDB.Query(queryChromiumDownload) + defer db.Close() + rows, err := db.Query(queryChromiumDownload) if err != nil { return err } @@ -71,7 +71,7 @@ func (c *ChromiumDownload) Name() string { return "download" } -func (c *ChromiumDownload) Length() int { +func (c *ChromiumDownload) Len() int { return len(*c) } @@ -83,33 +83,28 @@ const ( ) func (f *FirefoxDownload) Parse(masterKey []byte) error { - var ( - err error - keyDB *sql.DB - downloadRows *sql.Rows - ) - keyDB, err = sql.Open("sqlite3", item.TempFirefoxDownload) + db, err := sql.Open("sqlite3", item.TempFirefoxDownload) if err != nil { return err } defer os.Remove(item.TempFirefoxDownload) - defer keyDB.Close() - _, err = keyDB.Exec(closeJournalMode) + defer db.Close() + + _, err = db.Exec(closeJournalMode) if err != nil { - return err + log.Error(err) } - defer keyDB.Close() - downloadRows, err = keyDB.Query(queryFirefoxDownload) + rows, err := db.Query(queryFirefoxDownload) if err != nil { return err } - defer downloadRows.Close() - for downloadRows.Next() { + defer rows.Close() + for rows.Next() { var ( content, url string placeID, dateAdded int64 ) - if err = downloadRows.Scan(&placeID, &content, &url, &dateAdded); err != nil { + if err = rows.Scan(&placeID, &content, &url, &dateAdded); err != nil { log.Warn(err) } contentList := strings.Split(content, ",{") @@ -137,6 +132,6 @@ func (f *FirefoxDownload) Name() string { return "download" } -func (f *FirefoxDownload) Length() int { +func (f *FirefoxDownload) Len() int { return len(*f) } diff --git a/browingdata/extension/extension.go b/browingdata/extension/extension.go index e3b06bb..fe05680 100644 --- a/browingdata/extension/extension.go +++ b/browingdata/extension/extension.go @@ -30,12 +30,12 @@ func (c *ChromiumExtension) Parse(masterKey []byte) error { } defer os.RemoveAll(item.TempChromiumExtension) for _, f := range files { - file, err := fileutil.ReadFile(f) + content, err := fileutil.ReadFile(f) if err != nil { - log.Error("Failed to read file: %s", err) + log.Error("Failed to read content: %s", err) continue } - b := gjson.Parse(file) + b := gjson.Parse(content) *c = append(*c, &extension{ Name: b.Get("name").String(), Description: b.Get("description").String(), @@ -50,7 +50,7 @@ func (c *ChromiumExtension) Name() string { return "extension" } -func (c *ChromiumExtension) Length() int { +func (c *ChromiumExtension) Len() int { return len(*c) } @@ -78,6 +78,6 @@ func (f *FirefoxExtension) Name() string { return "extension" } -func (f *FirefoxExtension) Length() int { +func (f *FirefoxExtension) Len() int { return len(*f) } diff --git a/browingdata/history/history.go b/browingdata/history/history.go index 619d05c..492786a 100644 --- a/browingdata/history/history.go +++ b/browingdata/history/history.go @@ -28,13 +28,14 @@ const ( ) func (c *ChromiumHistory) Parse(masterKey []byte) error { - historyDB, err := sql.Open("sqlite3", item.TempChromiumHistory) + db, err := sql.Open("sqlite3", item.TempChromiumHistory) if err != nil { return err } defer os.Remove(item.TempChromiumHistory) - defer historyDB.Close() - rows, err := historyDB.Query(queryChromiumHistory) + defer db.Close() + + rows, err := db.Query(queryChromiumHistory) if err != nil { return err } @@ -66,7 +67,7 @@ func (c *ChromiumHistory) Name() string { return "history" } -func (c *ChromiumHistory) Length() int { +func (c *ChromiumHistory) Len() int { return len(*c) } @@ -78,34 +79,30 @@ const ( ) func (f *FirefoxHistory) Parse(masterKey []byte) error { - var ( - err error - keyDB *sql.DB - historyRows *sql.Rows - ) - keyDB, err = sql.Open("sqlite3", item.TempFirefoxHistory) + db, err := sql.Open("sqlite3", item.TempFirefoxHistory) if err != nil { return err } defer os.Remove(item.TempFirefoxHistory) - defer keyDB.Close() - _, err = keyDB.Exec(closeJournalMode) + defer db.Close() + + _, err = db.Exec(closeJournalMode) if err != nil { return err } - defer keyDB.Close() - historyRows, err = keyDB.Query(queryFirefoxHistory) + defer db.Close() + rows, err := db.Query(queryFirefoxHistory) if err != nil { return err } - defer historyRows.Close() - for historyRows.Next() { + defer rows.Close() + for rows.Next() { var ( id, visitDate int64 url, title string visitCount int ) - if err = historyRows.Scan(&id, &url, &visitDate, &title, &visitCount); err != nil { + if err = rows.Scan(&id, &url, &visitDate, &title, &visitCount); err != nil { log.Warn(err) } *f = append(*f, history{ @@ -125,6 +122,6 @@ func (f *FirefoxHistory) Name() string { return "history" } -func (f *FirefoxHistory) Length() int { +func (f *FirefoxHistory) Len() int { return len(*f) } diff --git a/browingdata/localstorage/localstorage.go b/browingdata/localstorage/localstorage.go index 6f3521a..5158f92 100644 --- a/browingdata/localstorage/localstorage.go +++ b/browingdata/localstorage/localstorage.go @@ -29,7 +29,6 @@ func (c *ChromiumLocalStorage) Parse(masterKey []byte) error { return err } defer os.RemoveAll(item.TempChromiumLocalStorage) - // log.Info("parsing local storage now") defer db.Close() iter := db.NewIterator(nil, nil) @@ -58,7 +57,7 @@ func (c *ChromiumLocalStorage) Name() string { return "localStorage" } -func (c *ChromiumLocalStorage) Length() int { +func (c *ChromiumLocalStorage) Len() int { return len(*c) } @@ -102,16 +101,13 @@ func (f *FirefoxLocalStorage) Parse(masterKey []byte) error { if err != nil { return err } - if err != nil { - return err - } defer os.Remove(item.TempFirefoxLocalStorage) defer db.Close() + _, err = db.Exec(closeJournalMode) if err != nil { - return err + log.Error(err) } - defer db.Close() rows, err := db.Query(queryFirefoxHistory) if err != nil { return err @@ -147,6 +143,6 @@ func (f *FirefoxLocalStorage) Name() string { return "localStorage" } -func (f *FirefoxLocalStorage) Length() int { +func (f *FirefoxLocalStorage) Len() int { return len(*f) } diff --git a/browingdata/password/password.go b/browingdata/password/password.go index 6196c92..e56c528 100644 --- a/browingdata/password/password.go +++ b/browingdata/password/password.go @@ -34,13 +34,14 @@ const ( ) func (c *ChromiumPassword) Parse(masterKey []byte) error { - loginDB, err := sql.Open("sqlite3", item.TempChromiumPassword) + db, err := sql.Open("sqlite3", item.TempChromiumPassword) if err != nil { return err } defer os.Remove(item.TempChromiumPassword) - defer loginDB.Close() - rows, err := loginDB.Query(queryChromiumLogin) + defer db.Close() + + rows, err := db.Query(queryChromiumLogin) if err != nil { return err } @@ -61,11 +62,10 @@ func (c *ChromiumPassword) Parse(masterKey []byte) error { LoginURL: url, } if len(pwd) > 0 { - var err error - if masterKey == nil { + if len(masterKey) == 0 { password, err = crypto.DPAPI(pwd) } else { - password, err = crypto.Chromium(masterKey, pwd) + password, err = crypto.DecryptPass(masterKey, pwd) } if err != nil { log.Error(err) @@ -90,7 +90,7 @@ func (c *ChromiumPassword) Name() string { return "password" } -func (c *ChromiumPassword) Length() int { +func (c *ChromiumPassword) Len() int { return len(*c) } @@ -101,13 +101,14 @@ const ( ) func (c *YandexPassword) Parse(masterKey []byte) error { - loginDB, err := sql.Open("sqlite3", item.TempYandexPassword) + db, err := sql.Open("sqlite3", item.TempYandexPassword) if err != nil { return err } defer os.Remove(item.TempYandexPassword) - defer loginDB.Close() - rows, err := loginDB.Query(queryYandexLogin) + defer db.Close() + + rows, err := db.Query(queryYandexLogin) if err != nil { return err } @@ -129,11 +130,10 @@ func (c *YandexPassword) Parse(masterKey []byte) error { } if len(pwd) > 0 { - var err error - if masterKey == nil { + if len(masterKey) == 0 { password, err = crypto.DPAPI(pwd) } else { - password, err = crypto.Chromium(masterKey, pwd) + password, err = crypto.DecryptPass(masterKey, pwd) } if err != nil { log.Errorf("decrypt yandex password error %s", err) @@ -158,7 +158,7 @@ func (c *YandexPassword) Name() string { return "password" } -func (c *YandexPassword) Length() int { +func (c *YandexPassword) Len() int { return len(*c) } @@ -183,24 +183,25 @@ func (f *FirefoxPassword) Parse(masterKey []byte) error { if err != nil { return err } - keyLin := []byte{248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} if bytes.Contains(k, []byte("password-check")) { - m := bytes.Compare(nssA102, keyLin) - if m == 0 { + keyLin := []byte{248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} + if bytes.Compare(nssA102, keyLin) == 0 { nssPBE, err := crypto.NewASN1PBE(nssA11) if err != nil { return err } finallyKey, err := nssPBE.Decrypt(globalSalt, masterKey) - finallyKey = finallyKey[:24] if err != nil { return err } - allLogin, err := getFirefoxLoginData() + + finallyKey = finallyKey[:24] + logins, err := getFirefoxLoginData() if err != nil { return err } - for _, v := range allLogin { + + for _, v := range logins { userPBE, err := crypto.NewASN1PBE(v.encryptUser) if err != nil { return err @@ -233,8 +234,7 @@ func (f *FirefoxPassword) Parse(masterKey []byte) error { } func getFirefoxDecryptKey(key4file string) (item1, item2, a11, a102 []byte, err error) { - var keyDB *sql.DB - keyDB, err = sql.Open("sqlite3", key4file) + keyDB, err := sql.Open("sqlite3", key4file) if err != nil { return nil, nil, nil, nil, err } @@ -251,15 +251,16 @@ func getFirefoxDecryptKey(key4file string) (item1, item2, a11, a102 []byte, err return item1, item2, a11, a102, nil } -func getFirefoxLoginData() (l []loginData, err error) { +func getFirefoxLoginData() ([]loginData, error) { s, err := os.ReadFile(item.TempFirefoxPassword) if err != nil { return nil, err } defer os.Remove(item.TempFirefoxPassword) - h := gjson.GetBytes(s, "logins") - if h.Exists() { - for _, v := range h.Array() { + loginsJSON := gjson.GetBytes(s, "logins") + var logins []loginData + if loginsJSON.Exists() { + for _, v := range loginsJSON.Array() { var ( m loginData user []byte @@ -277,16 +278,16 @@ func getFirefoxLoginData() (l []loginData, err error) { m.encryptUser = user m.encryptPass = pass m.CreateDate = typeutil.TimeStamp(v.Get("timeCreated").Int() / 1000) - l = append(l, m) + logins = append(logins, m) } } - return l, nil + return logins, nil } func (f *FirefoxPassword) Name() string { return "password" } -func (f *FirefoxPassword) Length() int { +func (f *FirefoxPassword) Len() int { return len(*f) } diff --git a/crypto/crypto_darwin.go b/crypto/crypto_darwin.go index 0a84f1d..a4ec686 100644 --- a/crypto/crypto_darwin.go +++ b/crypto/crypto_darwin.go @@ -4,7 +4,7 @@ package crypto var iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} -func Chromium(key, encryptPass []byte) ([]byte, error) { +func DecryptPass(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) <= 3 { return nil, errPasswordIsEmpty } diff --git a/crypto/crypto_linux.go b/crypto/crypto_linux.go index e9c6108..03e95bc 100644 --- a/crypto/crypto_linux.go +++ b/crypto/crypto_linux.go @@ -4,7 +4,7 @@ package crypto var iv = []byte{32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32} -func Chromium(key, encryptPass []byte) ([]byte, error) { +func DecryptPass(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) < 3 { return nil, errPasswordIsEmpty } diff --git a/crypto/crypto_windows.go b/crypto/crypto_windows.go index ba4e1a8..c5e1b58 100644 --- a/crypto/crypto_windows.go +++ b/crypto/crypto_windows.go @@ -9,7 +9,7 @@ import ( "unsafe" ) -func Chromium(key, encryptPass []byte) ([]byte, error) { +func DecryptPass(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) < 15 { return nil, errPasswordIsEmpty } @@ -17,7 +17,7 @@ func Chromium(key, encryptPass []byte) ([]byte, error) { return aesGCMDecrypt(encryptPass[15:], key, encryptPass[3:15]) } -func ChromiumForYandex(key, encryptPass []byte) ([]byte, error) { +func DecryptPassForYandex(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) < 3 { return nil, errPasswordIsEmpty }