mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-05-19 18:58:03 +02:00
99 lines
2.8 KiB
Go
99 lines
2.8 KiB
Go
//go:build linux
|
|
|
|
package keyretriever
|
|
|
|
import (
|
|
"crypto/sha1"
|
|
"fmt"
|
|
|
|
"github.com/godbus/dbus/v5"
|
|
keyring "github.com/ppacher/go-dbus-keyring"
|
|
)
|
|
|
|
// https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc
|
|
var linuxParams = pbkdf2Params{
|
|
salt: []byte("saltysalt"),
|
|
iterations: 1,
|
|
keySize: 16,
|
|
hashFunc: sha1.New,
|
|
}
|
|
|
|
// DBusRetriever queries GNOME Keyring / KDE Wallet via D-Bus Secret Service.
|
|
type DBusRetriever struct{}
|
|
|
|
func (r *DBusRetriever) RetrieveKey(hints Hints) ([]byte, error) {
|
|
storage := hints.KeychainLabel
|
|
conn, err := dbus.SessionBus()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("dbus session: %w", err)
|
|
}
|
|
|
|
svc, err := keyring.GetSecretService(conn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("secret service: %w", err)
|
|
}
|
|
|
|
session, err := svc.OpenSession()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("open session: %w", err)
|
|
}
|
|
defer session.Close()
|
|
|
|
collections, err := svc.GetAllCollections()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get collections: %w", err)
|
|
}
|
|
|
|
for _, col := range collections {
|
|
items, err := col.GetAllItems()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, item := range items {
|
|
label, err := item.GetLabel()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
if label == storage {
|
|
secret, err := item.GetSecret(session.Path())
|
|
if err != nil {
|
|
return nil, fmt.Errorf("get secret for %s: %w", storage, err)
|
|
}
|
|
if len(secret.Value) > 0 {
|
|
return linuxParams.deriveKey(secret.Value), nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil, fmt.Errorf("%q: %w", storage, errStorageNotFound)
|
|
}
|
|
|
|
// PosixRetriever produces Chromium's kV10Key by applying PBKDF2 to the hardcoded password
|
|
// "peanuts". Matches Chromium's upstream PosixKeyProvider (components/os_crypt/async/browser/
|
|
// posix_key_provider.cc): a deterministic 16-byte AES-128 key used to encrypt ciphertexts with
|
|
// the "v10" prefix when no keyring is available (headless servers, Docker, CI).
|
|
type PosixRetriever struct{}
|
|
|
|
func (r *PosixRetriever) RetrieveKey(_ Hints) ([]byte, error) {
|
|
return linuxParams.deriveKey([]byte("peanuts")), nil
|
|
}
|
|
|
|
// DefaultRetrievers returns the Linux Retrievers, one per cipher tier. Chromium on Linux emits
|
|
// distinct prefixes for distinct key sources:
|
|
//
|
|
// - v10 prefix → PBKDF2("peanuts") — Chromium's kV10Key, emitted when no keyring is available
|
|
// (headless servers, Docker, CI).
|
|
// - v11 prefix → PBKDF2(keyring secret) — Chromium's kV11Key, emitted when D-Bus Secret
|
|
// Service (GNOME Keyring / KWallet) is reachable.
|
|
//
|
|
// A profile can carry both prefixes if the host moved between keyring-equipped and headless
|
|
// sessions, so both tiers run independently with per-tier logging rather than a first-success
|
|
// chain.
|
|
func DefaultRetrievers() Retrievers {
|
|
return Retrievers{
|
|
V10: &PosixRetriever{},
|
|
V11: &DBusRetriever{},
|
|
}
|
|
}
|