got module integ checking working FUCK YESSS

This commit is contained in:
lhodges1 2023-09-06 02:04:06 +10:00
parent 44e5ed6232
commit 289c2bbbb1
9 changed files with 163 additions and 70 deletions

View file

@ -17,6 +17,11 @@
#define TEMP_BUFFER_POOL 'ffff'
#define DRIVER_PATH_POOL_TAG 'path'
#define POOL_TAG_INTEGRITY 'intg'
#define POOL_TAG_MODULE_MEMORY_BUF 'lolo'
#define POOL_TAG_MODULE_MEMORY_BUF_2 'leeo'
#define POOL_TAG_HASH_OBJECT 'hobj'
#define POOL_TAG_RESULTING_HASH 'hash'
#define POOL_TAG_SAVE_EX_REGIONS 'sexc'
#define POOL_DUMP_BLOCK_TAG 'dump'
#define POOL_DEBUGGER_DATA_TAG 'data'
#define PROCESS_ADDRESS_LIST_TAG 'addr'

View file

@ -66,7 +66,7 @@ VOID GetDriverPath(
)
{
KeAcquireGuardedMutex( &driver_config.lock );
RtlCopyUnicodeString( DriverPath, &driver_config.driver_path );
RtlInitUnicodeString( DriverPath, driver_config.driver_path.Buffer );
KeReleaseGuardedMutex( &driver_config.lock );
}
@ -109,47 +109,45 @@ NTSTATUS RegistryPathQueryCallbackRoutine(
UNICODE_STRING value_name;
UNICODE_STRING image_path = RTL_CONSTANT_STRING( L"ImagePath" );
UNICODE_STRING display_name = RTL_CONSTANT_STRING( L"DisplayName" );
UNICODE_STRING value;
PVOID temp_buffer;
RtlInitUnicodeString( &value_name, ValueName );
if ( RtlCompareUnicodeString(&value_name, &image_path, FALSE) == FALSE )
{
DEBUG_LOG( "Value type image path given" );
driver_config.driver_path.Buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, ValueLength, DRIVER_PATH_POOL_TAG );
driver_config.driver_path.Length = ValueLength;
driver_config.driver_path.MaximumLength = ValueLength;
temp_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, ValueLength, POOL_TAG_STRINGS );
if ( !driver_config.driver_path.Buffer )
{
DEBUG_ERROR( "Failed to allocate buffer for unicode string driver path" );
return STATUS_ABANDONED;
}
if ( !temp_buffer )
return STATUS_MEMORY_NOT_ALLOCATED;
RtlCopyMemory(
driver_config.driver_path.Buffer,
ValueData,
ValueLength
RtlCopyMemory(
temp_buffer,
ValueData,
ValueLength
);
driver_config.driver_path.Buffer = (PWCH)temp_buffer;
driver_config.driver_path.Length = ValueLength;
driver_config.driver_path.MaximumLength = ValueLength + 1;
}
if ( RtlCompareUnicodeString( &value_name, &display_name, FALSE ) == FALSE )
{
DEBUG_LOG( "Value type display name given" );
driver_config.unicode_driver_name.Buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, ValueLength, DRIVER_PATH_POOL_TAG );
driver_config.unicode_driver_name.Length = ValueLength;
driver_config.unicode_driver_name.MaximumLength = ValueLength;
temp_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, ValueLength, POOL_TAG_STRINGS );
if ( !driver_config.unicode_driver_name.Buffer )
{
DEBUG_ERROR( "Failed to allocate buffer for unicode string driver name" );
return STATUS_ABANDONED;
}
if ( !temp_buffer )
return STATUS_MEMORY_NOT_ALLOCATED;
RtlCopyMemory(
driver_config.unicode_driver_name.Buffer,
temp_buffer,
ValueData,
ValueLength
);
driver_config.unicode_driver_name.Buffer = ( PWCH )temp_buffer;
driver_config.unicode_driver_name.Length = ValueLength;
driver_config.unicode_driver_name.MaximumLength = ValueLength + 1;
}
return STATUS_SUCCESS;
@ -158,10 +156,10 @@ NTSTATUS RegistryPathQueryCallbackRoutine(
VOID FreeDriverConfigurationStringBuffers()
{
if ( driver_config.unicode_driver_name.Buffer )
ExFreePoolWithTag( driver_config.unicode_driver_name.Buffer, DRIVER_PATH_POOL_TAG );
ExFreePoolWithTag( driver_config.unicode_driver_name.Buffer, POOL_TAG_STRINGS );
if ( driver_config.driver_path.Buffer )
ExFreePoolWithTag( driver_config.driver_path.Buffer, DRIVER_PATH_POOL_TAG );
ExFreePoolWithTag( driver_config.driver_path.Buffer, POOL_TAG_STRINGS );
if (driver_config.ansi_driver_name.Buffer )
RtlFreeAnsiString( &driver_config.ansi_driver_name );

View file

@ -9,6 +9,8 @@
#define DRIVER_PATH_MAX_LENGTH 512
#define MOTHERBOARD_SERIAL_CODE_LENGTH 128
#define POOL_TAG_STRINGS 'strs'
typedef struct _SYSTEM_INFORMATION
{
CHAR motherboard_serial[ MOTHERBOARD_SERIAL_CODE_LENGTH ];

View file

@ -61,7 +61,7 @@ NTSTATUS GetModuleInformationByName(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "GetSystemModuleInformation failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
return status;
}
@ -107,8 +107,6 @@ NTSTATUS StoreModuleExecutableRegionsInBuffer(
if ( !ModuleBase || !ModuleSize )
return STATUS_INVALID_PARAMETER;
DEBUG_LOG( "Module base: %llx, size: %llx", (UINT64)ModuleBase, ModuleSize );
/*
* The reason we allocate a buffer to temporarily hold the section data is that
* we don't know the total size until after we iterate over the sections meaning
@ -165,7 +163,8 @@ NTSTATUS StoreModuleExecutableRegionsInBuffer(
{
DEBUG_ERROR( "MmCopyMemory failed with status %x", status );
ExFreePoolWithTag( *Buffer, POOL_TAG_INTEGRITY );
TerminateProtectedProcessOnViolation();
*Buffer = NULL;
//TerminateProtectedProcessOnViolation();
return status;
}
@ -183,7 +182,8 @@ NTSTATUS StoreModuleExecutableRegionsInBuffer(
{
DEBUG_ERROR( "MmCopyMemory failed with status %x", status );
ExFreePoolWithTag( *Buffer, POOL_TAG_INTEGRITY );
TerminateProtectedProcessOnViolation();
*Buffer = NULL;
//TerminateProtectedProcessOnViolation();
return status;
}
@ -220,9 +220,9 @@ NTSTATUS MapDiskImageIntoVirtualAddressSpace(
HANDLE file_handle;
OBJECT_ATTRIBUTES object_attributes;
PIO_STATUS_BLOCK pio_block;
UNICODE_STRING path = { 0 };
UNICODE_STRING path;
GetDriverPath( &path );
RtlInitUnicodeString( &path, Path->Buffer );
InitializeObjectAttributes(
&object_attributes,
@ -234,17 +234,17 @@ NTSTATUS MapDiskImageIntoVirtualAddressSpace(
status = ZwOpenFile(
&file_handle,
FILE_GENERIC_READ | SYNCHRONIZE,
FILE_GENERIC_READ,
&object_attributes,
&pio_block,
FILE_GENERIC_READ,
NULL,
NULL
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "ZwOpenFile failed with statsu %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
return status;
}
@ -254,7 +254,7 @@ NTSTATUS MapDiskImageIntoVirtualAddressSpace(
{
DEBUG_ERROR( "NTSetInformationProcess failed with status %x", status );
ZwClose( file_handle );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
return status;
}
@ -276,7 +276,8 @@ NTSTATUS MapDiskImageIntoVirtualAddressSpace(
{
DEBUG_ERROR( "ZwCreateSection failed with status %x", status );
ZwClose( file_handle );
TerminateProtectedProcessOnViolation();
*SectionHandle = NULL;
//TerminateProtectedProcessOnViolation();
return status;
}
@ -304,7 +305,8 @@ NTSTATUS MapDiskImageIntoVirtualAddressSpace(
DEBUG_ERROR( "ZwMapViewOfSection failed with status %x", status );
ZwClose( file_handle );
ZwClose( *SectionHandle );
TerminateProtectedProcessOnViolation();
*SectionHandle = NULL;
//TerminateProtectedProcessOnViolation();
return status;
}
@ -352,7 +354,7 @@ NTSTATUS ComputeHashOfBuffer(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "BCryptOpenAlogrithmProvider failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -373,7 +375,7 @@ NTSTATUS ComputeHashOfBuffer(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "BCryptGetProperty failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -401,7 +403,7 @@ NTSTATUS ComputeHashOfBuffer(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "BCryptGetProperty failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -429,7 +431,7 @@ NTSTATUS ComputeHashOfBuffer(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "BCryptCreateHash failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -447,7 +449,7 @@ NTSTATUS ComputeHashOfBuffer(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "BCryptHashData failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -465,7 +467,7 @@ NTSTATUS ComputeHashOfBuffer(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "BCryptFinishHash failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
return status;
}
@ -528,7 +530,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "MapDiskImageIntoVirtualAddressSpace failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
return status;
}
@ -542,7 +544,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "StoreModuleExecutableRegionsInBuffer failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -557,7 +559,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "GetModuleInformationByName failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -571,7 +573,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "StoreModuleExecutableRegionsInBuffe failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -584,7 +586,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !disk_base || !memory_base || !disk_buffer || !in_memory_buffer )
{
DEBUG_ERROR( "buffers are null lmao" );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -592,7 +594,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
{
/* report or bug check etc. */
DEBUG_LOG( "Executable section size differs, LOL" );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -606,7 +608,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "ComputeHashOfBuffer failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -620,14 +622,14 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "ComputeHashOfBuffer failed with status %x", status );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
if ( memory_text_hash_size != disk_text_hash_size )
{
DEBUG_ERROR( "Error with the hash algorithm, hash sizes are different." );
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -641,7 +643,7 @@ NTSTATUS VerifyInMemoryImageVsDiskImage(
{
/* report etc. bug check etc. */
DEBUG_ERROR( "Text sections are different from each other!!");
TerminateProtectedProcessOnViolation();
//TerminateProtectedProcessOnViolation();
goto end;
}
@ -652,7 +654,8 @@ end:
if ( section_handle != NULL )
ZwClose( section_handle );
ZwUnmapViewOfSection( ZwCurrentProcess(), section );
if ( section )
ZwUnmapViewOfSection( ZwCurrentProcess(), section );
if ( disk_buffer )
ExFreePoolWithTag( disk_buffer, POOL_TAG_INTEGRITY );
@ -921,16 +924,13 @@ NTSTATUS ValidateProcessLoadedModule(
ULONG disk_hash_size = NULL;
SIZE_T bytes_written = NULL;
UNICODE_STRING module_path;
HANDLE section_handle = NULL;
PVOID section = NULL;
ULONG section_size = NULL;
module_info = ( PPROCESS_MODULE_INFORMATION )Irp->AssociatedIrp.SystemBuffer;
GetProtectedProcessEProcess( &process );
in_memory_buffer = ExAllocatePool2( POOL_FLAG_NON_PAGED, module_info->module_size, POOL_TAG_INTEGRITY );
if ( !in_memory_buffer )
return STATUS_ABANDONED;
KeStackAttachProcess( process, &apc_state );
status = StoreModuleExecutableRegionsInBuffer(
@ -964,6 +964,59 @@ NTSTATUS ValidateProcessLoadedModule(
RtlInitUnicodeString( &module_path, &module_info->module_path );
status = MapDiskImageIntoVirtualAddressSpace(
&section_handle,
&section,
&module_path,
&section_size
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "MapDiskImageIntoVirtualAddressSpace failed with status %x", status );
goto end;
}
status = StoreModuleExecutableRegionsInBuffer(
&disk_buffer,
section,
section_size,
&bytes_written
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "StoreModuleExecutableRegionsInbuffer 2 failed with status %x", status );
goto end;
}
status = ComputeHashOfBuffer(
disk_buffer,
bytes_written,
&disk_hash,
&disk_hash_size
);
if ( !NT_SUCCESS( status ) )
{
DEBUG_ERROR( "ComputeHashOfBuffer 2 failed with status %x", status );
goto end;
}
if ( !in_memory_hash || !disk_hash )
goto end;
bstatus = RtlEqualMemory( in_memory_hash, disk_hash, in_memory_hash_size );
if ( bstatus == TRUE )
{
DEBUG_LOG( "ALL BYTES EQUAL!" );
}
else
{
DEBUG_ERROR( "BBTES NOT EQUAL!!" );
}
validation_result.is_module_valid = TRUE;
Irp->IoStatus.Information = sizeof( PROCESS_MODULE_VALIDATION_RESULT );
@ -974,6 +1027,12 @@ NTSTATUS ValidateProcessLoadedModule(
);
end:
if ( section_handle != NULL )
ZwClose( section_handle );
if ( section )
ZwUnmapViewOfSection( ZwCurrentProcess(), section );
if ( in_memory_buffer )
ExFreePoolWithTag( in_memory_buffer, POOL_TAG_INTEGRITY );
@ -981,4 +1040,11 @@ end:
if ( in_memory_hash )
ExFreePoolWithTag( in_memory_hash, POOL_TAG_INTEGRITY );
if ( disk_buffer )
ExFreePoolWithTag( disk_buffer, POOL_TAG_INTEGRITY );
if ( disk_hash )
ExFreePoolWithTag( disk_hash, POOL_TAG_INTEGRITY );
return status;
}

View file

@ -115,10 +115,10 @@ NTSTATUS DeviceControl(
goto end;
}
status = InitiateDriverCallbacks();
//status = InitiateDriverCallbacks();
if ( !NT_SUCCESS( status ) )
DEBUG_ERROR( "InitiateDriverCallbacks failed with status %x", status );
//if ( !NT_SUCCESS( status ) )
// DEBUG_ERROR( "InitiateDriverCallbacks failed with status %x", status );
break;
@ -207,7 +207,7 @@ NTSTATUS DeviceControl(
case IOCTL_NOTIFY_DRIVER_ON_PROCESS_TERMINATION:
ClearProcessConfigOnProcessTermination();
UnregisterCallbacksOnProcessTermination();
//UnregisterCallbacksOnProcessTermination();
break;
@ -270,7 +270,7 @@ NTSTATUS DeviceClose(
FreeGlobalReportQueueObjects();
ClearProcessConfigOnProcessTermination();
UnregisterCallbacksOnProcessTermination();
//UnregisterCallbacksOnProcessTermination();
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return Irp->IoStatus.Status;

View file

@ -3,6 +3,7 @@
#include <iostream>
#include "../common.h"
#include <winternl.h>
kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface )
{
@ -512,6 +513,9 @@ VOID kernelmode::Driver::CheckDriverHeartbeat()
}
typedef BOOLEAN( NTAPI* RtlDosPathNameToNtPathName_U )(
PCWSTR DosPathName, PUNICODE_STRING NtPathName, PCWSTR* NtFileNamePart, PVOID DirectoryInfo );
VOID kernelmode::Driver::VerifyProcessLoadedModuleExecutableRegions()
{
HANDLE process_modules_handle;
@ -520,6 +524,11 @@ VOID kernelmode::Driver::VerifyProcessLoadedModuleExecutableRegions()
PROCESS_MODULE_INFORMATION module_information;
PROCESS_MODULE_VALIDATION_RESULT validation_result;
DWORD bytes_returned;
RtlDosPathNameToNtPathName_U pRtlDosPathNameToNtPathName_U = NULL;
UNICODE_STRING nt_path_name;
pRtlDosPathNameToNtPathName_U = ( RtlDosPathNameToNtPathName_U )
GetProcAddress( GetModuleHandle( L"ntdll.dll" ), "RtlDosPathNameToNtPathName_U" );
process_modules_handle = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetCurrentProcessId() );
@ -541,7 +550,15 @@ VOID kernelmode::Driver::VerifyProcessLoadedModuleExecutableRegions()
{
module_information.module_base = module_entry.modBaseAddr;
module_information.module_size = module_entry.modBaseSize;
memcpy( module_information.module_path, module_entry.szExePath, MAX_MODULE_PATH );
( *pRtlDosPathNameToNtPathName_U )(
module_entry.szExePath,
&nt_path_name,
NULL,
NULL
);
memcpy( module_information.module_path, nt_path_name.Buffer, MAX_MODULE_PATH );
status = DeviceIoControl(
this->driver_handle,

View file

@ -30,9 +30,10 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
while ( !GetAsyncKeyState( VK_DELETE ) )
{
kmanager.ValidateProcessModules();
kmanager.PerformIntegrityCheck();
std::this_thread::sleep_for( std::chrono::milliseconds( 10000 ) );
std::this_thread::sleep_for( std::chrono::milliseconds( 5000 ) );
kmanager.ValidateProcessModules();
}
fclose( stdout );

View file

@ -5,8 +5,10 @@
usermode::Imports::Imports()
{
NtQueryInformationThread = nullptr;
RtlDosPathNameToNtPathName_U = nullptr;
this->ImportMap[ "NtQueryInformationThread" ] = NtQueryInformationThread;
this->ImportMap[ "RtlDosPathNameToNtPathName_U" ] = RtlDosPathNameToNtPathName_U;
std::map<std::string, void*>::iterator it;

View file

@ -7,6 +7,7 @@
#include <string>
typedef NTSTATUS( WINAPI* pNtQueryInformationThread )( HANDLE, LONG, PVOID, ULONG, PULONG );
typedef BOOLEAN( NTAPI pRtlDosPathNameToNtPathName_U( PCWSTR, PVOID, PCWSTR*, PVOID ));
namespace usermode
{
@ -17,6 +18,7 @@ namespace usermode
void* NtQueryInformationThread;
void* NtQueryVirtualMemory;
void* RtlDosPathNameToNtPathName_U;
Imports();
};