Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 16 to 30 of 32

Thread: DPAPI en CryptUnprotectData

  1. #16
    Quote Originally Posted by Paul-Jan View Post
    Je koopt er verder niets voor, maar ik wilde je even complimenteren met deze zeer duidelijke en complete probleemomschrijving. ?????? <- dit is een emoji van een duimpje: het forum houdt niet van unicode, ik wel.
    Bedankt Paul-Jan, het ware nog beter geweest als ik het preciese probleem met de aes-256 decryptie kon omschrijven maar dat is nu net deel waar ik niets van af weet

    PS de bron van het python project is https://github.com/taizan-hokuto/chrome_cookie

  2. #17
    Quote Originally Posted by Delphiwizard View Post
    Bedankt Paul-Jan, het ware nog beter geweest als ik het preciese probleem met de aes-256 decryptie kon omschrijven maar dat is nu net deel waar ik niets van af weet

    PS de bron van het python project is https://github.com/taizan-hokuto/chrome_cookie
    Had je al een methode om AES-256 in GCM mode te decoderen?
    Want tot zover was ik ook gekomen

    De cookies bevatten #01 #00 #00 etc en dan kun je ze gewoon zonder key nogmaals door CryptUnprotectData gooien. Dit zijn de cookies van voor v80.
    En daarna bevatten ze v10 + data (0x763130) Ik neem aan dat je die records structuur al gevonden hebt.
    Alleen dan nog door een AES-256-GCM decryptor gooien samen met de nonce (onderdeel van dat record) en je voorheen verkregen key.
    De tag (van 16 bytes) kun je tijdens het decrypten gebruiken om de decryptie te controleren.

    Het grootste probleem zal dus die AES-256-GCM decryptor zijn.

    Edit: Tadatadadaaaaaaaaaaaaa
    Ik heb het werkend.
    Wel in Lazarus en met heel veel gehannes om jwawincrypt.pas en jwabcrypt.pas werkend te krijgen.

    Delphi Code:
    1. Line := '';
    2. Line := SQLQuery1.FieldByName('host_key').AsString;
    3. Line := Line + ' ' + SQLQuery1.FieldByName('name').AsString;
    4.  
    5. Encrypted_Value := SQLQuery1.FieldByName('encrypted_value').AsBytes;
    6. // v10 (i.e. 0x763130)
    7. // of
    8. // DPAPI = 0x01000000D08C9DDF0115D1118C7A00C04FC297EB
    9.  
    10. if Copy(TEncoding.ANSI.GetAnsiString(Encrypted_Value), 1, 3) = 'v10' then
    11. begin
    12.   // v10 (i.e. 0x763130)
    13.   // data = bytes.fromhex('763130...') # the encrypted cookie
    14.   // nonce = data[3:3+12]
    15.   // ciphertext = data[3+12:-16]
    16.   // tag = data[-16:]
    17.   // cipher = AES.new(decrypted_key, AES.MODE_GCM, nonce=nonce)
    18.   // plaintext = cipher.decrypt_and_verify(ciphertext, tag) # the decrypted cookie
    19.  
    20.   if Length(Encrypted_Value) > 3 + 12 + 16 then
    21.   begin
    22.     SetLength(Nonce, 12);
    23.     SetLength(InBuf, Length(Encrypted_Value) - 15);
    24.     SetLength(OutBuf, Length(InBuf) - 16 { tag});
    25.     Move(Encrypted_Value[3], Nonce[0], 12);
    26.     Move(Encrypted_Value[15], InBuf[0], Length(InBuf));
    27.     if bdecrypt_gcm('AES', InBuf, @OutBuf[0], Key, Nonce) <> 0 then
    28.     begin
    29.       Line := Line + ' - ' + TEncoding.UTF8.GetString(OutBuf);
    30.     end;
    31.   end;
    32.  
    33. end
    34. else
    35. begin
    36.   // DPAPI = 0x01000000D08C9DDF0115D1118C7A00C04FC297EB
    37.  
    38.   DataIn.pbData := @Encrypted_Value[0];
    39.   DataIn.cbData := Length(Encrypted_Value);
    40.   if CryptUnprotectData(@DataIn, nil, nil, nil, nil, 0, @DataOut) then
    41.   begin
    42.     SetLength(Result, DataOut.cbData);
    43.     Move(DataOut.pbData^, Result[0], DataOut.cbData);
    44.     LocalFree(cardinal(DataOut.pbData));
    45.     LocalFree(cardinal(DataIn.pbData));
    46.     Line := Line + ' - ' + TEncoding.ANSI.GetAnsiString(Result);
    47.   end;
    48.  
    49. end;
    Last edited by rvk; 15-Jun-20 at 22:06.

  3. #18
    Alles nu in één unit gezet (geen jwa en geen andere dependencies meer).
    Laat maar weten als je interesse hebt. Dan plop ik het voorbeeldprojectje hier neer.
    (maar code uit voorgaand bericht was de essentie)

  4. #19
    Quote Originally Posted by rvk View Post
    Alles nu in één unit gezet (geen jwa en geen andere dependencies meer).
    Laat maar weten als je interesse hebt. Dan plop ik het voorbeeldprojectje hier neer.
    (maar code uit voorgaand bericht was de essentie)
    Zeer graag het demo projectje Rik, dat zou fantastisch zijn, het is momenteel druk druk dus ik moet eerst de focus op iets anders leggen maar bekijk het dan zeker eens.
    Last edited by Delphiwizard; 20-Jun-20 at 19:32.

  5. #20
    Ok. Hier is het Lazarus projectje.
    Zelf even de AFilename aanpassen naar de directory voor je cookie file en Local state. Kan natuurlijk ook automatisch maar dit was meer even snel en dirty in elkaar gezet
    Dit is op 2 plaatsen. Regel 92 voor de Local State file om de envrypted key op te halen en op regel 210 voor het SQLite bestand met de cookies.

    Als eerste zoek je naar de encrypted key om chrome v80+ cookies te kunnen decrypten.

    In de Local State zoek je dus naar os_crypt en dan naar encrypted_key.
    Deze key wordt daarna alleen gebruikt voor de encryptie van de cookies van Chrome v80 en hoger.
    De encrypted key moet door CryptUnprotectData gegooid worden om de key te krijgen

    Voor cookies onder de v80 heb je die key echter niet nodig. Daarvan kun je de cookie value direct door CryptUnprotectData gooien.

    Voor v80+ cookies heb je de key dus wel nodig en moet die met AES GCM mode decrypted worden.
    Het was een beetje een gedoe om een decrypter te vinden daarvoor maar uiteindelijk kan dat dus door Windows API zelf gedaan worden in BCryptDecrypt.

    De encrypted value van een v80+ cookie ziet er zo uit (en is eigenlijk een record)
    data = bytes.fromhex('763130') # the encrypted cookie
    nonce = data[3 tot 3+12]
    ciphertext = data[3+12 tot eind-16]
    tag = data[eind-16 tot eind]

    Overigens doe ik wel een BCryptOpenAlgorithmProvider maart ik heb eigenlijk geen idee of het verplicht is om ook weer een Close te doen op die hProvider (BCryptCloseAlgorithmProvider). Het lijkt in ieder geval goed te gaan zonder.

    Ik hoop dat je het een beetje naar Delphi kunt vertalen.
    Attached Files Attached Files

  6. #21
    Bedankt Rik, als we elkaar ooit ontmoeten, ik trakteer
    Ik probeer het morgen in een Delphi project te gieten.

  7. #22
    Quote Originally Posted by Delphiwizard View Post
    Bedankt Rik, als we elkaar ooit ontmoeten, ik trakteer
    Ooit hadden we daar een pannenkoekendag voor
    10.4.2, Delphi2010, of Lazarus 2.2.0

  8. #23
    Ondertussen succesvol overgenomen van Lazarus naar Delphi
    Nu nog uitzoeken hoe ik de cookie expires_utc moet omzetten naar een Delphi datetime.

  9. #24
    Blijkbaar is bevat deze timestamp het aantal microseconden sinds 1-1-1601. Zie ook WebKit/Chrome Timestamp Converter.

    Ik kon geen bestaande Delphi functie vinden (in DateUtils) die deze conversie doet. Wel van een normale Unix timestamp, maar dat is dit niet.
    Onderstaande functie lijkt het goed te converteren naar een UTC datetime, maar het lijkt me verstandig dat je 'm nog even test met wat waarden waarvan je weet wat het antwoord moet zijn.
    Aangezien de timestamp in UTC is, is het resultaat van de functie dat ook. Met TTimeZone.ToLocalTime kan je deze omzetten naar je lokale timezone.

    Delphi Code:
    1. function CookieTimestampToUTCDateTime(const CookieTimeStamp: Int64): TDateTime;
    2. const
    3.   DaysBetweenCookieAndDelphi= 109205;
    4. var
    5.   CookieDateTime: TDateTime;
    6. begin
    7.   CookieDateTime:= CookieTimeStamp / MSecsPerDay / 1000;
    8.   Result := CookieDateTime- DaysBetweenCookieAndDelphi;
    9. end;
    Last edited by GolezTrol; 22-Jun-20 at 15:59.
    1+1=b

  10. #25
    Had ik gisteren dan nog gevonden, probleem was wel dat die waarde in de SqlLite db een Int64 is en dat zowel Unidac als Firedac het als Int32 ophalen.
    In Firedac heb ik dat kunnen oplossen door de Maprules aan te passen, in Unidac heb ik niet zo'n mogelijkheid gevonden, ik heb bij hen een ticket aangemaakt hiervoor.

    Delphi Code:
    1. CookieTime := qry_chromecookies.FieldByName('expires_utc').AsLargeInt;
    2. CookieTime := (CookieTime div 1000000) - 11644473600;
    3. Expires := UnixToDateTime(CookieTime);

  11. #26
    Quote Originally Posted by rvk View Post
    Had je al een methode om AES-256 in GCM mode te decoderen?
    Want tot zover was ik ook gekomen

    De cookies bevatten #01 #00 #00 etc en dan kun je ze gewoon zonder key nogmaals door CryptUnprotectData gooien. Dit zijn de cookies van voor v80.
    En daarna bevatten ze v10 + data (0x763130) Ik neem aan dat je die records structuur al gevonden hebt.
    Alleen dan nog door een AES-256-GCM decryptor gooien samen met de nonce (onderdeel van dat record) en je voorheen verkregen key.
    De tag (van 16 bytes) kun je tijdens het decrypten gebruiken om de decryptie te controleren.

    Het grootste probleem zal dus die AES-256-GCM decryptor zijn.

    Edit: Tadatadadaaaaaaaaaaaaa
    Ik heb het werkend.
    Wel in Lazarus en met heel veel gehannes om jwawincrypt.pas en jwabcrypt.pas werkend te krijgen.

    Delphi Code:
    1. Line := '';
    2. Line := SQLQuery1.FieldByName('host_key').AsString;
    3. Line := Line + ' ' + SQLQuery1.FieldByName('name').AsString;
    4.  
    5. Encrypted_Value := SQLQuery1.FieldByName('encrypted_value').AsBytes;
    6. // v10 (i.e. 0x763130)
    7. // of
    8. // DPAPI = 0x01000000D08C9DDF0115D1118C7A00C04FC297EB
    9.  
    10. if Copy(TEncoding.ANSI.GetAnsiString(Encrypted_Value), 1, 3) = 'v10' then
    11. begin
    12.   // v10 (i.e. 0x763130)
    13.   // data = bytes.fromhex('763130...') # the encrypted cookie
    14.   // nonce = data[3:3+12]
    15.   // ciphertext = data[3+12:-16]
    16.   // tag = data[-16:]
    17.   // cipher = AES.new(decrypted_key, AES.MODE_GCM, nonce=nonce)
    18.   // plaintext = cipher.decrypt_and_verify(ciphertext, tag) # the decrypted cookie
    19.  
    20.   if Length(Encrypted_Value) > 3 + 12 + 16 then
    21.   begin
    22.     SetLength(Nonce, 12);
    23.     SetLength(InBuf, Length(Encrypted_Value) - 15);
    24.     SetLength(OutBuf, Length(InBuf) - 16 { tag});
    25.     Move(Encrypted_Value[3], Nonce[0], 12);
    26.     Move(Encrypted_Value[15], InBuf[0], Length(InBuf));
    27.     if bdecrypt_gcm('AES', InBuf, @OutBuf[0], Key, Nonce) <> 0 then
    28.     begin
    29.       Line := Line + ' - ' + TEncoding.UTF8.GetString(OutBuf);
    30.     end;
    31.   end;
    32.  
    33. end
    34. else
    35. begin
    36.   // DPAPI = 0x01000000D08C9DDF0115D1118C7A00C04FC297EB
    37.  
    38.   DataIn.pbData := @Encrypted_Value[0];
    39.   DataIn.cbData := Length(Encrypted_Value);
    40.   if CryptUnprotectData(@DataIn, nil, nil, nil, nil, 0, @DataOut) then
    41.   begin
    42.     SetLength(Result, DataOut.cbData);
    43.     Move(DataOut.pbData^, Result[0], DataOut.cbData);
    44.     LocalFree(cardinal(DataOut.pbData));
    45.     LocalFree(cardinal(DataIn.pbData));
    46.     Line := Line + ' - ' + TEncoding.ANSI.GetAnsiString(Result);
    47.   end;
    48.  
    49. end;
    Waar moet ik veranderen om wachtwoorden te decoderen (User Data\Default\Login Data)? Ik kan me voorstellen dat dat hier is:

    Code:
    SetLength(Nonce, 12);
    SetLength(InBuf, Length(Encrypted_Value) - 15);
    SetLength(OutBuf, Length(InBuf) - 16 { tag});
    Move(Encrypted_Value[3], Nonce[0], 12);
    Move(Encrypted_Value[15], InBuf[0], Length(InBuf));
    Ik heb deze code op Delphi 10 geprobeerd, maar de functie BCryptDecrypt retourneert altijd fout STATUS_AUTH_TAG_MISMATCH:

    Delphi Code:
    1. unit Unit2;
    2.  
    3. interface
    4.  
    5. uses
    6.   Windows, Messages, SysUtils, StrUtils, Variants, Classes, Graphics, Controls,
    7.   Forms, Dialogs, SQLiteTable3, SQLite3, JSON, IOUtils, System.NetEncoding,
    8.   Types, Vcl.StdCtrls;
    9.  
    10. type
    11.   _CRYPTOAPI_BLOB = record
    12.     cbData: DWORD;
    13.     pbData: PByte;
    14.   end;
    15.  
    16.   DATA_BLOB = _CRYPTOAPI_BLOB;
    17.  
    18.   PDATA_BLOB = ^DATA_BLOB;
    19.  
    20. type
    21.   _CRYPTPROTECT_PROMPTSTRUCT = record
    22.     cbSize: DWORD;
    23.     dwPromptFlags: DWORD;
    24.     hwndApp: HWND;
    25.     szPrompt: PWideChar;
    26.   end;
    27.  
    28.   CRYPTPROTECT_PROMPTSTRUCT = _CRYPTPROTECT_PROMPTSTRUCT;
    29.  
    30.   PCRYPTPROTECT_PROMPTSTRUCT = ^CRYPTPROTECT_PROMPTSTRUCT;
    31.  
    32. function CryptUnprotectData(pDataIn: PDATA_BLOB; ppszDataDescr: PPWideChar; pOptionalEntropy: PDATA_BLOB; pReserved: Pointer; pPromptStruct: PCRYPTPROTECT_PROMPTSTRUCT; dwFlags: DWORD; pDataOut: PDATA_BLOB): BOOL; stdcall; external 'Crypt32.dll';
    33.  
    34. type
    35.   BCRYPT_ALG_HANDLE = THandle;
    36.  
    37.   BCRYPT_HANDLE = THandle;
    38.  
    39.   BCRYPT_KEY_HANDLE = THandle;
    40.  
    41.   NTSTATUS = LONG;
    42.  
    43.   TNTStatus = NTSTATUS;
    44.  
    45. type
    46.   _BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO = record
    47.     cbSize: ULONG;
    48.     dwInfoVersion: ULONG;
    49.     pbNonce: PBYTE;
    50.     cbNonce: ULONG;
    51.     pbAuthData: PBYTE;
    52.     cbAuthData: ULONG;
    53.     pbTag: PBYTE;
    54.     cbTag: ULONG;
    55.     pbMacContext: PBYTE;
    56.     cbMacContext: ULONG;
    57.     cbAAD: ULONG;
    58.     cbData: ULONGLONG;
    59.     dwFlags: ULONG;
    60.   end;
    61.  
    62.   BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO = _BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO;
    63.  
    64. const
    65.   bcryptdll = 'bcrypt.dll';
    66.   BCRYPT_CHAINING_MODE_: WideString = 'ChainingMode';
    67.   BCRYPT_CHAIN_MODE_GCM_: WideString = 'ChainingModeGCM';
    68.  
    69. function BCryptOpenAlgorithmProvider(out phAlgorithm: BCRYPT_ALG_HANDLE; pszAlgId, pszImplementation: LPCWSTR; dwFlags: ULONG): TNTStatus; stdcall; external bcryptdll;
    70.  
    71. function BCryptSetProperty(hObject: BCRYPT_HANDLE; pszProperty: LPCWSTR; pbInput: PUCHAR; cbInput: ULONG; dwFlags: ULONG): TNTStatus; stdcall; external bcryptdll;
    72.  
    73. function BCryptGenerateSymmetricKey(hAlgorithm: BCRYPT_ALG_HANDLE; out phKey: BCRYPT_KEY_HANDLE; pbKeyObject: PUCHAR; cbKeyObject: ULONG; pbSecret: PUCHAR; cbSecret, dwFlags: ULONG): TNTStatus; stdcall; external bcryptdll;
    74.  
    75. function BCryptDecrypt(hKey: BCRYPT_KEY_HANDLE; pbInput: PUCHAR; cbInput: ULONG; pPaddingInfo: Pointer; pbIV: PUCHAR; cbIV: ULONG; pbOutput: PUCHAR; cbOutput: ULONG; out pcbResult: ULONG; dwFlags: ULONG): TNTStatus; stdcall; external bcryptdll;
    76.  
    77. type
    78.   TForm2 = class(TForm)
    79.     Button1: TButton;
    80.     Memo1: TMemo;
    81.     procedure Button1Click(Sender: TObject);
    82.   private
    83.     { Private declarations }
    84.   public
    85.     { Public declarations }
    86.   end;
    87.  
    88. var
    89.   Form2: TForm2;
    90.  
    91. implementation
    92.  
    93. {$R *.dfm}
    94.  
    95. function TempFolder: string;
    96. var
    97.   BufFolder: array[0..MAX_PATH] of Char;
    98. begin
    99.   GetTempPath(SizeOf(BufFolder), BufFolder);
    100.   Result := IncludeTrailingPathDelimiter(string(BufFolder));
    101. end;
    102.  
    103. function ByteArrayToHexStr(const ByteArray: TByteDynArray): string;
    104. var
    105.   i: Integer;
    106. begin
    107.   Result := '';
    108.   try
    109.     for i := 0 to Length(ByteArray) - 1 do
    110.       Result := Result + Format('%x|', [ByteArray[i]]);
    111.   except
    112.     on e: Exception do
    113.     begin
    114.       Result := '';
    115.     end;
    116.   end;
    117. end;
    118.  
    119. function UnprotectData(fpDataIn: TBytes): TBytes;
    120. var
    121.   DataIn, DataOut: DATA_BLOB;
    122. begin
    123.   DataOut.cbData := 0;
    124.   DataOut.pbData := nil;
    125.  
    126.   DataIn.cbData := Length(fpDataIn);
    127.   DataIn.pbData := @fpDataIn[0];
    128.  
    129.   if not CryptUnprotectData(@DataIn, nil, nil, nil, nil, 0, @DataOut) then
    130.     RaiseLastOSError;
    131.  
    132.   SetLength(Result, DataOut.cbData * 2);
    133.   Move(DataOut.pbData^, Result[0], DataOut.cbData * 2);
    134.   LocalFree(HLOCAL(DataOut.pbData));
    135. end;
    136.  
    137. function GetEncryptedKey: TBytes;
    138. var
    139.   FileName, DecodedKey: string;
    140.   FJsonObj: TJSONObject;
    141.   JsonObj: TJSONObject;
    142.   JsonCrypt: TJSONString;
    143.   BytesString: TBytes;
    144. begin
    145.   FileName := TFile.ReadAllText(GetEnvironmentVariable('LOCALAPPDATA') + '\Google\Chrome\User Data\Local State');
    146.   FJsonObj := TJSONObject.ParseJSONValue(TEncoding.UTF8.GetBytes(FileName), 0) as TJSONObject;
    147.   try
    148.     JsonObj := FJsonObj.GetValue('os_crypt') as TJSONObject;
    149.     JsonCrypt := JsonObj.GetValue('encrypted_key') as TJSONString;
    150.     BytesString := TNetEncoding.Base64.DecodeStringToBytes(JsonCrypt.Value);
    151.     Delete(BytesString, 0, 5);
    152.     Result := UnprotectData(BytesString);
    153.     SetString(DecodedKey, PAnsiChar(@Result[0]), Length(Result));
    154.     Form2.Memo1.Lines.Add(#13#10 + DecodedKey + #13#10);
    155.     Form2.Memo1.Lines.Add(#13#10 + ByteArrayToHexStr(Result) + #13#10#13#10);
    156.   finally
    157.     FJsonObj.Free;
    158.   end;
    159. end;
    160.  
    161. function BDecrypt_GCM(Algoritme: LPCWSTR; Encryped: array of Byte; Output: Pointer; const gKey, IV: array of Byte): ULONG;
    162. const
    163.   AES_BLOCK_SIZE = 16;
    164. var
    165.   hProvider: BCRYPT_ALG_HANDLE;
    166.   Decrypted: array[0..1023] of Byte;
    167.   hKey: BCRYPT_KEY_HANDLE;
    168.   Status: NTSTATUS;
    169.   Info: BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO;
    170. begin
    171.   Result := 0;
    172.   hProvider := 0;
    173.   hKey := 0;
    174.   Status := BCryptOpenAlgorithmProvider(hProvider, Algoritme, nil, 0);
    175.   if Status <> 0 then
    176.     Exit;
    177.   Status := BCryptSetProperty(hProvider, pwidechar(BCRYPT_CHAINING_MODE_), @BCRYPT_CHAIN_MODE_GCM_[1], sizeof(BCRYPT_CHAIN_MODE_GCM_), 0);
    178.   if Status <> 0 then
    179.     Exit;
    180.   Status := BCryptGenerateSymmetricKey(hProvider, hKey, nil, 0, @gKey[0], sizeof(gKey), 0);
    181.   if Status <> 0 then
    182.     Exit;
    183.   FillChar(Decrypted, Length(Decrypted), 0);
    184.   FillChar(Info, Sizeof(Info), 0);
    185.   Info.cbSize := Sizeof(Info);
    186.   Info.dwInfoVersion := 1;
    187.   Info.pbNonce := @IV[0];
    188.   Info.cbNonce := SizeOf(IV);
    189.   Info.pbTag := @Encryped[SizeOf(Encryped) - AES_BLOCK_SIZE];
    190.   Info.cbTag := AES_BLOCK_SIZE;
    191.   Status := BCryptDecrypt(hKey, @Encryped[0], SizeOf(Encryped) - AES_BLOCK_SIZE, @Info, nil, 0, @Decrypted[0], Length(Decrypted), Result, 0);
    192.   if Status <> 0 then
    193.   begin
    194.     Form2.Memo1.Lines.Add(IntToHex(Status));
    195.     Exit;
    196.   end;
    197.   if Output = nil then
    198.     Output := AllocMem(Result);
    199.   CopyMemory(Output, @Decrypted[0], Result);
    200. end;
    201.  
    202. procedure TForm2.Button1Click(Sender: TObject);
    203. var
    204.   DB: TSQLiteDatabase;
    205.   Table: TSQLiteTable;
    206.   DataIn, DataOut: DATA_BLOB;
    207.   DataStream: TMemorystream;
    208.   Key, Nonce, InBuf, OutBuf: TBytes;
    209.   password, s: string;
    210. begin
    211.   Key := GetEncryptedKey;
    212.   DB := TSQLiteDatabase.Create(GetEnvironmentVariable('LOCALAPPDATA') + '\Google\Chrome\User Data\Default\Login Data');
    213.   Table := DB.GetTable('SELECT * FROM logins');
    214.  
    215.   while not Table.EOF do
    216.   begin
    217.     password := Table.FieldAsString(Table.FieldIndex['password_value']);
    218.     InBuf := TEncoding.ANSI.GetBytes(password);
    219.  
    220.     if (LeftStr(password, 3) = 'v10') then
    221.     begin
    222.       SetLength(Nonce, 12);
    223.       CopyMemory(@Nonce[0], @InBuf[0 + 3], Length(Nonce));
    224.       SetLength(OutBuf, Length(InBuf) - 12 - 3);
    225.       CopyMemory(@OutBuf[0], @InBuf[0 + 3 + 12], Length(OutBuf));
    226.       SetLength(OutBuf, Length(OutBuf) - 16);
    227.  
    228.       if BDecrypt_GCM('AES', InBuf, @OutBuf[0], Key, Nonce) <> 0 then
    229.         password := TEncoding.ANSI.GetString(OutBuf);
    230.     end
    231.     else
    232.     begin
    233.       DataStream := TMemoryStream.Create;
    234.       try
    235.         DataStream := Table.FieldAsBlob(Table.FieldIndex['password_value']);
    236.         DataIn.pbData := DataStream.Memory;
    237.         DataIn.cbData := DataStream.Size;
    238.         CryptUnProtectData(@DataIn, nil, nil, nil, nil, 0, @DataOut);
    239.         SetString(password, PAnsiChar(DataOut.pbData), DataOut.cbData);
    240.       finally
    241.         DataStream.Free;
    242.       end;
    243.     end;
    244.  
    245.     Memo1.Lines.Add(Table.FieldAsString(Table.FieldIndex['origin_url']) + #13#10 + Table.FieldAsString(Table.FieldIndex['username_value']) + ' - ' + password + #13#10 + #13#10);
    246.  
    247.     Table.Next;
    248.   end;
    249. end;
    250.  
    251. end.

    referentie voor lijnen van 222 tot 226.
    Last edited by @someone; 03-Aug-22 at 22:11.

  12. #27
    mov rax,marcov; push rax marcov's Avatar
    Join Date
    Apr 2004
    Location
    Ehv, Nl
    Posts
    10,341
    1601 is de originele start datum van julian. Dus misschien kan je het integer deel middels de julian functions doen?

  13. #28
    Quote Originally Posted by marcov View Post
    1601 is de originele start datum van julian. Dus misschien kan je het integer deel middels de julian functions doen?
    Mijn doel is om Chrome-wachtwoorden te herstellen, geen cookies.

  14. #29
    Quote Originally Posted by @someone View Post
    Ik heb deze code op Delphi 10 geprobeerd, maar de functie BCryptDecrypt retourneert altijd fout STATUS_AUTH_TAG_MISMATCH:
    https://docs.microsoft.com/en-us/win...-bcryptdecrypt
    "
    STATUS_AUTH_TAG_MISMATCH

    The computed authentication tag did not match the value supplied in the pPaddingInfo parameter. "

  15. #30
    @someone, Ik hoefde eigenlijk vrij weinig aan te passen in mijn oorspronkelijke project uit Lazarus om dit ook voor passwords werkend te maken.

    Ik heb het wel voor Brave gedaan maar aangezien de oorspronkelijke voor de cookies voor Chrome was en bij Brave ook werkte, neem ik aan dat de password versie, die op Brave werkt, ook gewoon op Chrome werkt.

    Ik heb de volgende regel aangepast.
    Delphi Code:
    1. //AFileName := 'C:\Users\Rik\AppData\Local\Google\Chrome\User Data\Default\Network\Cookies'; // <- cookies
    2. //AFileName := 'C:\Users\Rik\AppData\Local\Google\Chrome\User Data\Default\Login Data'; // <- chrome passwords
    3. AFileName := 'C:\Users\Rik\AppData\Local\BraveSoftware\Brave-Browser\User Data\Default\Login Data'; // <- Brave passwords
    4. SQLite3Connection1.Databasename := AFilename;
    5. SQLQuery1.SQL.Text := 'SELECT origin_url, username_value, password_value FROM logins';
    6. //...
    7.     Line := SQLQuery1.FieldByName('origin_url').AsString;
    8.     Line := Line + ' ' + SQLQuery1.FieldByName('username_value').AsString;
    9.     Encrypted_Value := SQLQuery1.FieldByName('password_value').AsBytes;

    Meer heb ik niet aan hoeven te passen.

    (Als je er niet uitkomt kan ik de Lazarus versie van decrypt_password.zip ook wel uploaden, de decrypt_cookie.zip hangt aan de eerdere post.)

    PS. Voor Brave passwords moest Brave wel afgesloten worden anders is de database locked. Ik neem aan dat dat bij Chrome ook zo is.

Page 2 of 3 FirstFirst 1 2 3 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •