2017-01-23 1 views
0

프로젝트의 일환으로 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입니다?

+0

는 ARGV'의 값은 무엇입니까 [I] '(또는 단지 텍스트를 암호화하기 때문에? 당신이 파이썬 바이트 단위의 내용물을 비교하여 제대로 보이지 않음)와 가치는 무엇인가 'cbDataInput'의? 내 첫 번째 추측은 'strlen'이 제대로 작동하지 않는다는 것입니다 (예 : argv [i]가 null로 끝나지 않았을 수도 있습니다). –

+0

@TimSweet 어떻게 그렇게 할 것을 제안합니까? 디버거 (IDA Pro 또는 gdb) 사용하기. – x899

+1

개인적으로 저는 Windows를 사용하고 있기 때문에 디버거를 사용합니다. Visual Studio Community는 무료이며 매우 인기가 있습니다. 그렇지 않으면 gdb가 작동합니다. 또는 printf를 사용하여'callback()'에서 주석 처리 된 행과 비슷한 바이트를 출력 할 수 있습니다. –

답변

-1

이것은 2hex.txt에있는 당신의 crypted 데이터를 (그냥 DB 브라우저에서 저장했기 때문에) 저에게 잘 돌아갑니다. 귀하의 문제는 바이트 시퀀스에서 첫 번째 "0"을 충족하고 중지하기 때문에 strlen() 함수에 실제로있었습니다. 그냥 피하십시오.

#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()); 
} 
관련 문제