0
作爲項目的一部分,我們試圖在Google Chrome中解密保存的密碼。我們瞭解Chrome使用CryptProtectData函數加密密碼後,可以使用登錄用戶憑證加密數據,即加密數據只能由同一用戶在同一臺機器上解密(其他用戶也在提供相應參數時)。解密來自Chrome的C中的「已保存的密碼」C
總之,我以前寫過一個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;
}
它正確編譯沒有任何錯誤,但解密的數據是不正確的。
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:\>
據System Error Codes (0-499), 的0x57是ERROR_INVALID_PARAMETER(參數不正確)
我缺少什麼?
什麼的argv'值[I]'(或因爲它只會被加密的文本:它看起來正確的比較你在Python逐字節得到了什麼?)和價值是什麼'cbDataInput'?我的第一個猜測是'strlen'不能正確工作(例如,'argv [i]'不是空終止的?) –
@TimSweet如何建議這樣做?就像使用調試器(IDA Pro或gdb)一樣。 – x899
就我個人而言,我會使用調試器(因爲您使用的是Windows:Visual Studio社區是免費且非常流行的,否則gdb的作品)。或者只是使用printf來打印出類似於'callback()'中的註釋行的字節。 –