coupley more reports

This commit is contained in:
donnaskiez 2024-05-15 19:48:09 +10:00
parent 3a45a9fe04
commit f7dd6ae97f
7 changed files with 236 additions and 75 deletions

View file

@ -1,6 +1,8 @@
#include "hw.h"
#include "modules.h"
#include "crypt.h"
#include "imports.h"
#define PCI_VENDOR_ID_OFFSET 0x00
#define PCI_DEVICE_ID_OFFSET 0x02
@ -67,11 +69,11 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
_Out_opt_ PVOID Buffer,
_In_ UINT32 BufferLength)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
KEVENT event = {0};
IO_STATUS_BLOCK io = {0};
PIRP irp = NULL;
PIO_STACK_LOCATION io_stack_location = NULL;
NTSTATUS status = STATUS_UNSUCCESSFUL;
KEVENT event = {0};
IO_STATUS_BLOCK io = {0};
PIRP irp = NULL;
PIO_STACK_LOCATION packet = NULL;
if (BufferLength == 0)
return STATUS_BUFFER_TOO_SMALL;
@ -90,13 +92,12 @@ QueryPciDeviceConfigurationSpace(_In_ PDEVICE_OBJECT DeviceObject,
return STATUS_INSUFFICIENT_RESOURCES;
}
io_stack_location = IoGetNextIrpStackLocation(irp);
io_stack_location->MinorFunction = IRP_MN_READ_CONFIG;
io_stack_location->Parameters.ReadWriteConfig.WhichSpace =
PCI_WHICHSPACE_CONFIG;
io_stack_location->Parameters.ReadWriteConfig.Offset = Offset;
io_stack_location->Parameters.ReadWriteConfig.Buffer = Buffer;
io_stack_location->Parameters.ReadWriteConfig.Length = BufferLength;
packet = IoGetNextIrpStackLocation(irp);
packet->MinorFunction = IRP_MN_READ_CONFIG;
packet->Parameters.ReadWriteConfig.WhichSpace = PCI_WHICHSPACE_CONFIG;
packet->Parameters.ReadWriteConfig.Offset = Offset;
packet->Parameters.ReadWriteConfig.Buffer = Buffer;
packet->Parameters.ReadWriteConfig.Length = BufferLength;
status = IoCallDriver(DeviceObject, irp);
@ -255,6 +256,38 @@ IsPciConfigurationSpaceFlagged(_In_ PPCI_COMMON_HEADER Configuration)
return FALSE;
}
STATIC
VOID
ReportBlacklistedPcieDevice(_In_ PDEVICE_OBJECT DeviceObject,
_In_ PPCI_COMMON_HEADER Header)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 packet_size = CryptRequestRequiredBufferLength(
sizeof(BLACKLISTED_PCIE_DEVICE_REPORT));
PBLACKLISTED_PCIE_DEVICE_REPORT report =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, packet_size, REPORT_POOL_TAG);
if (!report)
return;
INIT_REPORT_PACKET(report, REPORT_BLACKLISTED_PCIE_DEVICE, 0);
report->device_object = (UINT64)DeviceObject;
report->device_id = Header->DeviceID;
report->vendor_id = Header->VendorID;
status = CryptEncryptBuffer(report, packet_size);
if (!NT_SUCCESS(status)) {
DEBUG_ERROR("CryptEncryptBuffer: %lx", status);
ImpExFreePoolWithTag(report, packet_size);
return;
}
IrpQueueSchedulePacket(report, packet_size);
}
STATIC
NTSTATUS
PciDeviceQueryCallback(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
@ -283,6 +316,7 @@ PciDeviceQueryCallback(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context)
DeviceObject,
header.DeviceID,
header.VendorID);
ReportBlacklistedPcieDevice(DeviceObject, &header);
}
return status;

View file

