프로젝트의 일환으로 Chrome에서 저장된 비밀번호의 암호를 해독하려고합니다. 조금 파기 만하면 Chrome은 CryptProtectData 기능을 사용하여 비밀번호를 암호화합니다.이 기능을 사용하면 로그인 사용자 자격증 명을 사용하여 데이터를 암호화 할 수 있습니다. 즉, 암호화 된 데이터는 같은 사용자가 동일한 컴퓨터에서 해독 할 수 있습니다 (적절한 사용자 매개 변수가있는 경우 다른 사용자에게도).C의 Chrome에서 "Saved Password"암호 해독
어쨌든 필자는 이전에 파이썬 스크립트를 작성하여 정확하게 작성했으며 완벽하게 올바르게 작동합니다.
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입니다?
는 ARGV'의 값은 무엇입니까 [I] '(또는 단지 텍스트를 암호화하기 때문에? 당신이 파이썬 바이트 단위의 내용물을 비교하여 제대로 보이지 않음)와 가치는 무엇인가 'cbDataInput'의? 내 첫 번째 추측은 'strlen'이 제대로 작동하지 않는다는 것입니다 (예 : argv [i]가 null로 끝나지 않았을 수도 있습니다). –
@TimSweet 어떻게 그렇게 할 것을 제안합니까? 디버거 (IDA Pro 또는 gdb) 사용하기. – x899
개인적으로 저는 Windows를 사용하고 있기 때문에 디버거를 사용합니다. Visual Studio Community는 무료이며 매우 인기가 있습니다. 그렇지 않으면 gdb가 작동합니다. 또는 printf를 사용하여'callback()'에서 주석 처리 된 행과 비슷한 바이트를 출력 할 수 있습니다. –