mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-05-19 18:58:03 +02:00
9fb5165fcb
* feat: add crypto/keyretriever package for Chromium master key retrieval * feat: complete keyretriever with gcoredump, chainbreaker, and tests * refactor: replace internal chainbreaker with keychainbreaker v0.1.0 Replace the incomplete internal chainbreaker implementation (~1400 lines of duplicated code) with the external keychainbreaker package, which provides a complete, well-tested keychain parsing library. Changes: - Add github.com/moond4rk/keychainbreaker v0.1.0 dependency - Update gcoredump_darwin.go to use keychainbreaker API (Open/Unlock/GenericPasswords) - Add KeychainPasswordRetriever for password-based keychain unlocking with sync.Once caching across multiple browser queries - Unify DefaultRetriever(keychainPassword string) signature across all platforms - Delete utils/chainbreaker/ (696 lines + test + testdata) - Delete crypto/keyretriever/chainbreaker_darwin.go (696 lines duplicate) - Delete browser/exploit/gcoredump/ (duplicate of keyretriever version) - Update chromium_darwin.go to use keyretriever.DecryptKeychain - Clean up .golangci.yml lint exceptions and .gitignore entries - Use errors.Is() instead of == for context.DeadlineExceeded check * refactor: improve gcoredump exploit code quality and add comments * fix: address Copilot review feedback on keyretriever
88 lines
2.1 KiB
Go
88 lines
2.1 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,
|
|
keyLen: 16,
|
|
hashFunc: sha1.New,
|
|
}
|
|
|
|
// DBusRetriever queries GNOME Keyring / KDE Wallet via D-Bus Secret Service.
|
|
type DBusRetriever struct{}
|
|
|
|
func (r *DBusRetriever) RetrieveKey(storage, _ string) ([]byte, error) {
|
|
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("secret %q not found in keyring", storage)
|
|
}
|
|
|
|
// FallbackRetriever uses the hardcoded "peanuts" password when D-Bus is unavailable.
|
|
// https://source.chromium.org/chromium/chromium/src/+/main:components/os_crypt/os_crypt_linux.cc;l=100
|
|
type FallbackRetriever struct{}
|
|
|
|
func (r *FallbackRetriever) RetrieveKey(_, _ string) ([]byte, error) {
|
|
return linuxParams.deriveKey([]byte("peanuts")), nil
|
|
}
|
|
|
|
// DefaultRetriever returns the Linux retriever chain:
|
|
// D-Bus Secret Service first, then "peanuts" fallback.
|
|
// The keychainPassword parameter is unused on Linux.
|
|
func DefaultRetriever(_ string) KeyRetriever {
|
|
return NewChain(
|
|
&DBusRetriever{},
|
|
&FallbackRetriever{},
|
|
)
|
|
}
|