@ -1609,7 +1609,7 @@ end:
*/
STATIC
VOID
ReportInvalidSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
ReportModifiedSystemImage(_In_ PRTL_MODULE_EXTENDED_INFO Module)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 packet_size = CryptRequestRequiredBufferLength(
@ -1684,7 +1684,7 @@ ValidateSystemModule(_In_ PRTL_MODULE_EXTENDED_INFO Module)
else {
DEBUG_WARNING("**!!** Module: %s text regions are NOT valid **!!**",
Module->FullPathName);
ReportInvalidSystemModule(Module);
ReportModifiedSystemImage(Module);
}
end:
@ -1693,6 +1693,39 @@ end:
ExFreePoolWithTag(hash, POOL_TAG_INTEGRITY);
}
STATIC
VOID
ReportModifiedSelfDriverImage(_In_ PRTL_MODULE_EXTENDED_INFO Module)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
UINT32 packet_size = CryptRequestRequiredBufferLength(
sizeof(DRIVER_SELF_INTEGRITY_CHECK_REPORT));
PDRIVER_SELF_INTEGRITY_CHECK_REPORT report =
ImpExAllocatePool2(POOL_FLAG_NON_PAGED, packet_size, REPORT_POOL_TAG);
if (!report)
return;
INIT_REPORT_PACKET(report, REPORT_SELF_DRIVER_PATCHED, 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);
}
NTSTATUS
ValidateOurDriverImage()
{
@ -1750,10 +1783,13 @@ ValidateOurDriverImage()
* module error and stop the users game session ? since module .text
* section error would be a large red flag
*/
if (CompareHashes(memory_hash, entry->text_hash, SHA_256_HASH_LENGTH))
if (CompareHashes(memory_hash, entry->text_hash, SHA_256_HASH_LENGTH)) {
DEBUG_VERBOSE("Driver image is valid. Integrity check complete");
else
}
else {
DEBUG_WARNING("**!!** Driver image is NOT valid. **!!**");
ReportModifiedSelfDriverImage(module_info);
}
end:
@ -2312,7 +2348,7 @@ end:
* the right direction.
*/
NTSTATUS
InitialiseHeartbeatConfiguration(_Inout_ PHEARTBEAT_CONFIGURATION Configuration)
InitialiseHeartbeatConfiguration(_Out_ PHEARTBEAT_CONFIGURATION Configuration)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;

View file

@ -123,7 +123,7 @@ FindWinLogonProcess(_In_ PPROCESS_LIST_ENTRY Entry, _In_opt_ PVOID Context);
NTSTATUS
InitialiseHeartbeatConfiguration(
_Inout_ PHEARTBEAT_CONFIGURATION Configuration);
_Out_ PHEARTBEAT_CONFIGURATION Configuration);
VOID
FreeHeartbeatConfiguration(_Inout_ PHEARTBEAT_CONFIGURATION Configuration);

View file

@ -337,12 +337,12 @@ IrpQueueCompletePacket(_In_ PVOID Buffer, _In_ ULONG BufferSize)
}
/*
* Not only does this allow reporting threads to continue execution once the
* report is scheduled (which in some cases such as handle reporting is very
* important for performance reasons), but it allows us to safely report from
* within a region guarded by a mutex as we use a spinlock here (for performance
* reasons, we dont need certain time critical threads being slept whilst we
* wait).
* Due to the fact that many reporting structures are holding a mutex when
* scheduling a report packet, we need an alternative queueing option from DPCs
* and spinlocks. Here we will use an array of work items (
*
* Hmm this is an interesting issue. Not sure how we shall resolve this, for now
* this works well enough.
*/
VOID
IrpQueueSchedulePacket(_In_ PVOID Buffer, _In_ UINT32 BufferLength)

View file

@ -13,7 +13,9 @@
#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_PATCHED_SYSTEM_MODULE 150
#define REPORT_SELF_DRIVER_PATCHED 160
#define REPORT_BLACKLISTED_PCIE_DEVICE 170
#define REPORT_SUBTYPE_NO_BACKING_MODULE 0x0
#define REPORT_SUBTYPE_INVALID_DISPATCH 0x1
@ -198,4 +200,20 @@ typedef struct _SYSTEM_MODULE_INTEGRITY_CHECK_REPORT {
} SYSTEM_MODULE_INTEGRITY_CHECK_REPORT, *PSYSTEM_MODULE_INTEGRITY_CHECK_REPORT;
typedef struct _DRIVER_SELF_INTEGRITY_CHECK_REPORT {
REPORT_PACKET_HEADER header;
UINT64 image_base;
UINT32 image_size;
CHAR path_name[0x100];
} DRIVER_SELF_INTEGRITY_CHECK_REPORT, *PDRIVER_SELF_INTEGRITY_CHECK_REPORT;
typedef struct _BLACKLISTED_PCIE_DEVICE_REPORT {
REPORT_PACKET_HEADER header;
UINT64 device_object;
UINT16 device_id;
UINT16 vendor_id;
} BLACKLISTED_PCIE_DEVICE_REPORT, *PBLACKLISTED_PCIE_DEVICE_REPORT;
#endif

