Skip to content

Commit

Permalink
Fixing issues github issues #1 #2 #3. Disabled CryptDestroyKey hookin…
Browse files Browse the repository at this point in the history
…g as it's broken. Updated README, and made sure the round trip instructions work this time.
  • Loading branch information
eugenekolo committed Sep 9, 2017
1 parent f2e5b3a commit 89f0454
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 44 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -28,7 +28,7 @@ cl ./test/kEncrypt.cpp ./test/easy_cryptoapi.cpp
kEncrypt.exe ./test/test1.txt test1.enc no
# Check the log and extract the key data
grep "C:/CryptoHookLog.dll" ExfilKeyData
grep ExfilKeyData "C:/CryptoHookLog.dll"
# Decrypt using the extracted data and compare to the original (should be same)
./scripts/decrypt-file.py -f test1.enc -o test1.out -x <keydata>
Expand Down
93 changes: 55 additions & 38 deletions src/antiransom.cpp → antiransom.cpp
Expand Up @@ -98,47 +98,48 @@ BOOL WINAPI Fake_CryptSetKeyParam(HCRYPTKEY hKey, DWORD dwParam, BYTE* pbData, D

}

BOOL WINAPI Fake_CryptDestroyKey(HCRYPTKEY hKey) {
FILE *fd = fopen("C:\\CryptoHookLog.dll", "a");
std::string mytime = CurrentTime();

fprintf(fd, "[CryptDestroyKey] %s\n", mytime.c_str());

DWORD dwCount;
BYTE pbData2[16];
CryptGetKeyParam(hKey, KP_IV, NULL, &dwCount, 0); // Get size of KP_IV
CryptGetKeyParam(hKey, KP_IV, pbData2, &dwCount, 0); // Get KP_IV data
fprintf(fd, "KP_IV = ");
for (int i = 0 ; i < dwCount ; i++) {
fprintf(fd, "%02x ",pbData2[i]);
}

if (recursive == FALSE) {
recursive = TRUE;

Real_CryptExportKey(hKey, NULL, PLAINTEXTKEYBLOB, 0, NULL, &g_dwKeyBlobLen_Exfil);
fprintf(fd, "\t ExfilKeyLen = %d\n", g_dwKeyBlobLen_Exfil);
// BOOL WINAPI Fake_CryptDestroyKey(HCRYPTKEY hKey) {
// FILE *fd = fopen("C:\\CryptoHookLog.dll", "a");
// std::string mytime = CurrentTime();

// fprintf(fd, "[CryptDestroyKey] %s\n", mytime.c_str());

// // TODO(eugenek): This is broken, for some reason dwCount doesn't get updated correctly.
// // DWORD dwCount;
// // BYTE pbData2[16];
// // CryptGetKeyParam(hKey, KP_IV, NULL, &dwCount, 0); // Get size of KP_IV
// // CryptGetKeyParam(hKey, KP_IV, pbData2, &dwCount, 0); // Get KP_IV data
// // fprintf(fd, "KP_IV = ");
// // for (int i = 0 ; i < dwCount ; i++) {
// // fprintf(fd, "%02x ",pbData2[i]);
// // }

// if (recursive == FALSE) {
// recursive = TRUE;

// Real_CryptExportKey(hKey, NULL, PLAINTEXTKEYBLOB, 0, NULL, &g_dwKeyBlobLen_Exfil);
// fprintf(fd, "\t ExfilKeyLen = %d\n", g_dwKeyBlobLen_Exfil);

g_pbKeyBlob_Exfil = (BYTE*)malloc(g_dwKeyBlobLen_Exfil);
// g_pbKeyBlob_Exfil = (BYTE*)malloc(g_dwKeyBlobLen_Exfil);

// Get the export blob
if (!Real_CryptExportKey(hKey, NULL, PLAINTEXTKEYBLOB, 0, g_pbKeyBlob_Exfil, &g_dwKeyBlobLen_Exfil)){
MyHandleError(TEXT("[FAIL] Exfil key data failed \n"), GetLastError());
fprintf(fd, "[FAIL] no-alloca Exfil key data failed \n");
}
// // Get the export blob
// if (!Real_CryptExportKey(hKey, NULL, PLAINTEXTKEYBLOB, 0, g_pbKeyBlob_Exfil, &g_dwKeyBlobLen_Exfil)){
// MyHandleError(TEXT("[FAIL] Exfil key data failed \n"), GetLastError());
// fprintf(fd, "[FAIL] no-alloca Exfil key data failed \n");
// }

fprintf(fd, "\t no-alloca ExfilKeyData = ");
for (int i = 0 ; i < g_dwKeyBlobLen_Exfil ; i++) {
fprintf(fd, "%02x", g_pbKeyBlob_Exfil[i]);
}
fprintf(fd, "\n");
// fprintf(fd, "\t no-alloca ExfilKeyData = ");
// for (int i = 0 ; i < g_dwKeyBlobLen_Exfil ; i++) {
// fprintf(fd, "%02x", g_pbKeyBlob_Exfil[i]);
// }
// fprintf(fd, "\n");

recursive = FALSE;
}
// recursive = FALSE;
// }

fclose(fd);
return Real_CryptDestroyKey(hKey);
}
// fclose(fd);
// return Real_CryptDestroyKey(hKey);
// }


