From 221c059642f3d84e4fc680da5a478652198f8aa0 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: Fri, 7 Aug 2020 11:45:37 +0800 Subject: [PATCH] feat: add compress result to zip file Close #24 --- cmd/cmd.go | 14 ++++++++--- core/common/output.go | 17 +++++++------ core/common/parse.go | 24 ++++--------------- core/decrypt/decrypt_windows.go | 2 +- utils/utils.go | 42 +++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 32 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index b930c70..6b8a086 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -16,16 +16,18 @@ var ( exportDir string outputFormat string verbose bool + compress bool ) 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 -e all]\n Get all data(password/cookie/history/bookmark) from chrome", - Version: "0.2.0", + UsageText: "[hack-browser-data -b chrome -f json -dir results -e all -cc]\n Get all data(password/cookie/history/bookmark) from chrome", + Version: "0.2.1", 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"}, &cli.StringFlag{Name: "browser", Aliases: []string{"b"}, Destination: &browser, 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: "json", Usage: "Format, csv|json|console"}, @@ -78,7 +80,7 @@ func Execute() { } err = item.Release() if err != nil { - return err + log.Error(err) } err = item.OutPut(outputFormat, name, exportDir) if err != nil { @@ -86,6 +88,12 @@ func Execute() { } } } + if compress { + err = utils.Compress(exportDir) + if err != nil { + log.Error(err) + } + } return nil }, } diff --git a/core/common/output.go b/core/common/output.go index 4cbe60a..0066298 100644 --- a/core/common/output.go +++ b/core/common/output.go @@ -14,7 +14,6 @@ import ( var ( utf8Bom = []byte{239, 187, 191} - prefix = "[x]: " ) func (b *bookmarks) outPutJson(browser, dir string) error { @@ -26,7 +25,7 @@ func (b *bookmarks) outPutJson(browser, dir string) error { if err != nil { return err } - fmt.Printf("%s Get %d bookmarks, filename is %s \n", prefix, len(b.bookmarks), filename) + fmt.Printf("%s Get %d bookmarks, filename is %s \n", utils.Prefix, len(b.bookmarks), filename) return nil } @@ -39,7 +38,7 @@ func (h *historyData) outPutJson(browser, dir string) error { if err != nil { return err } - fmt.Printf("%s Get %d history, filename is %s \n", prefix, len(h.history), filename) + fmt.Printf("%s Get %d history, filename is %s \n", utils.Prefix, len(h.history), filename) return nil } @@ -49,7 +48,7 @@ func (p *passwords) outPutJson(browser, dir string) error { if err != nil { return err } - fmt.Printf("%s Get %d passwords, filename is %s \n", prefix, len(p.logins), filename) + fmt.Printf("%s Get %d passwords, filename is %s \n", utils.Prefix, len(p.logins), filename) return nil } @@ -59,7 +58,7 @@ func (c *cookies) outPutJson(browser, dir string) error { if err != nil { return err } - fmt.Printf("%s Get %d cookies, filename is %s \n", prefix, len(c.cookies), filename) + fmt.Printf("%s Get %d cookies, filename is %s \n", utils.Prefix, len(c.cookies), filename) return nil } @@ -89,7 +88,7 @@ func (b *bookmarks) outPutCsv(browser, dir string) error { if err := writeToCsv(filename, b.bookmarks); err != nil { return err } - fmt.Printf("%s Get %d bookmarks, filename is %s \n", prefix, len(b.bookmarks), filename) + fmt.Printf("%s Get %d bookmarks, filename is %s \n", utils.Prefix, len(b.bookmarks), filename) return nil } @@ -98,7 +97,7 @@ func (h *historyData) outPutCsv(browser, dir string) error { if err := writeToCsv(filename, h.history); err != nil { return err } - fmt.Printf("%s Get %d history, filename is %s \n", prefix, len(h.history), filename) + fmt.Printf("%s Get %d history, filename is %s \n", utils.Prefix, len(h.history), filename) return nil } @@ -107,7 +106,7 @@ func (p *passwords) outPutCsv(browser, dir string) error { if err := writeToCsv(filename, p.logins); err != nil { return err } - fmt.Printf("%s Get %d passwords, filename is %s \n", prefix, len(p.logins), filename) + fmt.Printf("%s Get %d passwords, filename is %s \n", utils.Prefix, len(p.logins), filename) return nil } @@ -120,7 +119,7 @@ func (c *cookies) outPutCsv(browser, dir string) error { if err := writeToCsv(filename, tempSlice); err != nil { return err } - fmt.Printf("%s Get %d cookies, filename is %s \n", prefix, len(c.cookies), filename) + fmt.Printf("%s Get %d cookies, filename is %s \n", utils.Prefix, len(c.cookies), filename) return nil } diff --git a/core/common/parse.go b/core/common/parse.go index c94a4b5..962da27 100644 --- a/core/common/parse.go +++ b/core/common/parse.go @@ -59,7 +59,6 @@ func NewBookmarks(main, sub string) Item { func (b *bookmarks) ChromeParse(key []byte) error { bookmarks, err := utils.ReadFile(ChromeBookmarkFile) if err != nil { - log.Error(err) return err } r := gjson.Parse(bookmarks) @@ -104,16 +103,12 @@ func (b *bookmarks) FirefoxParse() error { ) keyDB, err = sql.Open("sqlite3", FirefoxDataFile) if err != nil { - log.Error(err) return err } defer func() { if err := keyDB.Close(); err != nil { log.Error(err) } - if err := bookmarkRows.Close(); err != nil { - log.Error(err) - } }() _, err = keyDB.Exec(closeJournalMode) if err != nil { @@ -121,7 +116,7 @@ func (b *bookmarks) FirefoxParse() error { } bookmarkRows, err = keyDB.Query(queryFirefoxBookMarks) if err != nil { - log.Error(err) + return err } for bookmarkRows.Next() { var ( @@ -181,7 +176,6 @@ func (c *cookies) ChromeParse(secretKey []byte) error { c.cookies = make(map[string][]cookie) cookieDB, err := sql.Open("sqlite3", ChromeCookieFile) if err != nil { - log.Debug(err) return err } defer func() { @@ -215,7 +209,7 @@ func (c *cookies) ChromeParse(secretKey []byte) error { CreateDate: utils.TimeEpochFormat(createDate), ExpireDate: utils.TimeEpochFormat(expireDate), } - // remove prefix 'v10' + // remove utils.Prefix 'v10' if secretKey == nil { value, err = decrypt.DPApi(encryptValue) } else { @@ -232,7 +226,6 @@ func (c *cookies) FirefoxParse() error { c.cookies = make(map[string][]cookie) cookieDB, err := sql.Open("sqlite3", FirefoxCookieFile) if err != nil { - log.Debug(err) return err } defer func() { @@ -242,7 +235,6 @@ func (c *cookies) FirefoxParse() error { }() rows, err := cookieDB.Query(queryFirefoxCookie) if err != nil { - log.Error(err) return err } defer func() { @@ -257,6 +249,9 @@ func (c *cookies) FirefoxParse() error { creationTime, expiry int64 ) err = rows.Scan(&name, &value, &host, &path, &creationTime, &expiry, &isSecure, &isHttpOnly) + if err != nil { + log.Error(err) + } c.cookies[host] = append(c.cookies[host], cookie{ KeyName: name, Host: host, @@ -305,7 +300,6 @@ func NewHistoryData(main, sub string) Item { func (h *historyData) ChromeParse(key []byte) error { historyDB, err := sql.Open("sqlite3", ChromeHistoryFile) if err != nil { - log.Error(err) return err } defer func() { @@ -334,7 +328,6 @@ func (h *historyData) ChromeParse(key []byte) error { } if err != nil { log.Error(err) - continue } h.history = append(h.history, data) } @@ -351,7 +344,6 @@ func (h *historyData) FirefoxParse() error { tempMap = make(map[int64]string) keyDB, err = sql.Open("sqlite3", FirefoxDataFile) if err != nil { - log.Error(err) return err } _, err = keyDB.Exec(closeJournalMode) @@ -433,7 +425,6 @@ func NewCPasswords(main, sub string) Item { func (p *passwords) ChromeParse(key []byte) error { loginDB, err := sql.Open("sqlite3", ChromePasswordFile) if err != nil { - log.Error(err) return err } defer func() { @@ -484,7 +475,6 @@ func (p *passwords) ChromeParse(key []byte) error { func (p *passwords) FirefoxParse() error { globalSalt, metaBytes, nssA11, nssA102, err := getDecryptKey() if err != nil { - log.Error(err) return err } keyLin := []byte{248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} @@ -505,14 +495,12 @@ func (p *passwords) FirefoxParse() error { if m == 0 { nss, err := decrypt.DecodeNss(nssA11) if err != nil { - log.Error(err) return err } log.Debug("decrypt asn1 pbe success") finallyKey, err := decrypt.Nss(globalSalt, masterPwd, nss) finallyKey = finallyKey[:24] if err != nil { - log.Error(err) return err } log.Debug("get firefox finally key success") @@ -526,12 +514,10 @@ func (p *passwords) FirefoxParse() error { user, err := decrypt.Des3Decrypt(finallyKey, userPBE.Iv, userPBE.Encrypted) if err != nil { log.Error(err) - return err } pwd, err := decrypt.Des3Decrypt(finallyKey, pwdPBE.Iv, pwdPBE.Encrypted) if err != nil { log.Error(err) - return err } log.Debug("decrypt firefox success") p.logins = append(p.logins, loginData{ diff --git a/core/decrypt/decrypt_windows.go b/core/decrypt/decrypt_windows.go index ce359f3..bbf0a89 100644 --- a/core/decrypt/decrypt_windows.go +++ b/core/decrypt/decrypt_windows.go @@ -16,7 +16,7 @@ import ( func ChromePass(key, encryptPass []byte) ([]byte, error) { if len(encryptPass) > 15 { - // remove prefix 'v10' + // remove Prefix 'v10' return aesGCMDecrypt(encryptPass[15:], key, encryptPass[3:15]) } else { return nil, errPasswordIsEmpty diff --git a/utils/utils.go b/utils/utils.go index b05f331..f0019ea 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,6 +1,8 @@ package utils import ( + "archive/zip" + "bytes" "fmt" "io/ioutil" "os" @@ -12,6 +14,8 @@ import ( "hack-browser-data/log" ) +const Prefix = "[x]: " + func CopyDB(src, dst string) error { locals, _ := filepath.Glob("*") for _, v := range locals { @@ -104,3 +108,41 @@ func MakeDir(dirName string) error { } return nil } + +func Compress(exportDir string) error { + files, err := ioutil.ReadDir(exportDir) + if err != nil { + log.Error(err) + } + var b = new(bytes.Buffer) + zw := zip.NewWriter(b) + for _, f := range files { + fw, _ := zw.Create(f.Name()) + fileName := path.Join(exportDir, f.Name()) + fileContent, err := ioutil.ReadFile(fileName) + if err != nil { + zw.Close() + return err + } + _, err = fw.Write(fileContent) + if err != nil { + zw.Close() + return err + } + err = os.Remove(fileName) + if err != nil { + log.Error(err) + } + } + if err := zw.Close(); err != nil { + return err + } + zipName := exportDir + `/archive.zip` + outFile, _ := os.Create(zipName) + _, err = b.WriteTo(outFile) + if err != nil { + return err + } + fmt.Printf("%s Compress success, zip filename is %s \n", Prefix, zipName) + return nil +}