Simple script to extract (encrypted) cookies out of Chrome OS X cookie store. Usage: ./cookiemonster domain.com
September 23, 2014 ยท View on GitHub
package main
import ( "code.google.com/p/go.crypto/pbkdf2" "crypto/aes" "crypto/cipher" "crypto/sha1" "database/sql" "fmt" "log" "os" "os/exec" "os/user" "strings"
_ "github.com/mattn/go-sqlite3"
)
// Inpsiration // http://n8henrie.com/2013/11/use-chromes-cookies-for-easier-downloading-with-python-requests/
// Chromium Mac os_crypt: http://dacort.me/1ynPMgx var ( salt = "saltysalt" iv = " " length = 16 password = "" iterations = 1003 )
// Cookie - Items for a cookie type Cookie struct { Domain string Key string Value string EncryptedValue []byte }
// DecryptedValue - Get the unencrypted value of a Chrome cookie func (c *Cookie) DecryptedValue() string { if c.Value > "" { return c.Value }
if len(c.EncryptedValue) > 0 {
encryptedValue := c.EncryptedValue[3:]
return decryptValue(encryptedValue)
}
return ""
}
func usage() { fmt.Fprintf(os.Stderr, "usage: %s [domain]\n", os.Args[0]) os.Exit(2) }
func main() { if len(os.Args) != 2 { usage() }
domain := os.Args[1]
password = getPassword()
// TODO: Output in Netscape format
for _, cookie := range getCookies(domain) {
fmt.Printf("%s/%s: %s\n", cookie.Domain, cookie.Key, cookie.DecryptedValue())
}
}
func decryptValue(encryptedValue []byte) string { key := pbkdf2.Key([]byte(password), []byte(salt), iterations, length, sha1.New) block, err := aes.NewCipher(key) if err != nil { log.Fatal(err) }
decrypted := make([]byte, len(encryptedValue))
cbc := cipher.NewCBCDecrypter(block, []byte(iv))
cbc.CryptBlocks(decrypted, encryptedValue)
plainText, err := aesStripPadding(decrypted)
if err != nil {
fmt.Println("Error decrypting:", err)
return ""
}
return string(plainText)
}
// In the padding scheme the last
func getPassword() string { parts := strings.Fields("security find-generic-password -wga Chrome") cmd := parts[0] parts = parts[1:len(parts)]
out, err := exec.Command(cmd, parts...).Output()
if err != nil {
log.Fatal("error finding password ", err)
}
return strings.Trim(string(out), "\n")
}
func getCookies(domain string) (cookies []Cookie) { usr, _ := user.Current() cookiesFile := fmt.Sprintf("%s/Library/Application Support/Google/Chrome/Default/Cookies", usr.HomeDir)
db, err := sql.Open("sqlite3", cookiesFile)
if err != nil {
log.Fatal(err)
}
defer db.Close()
rows, err := db.Query("SELECT name, value, host_key, encrypted_value FROM cookies WHERE host_key like ?", fmt.Sprintf("%%%s%%", domain))
if err != nil {
log.Fatal(err)
}
defer rows.Close()
for rows.Next() {
var name, value, hostKey string
var encryptedValue []byte
rows.Scan(&name, &value, &hostKey, &encryptedValue)
cookies = append(cookies, Cookie{hostKey, name, value, encryptedValue})
}
return
}