From 15ef3a1d75a770a50f3d515e52ffc2121ba51fcc Mon Sep 17 00:00:00 2001 From: donnaskiez Date: Sun, 12 May 2024 02:06:34 +1000 Subject: [PATCH] bed --- driver/integrity.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- driver/types/types.h | 12 ++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/driver/integrity.c b/driver/integrity.c index ff9ea14..c1042a7 100644 --- a/driver/integrity.c +++ b/driver/integrity.c @@ -1602,6 +1602,44 @@ end: return status; } +/* + * As said in the comment below, in the future we want to be able to copy a + * small part of the spot where the image has changed, say the next 50 bytes. + * This would be useful for scanning for any jmp x etc. For this thisl do. + */ +STATIC +VOID +ReportInvalidSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module) +{ + NTSTATUS status = STATUS_UNSUCCESSFUL; + UINT32 packet_size = CryptRequestRequiredBufferLength( + sizeof(SYSTEM_MODULE_INTEGRITY_CHECK_REPORT)); + + PSYSTEM_MODULE_INTEGRITY_CHECK_REPORT report = + ImpExAllocatePool2(POOL_FLAG_NON_PAGED, packet_size, REPORT_POOL_TAG); + + if (!report) + return; + + INIT_REPORT_PACKET(report, REPORT_PATCHED_SYSTEM_MODULE, 0); + + report->image_base = Module->ImageBase; + report->image_size = Module->ImageSize; + + RtlCopyMemory( + report->path_name, Module->FullPathName, sizeof(report->path_name)); + + status = CryptEncryptBuffer(report, packet_size); + + if (!NT_SUCCESS(status)) { + DEBUG_ERROR("CryptEncryptBuffer: %lx", status); + ImpExFreePoolWithTag(report, packet_size); + return; + } + + IrpQueueSchedulePacket(report, packet_size); +} + VOID ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module) { @@ -1622,6 +1660,16 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module) goto end; } + /* + * Ideally, we would like to have access to the offset into the module that + * doesnt match, allowing us to copy the next 50 bytes for example. Since we + * only store the hash, we can only check whether something has changed, but + * we dont really have access to any information regarding what changed. In + * the future it might be nice (though requires a fair amount of memory) to + * store a copy of images on load in the list alongside the hash. That way + * if there is a change in the hash, we can access the old buffer, perform a + * memory comparison, and find the point where the change exists. + */ status = HashModule(Module, hash); if (!NT_SUCCESS(status)) { @@ -1629,12 +1677,15 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module) goto end; } - if (CompareHashes(hash, entry->text_hash, SHA_256_HASH_LENGTH)) + if (CompareHashes(hash, entry->text_hash, SHA_256_HASH_LENGTH)) { DEBUG_VERBOSE("Module: %s text regions are valid.", Module->FullPathName); - else + } + else { DEBUG_WARNING("**!!** Module: %s text regions are NOT valid **!!**", Module->FullPathName); + ReportInvalidSystemModule(Module); + } end: diff --git a/driver/types/types.h b/driver/types/types.h index 026bd33..f3a0c49 100644 --- a/driver/types/types.h +++ b/driver/types/types.h @@ -13,6 +13,7 @@ #define REPORT_DPC_STACKWALK 120 #define REPORT_DATA_TABLE_ROUTINE 130 #define REPORT_INVALID_PROCESS_MODULE 140 +#define REPORT_PATCHED_SYSTEM_MODULE 150 #define REPORT_SUBTYPE_NO_BACKING_MODULE 0x0 #define REPORT_SUBTYPE_INVALID_DISPATCH 0x1 @@ -36,6 +37,9 @@ (packet)->header.packet_header.magic_number = PACKET_MAGIC_NUMBER; \ } +/* TODO: the naming here is fucking terrible need to clean everything up */ +/* infact lots of the mess in the header files needs to be cleaned up */ + /* use a UINT16 rather then enum to explicitly state the size */ typedef struct _PACKET_HEADER { UINT32 packet_type; @@ -186,4 +190,12 @@ typedef struct _HEARTBEAT_PACKET { } HEARTBEAT_PACKET, *PHEARTBEAT_PACKET; +typedef struct _SYSTEM_MODULE_INTEGRITY_CHECK_REPORT { + REPORT_PACKET_HEADER header; + UINT64 image_base; + UINT32 image_size; + CHAR path_name[0x100]; + +} SYSTEM_MODULE_INTEGRITY_CHECK_REPORT, *PSYSTEM_MODULE_INTEGRITY_CHECK_REPORT; + #endif \ No newline at end of file