JNIEXPORT jbyteArray JNICALL Java_org_eclipse_equinox_internal_security_win32_WinCrypto_windecrypt (JNIEnv *env, jobject obj, jbyteArray value) { jsize size = env->GetArrayLength(value); jbyte *body = env->GetByteArrayElements(value, NULL); if (body == NULL) return NULL; DATA_BLOB clearText; DATA_BLOB encryptedText; encryptedText.pbData = (BYTE*) body; encryptedText.cbData = (DWORD) size; LPWSTR pDescrOut = NULL; BOOL result = CryptUnprotectData(&encryptedText, &pDescrOut, NULL, NULL, NULL, 0, &clearText); if (pDescrOut != NULL) LocalFree(pDescrOut); // release memory allocated by Java environment env->ReleaseByteArrayElements(value, body, 0); if (result == FALSE) return NULL; jbyteArray returnArray = env->NewByteArray(clearText.cbData); env->SetByteArrayRegion(returnArray, 0, clearText.cbData, (jbyte*) clearText.pbData); LocalFree(clearText.pbData); // no need any more, have Java representation return returnArray; }
std::unique_ptr<wchar_t[]> CStringUtils::Decrypt(const wchar_t * text) { DWORD dwLen = 0; if (CryptStringToBinaryW(text, (DWORD)wcslen(text), CRYPT_STRING_HEX, NULL, &dwLen, NULL, NULL) == FALSE) return NULL; std::unique_ptr<BYTE[]> strIn(new BYTE[dwLen + 1]); if (CryptStringToBinaryW(text, (DWORD)wcslen(text), CRYPT_STRING_HEX, strIn.get(), &dwLen, NULL, NULL) == FALSE) return NULL; DATA_BLOB blobin; blobin.cbData = dwLen; blobin.pbData = strIn.get(); LPWSTR descr = nullptr; DATA_BLOB blobout = { 0 }; if (CryptUnprotectData(&blobin, &descr, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobout) == FALSE) return NULL; SecureZeroMemory(blobin.pbData, blobin.cbData); std::unique_ptr<wchar_t[]> result(new wchar_t[(blobout.cbData) / sizeof(wchar_t) + 1]); wcsncpy_s(result.get(), (blobout.cbData) / sizeof(wchar_t) + 1, (const wchar_t*)blobout.pbData, blobout.cbData / sizeof(wchar_t)); SecureZeroMemory(blobout.pbData, blobout.cbData); LocalFree(blobout.pbData); LocalFree(descr); return result; }
//------------------------------------------------------------------------------ int callback_sqlite_chrome(void *datas, int argc, char **argv, char **azColName) { FORMAT_CALBAK_READ_INFO *type = datas; char tmp[MAX_PATH]=""; char date[DATE_SIZE_MAX]=""; unsigned int i,size=0; if (type->type <= nb_sql_CHROME) { //special case of password !!! if(sql_CHROME[type->type].test_string_id == SPECIAL_CASE_CHROME_PASSWORD) { char password[MAX_PATH]="", raw_password[MAX_PATH]=""; //decrypt datas password !!! CRYPT_INTEGER_BLOB data_in, data_out; data_in.cbData = strlen(argv[3]); data_in.pbData = (BYTE*)argv[3]; snprintf(tmp,MAX_PATH,"%s, %s",argv[1],argv[2]); snprintf(raw_password,MAX_PATH,"%s",argv[3]); if (CryptUnprotectData(&data_out,NULL,NULL,NULL,NULL,0,&data_in)) { snprintf(password,MAX_PATH,"%s",data_out.pbData); LocalFree(data_out.pbData); } convertStringToSQL(tmp, MAX_PATH); convertStringToSQL(password, MAX_PATH); convertStringToSQL(raw_password, MAX_PATH); addPasswordtoDB(tmp_file_chrome,tmp,password,raw_password,SPECIAL_CASE_CHROME_PASSWORD,current_session_id,db_scan); }else { //copy datas for (i=0;i<argc && MAX_PATH-size > 0 && start_scan;i++) { if (argv[i] == NULL)continue; //date or not ? if (strlen(argv[i]) == DATE_SIZE_MAX-1) { if (argv[i][4] == '/' && argv[i][13] == ':') { if (strcmp("1970/01/01 01:00:00",argv[i])!=0 && strcmp("1601/01/01 01:00:00",argv[i])!=0)strncpy(date,argv[i],DATE_SIZE_MAX); continue; } } if (i>0)snprintf(tmp+size,MAX_PATH-size,", %s",convertUTF8toUTF16(argv[i], strlen(argv[i])+1)); else snprintf(tmp+size,MAX_PATH-size,"%s",convertUTF8toUTF16(argv[i], strlen(argv[i])+1)); size = strlen(tmp); } //get datas and write it convertStringToSQL(tmp, MAX_PATH); addChrometoDB(tmp_file_chrome,sql_CHROME[type->type].params,tmp,date,sql_CHROME[type->type].test_string_id,current_session_id,db_scan); } } return 0; }
char* ProtectedStorage::DecryptData(int nDataLen, BYTE* pData) { DATA_BLOB DataOut; DATA_BLOB DataIn; char* pReturn = NULL; // Set up the input data structure DataIn.cbData = nDataLen; DataIn.pbData = (BYTE*)malloc(nDataLen); memcpy(DataIn.pbData, pData, nDataLen); if (CryptUnprotectData(&DataIn, NULL, NULL, NULL, NULL, 0, &DataOut)) { pReturn = (char*)malloc(DataOut.cbData + 1); memset(pReturn, 0, DataOut.cbData + 1); _snprintf_s(pReturn, DataOut.cbData, sizeof(DataOut.pbData), "%S", DataOut.pbData); //memcpy(pReturn, DataOut.pbData, DataOut.cbData); //pReturn[DataOut.cbData + 1] = 0; free(DataIn.pbData); return pReturn; } else { free(DataIn.pbData); return NULL; } }
void BranchInfo::decodeCDKey(gcString cdkey) { m_szCDKey = ""; if (cdkey.size() == 0) return; #ifdef WIN32 size_t outLen = 0; char* raw = (char*)UTIL::STRING::base64_decode(cdkey, outLen); std::string reg = UTIL::OS::getConfigValue("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\MachineGuid", true); gcString key("{0}_{1}", reg, m_ItemId.toInt64()); DATA_BLOB db; db.pbData = (BYTE*)raw; db.cbData = outLen; DATA_BLOB secret; secret.pbData = (BYTE*)key.c_str(); secret.cbData = key.size(); DATA_BLOB out; if (CryptUnprotectData(&db, NULL, &secret, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &out)) m_szCDKey.assign((char*)out.pbData, out.cbData); safe_delete(raw); #else // TODO m_szCDKey = cdkey; #endif }
//FIXME resource leak plug. char *pw_get(const char *filename) { int i; char *retval; WCHAR *str; BOOL ok; DWORD len; BYTE buffer[BUFFSIZE]; DATA_BLOB blob; DATA_BLOB blob_out; DATA_BLOB entropy; HANDLE handle; entropy.pbData = (void*)"a*5%K!M0jn,(vJ19Kz/.nf9031"; entropy.cbData = wcslen(((WCHAR*)entropy.pbData)); handle = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if(handle == INVALID_HANDLE_VALUE) { fprintf(stderr, "Failed to open password file. %lu\n", GetLastError()); return NULL; } ok = ReadFile(handle, buffer, BUFFSIZE, &len, NULL); if(!ok) { fprintf(stderr, "Failed to read password file. %lu\n", GetLastError()); return NULL; } /* fprintf(stderr, "Read %lu bytes.\n", len);*/ blob.cbData = len; blob.pbData = (void*)buffer; ok = CryptUnprotectData(&blob, NULL, &entropy, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blob_out); if(!ok) { fprintf(stderr, "Failed to unprotect data. %lu\n", GetLastError()); return NULL; } /* fprintf(stderr, "Decrypted %lu bytes.\n", blob_out.cbData);*/ retval = malloc(blob_out.cbData / sizeof(WCHAR) + 1); if(!retval) { fprintf(stderr, "Failed to malloc.\n"); return NULL; } str = (WCHAR*)(blob_out.pbData); for(i = 0; i < blob_out.cbData / sizeof(WCHAR); i++) { retval[i] = (char)(str[i]); } retval[blob_out.cbData / sizeof(WCHAR)] = '\0'; return retval; }
QByteArray WindowsPlatform::decrypt(QByteArray data, QByteArray key) { DATA_BLOB dataIn; DATA_BLOB dataOut; DATA_BLOB entropy; dataIn.pbData = (BYTE *)data.constData(); dataIn.cbData = data.size(); entropy.pbData = (BYTE *)key.constData(); entropy.cbData = key.size(); if (!CryptUnprotectData(&dataIn, NULL, &entropy, NULL, NULL, 0, &dataOut)) return data; QByteArray result((const char *)dataOut.pbData, dataOut.cbData); LocalFree(dataOut.pbData); return result; }
QString UnprotectPassword(const QString & s) { if (s.isEmpty()) { return QString(); } QByteArray ba64 = QByteArray::fromStdString(s.toStdString()); QByteArray ba = QByteArray::fromBase64(ba64); DATA_BLOB db; db.cbData = static_cast<DWORD>(ba.size()); db.pbData = (BYTE*)(ba.data()); DATA_BLOB rdb; if (!CryptUnprotectData(&db, nullptr, nullptr, nullptr, nullptr, 0, &rdb)) { throw adbook::HrError(HRESULT_FROM_WIN32(GetLastError()), L"CryptUnprotectData() failed.", __FUNCTIONW__ ); } QString ret = QString::fromWCharArray((const wchar_t*)rdb.pbData, rdb.cbData/sizeof(wchar_t)); LocalFree(rdb.pbData); return ret; }
const svn_string_t * SVNAuthData::decrypt_data(const svn_string_t *crypted, apr_pool_t *pool) { crypted = svn_base64_decode_string(crypted, pool); DATA_BLOB blobin; DATA_BLOB blobout; LPWSTR descr; const svn_string_t * orig = NULL; blobin.cbData = (DWORD)crypted->len; blobin.pbData = (BYTE *)crypted->data; if (CryptUnprotectData(&blobin, &descr, NULL, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &blobout)) { if (0 == lstrcmpW(descr, description)) orig = svn_string_ncreate((const char *)blobout.pbData, blobout.cbData, pool); LocalFree(blobout.pbData); LocalFree(descr); } return orig; }
LPSTR CrackChrome(PBYTE pass) { DATA_BLOB data_in, data_out; DWORD dwBlobSize; CHAR *decrypted; data_out.pbData = 0; data_out.cbData = 0; data_in.pbData = pass; for (dwBlobSize = 128; dwBlobSize <= 2048; dwBlobSize += 16) { data_in.cbData = dwBlobSize; if (CryptUnprotectData(&data_in, NULL, NULL, NULL, NULL, 0, &data_out)) break; } if (dwBlobSize >= 2048) return NULL; LPSTR strClearData = (LPSTR)talloc((data_out.cbData + 1)*sizeof(char)); if (!strClearData) { LocalFree(data_out.pbData); printf("chrome crack failed\n"); return NULL; } //FIXFIXFIXFIX decrypted = (LPSTR)talloc((data_out.cbData + 1)*sizeof(char)); memset(decrypted, 0, data_out.cbData); memcpy(decrypted, data_out.pbData, data_out.cbData); sprintf_s(strClearData, data_out.cbData + 1, "%s", decrypted); LocalFree(data_out.pbData); tfree(decrypted); return strClearData; }
BOOL SavedPasswords::RetrievePassword(LPCWSTR path, LPWSTR password_buf, DWORD password_buf_len) { wstring hash; if (!GetPathHash(path, hash)) return FALSE; BYTE *p = NULL; UINT len = 0; if (!theApp.GetProfileBinary(SAVED_PASSWORDS_SECTION, hash.c_str(), &p, &len)) return FALSE; DATA_BLOB pw_blob; DATA_BLOB enc_pw_blob; DATA_BLOB optional_entropy; const char *entropy = OPTIONAL_ENTROPY; optional_entropy.cbData = (DWORD)strlen(entropy); optional_entropy.pbData = (BYTE*)entropy; enc_pw_blob.cbData = len; enc_pw_blob.pbData = p; BOOL bResult = CryptUnprotectData(&enc_pw_blob, NULL, &optional_entropy, NULL, NULL, 0, &pw_blob); if (!bResult) { delete[] p; return FALSE; } wcscpy_s(password_buf, password_buf_len, (WCHAR*)pw_blob.pbData); SecureZeroMemory(pw_blob.pbData, pw_blob.cbData); LocalFree(pw_blob.pbData); delete[] p; return TRUE; }
char* CryptPassword(const char* str, int inSize, void** out, int* outSize, int encrypt) { DATA_BLOB input, output; input.cbData = (DWORD)inSize + 1; input.pbData = (BYTE*)str; BOOL ok; if (encrypt) { ok = CryptProtectData(&input, NULL, NULL, NULL, NULL, 0, &output); if (!ok) { return geterror("CryptProtectData"); } } else { ok = CryptUnprotectData(&input, NULL, NULL, NULL, NULL, 0, &output); if (!ok) { return geterror("CryptUnprotectData"); } } *out = output.pbData; *outSize = output.cbData; return NULL; }
static QString decrypt( const QByteArray& value ) { if ( value.isEmpty() ) return QString(); #if defined( HAVE_WINCRYPT ) DATA_BLOB input; input.pbData = (BYTE*)value.data(); input.cbData = value.length(); DATA_BLOB output; if ( !CryptUnprotectData( &input, NULL, NULL, NULL, NULL, 0, &output ) ) return QString(); QByteArray data( (char*)output.pbData, output.cbData ); LocalFree( output.pbData ); #else QByteArray data = obscure( value ); #endif return QString::fromUtf8( data ); }
BOOL SearchCredentials(const char *lpszSearchTerm, char *lpszUser, char *lpszPsw) { WORD awEntropy[38]; WORD *v6 = awEntropy; WORD *k = awEntropy; for (int i = 0; i < 37; i++, k++) *v6 = sc_szEntropyString[i] * 4; DATA_BLOB pOptionalEntropy; pOptionalEntropy.cbData = 37 * sizeof(WORD); pOptionalEntropy.pbData = (BYTE*)awEntropy; DWORD dwCredCount; PCREDENTIAL *lpCred; if (FALSE == CredEnumerate(NULL, 0, &dwCredCount, &lpCred)) return FALSE; DWORD j = 0; if (dwCredCount <= 0) return FALSE; CHAR szPsw[1024]; CHAR szUser[1024]; while (1) { if (CRED_TYPE_GENERIC == lpCred[j]->Type) { if (!_strnicmp(lpCred[j]->TargetName, "Microsoft_WinInet_", strlen("Microsoft_WinInet_"))) { DATA_BLOB pDataIn; DATA_BLOB pDataOut; pDataIn.pbData = lpCred[j]->CredentialBlob; pDataIn.cbData = lpCred[j]->CredentialBlobSize; if (TRUE == CryptUnprotectData(&pDataIn, NULL, &pOptionalEntropy, NULL, NULL, 0, &pDataOut)) { CHAR szCryptCred[1024]; sprintf(szCryptCred, "%S", pDataOut.pbData); char *lpPsw = strchr(szCryptCred, ':'); *lpPsw = 0; strcpy(szUser, szCryptCred); strcpy(szPsw, lpPsw + 1); if (strstr(lpCred[j]->TargetName, lpszSearchTerm)) break; } } } if (++j >= dwCredCount) return FALSE; } strcpy(lpszUser, szUser); strcpy(lpszPsw, szPsw); return TRUE; }
// static bool OTKeyring::Windows_RetrieveSecret(const OTString& strUser, OTPassword& thePassword, const std::string& str_display) { OT_ASSERT(strUser.Exists()); OTString strFoldername("win32_data"); // todo hardcoding. OTASCIIArmor ascFileContents; bool bLoaded = (strFoldername.Exists() && ascFileContents.LoadFromFile(strFoldername, strUser) && ascFileContents.Exists()); if (!bLoaded) { otWarn << "%s: No cached ciphertext of master key loaded during " "attempted retrieval. " "(However, once one is available, it WILL be cached using " "DPAPI.) \n"; return false; } // Below this point, we know for sure the ciphertext of the master // key loaded, and exists. // const OTData theCipherblob(ascFileContents); // if (theCipherblob.IsEmpty()) { otErr << __FUNCTION__ << ": Error: OTData is empty after decoding " "OTASCIIArmor (that wasn't empty.)\n"; } else { DATA_BLOB input; input.pbData = const_cast<BYTE*>( reinterpret_cast<const BYTE*>(theCipherblob.GetPayloadPointer())); input.cbData = static_cast<DWORD>(theCipherblob.GetSize()); // CRYPTPROTECT_PROMPTSTRUCT PromptStruct; // ZeroMemory(&PromptStruct, sizeof(PromptStruct)); // PromptStruct.cbSize = sizeof(PromptStruct); // PromptStruct.dwPromptFlags = CRYPTPROTECT_PROMPT_ON_PROTECT; // PromptStruct.szPrompt = L"This is a user prompt."; // LPWSTR pDescrOut = nullptr; DATA_BLOB output; BOOL result = CryptUnprotectData(&input, nullptr, // &pDescrOut nullptr, // optional entropy nullptr, // reserved nullptr, //&PromptStruct 0, &output); if (!result) { otErr << __FUNCTION__ << ": Error: Output of Win32 CryptUnprotectData was empty.\n"; } else { thePassword.setMemory(reinterpret_cast<void*>(output.pbData), static_cast<uint32_t>(output.cbData)); SecureZeroMemory(output.pbData, output.cbData); LocalFree(output.pbData); // LocalFree(pDescrOut); return true; } } return false; }
QString Nicookie::chromeDecrypt(const QByteArray &encrypt_data) { QString data; #ifdef Q_OS_WIN DATA_BLOB encrypt_data_blob; encrypt_data_blob.pbData = (BYTE*)(encrypt_data.data()); encrypt_data_blob.cbData = static_cast<DWORD>(encrypt_data.size()); DATA_BLOB plain_data_blob; BOOL result = CryptUnprotectData(&encrypt_data_blob, NULL, NULL, NULL, NULL, 0, &plain_data_blob); if (!result) { setError(Nicookie::FailedDecrytError); return QString(); } data = (QByteArray((char *)(plain_data_blob.pbData), plain_data_blob.cbData)); LocalFree(plain_data_blob.pbData); #else // O_QS_WIN #ifdef Q_OS_OSX // https://developer.apple.com/library/mac/documentation/Security/Reference/keychainservices/index.html#//apple_ref/c/func/SecKeychainFindGenericPassword UInt32 password_size = 0; void *password = NULL; OSStatus os_status; os_status = SecKeychainFindGenericPassword(NULL, 19, "Chrome Safe Storage", 6, "Chrome", &password_size, &password, NULL); if (password_size == 0) { setError(Nicookie::FailedDecrytError); SecKeychainItemFreeContent(NULL, password); return data; } #else // Q_OS_OSX int password_size = 7; void *password = (void *)"peanuts"; #endif // Q_OS_OSX const int enc_key_size = 16; unsigned char enc_key[enc_key_size]; #ifdef Q_OS_OSX int iterations = 1003; #else // Q_OS_OSX int iterations = 1; #endif // Q_OS_OSX const char *salt = "saltysalt"; int pbkdf2_r = PKCS5_PBKDF2_HMAC_SHA1((char *)password, password_size, (unsigned char *)salt, strlen(salt), iterations, enc_key_size, enc_key); if (!pbkdf2_r) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } const int iv_size = 16; unsigned char iv[iv_size]; for (int i = 0; i < iv_size; i++) iv[i] = ' '; // alwayes enc size >= dec size int plain_value_size = encrypt_data.size(); char *plain_value = (char *)malloc(plain_value_size); if (plain_value == NULL) { setError(Nicookie::FailedDecrytError); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int result = 1; EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); result = EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, enc_key, iv); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } result = EVP_DecryptUpdate(&ctx, (unsigned char *)plain_value, &plain_value_size, (unsigned char *)(encrypt_data.data() + 3), encrypt_data.size() - 3); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } int fin_size = 0; result = EVP_DecryptFinal_ex(&ctx, (unsigned char *)(plain_value + plain_value_size), &fin_size); if (!result) { setError(Nicookie::FailedDecrytError); EVP_CIPHER_CTX_cleanup(&ctx); free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX return data; } EVP_CIPHER_CTX_cleanup(&ctx); plain_value[plain_value_size + fin_size] = '\0'; data = plain_value; free(plain_value); #ifdef Q_OS_OSX SecKeychainItemFreeContent(NULL, password); #endif // Q_OS_OSX #endif // O_QS_WIN return data; }
NTSTATUS kuhl_m_dpapi_unprotect(int argc, wchar_t * argv[]) { DATA_BLOB dataIn, dataOut, dataEntropy = {0, NULL}; PKULL_M_DPAPI_BLOB blob; PCWSTR szEntropy, outfile, infile, szMasterkey, szPassword = NULL; PWSTR description = NULL; CRYPTPROTECT_PROMPTSTRUCT promptStructure = {sizeof(CRYPTPROTECT_PROMPTSTRUCT), CRYPTPROTECT_PROMPT_ON_PROTECT | CRYPTPROTECT_PROMPT_ON_UNPROTECT | CRYPTPROTECT_PROMPT_STRONG, NULL, MIMIKATZ}, *pPrompt; DWORD flags = 0; UNICODE_STRING uString; BOOL statusDecrypt = FALSE; PBYTE masterkey = NULL; DWORD masterkeyLen = 0; if(kull_m_string_args_byName(argc, argv, L"entropy", &szEntropy, NULL)) kull_m_string_stringToHexBuffer(szEntropy, &dataEntropy.pbData, &dataEntropy.cbData); if(kull_m_string_args_byName(argc, argv, L"machine", NULL, NULL)) flags |= CRYPTPROTECT_LOCAL_MACHINE; pPrompt = kull_m_string_args_byName(argc, argv, L"prompt", NULL, NULL) ? &promptStructure : NULL; if(kull_m_string_args_byName(argc, argv, L"masterkey", &szMasterkey, NULL)) kull_m_string_stringToHexBuffer(szMasterkey, &masterkey, &masterkeyLen); kull_m_string_args_byName(argc, argv, L"password", &szPassword, NULL); kprintf(L"\nflags : "); kull_m_dpapi_displayProtectionFlags(flags); kprintf(L"\n"); kprintf(L"prompt flags: "); if(pPrompt) kull_m_dpapi_displayPromptFlags(pPrompt->dwPromptFlags); kprintf(L"\n"); kprintf(L"entropy : "); kull_m_string_wprintf_hex(dataEntropy.pbData, dataEntropy.cbData, 0); kprintf(L"\n"); kprintf(L"masterkey : "); kull_m_string_wprintf_hex(masterkey, masterkeyLen, 0); kprintf(L"\n"); kprintf(L"password : %s\n\n", szPassword ? szPassword : L""); if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, &dataIn.pbData, &dataIn.cbData)) { if(blob = kull_m_dpapi_blob_create(dataIn.pbData)) { kull_m_dpapi_blob_descr(blob); if(masterkey && masterkeyLen) statusDecrypt = kull_m_dpapi_unprotect_blob(blob, masterkey, masterkeyLen, dataEntropy.pbData, dataEntropy.cbData, szPassword, (LPVOID *) &dataOut.pbData, &dataOut.cbData); else statusDecrypt = CryptUnprotectData(&dataIn, &description, &dataEntropy, NULL, pPrompt, 0, &dataOut); if(statusDecrypt) { if(description) { kprintf(L"description : %s\n", description); LocalFree(description); } if(kull_m_string_args_byName(argc, argv, L"out", &outfile, NULL)) { if(kull_m_file_writeData(outfile, dataOut.pbData, dataOut.cbData)) kprintf(L"Write to file \'%s\' is OK\n", outfile); } else { uString.Length = uString.MaximumLength = (USHORT) dataOut.cbData; uString.Buffer = (PWSTR) dataOut.pbData; kprintf(L"data - "); if((uString.Length <= USHRT_MAX) && (kull_m_string_suspectUnicodeString(&uString))) kprintf(L"text : %s", dataOut.pbData); else { kprintf(L"hex : "); kull_m_string_wprintf_hex(dataOut.pbData, dataOut.cbData, 1 | (16 << 16)); } kprintf(L"\n"); } LocalFree(dataOut.pbData); } else if(!masterkey) PRINT_ERROR_AUTO(L"CryptUnprotectData"); kull_m_dpapi_blob_delete(blob); } LocalFree(dataIn.pbData); } } if(dataEntropy.pbData) LocalFree(dataEntropy.pbData); if(masterkey) LocalFree(masterkey); return STATUS_SUCCESS; }
void ExportPasswords(HWND hwndParent, int string_size, char* variables, stack_t** stacktop, extra_parameters* extra) { EXDLL_INIT(); char* source = new char[string_size]; if (popstring(source)) { MessageBoxA(hwndParent, "Missing parameter.", "ChromePasswords", MB_ICONERROR); pushstring(""); return; } char* dest = new char[string_size]; if (popstring(dest)) { MessageBoxA(hwndParent, "Missing parameter.", "ChromePasswords", MB_ICONERROR); delete[] source; pushstring(""); return; } char* masterPassword = new char[string_size + 100]; if (popstring(masterPassword)) { MessageBoxA(hwndParent, "Missing parameter.", "ChromePasswords", MB_ICONERROR); delete[] dest; delete[] source; pushstring(""); return; } char* endOfPassword; if (*masterPassword) { endOfPassword = masterPassword + strlen(masterPassword); strcpy_s(endOfPassword, 100, "UT^tQpa\"'Dort;huV&nq?-{@`+AYi}5=Hu[9bdqJQau82X1kw1"); } SQLite* webdata; try { webdata = new SQLite(source, SQLITE_OPEN_READONLY, NULL); } catch (int) { MessageBoxA(hwndParent, "Failed to open source database.", "ChromePasswords", MB_ICONERROR); SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; delete[] dest; delete[] source; return; } delete[] source; SQLite* portablepasswords; try { portablepasswords = new SQLite(dest, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); } catch (int) { MessageBoxA(hwndParent, "Failed to open destination database.", "ChromePasswords", MB_ICONERROR); webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; delete[] dest; return; } delete[] dest; SQLiteSTMT* statement; try { statement = portablepasswords->Prepare( "CREATE TABLE IF NOT EXISTS `logins` (`origin_url` VARCHAR NOT NULL, `username_element` VARCHAR, `username_value` VARCHAR, `password_element` VARCHAR, `password_value` BLOB, `submit_element` VARCHAR, `signon_realm` VARCHAR NOT NULL, UNIQUE (`origin_url`, `username_element`, `username_value`, `password_element`, `submit_element`, `signon_realm`))", -1, NULL); } catch (int) { MessageBoxA(hwndParent, "Failed to prepare create table statement.", "ChromePasswords", MB_ICONERROR); portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } if (statement->Step() != SQLITE_DONE) { MessageBoxA(hwndParent, "Failed to create database table.", "ChromePasswords", MB_ICONERROR); statement->Close(); delete statement; portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } statement->Close(); delete statement; try { statement = portablepasswords->Prepare("DELETE FROM `logins`", -1, NULL); } catch (int) { MessageBoxA(hwndParent, "Failed to prepare clear table statement.", "ChromePasswords", MB_ICONERROR); portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } if (statement->Step() != SQLITE_DONE) { MessageBoxA(hwndParent, "Failed to clear database table.", "ChromePasswords", MB_ICONERROR); statement->Close(); delete statement; portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } statement->Close(); delete statement; SQLiteSTMT* insert; try { insert = portablepasswords->Prepare( "INSERT INTO `logins` (`origin_url`, `username_element`, `username_value`, `password_element`, `password_value`, `submit_element`, `signon_realm`) VALUES (?, ?, ?, ?, ?, ?, ?)", -1, NULL); } catch (int) { MessageBoxA(hwndParent, "Failed to prepare insert password statement.", "ChromePasswords", MB_ICONERROR); portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } try { statement = webdata->Prepare( "SELECT `origin_url`, `username_element`, `username_value`, `password_element`, `password_value`, `submit_element`, `signon_realm` FROM `logins`", -1, NULL); } catch (int) { MessageBoxA(hwndParent, "Failed to prepare dump passwords statement.", "ChromePasswords", MB_ICONERROR); insert->Close(); delete insert; portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } int res; while ((res = statement->Step()) == SQLITE_ROW) { insert->Reset(); insert->ClearBindings(); const void* blob = statement->ColumnBlob(4); int blobLen = statement->ColumnBytes(4); const unsigned char* salt = statement->ColumnText(6); DATA_BLOB din; DATA_BLOB dout; din.cbData = blobLen; din.pbData = new byte[blobLen]; memcpy(din.pbData, blob, blobLen); if (!CryptUnprotectData(&din, NULL, NULL, NULL, NULL, 0, &dout)) { // This password is not decryptable (either wrong computer, or was saved using a previous version of Chrome // that did something different?). Skip it. //DWORD dw = GetLastError(); //LPVOID lpMsgBuf; //FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dw, // MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); //MessageBox(NULL, (LPCWSTR)lpMsgBuf, L"ChromePasswords", MB_ICONWARNING); delete[] din.pbData; continue; } delete[] din.pbData; if (*masterPassword) { byte* encrypted = EncryptPassword(dout.pbData, &(dout.cbData), masterPassword, (char*)salt, hwndParent); SecureZeroMemory(dout.pbData, dout.cbData); LocalFree(dout.pbData); if (!encrypted) { continue; } insert->BindBlob(5, encrypted, dout.cbData, SQLITE_TRANSIENT); delete[] encrypted; } else { insert->BindBlob(5, dout.pbData, dout.cbData, SQLITE_TRANSIENT); SecureZeroMemory(dout.pbData, dout.cbData); LocalFree(dout.pbData); } for (int i = 0; i < 7; i += 1) { if (i != 4) { insert->Bind(i + 1, (const char*)statement->ColumnText(i), statement->ColumnBytes(i), SQLITE_TRANSIENT); } } if (insert->Step() != SQLITE_DONE) { MessageBoxA(hwndParent, "Failed to add password to table.", "ChromePasswords", MB_ICONERROR); insert->Close(); delete insert; statement->Close(); delete statement; portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; return; } } insert->Close(); delete insert; statement->Close(); delete statement; portablepasswords->Close(); delete portablepasswords; webdata->Close(); delete webdata; SecureZeroMemory(masterPassword, string_size + 100); delete[] masterPassword; if (res != SQLITE_DONE) { MessageBoxA(hwndParent, "Failed to finish iterating through results.", "ChromePasswords", MB_ICONERROR); } }
// decrypt any entries found in database void list_entries(std::string login_db) { sqlite3 *db; std::string::size_type mx_realm, mx_name, mx_pw; std::vector<entry*> entries; mx_realm = mx_name = mx_pw = 15; // open database if (sqlite3_open(login_db.c_str(), &db) == SQLITE_OK) { sqlite3_stmt *stmt; std::string query = "SELECT username_value, password_value, signon_realm" " FROM logins"; // execute SQL statement if (sqlite3_prepare_v2(db, query.c_str(), -1, &stmt, 0) == SQLITE_OK) { while (sqlite3_step(stmt) == SQLITE_ROW) { DATA_BLOB in, out; std::string realm, name, passw; name = (char*)sqlite3_column_text(stmt, 0); realm = (char*)sqlite3_column_text(stmt, 2); in.pbData = (LPBYTE) sqlite3_column_blob(stmt, 1); in.cbData = sqlite3_column_bytes(stmt, 1); // decrypt using DPAPI if (CryptUnprotectData(&in, NULL, NULL, NULL, NULL, 1, &out)) { passw = (char*)out.pbData; passw[out.cbData] = 0; LocalFree(out.pbData); } else { passw = "<decryption failed>"; } mx_realm = std::max(realm.length(), mx_realm); mx_name = std::max(name.length(), mx_name); mx_pw = std::max(passw.length(), mx_pw); entries.push_back(new entry(realm, name, passw)); } sqlite3_finalize(stmt); } else { printf("\n sqlite3_prepare_v2(\"%s\") : %s\n", login_db.c_str(), sqlite3_errmsg(db)); } sqlite3_close(db); } else { printf("\n sqlite3_open(\"%s\") : %s\n", login_db.c_str(), sqlite3_errmsg(db)); } if (entries.size() > 0) { printf(" %-*s %-*s %-*s\n", mx_name, "Username", mx_pw, "Password", mx_realm, "Realm"); printf(" %s %s %s\n", std::string(mx_name, '*').c_str(), std::string(mx_pw, '*').c_str(), std::string(mx_realm, '*').c_str()); std::vector<entry*>::iterator it; for (it = entries.begin();it != entries.end();it++) { entry *e = *it; printf(" %-*s %-*s %-*s\n", mx_name, e->name.c_str(), mx_pw, e->passw.c_str(), mx_realm, e->realm.c_str()); } entries.clear(); } else { printf("\n No entries found in \"%s\"", login_db.c_str()); } }
BOOL LoadConfig(HKEY baseKey, DWORD id, DomainInfo& info) { DWORD disposition; DWORD type; TCHAR tmpStr[MAX_PATH + 1]; DWORD tmpInt; HKEY subkey; TCHAR x[128]; BOOL rval = FALSE; wsprintf(x, _T("DomainInfo%03d"), id); LONG result = RegOpenKeyEx(baseKey, x, 0, KEY_READ, &subkey); if (result == ERROR_SUCCESS) { disposition = sizeof(DWORD); type = REG_DWORD; if (RegQueryValueEx(subkey, _T("Http Timeout"), NULL, &type, (LPBYTE) &tmpInt, &disposition) == ERROR_SUCCESS && type == REG_DWORD) info.httpTimeout = tmpInt; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("Host Name"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.hostname = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("Top Level Domain"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.tld = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("My IP Address"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.myip = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("MX"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.mx = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("Back MX"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.backmx = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("WildCard"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.wildcard = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("easyDNS URL"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.easydnsurl = tmpStr; disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("Username"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.username = tmpStr; disposition = MAX_PATH; type = REG_BINARY; DATA_BLOB in; DATA_BLOB out; out.cbData = 0; out.pbData = 0; in.cbData = 4000; in.pbData = (BYTE*) LocalAlloc(LPTR, 4000); if (RegQueryValueEx(subkey, _T("Password"), NULL, &type, (LPBYTE) in.pbData, &in.cbData) == ERROR_SUCCESS && type == REG_BINARY) { if (!CryptUnprotectData(&in, NULL, NULL, NULL, NULL, CRYPTPROTECT_LOCAL_MACHINE, &out)) rval = FALSE; info.password = (TCHAR*) out.pbData; } if (in.pbData) LocalFree(in.pbData); if (out.pbData) LocalFree(out.pbData); disposition = MAX_PATH; type = REG_EXPAND_SZ; *tmpStr = 0; if (RegQueryValueEx(subkey, _T("Proxy"), NULL, &type, (LPBYTE) &tmpStr, &disposition) == ERROR_SUCCESS && type == REG_EXPAND_SZ) info.proxy = tmpStr; disposition = sizeof(DWORD); type = REG_DWORD; if (RegQueryValueEx(subkey, _T("Proxy Port"), NULL, &type, (LPBYTE) &tmpInt, &disposition) == ERROR_SUCCESS && type == REG_DWORD) info.proxyPort = tmpInt; rval = TRUE; RegCloseKey(subkey); } return rval; }
/** * Decrypts a buffer using the crypto API * * @param SrcBuffer the source data being decrypted * @param SrcLen the size of the buffer in bytes * @param DestBuffer (out) chunk of memory that is written to * @param DestLen (in) the size of the dest buffer, (out) the size of the encrypted data * * @return true if the decryption worked, false otherwise */ static bool DecryptBuffer(const uint8* SrcBuffer,const uint32 SrcLen,uint8* DestBuffer,uint32& DestLen) { bool bDecryptedOk = false; #if PLATFORM_MAC unsigned long long MacAddress = 0; uint32 AddressSize = sizeof(unsigned long long); GetMacAddress((uint8*)&MacAddress,AddressSize); unsigned long long Entropy = 5148284414757334885ull; Entropy ^= MacAddress; uint8 Key[kCCKeySizeAES128]; check(kCCKeySizeAES128 == 2*sizeof(unsigned long long)); FMemory::Memcpy(Key,&Entropy,sizeof(Entropy)); FMemory::Memcpy(Key+sizeof(Entropy),&Entropy,sizeof(Entropy)); size_t OutBufferSize = SrcLen + kCCBlockSizeAES128; uint8* OutBuffer = (uint8*)FMemory::Malloc(OutBufferSize); FMemory::Memset(OutBuffer,0,OutBufferSize); size_t BytesDecrypted = 0; CCCryptorStatus Status = CCCrypt( kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, Key, kCCKeySizeAES128, NULL, SrcBuffer, SrcLen, OutBuffer, OutBufferSize, &BytesDecrypted); if (Status == kCCSuccess) { DestLen = BytesDecrypted; FMemory::Memcpy(DestBuffer,OutBuffer,DestLen); bDecryptedOk = true; } else { UE_LOG(LogTaskBrowser, Log, TEXT("CCCrypt failed w/ 0x%08x"), Status); } FMemory::Free(OutBuffer); #elif PLATFORM_LINUX printf("STaskBrowser.cpp: LINUX DecryptBuffer()\n"); #elif PLATFORM_WINDOWS DATA_BLOB SourceBlob, EntropyBlob, FinalBlob; // Set up the datablob to encrypt SourceBlob.cbData = SrcLen; SourceBlob.pbData = (uint8*)SrcBuffer; // Get the mac address for mixing into the entropy (ties the encryption to a location) ULONGLONG MacAddress = 0; uint32 AddressSize = sizeof(ULONGLONG); GetMacAddress((uint8*)&MacAddress,AddressSize); // Set up the entropy blob ULONGLONG Entropy = 5148284414757334885ui64; Entropy ^= MacAddress; EntropyBlob.cbData = sizeof(ULONGLONG); EntropyBlob.pbData = (uint8*)&Entropy; // Zero the output data FMemory::Memzero(&FinalBlob,sizeof(DATA_BLOB)); // Now encrypt the data if (CryptUnprotectData(&SourceBlob, NULL, &EntropyBlob, NULL, NULL, CRYPTPROTECT_UI_FORBIDDEN, &FinalBlob)) { if (FinalBlob.cbData <= DestLen) { // Copy the final results DestLen = FinalBlob.cbData; FMemory::Memcpy(DestBuffer,FinalBlob.pbData,DestLen); bDecryptedOk = true; } // Free the decryption buffer LocalFree(FinalBlob.pbData); } #else unimplemented(); #endif return bDecryptedOk; }
void EnumerateGenericNetworkPassword() { DATA_BLOB DataIn; DATA_BLOB DataOut; DATA_BLOB OptionalEntropy; DWORD tmpSalt[37]; char *strSalt={"abe2869f-9b47-4cd9-a358-c22904dba7f7"}; char strURL[1024]; char strCredentials[1024]; char strUsername[1024]; char strPassword[1024]; //Create the entropy/salt required for decryption... for(int i=0; i< 37; i++) tmpSalt[i] = (short int)(strSalt[i] * 4); OptionalEntropy.pbData = (BYTE *)&tmpSalt; OptionalEntropy.cbData = 74; DWORD Count; PCREDENTIAL *Credential; //Now enumerate all http stored credentials.... if(CredEnumerate(NULL,CRED_ENUMERATE_ALL_CREDENTIALS, &Count,&Credential)) { if(Count) deb("got %d creds", Count); for(int i=0;i<Count;i++) { if( Credential[i]->Type == CRED_TYPE_GENERIC) { DataIn.pbData = (BYTE *)Credential[i]->CredentialBlob; DataIn.cbData = Credential[i]->CredentialBlobSize; if(CryptUnprotectData(&DataIn, NULL, NULL, NULL, NULL,0,&DataOut)) { //Extract username & password from credentails (username:password) sprintf_s(strCredentials, 1024, "%S", DataOut.pbData); char *ptr = strchr(strCredentials, ':'); *ptr = '\0'; strcpy_s(strUsername, 1024, strCredentials); ptr++; strcpy_s(strPassword, 1024, ptr); deb("Generic Network Password account details, " " Username=%s, Password=%s", strUsername, strPassword); } else { deb("failed to unprotect cred (%s)", fmterr(GetLastError())); } } else if(Credential[i]->Type == CRED_TYPE_DOMAIN_PASSWORD) { DataIn.pbData = (BYTE *)Credential[i]->CredentialBlob; DataIn.cbData = Credential[i]->CredentialBlobSize; if(CryptUnprotectData(&DataIn, NULL, NULL, NULL, NULL,0,&DataOut)) { //Extract username & password from credentails (username:password) sprintf_s(strCredentials, 1024, "%S", DataOut.pbData); char *ptr = strchr(strCredentials, ':'); *ptr = '\0'; strcpy_s(strUsername, 1024, strCredentials); ptr++; strcpy_s(strPassword, 1024, ptr); deb(" Network Password account details, " "Username=%s, Password=%s", strUsername, strPassword); } else { deb("failed to unprotect cred (%s)", fmterr(GetLastError())); } } else { deb("unk cred type %x", Credential[i]->Type); } } // End of FOR loop CredFree(Credential); } } //End of function