From 83e07583f4f2e7cb6d602fa0987532e2d3b4a3d5 Mon Sep 17 00:00:00 2001 From: Cyrus <50967051+Not-Cyrus@users.noreply.github.com> Date: Tue, 8 Dec 2020 21:52:17 -0500 Subject: [PATCH] Support credit cards for chrome (#52) --- core/browser.go | 13 +++++-- core/data/output.go | 29 ++++++++++++++ core/data/parse.go | 93 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 4 deletions(-) diff --git a/core/browser.go b/core/browser.go index 48586b1..08991d7 100644 --- a/core/browser.go +++ b/core/browser.go @@ -41,10 +41,11 @@ type Browser interface { } const ( - cookie = "cookie" - history = "history" - bookmark = "bookmark" - password = "password" + cookie = "cookie" + history = "history" + bookmark = "bookmark" + password = "password" + creditcard = "creditcard" ) var ( @@ -75,6 +76,10 @@ var ( mainFile: data.ChromePasswordFile, newItem: data.NewCPasswords, }, + creditcard: { + mainFile: data.ChromeCreditFile, + newItem: data.NewCCards, + }, } firefoxItems = map[string]struct { mainFile string diff --git a/core/data/output.go b/core/data/output.go index dae6fda..4c8bb5a 100644 --- a/core/data/output.go +++ b/core/data/output.go @@ -62,6 +62,16 @@ func (c *cookies) outPutJson(browser, dir string) error { return nil } +func (credit *creditcards) outPutJson(browser, dir string) error { + filename := utils.FormatFileName(dir, browser, "credit", "json") + err := writeToJson(filename, credit.cards) + if err != nil { + return err + } + fmt.Printf("%s Get %d cards, filename is %s \n", utils.Prefix, len(credit.cards), filename) + return nil +} + func writeToJson(filename string, data interface{}) error { f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0644) if err != nil { @@ -123,6 +133,19 @@ func (c *cookies) outPutCsv(browser, dir string) error { return nil } +func (credit *creditcards) outPutCsv(browser, dir string) error { + filename := utils.FormatFileName(dir, browser, "credit", "csv") + var tempSlice []card + for _, v := range credit.cards { + tempSlice = append(tempSlice, v...) + } + if err := writeToCsv(filename, tempSlice); err != nil { + return err + } + fmt.Printf("%s Get %d cards, filename is %s \n", utils.Prefix, len(credit.cards), filename) + return nil +} + func writeToCsv(filename string, data interface{}) error { var d []byte f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_APPEND, 0644) @@ -168,3 +191,9 @@ func (p *passwords) outPutConsole() { fmt.Printf("%+v\n", v) } } + +func (credit *creditcards) outPutConsole() { + for _, v := range credit.cards { + fmt.Printf("%+v\n", v) + } +} diff --git a/core/data/parse.go b/core/data/parse.go index 66ffd30..ee2702d 100644 --- a/core/data/parse.go +++ b/core/data/parse.go @@ -36,6 +36,7 @@ type Item interface { } const ( + ChromeCreditFile = "Web Data" ChromePasswordFile = "Login Data" ChromeHistoryFile = "History" ChromeCookieFile = "Cookies" @@ -47,6 +48,7 @@ const ( ) var ( + queryChromiumCredit = `SELECT guid,name_on_card,expiration_month,expiration_year,card_number_encrypted FROM credit_cards` queryChromiumLogin = `SELECT origin_url, username_value, password_value, date_created FROM logins` queryChromiumHistory = `SELECT url, title, visit_count, last_visit_time FROM urls` queryChromiumCookie = `SELECT name, encrypted_value, host_key, path, creation_utc, expires_utc, is_secure, is_httponly, has_expires, is_persistent FROM cookies` @@ -609,6 +611,90 @@ func (p *passwords) OutPut(format, browser, dir string) error { } } +type creditcards struct { + mainPath string + cards map[string][]card +} + +func NewCCards(main string, sub string) Item { + return &creditcards{mainPath: main} +} + +func (credit *creditcards) FirefoxParse() error { + return nil // FireFox does not have a credit card saving feature +} + +func (credit *creditcards) ChromeParse(secretKey []byte) error { + credit.cards = make(map[string][]card) + creditDB, err := sql.Open("sqlite3", ChromeCreditFile) + if err != nil { + return err + } + defer func() { + if err := creditDB.Close(); err != nil { + log.Debug(err) + } + }() + rows, err := creditDB.Query(queryChromiumCredit) + if err != nil { + return err + } + defer func() { + if err := rows.Close(); err != nil { + log.Debug(err) + } + }() + for rows.Next() { + var ( + name, expirationm, expirationy, guid string + value, encryptValue []byte + ) + err := rows.Scan(&guid, &name, &expirationm, &expirationy, &encryptValue) + if err != nil { + log.Error(err) + } + creditCardInfo := card{ + GUID: guid, + Name: name, + ExpirationMonth: expirationm, + ExpirationYear: expirationy, + } + if secretKey == nil { + value, err = decrypt.DPApi(encryptValue) + } else { + value, err = decrypt.ChromePass(secretKey, encryptValue) + } + if err != nil { + log.Debug(err) + } + creditCardInfo.Cardnumber = string(value) + credit.cards[guid] = append(credit.cards[guid], creditCardInfo) + } + return nil +} + +func (credit *creditcards) CopyDB() error { + return copyToLocalPath(credit.mainPath, filepath.Base(credit.mainPath)) +} + +func (credit *creditcards) Release() error { + return os.Remove(filepath.Base(credit.mainPath)) +} + +func (credit *creditcards) OutPut(format, browser, dir string) error { + switch format { + case "csv": + err := credit.outPutCsv(browser, dir) + return err + case "console": + credit.outPutConsole() + return nil + default: + err := credit.outPutJson(browser, dir) + return err + } +} + // getFirefoxDecryptKey get value from key4.db func getFirefoxDecryptKey() (item1, item2, a11, a102 []byte, err error) { var ( @@ -720,6 +806,13 @@ type ( VisitCount int LastVisitTime time.Time } + card struct { + GUID string + Name string + ExpirationMonth string + ExpirationYear string + Cardnumber string + } ) func (p passwords) Len() int {