mirror of
https://github.com/donnaskiez/ac.git
synced 2024-11-21 22:24:08 +01:00
working on integrity checks
This commit is contained in:
parent
77525c1ccf
commit
af62e47949
9 changed files with 223 additions and 58 deletions
|
@ -3,6 +3,47 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* note: this can be put into its own function wihtout an IRP as argument then it can be used
|
||||||
|
* in both the get driver image ioctl handler and the CopyDriverExecvutableRegions func
|
||||||
|
*/
|
||||||
|
NTSTATUS GetDriverImageSize(
|
||||||
|
_In_ PIRP Irp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
NTSTATUS status;
|
||||||
|
SYSTEM_MODULES modules = { 0 };
|
||||||
|
PRTL_MODULE_EXTENDED_INFO driver_info;
|
||||||
|
|
||||||
|
status = GetSystemModuleInformation( &modules );
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
{
|
||||||
|
DEBUG_ERROR( "GetSystemModuleInformation failed with status %x", status );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
driver_info = FindSystemModuleByName(
|
||||||
|
"driver.sys",
|
||||||
|
&modules
|
||||||
|
);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = sizeof( ULONG );
|
||||||
|
RtlCopyMemory( Irp->AssociatedIrp.SystemBuffer, &driver_info->ImageSize, sizeof( ULONG ) );
|
||||||
|
|
||||||
|
if (modules.address )
|
||||||
|
ExFreePoolWithTag( modules.address, SYSTEM_MODULES_POOL );
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Instead of copying pages with the EDB (execute disable bit) not set, I am simply
|
||||||
|
* copying the entire image which we can then send to the server which can then can
|
||||||
|
* analyse the executable sections from there. Until I find a better way to enumerate
|
||||||
|
* kernel memory without having to walk the pages tables to check the EDB bit this
|
||||||
|
* is how I will be doing it. c:
|
||||||
|
*/
|
||||||
NTSTATUS CopyDriverExecutableRegions(
|
NTSTATUS CopyDriverExecutableRegions(
|
||||||
_In_ PIRP Irp
|
_In_ PIRP Irp
|
||||||
)
|
)
|
||||||
|
@ -10,10 +51,10 @@ NTSTATUS CopyDriverExecutableRegions(
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SYSTEM_MODULES modules = { 0 };
|
SYSTEM_MODULES modules = { 0 };
|
||||||
PRTL_MODULE_EXTENDED_INFO driver_info;
|
PRTL_MODULE_EXTENDED_INFO driver_info;
|
||||||
MEMORY_BASIC_INFORMATION region_info;
|
MM_COPY_ADDRESS address;
|
||||||
SIZE_T return_length;
|
PVOID mapped_address;
|
||||||
PVOID current;
|
PHYSICAL_ADDRESS physical_address;
|
||||||
INT count = 0;
|
SIZE_T bytes_returned;
|
||||||
|
|
||||||
status = GetSystemModuleInformation( &modules );
|
status = GetSystemModuleInformation( &modules );
|
||||||
|
|
||||||
|
@ -28,33 +69,35 @@ NTSTATUS CopyDriverExecutableRegions(
|
||||||
&modules
|
&modules
|
||||||
);
|
);
|
||||||
|
|
||||||
current = driver_info->ImageBase;
|
|
||||||
|
|
||||||
Irp->IoStatus.Information = driver_info->ImageSize;
|
Irp->IoStatus.Information = driver_info->ImageSize;
|
||||||
|
|
||||||
while (NT_SUCCESS( NtQueryVirtualMemory(
|
/*
|
||||||
NtCurrentProcess(),
|
* Map the drivers physical memory into our IO space, then copy it into
|
||||||
current,
|
* our IRP buffer.
|
||||||
MemoryBasicInformation,
|
*/
|
||||||
®ion_info,
|
physical_address.QuadPart = MmGetPhysicalAddress( driver_info->ImageBase ).QuadPart;
|
||||||
sizeof( MEMORY_BASIC_INFORMATION ),
|
|
||||||
&return_length
|
mapped_address = MmMapIoSpace(
|
||||||
)))
|
physical_address,
|
||||||
|
driver_info->ImageSize,
|
||||||
|
MmNonCached
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !mapped_address )
|
||||||
{
|
{
|
||||||
if ( region_info.AllocationProtect & PAGE_EXECUTE )
|
DEBUG_ERROR( "Failed to MmMapIoSpace " );
|
||||||
{
|
goto end;
|
||||||
RtlCopyMemory(
|
|
||||||
(UINT64)Irp->AssociatedIrp.SystemBuffer + count * region_info.RegionSize,
|
|
||||||
current,
|
|
||||||
region_info.RegionSize
|
|
||||||
);
|
|
||||||
|
|
||||||
DEBUG_LOG( "Copied region at address: %p, with protect: %lx", current, region_info.AllocationProtect );
|
|
||||||
}
|
|
||||||
|
|
||||||
current = (UINT64)current + region_info.RegionSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlCopyMemory(
|
||||||
|
Irp->AssociatedIrp.SystemBuffer,
|
||||||
|
mapped_address,
|
||||||
|
driver_info->ImageSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
DEBUG_ERROR( "MmCopyMemory failed with status %x", status );
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
||||||
Irp->IoStatus.Status = status;
|
Irp->IoStatus.Status = status;
|
||||||
|
|
|
@ -9,4 +9,8 @@ NTSTATUS CopyDriverExecutableRegions(
|
||||||
_In_ PIRP Irp
|
_In_ PIRP Irp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS GetDriverImageSize(
|
||||||
|
_In_ PIRP Irp
|
||||||
|
);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -126,13 +126,59 @@ NTSTATUS DeviceControl(
|
||||||
|
|
||||||
case IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS:
|
case IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS:
|
||||||
|
|
||||||
status = CopyDriverExecutableRegions( Irp );
|
status = PsCreateSystemThread(
|
||||||
|
&handle,
|
||||||
|
PROCESS_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
CopyDriverExecutableRegions,
|
||||||
|
Irp
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
{
|
||||||
|
DEBUG_ERROR( "Failed to start system thread to get executable regions" );
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = ObReferenceObjectByHandle(
|
||||||
|
handle,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
*PsThreadType,
|
||||||
|
KernelMode,
|
||||||
|
&thread,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
{
|
||||||
|
DEBUG_ERROR( "ObReferenceObjectbyhandle failed with status %lx", status );
|
||||||
|
ZwClose( handle );
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
KeWaitForSingleObject( thread, Executive, KernelMode, FALSE, NULL );;
|
||||||
|
|
||||||
|
ZwClose( handle );
|
||||||
|
ObDereferenceObject( thread );
|
||||||
|
|
||||||
if ( !NT_SUCCESS( status ) )
|
if ( !NT_SUCCESS( status ) )
|
||||||
DEBUG_ERROR( "Failed to retrieve executable regions" );
|
DEBUG_ERROR( "Failed to retrieve executable regions" );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IOCTL_REQUEST_TOTAL_MODULE_SIZE:
|
||||||
|
|
||||||
|
status = GetDriverImageSize( Irp );
|
||||||
|
|
||||||
|
if ( !NT_SUCCESS( status ) )
|
||||||
|
DEBUG_ERROR( "Failed to retrieve driver image size" );
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -44,6 +44,8 @@ void global::Client::ServerSend(PVOID Buffer, SIZE_T Size, INT RequestId)
|
||||||
header_extension.current_packet_number = count;
|
header_extension.current_packet_number = count;
|
||||||
header_extension.packet_size = ( count + 1 ) == total_packets ? remaining_bytes : SEND_BUFFER_SIZE;
|
header_extension.packet_size = ( count + 1 ) == total_packets ? remaining_bytes : SEND_BUFFER_SIZE;
|
||||||
|
|
||||||
|
LOG_INFO( "current packet number: %lx, packet size: %lx", header_extension.current_packet_number, header_extension.packet_size );
|
||||||
|
|
||||||
memcpy( PVOID( ( UINT64 )this->send_buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ),
|
memcpy( PVOID( ( UINT64 )this->send_buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ),
|
||||||
&header_extension, sizeof(global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER));
|
&header_extension, sizeof(global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER));
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr<global::Client>
|
||||||
LOG_ERROR( "Failed to open handle to driver with status 0x%x", GetLastError() );
|
LOG_ERROR( "Failed to open handle to driver with status 0x%x", GetLastError() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::RunNmiCallbacks()
|
VOID kernelmode::Driver::RunNmiCallbacks()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
DWORD bytes_returned;
|
DWORD bytes_returned;
|
||||||
|
@ -60,7 +60,7 @@ void kernelmode::Driver::RunNmiCallbacks()
|
||||||
* 2. Checks the IOCTL dispatch routines to ensure they lie within the module
|
* 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;
|
||||||
DWORD bytes_returned;
|
DWORD bytes_returned;
|
||||||
|
@ -145,7 +145,7 @@ void kernelmode::Driver::VerifySystemModules()
|
||||||
* modules.
|
* modules.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void kernelmode::Driver::QueryReportQueue()
|
VOID kernelmode::Driver::QueryReportQueue()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
DWORD bytes_returned;
|
DWORD bytes_returned;
|
||||||
|
@ -199,7 +199,7 @@ end:
|
||||||
free( buffer );
|
free( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::RunCallbackReportQueue()
|
VOID kernelmode::Driver::RunCallbackReportQueue()
|
||||||
{
|
{
|
||||||
/*TODO have some volatile flag instead */
|
/*TODO have some volatile flag instead */
|
||||||
while ( true )
|
while ( true )
|
||||||
|
@ -209,7 +209,7 @@ void kernelmode::Driver::RunCallbackReportQueue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
VOID kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
kernelmode::DRIVER_INITIATION_INFORMATION information;
|
kernelmode::DRIVER_INITIATION_INFORMATION information;
|
||||||
|
@ -230,7 +230,7 @@ void kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
||||||
LOG_ERROR( "DeviceIoControl failed with status code 0x%x", GetLastError() );
|
LOG_ERROR( "DeviceIoControl failed with status code 0x%x", GetLastError() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::DetectSystemVirtualization()
|
VOID kernelmode::Driver::DetectSystemVirtualization()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
HYPERVISOR_DETECTION_REPORT report;
|
HYPERVISOR_DETECTION_REPORT report;
|
||||||
|
@ -259,7 +259,7 @@ void kernelmode::Driver::DetectSystemVirtualization()
|
||||||
/* shutdown the application or smth lmao */
|
/* shutdown the application or smth lmao */
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::CheckHandleTableEntries()
|
VOID kernelmode::Driver::CheckHandleTableEntries()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
DWORD bytes_returned;
|
DWORD bytes_returned;
|
||||||
|
@ -284,22 +284,80 @@ void kernelmode::Driver::CheckHandleTableEntries()
|
||||||
LOG_ERROR( "CheckHandleTableEntries failed with status %x", status );
|
LOG_ERROR( "CheckHandleTableEntries failed with status %x", status );
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::RequestModuleExecutableRegions()
|
VOID kernelmode::Driver::RequestModuleExecutableRegions()
|
||||||
{
|
{
|
||||||
BOOLEAN status;
|
BOOLEAN status;
|
||||||
|
DWORD bytes_returned;
|
||||||
|
ULONG module_size;
|
||||||
|
PVOID buffer;
|
||||||
|
|
||||||
|
module_size = this->RequestTotalModuleSize();
|
||||||
|
|
||||||
|
if ( module_size == NULL )
|
||||||
|
{
|
||||||
|
LOG_ERROR( "RequestTotalModuleSize failed lolz" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO( "module size: %lx", module_size );
|
||||||
|
|
||||||
|
buffer = malloc( module_size );
|
||||||
|
|
||||||
|
if ( !buffer )
|
||||||
|
return;
|
||||||
|
|
||||||
|
status = DeviceIoControl(
|
||||||
|
this->driver_handle,
|
||||||
|
IOCTL_RETRIEVE_MODULE_EXECUTABLE_REGIONS,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
buffer,
|
||||||
|
module_size,
|
||||||
|
&bytes_returned,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( status == NULL )
|
||||||
|
{
|
||||||
|
LOG_ERROR( "failed to retrieve module executable regions lozl %x", GetLastError() );
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO( "bytes returned: %lx", bytes_returned );
|
||||||
|
|
||||||
|
end:
|
||||||
|
free( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::RequestTotalModuleSize()
|
ULONG kernelmode::Driver::RequestTotalModuleSize()
|
||||||
|
{
|
||||||
|
BOOLEAN status;
|
||||||
|
DWORD bytes_returned;
|
||||||
|
ULONG module_size;
|
||||||
|
|
||||||
|
status = DeviceIoControl(
|
||||||
|
this->driver_handle,
|
||||||
|
IOCTL_REQUEST_TOTAL_MODULE_SIZE,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&module_size,
|
||||||
|
sizeof(ULONG),
|
||||||
|
&bytes_returned,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( status == NULL )
|
||||||
|
LOG_ERROR( "CheckHandleTableEntries failed with status %x", status );
|
||||||
|
|
||||||
|
return module_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID kernelmode::Driver::ValidateKPRCBThreads()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernelmode::Driver::ValidateKPRCBThreads()
|
VOID kernelmode::Driver::CheckDriverHeartbeat()
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernelmode::Driver::CheckDriverHeartbeat()
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,22 +27,22 @@ namespace kernelmode
|
||||||
LPCWSTR driver_name;
|
LPCWSTR driver_name;
|
||||||
std::shared_ptr<global::Client> report_interface;
|
std::shared_ptr<global::Client> report_interface;
|
||||||
|
|
||||||
void QueryReportQueue();
|
VOID QueryReportQueue();
|
||||||
void RequestTotalModuleSize();
|
ULONG RequestTotalModuleSize();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Driver(LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface );
|
Driver(LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface );
|
||||||
|
|
||||||
void RunNmiCallbacks();
|
VOID RunNmiCallbacks();
|
||||||
void VerifySystemModules();
|
VOID VerifySystemModules();
|
||||||
void RunCallbackReportQueue();
|
VOID RunCallbackReportQueue();
|
||||||
void NotifyDriverOnProcessLaunch();
|
VOID NotifyDriverOnProcessLaunch();
|
||||||
void DetectSystemVirtualization();
|
VOID DetectSystemVirtualization();
|
||||||
void ValidateKPRCBThreads();
|
VOID ValidateKPRCBThreads();
|
||||||
void CheckDriverHeartbeat();
|
VOID CheckDriverHeartbeat();
|
||||||
void CheckHandleTableEntries();
|
VOID CheckHandleTableEntries();
|
||||||
void RequestModuleExecutableRegions();
|
VOID RequestModuleExecutableRegions();
|
||||||
/* todo: driver integrity check */
|
/* todo: driver integrity check */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,3 +25,13 @@ void kernelmode::KManager::DetectSystemVirtualization()
|
||||||
{
|
{
|
||||||
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->DetectSystemVirtualization(); } );
|
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->DetectSystemVirtualization(); } );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kernelmode::KManager::EnumerateHandleTables()
|
||||||
|
{
|
||||||
|
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->CheckHandleTableEntries(); } );
|
||||||
|
}
|
||||||
|
|
||||||
|
void kernelmode::KManager::RequestModuleExecutableRegionsForIntegrityCheck()
|
||||||
|
{
|
||||||
|
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->RequestModuleExecutableRegions(); } );
|
||||||
|
}
|
|
@ -17,10 +17,12 @@ namespace kernelmode
|
||||||
public:
|
public:
|
||||||
KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface);
|
KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface);
|
||||||
|
|
||||||
void RunNmiCallbacks();
|
VOID RunNmiCallbacks();
|
||||||
void VerifySystemModules();
|
VOID VerifySystemModules();
|
||||||
void MonitorCallbackReports();
|
VOID MonitorCallbackReports();
|
||||||
void DetectSystemVirtualization();
|
VOID DetectSystemVirtualization();
|
||||||
|
VOID EnumerateHandleTables();
|
||||||
|
VOID RequestModuleExecutableRegionsForIntegrityCheck();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
|
||||||
//kmanager.MonitorCallbackReports();
|
//kmanager.MonitorCallbackReports();
|
||||||
//kmanager.RunNmiCallbacks();
|
//kmanager.RunNmiCallbacks();
|
||||||
//kmanager.VerifySystemModules();
|
//kmanager.VerifySystemModules();
|
||||||
kmanager.DetectSystemVirtualization();
|
kmanager.RequestModuleExecutableRegionsForIntegrityCheck();
|
||||||
|
|
||||||
//umanager.ValidateProcessModules();
|
//umanager.ValidateProcessModules();
|
||||||
//umanager.ValidateProcessMemory();
|
//umanager.ValidateProcessMemory();
|
||||||
|
|
Loading…
Reference in a new issue