golang读取chrome/edge浏览器本地cookies数据库
本帖最后由 cflying 于 2022-12-21 20:14 编辑去爬个资料,登录验证太麻烦,不如本地浏览器登录后读取cookies直接爬来的方便,本来打算网上找一个现成的代码来读取浏览器cookies数据库,结果度娘半天竟然没有(网上全都是python的,偶尔有个读保存账号和密码的,结果N年前的解密方式还没更新),要不就只有去仓库下,感觉有点小题大做了,所以不如拿python的改一个单文件的,这样使用起来一个文件带到哪都方便。
package main
import (
"database/sql"
"fmt"
"os"
"io/ioutil"
"encoding/json"
"encoding/base64"
"syscall"
"unsafe"
"crypto/aes"
"crypto/cipher"
_ "github.com/mattn/go-sqlite3"
)
type DATA_BLOB struct {
cbData uint32
pbData *byte
}
func NewBlob(d []byte) *DATA_BLOB {
if len(d)==0 {
return &DATA_BLOB{}
}
b:=&DATA_BLOB{
pbData:&d,
cbData:uint32(len(d)),
}
return b
}
func (b *DATA_BLOB) ToByteArray() []byte {
d:=make([]byte, b.cbData)
copy(d, (*byte)(unsafe.Pointer(b.pbData))[:])
return d
}
func dpapi_decrypt(encrypted []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(encrypted))), 0, 0, 0, 0,0x1, uintptr(unsafe.Pointer(&outblob)))
if r==0 {
return nil, err
}
defer procLocalFree.Call(uintptr(unsafe.Pointer(outblob.pbData)))
return outblob.ToByteArray(), err
}
func aesGCMDecrypt(data []byte, key []byte, iv []byte) []byte {
block,_:=aes.NewCipher(key)
aesGcm,_:=cipher.NewGCM(block)
plaintext,_:=aesGcm.Open(nil,iv,data, nil)
return plaintext
}
func aes_decrypt(encrypted_txt string)([]byte,){
key_file,_:=os.OpenFile(os.Getenv("LOCALAPPDATA")+ "\\Microsoft\\Edge\\User Data\\Local State",os.O_RDONLY,os.ModePerm)
defer key_file.Close()
key_data,_:=ioutil.ReadAll(key_file)
dynamic:=make(mapinterface{})
json.Unmarshal([]byte(string(key_data)),&dynamic)
encrypted_key,_:=base64.StdEncoding.DecodeString(dynamic["os_crypt"].(mapinterface{})["encrypted_key"].(string))
encrypted_key=encrypted_key//去掉DPAPI后的加密key
key,_:=dpapi_decrypt(encrypted_key)//解密后的key
nonce:=encrypted_txt//AES随机12位vi
decryptor:=aesGCMDecrypt([]byte(encrypted_txt),key,[]byte(nonce))
return decryptor
}
/*前缀处理*/
func chrome_decrypt (encrypted_txt string)[]byte{
var decrypted_txt []byte
if encrypted_txt[:3]=="v10"{
decrypted_txt=aes_decrypt(encrypted_txt)
}
if encrypted_txt[:4]=="DPAP"{
decrypted_txt,_=dpapi_decrypt([]byte(encrypted_txt))
}
return decrypted_txt
}
func get_cookies_from_chrome(domain string)([]mapstring){
query:=`SELECT name, encrypted_value as value,host_key as domain, path FROM cookies where host_key like `+`"%`+domain+`%"`
fmt.Println(query)
var file string
if _,err:=os.Stat(os.Getenv("LOCALAPPDATA")+"\\Microsoft\\Edge\\User Data\\Default\\Network\\Cookies");err==nil{
file=os.Getenv("LOCALAPPDATA")+"\\Microsoft\\Edge\\User Data\\Default\\Network\\Cookies"
}else if _,err:=os.Stat(os.Getenv("LOCALAPPDATA")+"\\Microsoft\\Edge\\User Data\\Profile 3\\Network\\Cookies");err==nil{
file=os.Getenv("LOCALAPPDATA")+"\\Microsoft\\Edge\\User Data\\Profile 3\\Network\\Cookies"
}
fmt.Println(file)
db,_:= sql.Open("sqlite3", file)
defer db.Close()
rows,_:= db.Query(query)
defer rows.Close()
var cookies []mapstring
for rows.Next() {
var name,value,domain,path string
rows.Scan(&name, &value, &domain, &path)
if name != "" && value != ""{
cc_data_tmp:=make(mapstring)
cc_data_tmp["name"]=name
cc_data_tmp["vlaue"]=string(chrome_decrypt(value))
cc_data_tmp["doamin"]=domain
cc_data_tmp["path"]=path
cookies=append(cookies,cc_data_tmp)
}
}
return cookies
}
func main() {
//fmt.Println(get_cookies_from_chrome(".hao123.com")["vlaue"])
for _,v:=range get_cookies_from_chrome(".hao123.com"){
fmt.Println(v)
}
}
{:5_106:}一看就是个高手
页:
[1]