2017-01-23 19 views
0

プロジェクトの一環として、Google Chromeで保存されたパスワードを復号しようとしています。少し掘り下げた後、ChromeはCryptProtectData関数を使用してパスワードを暗号化することがわかります。これにより、ログインユーザーの認証情報を使用してデータを暗号化できます。つまり、暗号化されたデータは同じユーザー(同じパラメータであれば他のユーザー)CのChromeから「保存されたパスワード」を復号する

これまで通り、私はこれまでにPythonスクリプトを書いていますが、それはまったく問題なく動作します。

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

dbpath = "C:\Users\\"+ getenv('username') +"\AppData\Local\Google\Chrome\User Data\Default\\" 
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") 

しかし、プロジェクトの要件のために、私はそれをC言語でコーディングする必要があります。 だから私は、次のコードを書いた:それはエラーなしで正常にコンパイルされ、復号化されたデータが正しくありませんでした

#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: \n", (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\n", DataOut.pbData); 
     else 
      printf("Error number %x.\n", GetLastError()); 
     } 
     // printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 
    } 
    printf("\n"); 
    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\n", sqlite3_errmsg(db)); 
     return(0); 
    }else{ 
     fprintf(stderr, "Opened database successfully\n"); 
    } 

    /* 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\n", zErrMsg); 
     sqlite3_free(zErrMsg); 
    }else{ 
     fprintf(stdout, "Operation done successfully\n"); 
    } 
    sqlite3_close(db); 
    return 0; 
} 

を。 System Error Codes (0-499)によると

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:\> 

、 0x57はERROR_INVALID_PARAMETERです(パラメータが間違っています)

私は何をしないのですか?

+0

(またはそれだけでテキストを暗号化されますので、?:それは右に見えるんあなたはPythonのバイトごとに得るものと比較) '[i]はargvの'の値は何であり、どのような価値があります'cbDataInput'の?私の最初の推測は、 'strlen'が正しく動作していないことです(例えば' argv [i] 'がヌルで終了していないなど) –

+0

@TimSweetこれを行う方法を教えてください。デバッガ(IDA Proまたはgdb)を使うのと同じです。 – x899

+1

個人的に私はデバッガを使用します(Windowsを使用しているので、Visual Studio Communityは無料で非常に普及しています。そうでなければgdbが動作します)。あるいは、printfを使って 'callback()'のコメントアウトされた行に似たバイトを出力してください。 –

答えて

-1

これは2hex.txtであなたのcryptedデータを持っているので(ちょうどDBブラウザからそれを保存しました)私にとってうまくいきます。あなたの問題は、実際にはstrlen()関数内にありました。なぜなら、バイト列の最初の "0"を満たして停止するからです。ただそれを避けてください。

#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:\n"); 
    for(i=0;(tmpbuf=getc(fp))!=EOF;i++) 
    { 
     buf[i]=tmpbuf; 
     if (i%16==0) printf("\n"); 
     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]='\0'; 
     printf("\nResult as string: %s\n", result); 

    } 

    else printf("Error number %x.\n", GetLastError()); 
} 
関連する問題