diff --git a/cmd/cmd.go b/cmd/cmd.go index 31860a4..3a76aa6 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -23,7 +23,7 @@ func Execute() { 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.2.6", + Version: "0.2.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"}, diff --git a/core/common/output.go b/core/data/output.go similarity index 99% rename from core/common/output.go rename to core/data/output.go index 0066298..dae6fda 100644 --- a/core/common/output.go +++ b/core/data/output.go @@ -1,4 +1,4 @@ -package common +package data import ( "bytes" diff --git a/core/common/parse.go b/core/data/parse.go similarity index 91% rename from core/common/parse.go rename to core/data/parse.go index 00fbb99..e2f8748 100644 --- a/core/common/parse.go +++ b/core/data/parse.go @@ -1,4 +1,4 @@ -package common +package data import ( "bytes" @@ -35,6 +35,17 @@ type Item interface { Release() error } +const ( + ChromePasswordFile = "Login Data" + ChromeHistoryFile = "History" + ChromeCookieFile = "Cookies" + ChromeBookmarkFile = "Bookmarks" + FirefoxCookieFile = "cookies.sqlite" + FirefoxKey4File = "key4.db" + FirefoxLoginFile = "logins.json" + FirefoxDataFile = "places.sqlite" +) + var ( queryChromiumLogin = `SELECT origin_url, username_value, password_value, date_created FROM logins` queryChromiumHistory = `SELECT url, title, visit_count, last_visit_time FROM urls` @@ -47,6 +58,15 @@ var ( closeJournalMode = `PRAGMA journal_mode=off` ) +const ( + bookmarkID = "id" + bookmarkAdded = "date_added" + bookmarkUrl = "url" + bookmarkName = "name" + bookmarkType = "type" + bookmarkChildren = "children" +) + type bookmarks struct { mainPath string bookmarks []bookmark @@ -124,6 +144,9 @@ func (b *bookmarks) FirefoxParse() error { title string ) err = bookmarkRows.Scan(&id, &fk, &bType, &dateAdded, &title) + if err != nil { + log.Error(err) + } if url, ok := tempMap[id]; ok { bookmarkUrl = url } @@ -139,7 +162,7 @@ func (b *bookmarks) FirefoxParse() error { } func (b *bookmarks) CopyDB() error { - return utils.CopyDB(b.mainPath, filepath.Base(b.mainPath)) + return copyToLocalPath(b.mainPath, filepath.Base(b.mainPath)) } func (b *bookmarks) Release() error { @@ -200,6 +223,9 @@ func (c *cookies) ChromeParse(secretKey []byte) error { value, encryptValue []byte ) err = rows.Scan(&key, &encryptValue, &host, &path, &createDate, &expireDate, &isSecure, &isHTTPOnly, &hasExpire, &isPersistent) + if err != nil { + log.Error(err) + } cookie := cookie{ KeyName: key, Host: host, @@ -212,13 +238,15 @@ func (c *cookies) ChromeParse(secretKey []byte) error { CreateDate: utils.TimeEpochFormat(createDate), ExpireDate: utils.TimeEpochFormat(expireDate), } - // remove utils.Prefix 'v10' + // remove 'v10' if secretKey == nil { value, err = decrypt.DPApi(encryptValue) } else { value, err = decrypt.ChromePass(secretKey, encryptValue) } - + if err != nil { + log.Error(err) + } cookie.Value = string(value) c.cookies[host] = append(c.cookies[host], cookie) } @@ -270,7 +298,7 @@ func (c *cookies) FirefoxParse() error { } func (c *cookies) CopyDB() error { - return utils.CopyDB(c.mainPath, filepath.Base(c.mainPath)) + return copyToLocalPath(c.mainPath, filepath.Base(c.mainPath)) } func (c *cookies) Release() error { @@ -378,6 +406,9 @@ func (h *historyData) FirefoxParse() error { visitCount int ) err = historyRows.Scan(&id, &url, &visitDate, &title, &visitCount) + if err != nil { + log.Error(err) + } h.history = append(h.history, history{ Title: title, Url: url, @@ -390,7 +421,7 @@ func (h *historyData) FirefoxParse() error { } func (h *historyData) CopyDB() error { - return utils.CopyDB(h.mainPath, filepath.Base(h.mainPath)) + return copyToLocalPath(h.mainPath, filepath.Base(h.mainPath)) } func (h *historyData) Release() error { @@ -402,14 +433,14 @@ func (h *historyData) OutPut(format, browser, dir string) error { return h.history[i].VisitCount > h.history[j].VisitCount }) switch format { - case "csv": - err := h.outPutCsv(browser, dir) + case "json": + err := h.outPutJson(browser, dir) return err case "console": h.outPutConsole() return nil default: - err := h.outPutJson(browser, dir) + err := h.outPutCsv(browser, dir) return err } } @@ -439,6 +470,9 @@ func (p *passwords) ChromeParse(key []byte) error { } }() rows, err := loginDB.Query(queryChromiumLogin) + if err != nil { + return err + } defer func() { if err := rows.Close(); err != nil { log.Debug(err) @@ -479,7 +513,7 @@ func (p *passwords) ChromeParse(key []byte) error { } func (p *passwords) FirefoxParse() error { - globalSalt, metaBytes, nssA11, nssA102, err := getDecryptKey() + globalSalt, metaBytes, nssA11, nssA102, err := getFirefoxDecryptKey() if err != nil { return err } @@ -492,7 +526,7 @@ func (p *passwords) FirefoxParse() error { var masterPwd []byte m, err := decrypt.Meta(globalSalt, masterPwd, meta) if err != nil { - log.Error("decrypt firefox failed", err) + log.Error("decrypt firefox meta failed", err) return err } if bytes.Contains(m, []byte("password-check")) { @@ -501,16 +535,16 @@ func (p *passwords) FirefoxParse() error { if m == 0 { nss, err := decrypt.DecodeNss(nssA11) if err != nil { + log.Error("decode firefox nssA11 bytes failed", err) return err } - log.Debug("decrypt asn1 pbe success") finallyKey, err := decrypt.Nss(globalSalt, masterPwd, nss) finallyKey = finallyKey[:24] if err != nil { + log.Error("get firefox finally key failed") return err } - log.Debug("get firefox finally key success") - allLogins, err := getLoginData() + allLogins, err := getFirefoxLoginData() if err != nil { return err } @@ -539,12 +573,12 @@ func (p *passwords) FirefoxParse() error { } func (p *passwords) CopyDB() error { - err := utils.CopyDB(p.mainPath, filepath.Base(p.mainPath)) + err := copyToLocalPath(p.mainPath, filepath.Base(p.mainPath)) if err != nil { log.Error(err) } if p.subPath != "" { - err = utils.CopyDB(p.subPath, filepath.Base(p.subPath)) + err = copyToLocalPath(p.subPath, filepath.Base(p.subPath)) } return err } @@ -575,7 +609,8 @@ func (p *passwords) OutPut(format, browser, dir string) error { } } -func getDecryptKey() (item1, item2, a11, a102 []byte, err error) { +// getFirefoxDecryptKey get value from key4.db +func getFirefoxDecryptKey() (item1, item2, a11, a102 []byte, err error) { var ( keyDB *sql.DB pwdRows *sql.Rows @@ -621,7 +656,8 @@ func getDecryptKey() (item1, item2, a11, a102 []byte, err error) { return item1, item2, a11, a102, nil } -func getLoginData() (l []loginData, err error) { +// getFirefoxLoginData use to get firefox +func getFirefoxLoginData() (l []loginData, err error) { s, err := ioutil.ReadFile(FirefoxLoginFile) if err != nil { return nil, err @@ -686,27 +722,6 @@ type ( } ) -const ( - bookmarkID = "id" - bookmarkAdded = "date_added" - bookmarkUrl = "url" - bookmarkName = "name" - bookmarkType = "type" - bookmarkChildren = "children" -) - -const ( - ChromePasswordFile = "Login Data" - ChromeHistoryFile = "History" - ChromeCookieFile = "Cookies" - ChromeBookmarkFile = "Bookmarks" - FirefoxCookieFile = "cookies.sqlite" - FirefoxKey4File = "key4.db" - FirefoxLoginFile = "logins.json" - FirefoxDataFile = "places.sqlite" - FirefoxKey3DB = "key3.db" -) - func (p passwords) Len() int { return len(p.logins) } @@ -718,3 +733,24 @@ func (p passwords) Less(i, j int) bool { func (p passwords) Swap(i, j int) { p.logins[i], p.logins[j] = p.logins[j], p.logins[i] } + +func copyToLocalPath(src, dst string) error { + locals, _ := filepath.Glob("*") + for _, v := range locals { + if v == dst { + err := os.Remove(dst) + if err != nil { + return err + } + } + } + sourceFile, err := ioutil.ReadFile(src) + if err != nil { + log.Debug(err.Error()) + } + err = ioutil.WriteFile(dst, sourceFile, 0777) + if err != nil { + log.Debug(err.Error()) + } + return err +}