View file

@ -5,50 +5,64 @@
#include "crypt/crypt.h"
void helper::generate_rand_seed() { srand(time(0)); }
int helper::generate_rand_int(int max) { return std::rand() % max; }
void helper::sleep_thread(int seconds) {
std::this_thread::sleep_for(std::chrono::seconds(seconds));
void
helper::generate_rand_seed()
{
srand(time(0));
}
int helper::get_report_id_from_buffer(void *buffer) {
kernel_interface::report_header *header =
reinterpret_cast<kernel_interface::report_header *>(
(uint64_t)buffer + sizeof(kernel_interface::report_header));
return header->report_code;
int
helper::generate_rand_int(int max)
{
return std::rand() % max;
}
kernel_interface::report_id helper::get_kernel_report_type(void *buffer) {
switch (helper::get_report_id_from_buffer(buffer)) {
case kernel_interface::report_id::report_nmi_callback_failure:
return kernel_interface::report_id::report_nmi_callback_failure;
void
helper::sleep_thread(int seconds)
{
std::this_thread::sleep_for(std::chrono::seconds(seconds));
}
case kernel_interface::report_id::report_module_validation_failure:
return kernel_interface::report_id::report_module_validation_failure;
int
helper::get_report_id_from_buffer(void* buffer)
{
kernel_interface::report_header* header =
reinterpret_cast<kernel_interface::report_header*>(
(uint64_t)buffer + sizeof(kernel_interface::report_header));
return header->report_code;
}
case kernel_interface::report_id::report_illegal_handle_operation:
return kernel_interface::report_id::report_illegal_handle_operation;
kernel_interface::report_id
helper::get_kernel_report_type(void* buffer)
{
switch (helper::get_report_id_from_buffer(buffer)) {
case kernel_interface::report_id::report_nmi_callback_failure:
return kernel_interface::report_id::report_nmi_callback_failure;
case kernel_interface::report_id::report_invalid_process_allocation:
return kernel_interface::report_id::report_invalid_process_allocation;
case kernel_interface::report_id::report_module_validation_failure:
return kernel_interface::report_id::report_module_validation_failure;
case kernel_interface::report_id::report_hidden_system_thread:
return kernel_interface::report_id::report_hidden_system_thread;
case kernel_interface::report_id::report_illegal_handle_operation:
return kernel_interface::report_id::report_illegal_handle_operation;
case kernel_interface::report_id::report_illegal_attach_process:
return kernel_interface::report_id::report_illegal_attach_process;
case kernel_interface::report_id::report_invalid_process_allocation:
return kernel_interface::report_id::report_invalid_process_allocation;
case kernel_interface::report_id::report_apc_stackwalk:
return kernel_interface::report_id::report_apc_stackwalk;
case kernel_interface::report_id::report_hidden_system_thread:
return kernel_interface::report_id::report_hidden_system_thread;
case kernel_interface::report_id::report_dpc_stackwalk:
return kernel_interface::report_id::report_dpc_stackwalk;
case kernel_interface::report_id::report_illegal_attach_process:
return kernel_interface::report_id::report_illegal_attach_process;
case kernel_interface::report_id::report_data_table_routine:
return kernel_interface::report_id::report_data_table_routine;
}
case kernel_interface::report_id::report_apc_stackwalk:
return kernel_interface::report_id::report_apc_stackwalk;
case kernel_interface::report_id::report_dpc_stackwalk:
return kernel_interface::report_id::report_dpc_stackwalk;
case kernel_interface::report_id::report_data_table_routine:
return kernel_interface::report_id::report_data_table_routine;
}
}
void
@ -156,6 +170,37 @@ print_report_packet(void* buffer)
LOG_INFO("********************************");
break;
}
case kernel_interface::report_id::report_patched_system_module: {
kernel_interface::system_module_integrity_check_report* r11 =
reinterpret_cast<
kernel_interface::system_module_integrity_check_report*>(
buffer);
LOG_INFO("image_base: %llx", r11->image_base);
LOG_INFO("image_size: %lx", r11->image_size);
LOG_INFO("path_name: %s", r11->path_name);
LOG_INFO("********************************");
break;
}
case kernel_interface::report_id::report_self_driver_patched: {
kernel_interface::driver_self_integrity_check_report* r12 =
reinterpret_cast<
kernel_interface::driver_self_integrity_check_report*>(buffer);
LOG_INFO("image_base: %llx", r12->image_base);
LOG_INFO("image_size: %lx", r12->image_size);
LOG_INFO("path_name: %s", r12->path_name);
LOG_INFO("********************************");
break;
}
case kernel_interface::report_id::report_blacklisted_pcie_device: {
kernel_interface::blacklisted_pcie_device_report* r13 =
reinterpret_cast<kernel_interface::blacklisted_pcie_device_report*>(
buffer);
LOG_INFO("device_object: %llx", r13->device_object);
LOG_INFO("device_id: %x", r13->device_id);
LOG_INFO("vendor_id: %x", r13->vendor_id);
LOG_INFO("********************************");
break;
}
default: LOG_INFO("Invalid report type."); break;
}
}
@ -172,28 +217,32 @@ print_heartbeat_packet(void* buffer)
LOG_INFO("********************************");
}
void helper::print_kernel_report(void *buffer) {
uint32_t size = crypt::get_padded_packet_size(
sizeof(kernel_interface::open_handle_failure_report));
crypt::decrypt_packet(buffer, size);
void
helper::print_kernel_report(void* buffer)
{
uint32_t size = crypt::get_padded_packet_size(
sizeof(kernel_interface::open_handle_failure_report));
crypt::decrypt_packet(buffer, size);
kernel_interface::packet_header *header =
reinterpret_cast<kernel_interface::packet_header *>(buffer);
kernel_interface::packet_header* header =
reinterpret_cast<kernel_interface::packet_header*>(buffer);
LOG_INFO("packet type: %lx", header->packet_type);
LOG_INFO("packet type: %lx", header->packet_type);
switch (header->packet_type)
{
case 0: print_report_packet(buffer); break;
case 1: print_heartbeat_packet(buffer); break;
}
switch (header->packet_type) {
case 0: print_report_packet(buffer); break;
case 1: print_heartbeat_packet(buffer); break;
}
}
unsigned __int64 helper::seconds_to_nanoseconds(int seconds) {
return ABSOLUTE(SECONDS(seconds));
unsigned __int64
helper::seconds_to_nanoseconds(int seconds)
{
return ABSOLUTE(SECONDS(seconds));
}
unsigned __int32 helper::seconds_to_milliseconds(int seconds) {
return seconds * 1000;
unsigned __int32
helper::seconds_to_milliseconds(int seconds)
{
return seconds * 1000;
}

View file

@ -22,7 +22,10 @@ enum report_id {
report_apc_stackwalk = 110,
report_dpc_stackwalk = 120,
report_data_table_routine = 130,
report_invalid_process_module = 140
report_invalid_process_module = 140,
report_patched_system_module = 150,
report_self_driver_patched = 160,
report_blacklisted_pcie_device = 170
};
#define AES_256_BLOCK_SIZE 16
@ -126,6 +129,20 @@ struct process_module_validation_report {
wchar_t module_path[MODULE_PATH_LEN];
};
struct system_module_integrity_check_report {
report_header header;
uint64_t image_base;
uint32_t image_size;
char path_name[0x100];
};
struct driver_self_integrity_check_report {
report_header header;
uint64_t image_base;
uint32_t image_size;
char path_name[0x100];
};
struct heartbeat_packet {
heartbeat_header header;
uint32_t heartbeat_count;
@ -134,6 +151,13 @@ struct heartbeat_packet {
uint32_t total_heartbeats_completed;
};
struct blacklisted_pcie_device_report {
report_header header;
uint64_t device_object;
uint16_t device_id;
uint16_t vendor_id;
};
enum apc_operation { operation_stackwalk = 0x1 };
// clang-format off