BOOL WINAPI Fake_CryptEncrypt(HCRYPTKEY hKey, HCRYPTHASH hHash, BOOL Final, DWORD dwFlags, BYTE* pbData,
Expand Down Expand Up @@ -598,17 +599,25 @@ INT APIENTRY DllMain(HMODULE hModule, DWORD Reason, LPVOID lpReserved) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());

DetourAttach(&(PVOID&)Real_CryptEncrypt, Fake_CryptDestroyKey);

DetourAttach(&(PVOID&)Real_CryptEncrypt, Fake_CryptEncrypt);
DetourAttach(&(PVOID&)Real_CryptDecrypt, Fake_CryptDecrypt);

DetourAttach(&(PVOID&)Real_CryptAcquireContext, Fake_CryptAcquireContext);
DetourAttach(&(PVOID&)Real_CryptSetKeyParam, Fake_CryptSetKeyParam);
// TODO(eugenek): Disabled because the function needs logic to check the key wasn't already
// exported, else it keeps crashing. Somebody should add this logic.
// DetourAttach(&(PVOID&)Real_CryptDestroyKey, Fake_CryptDestroyKey);

DetourAttach(&(PVOID&)Real_CryptCreateHash, Fake_CryptCreateHash);
DetourAttach(&(PVOID&)Real_CryptHashData, Fake_CryptHashData);

DetourAttach(&(PVOID&)Real_CryptDeriveKey, Fake_CryptDeriveKey);
DetourAttach(&(PVOID&)Real_CryptGenKey, Fake_CryptGenKey);

DetourAttach(&(PVOID&)Real_CryptImportKey, Fake_CryptImportKey);
DetourAttach(&(PVOID&)Real_CryptExportKey, Fake_CryptExportKey);

DetourAttach(&(PVOID&)Real_CryptGenRandom, Fake_CryptGenRandom);

//DetourAttach(&(PVOID&)Real_ReadFile, Fake_ReadFile);
Expand All @@ -627,17 +636,25 @@ INT APIENTRY DllMain(HMODULE hModule, DWORD Reason, LPVOID lpReserved) {
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)Real_CryptEncrypt, Fake_CryptDestroyKey);

DetourDetach(&(PVOID&)Real_CryptEncrypt, Fake_CryptEncrypt);
DetourDetach(&(PVOID&)Real_CryptDecrypt, Fake_CryptDecrypt);

DetourDetach(&(PVOID&)Real_CryptAcquireContext, Fake_CryptAcquireContext);
DetourDetach(&(PVOID&)Real_CryptSetKeyParam, Fake_CryptSetKeyParam);
// TODO(eugenek): Disabled because the function needs logic to check the key wasn't already
// exported, else it keeps crashing. Somebody should add this logic.
// DetourDetach(&(PVOID&)Real_CryptDestroyKey, Fake_CryptDestroyKey);

