mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
e
This commit is contained in:
parent
63a13f0c4d
commit
4321236a0f
8 changed files with 137 additions and 11 deletions
|
@ -30,6 +30,7 @@ NTSTATUS DeviceControl(
|
||||||
|
|
||||||
case IOCTL_VALIDATE_DRIVER_OBJECTS:
|
case IOCTL_VALIDATE_DRIVER_OBJECTS:
|
||||||
|
|
||||||
|
/* KeWaitForSingleObject with infinite time must be called from IRQL <= APC_LEVEL */
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -3,6 +3,47 @@
|
||||||
#include "nmi.h"
|
#include "nmi.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
NTSTATUS ValidateDriverIOCTLDispatchRegion(
|
||||||
|
_In_ PDRIVER_OBJECT Driver,
|
||||||
|
_In_ PSYSTEM_MODULES Modules,
|
||||||
|
_In_ PBOOLEAN Flag
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
UINT64 current_function;
|
||||||
|
|
||||||
|
UINT64 base = ( UINT64 )Driver->DriverStart;
|
||||||
|
UINT64 end = base + Driver->DriverSize;
|
||||||
|
|
||||||
|
*Flag = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the dispatch routine points to a location that is not in the confines of
|
||||||
|
* the module, report it. Basic check but every effective for catching driver
|
||||||
|
* dispatch hooking.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for ( INT index = 0; index < IRP_MJ_MAXIMUM_FUNCTION + 1; index++ )
|
||||||
|
{
|
||||||
|
current_function = *(UINT64*)
|
||||||
|
( ( UINT64 )Driver->MajorFunction + index * sizeof( PVOID ) );
|
||||||
|
|
||||||
|
DEBUG_LOG( "Current function: %llx", current_function );
|
||||||
|
|
||||||
|
if ( current_function == NULL )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ( current_function >= base && current_function <= end )
|
||||||
|
{
|
||||||
|
DEBUG_LOG( "THIS ADDRESS IS INSIDE ITS REGIUON :)" );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_ERROR( "Driver with invalid IOCTL dispatch routine found" );
|
||||||
|
*Flag = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID InitDriverList(
|
VOID InitDriverList(
|
||||||
_In_ PINVALID_DRIVERS_HEAD ListHead
|
_In_ PINVALID_DRIVERS_HEAD ListHead
|
||||||
)
|
)
|
||||||
|
@ -13,7 +54,8 @@ VOID InitDriverList(
|
||||||
|
|
||||||
VOID AddDriverToList(
|
VOID AddDriverToList(
|
||||||
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead,
|
_In_ PINVALID_DRIVERS_HEAD InvalidDriversHead,
|
||||||
_In_ PDRIVER_OBJECT Driver
|
_In_ PDRIVER_OBJECT Driver,
|
||||||
|
_In_ INT Reason
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PINVALID_DRIVER new_entry = ExAllocatePool2(
|
PINVALID_DRIVER new_entry = ExAllocatePool2(
|
||||||
|
@ -26,6 +68,7 @@ VOID AddDriverToList(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
new_entry->driver = Driver;
|
new_entry->driver = Driver;
|
||||||
|
new_entry->reason = Reason;
|
||||||
new_entry->next = InvalidDriversHead->first_entry;
|
new_entry->next = InvalidDriversHead->first_entry;
|
||||||
InvalidDriversHead->first_entry = new_entry;
|
InvalidDriversHead->first_entry = new_entry;
|
||||||
}
|
}
|
||||||
|
@ -215,6 +258,8 @@ NTSTATUS ValidateDriverObjects(
|
||||||
PDRIVER_OBJECT current_driver = sub_entry->Object;
|
PDRIVER_OBJECT current_driver = sub_entry->Object;
|
||||||
BOOLEAN flag;
|
BOOLEAN flag;
|
||||||
|
|
||||||
|
/* validate driver has backing module */
|
||||||
|
|
||||||
if ( !NT_SUCCESS( ValidateDriverObjectHasBackingModule(
|
if ( !NT_SUCCESS( ValidateDriverObjectHasBackingModule(
|
||||||
SystemModules,
|
SystemModules,
|
||||||
current_driver,
|
current_driver,
|
||||||
|
@ -231,7 +276,32 @@ NTSTATUS ValidateDriverObjects(
|
||||||
if ( !flag )
|
if ( !flag )
|
||||||
{
|
{
|
||||||
InvalidDriverListHead->count += 1;
|
InvalidDriverListHead->count += 1;
|
||||||
AddDriverToList( InvalidDriverListHead, current_driver );
|
AddDriverToList( InvalidDriverListHead, current_driver, REASON_NO_BACKING_MODULE );
|
||||||
|
}
|
||||||
|
|
||||||
|
/* validate drivers IOCTL dispatch routines */
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( ValidateDriverIOCTLDispatchRegion(
|
||||||
|
current_driver,
|
||||||
|
SystemModules,
|
||||||
|
&flag
|
||||||
|
) ) )
|
||||||
|
{
|
||||||
|
DEBUG_LOG( "Error validating drivers IOCTL routines" );
|
||||||
|
ExReleasePushLockExclusiveEx( &directory_object->Lock, 0 );
|
||||||
|
ObDereferenceObject( directory );
|
||||||
|
ZwClose( handle );
|
||||||
|
return STATUS_ABANDONED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !flag )
|
||||||
|
{
|
||||||
|
InvalidDriverListHead->count += 1;
|
||||||
|
AddDriverToList( InvalidDriverListHead, current_driver, REASON_INVALID_IOCTL_DISPATCH );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_LOG( "All drivers have valid dispatch routines :)" );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub_entry = sub_entry->ChainLink;
|
sub_entry = sub_entry->ChainLink;
|
||||||
|
@ -310,6 +380,7 @@ NTSTATUS HandleValidateDriversIOCTL(
|
||||||
|
|
||||||
MODULE_VALIDATION_FAILURE report;
|
MODULE_VALIDATION_FAILURE report;
|
||||||
report.report_code = REPORT_MODULE_VALIDATION_FAILURE;
|
report.report_code = REPORT_MODULE_VALIDATION_FAILURE;
|
||||||
|
report.report_type = head->first_entry->reason;
|
||||||
report.driver_base_address = head->first_entry->driver->DriverStart;
|
report.driver_base_address = head->first_entry->driver->DriverStart;
|
||||||
report.driver_size = head->first_entry->driver->Size;
|
report.driver_size = head->first_entry->driver->Size;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
#define MODULE_REPORT_DRIVER_NAME_BUFFER_SIZE 128
|
#define MODULE_REPORT_DRIVER_NAME_BUFFER_SIZE 128
|
||||||
|
|
||||||
|
#define REASON_NO_BACKING_MODULE 1
|
||||||
|
#define REASON_INVALID_IOCTL_DISPATCH 2
|
||||||
|
|
||||||
typedef struct _MODULE_VALIDATION_FAILURE_HEADER
|
typedef struct _MODULE_VALIDATION_FAILURE_HEADER
|
||||||
{
|
{
|
||||||
INT module_count;
|
INT module_count;
|
||||||
|
@ -18,6 +21,7 @@ typedef struct _MODULE_VALIDATION_FAILURE_HEADER
|
||||||
typedef struct _MODULE_VALIDATION_FAILURE
|
typedef struct _MODULE_VALIDATION_FAILURE
|
||||||
{
|
{
|
||||||
INT report_code;
|
INT report_code;
|
||||||
|
INT report_type;
|
||||||
UINT64 driver_base_address;
|
UINT64 driver_base_address;
|
||||||
UINT64 driver_size;
|
UINT64 driver_size;
|
||||||
PCHAR driver_name[ 128 ];
|
PCHAR driver_name[ 128 ];
|
||||||
|
@ -27,6 +31,7 @@ typedef struct _MODULE_VALIDATION_FAILURE
|
||||||
typedef struct _INVALID_DRIVER
|
typedef struct _INVALID_DRIVER
|
||||||
{
|
{
|
||||||
struct _INVALID_DRIVER* next;
|
struct _INVALID_DRIVER* next;
|
||||||
|
INT reason;
|
||||||
PDRIVER_OBJECT driver;
|
PDRIVER_OBJECT driver;
|
||||||
|
|
||||||
}INVALID_DRIVER, * PINVALID_DRIVER;
|
}INVALID_DRIVER, * PINVALID_DRIVER;
|
||||||
|
|
|
@ -44,5 +44,28 @@ namespace service
|
||||||
public int SignatureId;
|
public int SignatureId;
|
||||||
public UInt64 Address;
|
public UInt64 Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct NMI_CALLBACK_FAILURE
|
||||||
|
{
|
||||||
|
public int ReportCode;
|
||||||
|
public int WereNmisDisabled;
|
||||||
|
public UInt64 KThreadAddress;
|
||||||
|
public UInt64 InvalidRip;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public unsafe struct MODULE_VALIDATION_FAILURE
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public int ReportCode;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public int ReportType;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public UInt64 DriverBaseAddress;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public UInt64 DriverSize;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public fixed char ModuleName[128];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,12 @@ namespace service
|
||||||
private byte[] _headerBuf;
|
private byte[] _headerBuf;
|
||||||
private int _headerBufSize;
|
private int _headerBufSize;
|
||||||
|
|
||||||
private const int REPORT_CODE_MODULE_VERIFICATION = 10;
|
private const int REPORT_PROCESS_MODULE_FAILURE = 10;
|
||||||
private const int REPORT_CODE_START_ADDRESS_VERIFICATION = 20;
|
private const int REPORT_PROCESS_THREAD_START_ADDRESS_FAILURE = 20;
|
||||||
private const int REPORT_PAGE_PROTECTION_VERIFICATION = 30;
|
private const int REPORT_PAGE_PROTECTION_VERIFICATION = 30;
|
||||||
private const int REPORT_PATTERN_SCAN_FAILURE = 40;
|
private const int REPORT_PATTERN_SCAN_FAILURE = 40;
|
||||||
|
private const int REPORT_NMI_CALLBACK_FAILURE = 50;
|
||||||
|
private const int REPORT_KERNEL_MODULE_FAILURE = 60;
|
||||||
|
|
||||||
private const int MESSAGE_TYPE_REPORT = 1;
|
private const int MESSAGE_TYPE_REPORT = 1;
|
||||||
private const int MESSAGE_TYPE_REQUEST = 2;
|
private const int MESSAGE_TYPE_REQUEST = 2;
|
||||||
|
@ -94,7 +96,7 @@ namespace service
|
||||||
|
|
||||||
switch (reportCode)
|
switch (reportCode)
|
||||||
{
|
{
|
||||||
case REPORT_CODE_MODULE_VERIFICATION:
|
case REPORT_PROCESS_MODULE_FAILURE:
|
||||||
|
|
||||||
var checksumFailurePacket = BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>();
|
var checksumFailurePacket = BytesToStructure<MODULE_VERIFICATION_CHECKSUM_FAILURE>();
|
||||||
|
|
||||||
|
@ -108,7 +110,7 @@ namespace service
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
case REPORT_CODE_START_ADDRESS_VERIFICATION:
|
case REPORT_PROCESS_THREAD_START_ADDRESS_FAILURE:
|
||||||
|
|
||||||
var startAddressFailurePacket = BytesToStructure<PROCESS_THREAD_START_FAILURE>();
|
var startAddressFailurePacket = BytesToStructure<PROCESS_THREAD_START_FAILURE>();
|
||||||
|
|
||||||
|
@ -143,6 +145,29 @@ namespace service
|
||||||
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
case REPORT_NMI_CALLBACK_FAILURE:
|
||||||
|
|
||||||
|
var nmiCallbackFailure = BytesToStructure<NMI_CALLBACK_FAILURE>();
|
||||||
|
|
||||||
|
_logger.LogInformation("Report code: {0}, WereNmisDisabled: {1}, KThreadAddress: {2}, InvalidRip: {3}",
|
||||||
|
nmiCallbackFailure.ReportCode,
|
||||||
|
nmiCallbackFailure.WereNmisDisabled,
|
||||||
|
nmiCallbackFailure.KThreadAddress,
|
||||||
|
nmiCallbackFailure.InvalidRip);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
case REPORT_KERNEL_MODULE_FAILURE:
|
||||||
|
|
||||||
|
var kernelModuleFailure = BytesToStructure<MODULE_VALIDATION_FAILURE>();
|
||||||
|
|
||||||
|
_logger.LogInformation("Report code: {0}, DriverBaseAddress: {1}, DriverSize: {2}",
|
||||||
|
kernelModuleFailure.ReportCode,
|
||||||
|
kernelModuleFailure.DriverBaseAddress,
|
||||||
|
kernelModuleFailure.DriverSize);
|
||||||
|
|
||||||
|
goto end;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_logger.LogError("Invalid report code received");
|
_logger.LogError("Invalid report code received");
|
||||||
goto end;
|
goto end;
|
||||||
|
|
|
@ -53,6 +53,11 @@ void kernelmode::Driver::RunNmiCallbacks()
|
||||||
this->report_interface->ReportViolation( &report );
|
this->report_interface->ReportViolation( &report );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1. Checks that every device object has a system module to back it
|
||||||
|
* 2. Checks the IOCTL dispatch routines to ensure they lie within the module
|
||||||
|
*/
|
||||||
|
|
||||||
void kernelmode::Driver::VerifySystemModules()
|
void kernelmode::Driver::VerifySystemModules()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
|
@ -154,10 +159,6 @@ void kernelmode::Driver::CheckForHypervisor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::VerifySystemModulesIOCTLDispatchHandler()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernelmode::Driver::CheckDriverHeartbeat()
|
void kernelmode::Driver::CheckDriverHeartbeat()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ namespace kernelmode
|
||||||
void DisableProcessLoadNotifyCallbacks();
|
void DisableProcessLoadNotifyCallbacks();
|
||||||
void ValidateKPRCBThreads();
|
void ValidateKPRCBThreads();
|
||||||
void CheckForHypervisor();
|
void CheckForHypervisor();
|
||||||
void VerifySystemModulesIOCTLDispatchHandler();
|
|
||||||
void CheckDriverHeartbeat();
|
void CheckDriverHeartbeat();
|
||||||
/* todo: driver integrity check */
|
/* todo: driver integrity check */
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,6 +100,7 @@ namespace global
|
||||||
struct MODULE_VALIDATION_FAILURE
|
struct MODULE_VALIDATION_FAILURE
|
||||||
{
|
{
|
||||||
INT report_code;
|
INT report_code;
|
||||||
|
INT report_type;
|
||||||
UINT64 driver_base_address;
|
UINT64 driver_base_address;
|
||||||
UINT64 driver_size;
|
UINT64 driver_size;
|
||||||
BYTE driver_name[ 128 ];
|
BYTE driver_name[ 128 ];
|
||||||
|
|
Loading…
Reference in a new issue