python - Dekrypter 'Gemt kodeord' fra Chrome i C

Indlæg af Hanne Mølgaard Plasc

Problem



Som en del af et projekt forsøger vi at dekryptere gemt adgangskode i Google Chrome. Efter lidt udgravning forstår vi, at Chrome krypterer adgangskoden ved hjælp af CryptProtectData-funktionen, som giver dig mulighed for at kryptere dataene ved hjælp af login-brugeroplysninger, dvs. de krypterede data kan kun dekrypteres på samme maskine af samme bruger (andre brugere også hvis der findes passende parametre).


Under alle omstændigheder har jeg tidligere skrevet et Python-script til at gøre netop det, og det virker helt fint.


from os import getenv, unlink
from shutil import copy
import sqlite3
import win32crypt

dbpath = "C:Users\"+ getenv('username') +"AppDataLocalGoogleChromeUser DataDefault\"
copy(dbpath + "Login Data", dbpath + "Login Data.db")
conn = sqlite3.connect(dbpath + "Login Data.db")
cursor = conn.cursor()
cursor.execute('SELECT action\_url, username\_value, password\_value FROM logins')
for result in cursor.fetchall():
    password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]
    print result[0] + " - " + result[1] + ":" + password
conn.close()
unlink(dbpath + "Login Data.db")


Men på grund af projektkrav skal jeg kode det på C sprog.
Så jeg skrev følgende kode:


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>
#include "sqlite3.h"

static int callback(void *data, int argc, char **argv, char **azColName){
   int i;
   fprintf(stderr, "\%s: 
", (const char*)data);
   for(i=0; i<argc; i++){
      if (i == 2 ){
        DATA\_BLOB DataIn;
        DATA\_BLOB DataOut;
        BYTE *pbDataInput = (BYTE *) argv[i];
        DWORD cbDataInput = strlen((char *) pbDataInput) + 1;
        DataIn.pbData = pbDataInput;
        DataIn.cbData = cbDataInput;
        if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut))
          printf("\%s
", DataOut.pbData);
        else
          printf("Error number \%x.
", GetLastError());
      }
      // printf("\%s = \%s
", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("
");
   return 0;
}

int main(int argc, char* argv[])
{
   sqlite3 *db;
   char *zErrMsg = 0;
   int rc;
   char *sql;
   const char* data = "Callback function called";

   /* Open database */
   rc = sqlite3\_open("Login Data.db", &db);
   if( rc ){
      fprintf(stderr, "Can't open database: \%s
", sqlite3\_errmsg(db));
      return(0);
   }else{
      fprintf(stderr, "Opened database successfully
");
   }

   /* Create SQL statement */
   sql = "SELECT action\_url, username\_value, password\_value from logins";

   /* Execute SQL statement, */
   rc = sqlite3\_exec(db, sql, callback, (void*)data, &zErrMsg);
   if( rc != SQLITE\_OK ){
      fprintf(stderr, "SQL error: \%s
", zErrMsg);
      sqlite3\_free(zErrMsg);
   }else{
      fprintf(stdout, "Operation done successfully
");
   }
   sqlite3\_close(db);
   return 0;
}


Den kompilerede korrekt uden nogen fejl, men de dekrypterede data var ikke korrekte.


C:>gcc -o decryptor decryptor.c sqlite3.o -lcrypt32

C:>decryptor.exe
Opened database successfully
Callback function called: Important Data
Error Number 57.

Operation done successfully

C:>


Ifølge systemfejlkoder (0-499)
0x57 er for ERROR\_INVALID\_PARAMETER (parameteren er forkert) [5]


Hvad mangler jeg?

Bedste reference


Dette virker helt fint for mig, da du har dine krypterede data i 2hex.txt (lige gemt det fra DB Browser). Dit problem var virkelig i strlen () -funktionen, fordi det mødes først '0' i bytesekvensen og stopper. Bare undgå det.


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Wincrypt.h>


int main(){
    FILE *fp;
    DATA\_BLOB DataIn;
    DATA\_BLOB DataOut;
    char result[1000]="";
    unsigned char buf[1000]="";
    int tmpbuf;
    int i=0;
    fp=fopen("3hex.txt","rb");
    printf ("Crypted data:
");
    for(i=0;(tmpbuf=getc(fp))!=EOF;i++)
    {
        buf[i]=tmpbuf;
        if (i\%16==0) printf("
");
        printf("\%02X ",buf[i]);
    }
    DataIn.pbData=buf;
    DataIn.cbData=i+1;
    if (CryptUnprotectData (&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut)) 
    {
        for (i=0;i<DataOut.cbData;i++)
        {
            result[i]=DataOut.pbData[i];
        }
        result[i+1]='';
        printf("
Result as string: \%s
", result);

    }

    else printf("Error number \%x.
", GetLastError());
}