DetourDetach(&(PVOID&)Real_CryptCreateHash, Fake_CryptCreateHash);
DetourDetach(&(PVOID&)Real_CryptHashData, Fake_CryptHashData);

DetourDetach(&(PVOID&)Real_CryptDeriveKey, Fake_CryptDeriveKey);
DetourDetach(&(PVOID&)Real_CryptGenKey, Fake_CryptGenKey);

DetourDetach(&(PVOID&)Real_CryptImportKey, Fake_CryptImportKey);
DetourDetach(&(PVOID&)Real_CryptExportKey, Fake_CryptExportKey);

DetourDetach(&(PVOID&)Real_CryptGenRandom, Fake_CryptGenRandom);

//DetourDetach(&(PVOID&)Real_ReadFile, Fake_ReadFile);
Expand Down
File renamed without changes.
File renamed without changes.
14 changes: 12 additions & 2 deletions scripts/decrypt-file.py 100755 → 100644
Expand Up @@ -172,8 +172,10 @@ def main(key_blob):
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file', required=True,
help="Required. Specify the encrypted file to decrypt.")
parser.add_argument('-k', '--key_blobs', required=True, default='keys.txt',
parser.add_argument('-k', '--key_blobs', required=False, default='keys.txt',
help="Specify where the list of potential keys is, default=keys.txt")
parser.add_argument('-k0', '--key_blob', required=False,
help="Specify a single key to use.")
parser.add_argument('-o', '--out', default=sys.stdout,
help="Specify where you want the decrypted file to go, default=stdout")
parser.add_argument('-m', '--mode', default='cbc', choices=['cbc', 'ofb', 'ecb'],
Expand All @@ -193,6 +195,10 @@ def main(key_blob):

args = parser.parse_args()

if (not args.key_blobs and not args.key_blob):
print("You must provide either a --key_blob xor --key_blobs")
sys.exit(3)

if args.mode == 'cbc':
args.mode = AES.MODE_CBC
elif args.mode == 'ofb':
Expand All @@ -215,7 +221,11 @@ def main(key_blob):
encrypted_data = encrypt_file(args.file, key_val, args.mode, args.iv)
sys.exit(1)

key_blobs = set([line.rstrip('\r\n') for line in open(args.key_blobs)])
if args.key_blob:
key_blobs = [args.key_blob]
else:
key_blobs = set([line.rstrip('\r\n') for line in open(args.key_blobs)])

count = 1
for key_blob in key_blobs:
if main(key_blob):
Expand Down
1 change: 0 additions & 1 deletion test/easy_cryptoapi.cpp
Expand Up @@ -9,7 +9,6 @@
* Refer to MSDN CryptoAPI documentation for more information.
*
* NOTE:
* + Sessions keys are always set to CRYPT_EXPORTABLE.
* + Some functions write files for you. This behaviour might be annoying.
*
* TODO:
Expand Down
4 changes: 2 additions & 2 deletions test/kEncrypt.cpp
Expand Up @@ -87,14 +87,14 @@ BOOL kEncrypt(LPTSTR pszSourceFile, LPTSTR pszDestinationFile, LPTSTR pszPasswor
}

if(!pszPassword || !pszPassword[0]) { // No password given
if (GenSessionKeyWithRandom(hCryptProv, ENCRYPT_ALGORITHM, KEYLENGTH, hKey)) {
if (GenSessionKeyWithRandom(hCryptProv, ENCRYPT_ALGORITHM, KEYLENGTH, CRYPT_EXPORTABLE, hKey)) {
_tprintf(TEXT("[GOOD] Generated random session key \n"));
} else {
MyHandleError(TEXT("[FAIL] Random session not generated. \n"), GetLastError());
return FALSE;
}
} else {
if (GenSessionKeyWithPassword(pszPassword, hCryptProv, ENCRYPT_ALGORITHM, KEYLENGTH,
if (GenSessionKeyWithPassword(pszPassword, hCryptProv, ENCRYPT_ALGORITHM, KEYLENGTH, CRYPT_EXPORTABLE,
hHash, hKey)) {
_tprintf(TEXT("[GOOD] Generated passworded session key \n"));
} else {
Expand Down

0 comments on commit 89f0454

Please sign in to comment.