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 "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(
|
||||
_In_ PIRP Irp
|
||||
)
|
||||
|
@ -10,10 +51,10 @@ NTSTATUS CopyDriverExecutableRegions(
|
|||
NTSTATUS status;
|
||||
SYSTEM_MODULES modules = { 0 };
|
||||
PRTL_MODULE_EXTENDED_INFO driver_info;
|
||||
MEMORY_BASIC_INFORMATION region_info;
|
||||
SIZE_T return_length;
|
||||
PVOID current;
|
||||
INT count = 0;
|
||||
MM_COPY_ADDRESS address;
|
||||
PVOID mapped_address;
|
||||
PHYSICAL_ADDRESS physical_address;
|
||||
SIZE_T bytes_returned;
|
||||
|
||||
status = GetSystemModuleInformation( &modules );
|
||||
|
||||
|
@ -28,33 +69,35 @@ NTSTATUS CopyDriverExecutableRegions(
|
|||
&modules
|
||||
);
|
||||
|
||||
current = driver_info->ImageBase;
|
||||
|
||||
Irp->IoStatus.Information = driver_info->ImageSize;
|
||||
|
||||
while (NT_SUCCESS( NtQueryVirtualMemory(
|
||||
NtCurrentProcess(),
|
||||
current,
|
||||
MemoryBasicInformation,
|
||||
®ion_info,
|
||||
sizeof( MEMORY_BASIC_INFORMATION ),
|
||||
&return_length
|
||||
)))
|
||||
/*
|
||||
* Map the drivers physical memory into our IO space, then copy it into
|
||||
* our IRP buffer.
|
||||
*/
|
||||
physical_address.QuadPart = MmGetPhysicalAddress( driver_info->ImageBase ).QuadPart;
|
||||
|
||||
mapped_address = MmMapIoSpace(
|
||||
physical_address,
|
||||
driver_info->ImageSize,
|
||||
MmNonCached
|
||||
);
|
||||
|
||||
if ( !mapped_address )
|
||||
{
|
||||
if ( region_info.AllocationProtect & PAGE_EXECUTE )
|
||||
{
|
||||
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;
|
||||
DEBUG_ERROR( "Failed to MmMapIoSpace " );
|
||||
goto end;
|
||||
}
|
||||
|
||||
RtlCopyMemory(
|
||||
Irp->AssociatedIrp.SystemBuffer,
|
||||
mapped_address,
|
||||
driver_info->ImageSize
|
||||
);
|
||||
|
||||
if ( !NT_SUCCESS( status ) )
|
||||
DEBUG_ERROR( "MmCopyMemory failed with status %x", status );
|
||||
|
||||
end:
|
||||
|
||||
Irp->IoStatus.Status = status;
|
||||
|
|
|
@ -9,4 +9,8 @@ NTSTATUS CopyDriverExecutableRegions(
|
|||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
NTSTATUS GetDriverImageSize(
|
||||
_In_ PIRP Irp
|
||||
);
|
||||
|
||||
#endif
|
|
@ -126,13 +126,59 @@ NTSTATUS DeviceControl(
|
|||
|
||||
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 ) )
|
||||
DEBUG_ERROR( "Failed to retrieve executable regions" );
|
||||
|
||||
break;
|
||||
|
||||
case IOCTL_REQUEST_TOTAL_MODULE_SIZE:
|
||||
|
||||
status = GetDriverImageSize( Irp );
|
||||
|
||||
if ( !NT_SUCCESS( status ) )
|
||||
DEBUG_ERROR( "Failed to retrieve driver image size" );
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
|
||||
break;
|
||||
|
|
|
@ -44,6 +44,8 @@ void global::Client::ServerSend(PVOID Buffer, SIZE_T Size, INT RequestId)
|
|||
header_extension.current_packet_number = count;
|
||||
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 ) ),
|
||||
&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() );
|
||||
}
|
||||
|
||||
void kernelmode::Driver::RunNmiCallbacks()
|
||||
VOID kernelmode::Driver::RunNmiCallbacks()
|
||||
{
|
||||
BOOLEAN status;
|
||||
DWORD bytes_returned;
|
||||
|
@ -60,7 +60,7 @@ void kernelmode::Driver::RunNmiCallbacks()
|
|||
* 2. Checks the IOCTL dispatch routines to ensure they lie within the module
|
||||
*/
|
||||
|
||||
void kernelmode::Driver::VerifySystemModules()
|
||||
VOID kernelmode::Driver::VerifySystemModules()
|
||||
{
|
||||
BOOLEAN status;
|
||||
DWORD bytes_returned;
|
||||
|
@ -145,7 +145,7 @@ void kernelmode::Driver::VerifySystemModules()
|
|||
* modules.
|
||||
*/
|
||||
|
||||
void kernelmode::Driver::QueryReportQueue()
|
||||
VOID kernelmode::Driver::QueryReportQueue()
|
||||
{
|
||||
BOOLEAN status;
|
||||
DWORD bytes_returned;
|
||||
|
@ -199,7 +199,7 @@ end:
|
|||
free( buffer );
|
||||
}
|
||||
|
||||
void kernelmode::Driver::RunCallbackReportQueue()
|
||||
VOID kernelmode::Driver::RunCallbackReportQueue()
|
||||
{
|
||||
/*TODO have some volatile flag instead */
|
||||
while ( true )
|
||||
|
@ -209,7 +209,7 @@ void kernelmode::Driver::RunCallbackReportQueue()
|
|||
}
|
||||
}
|
||||
|
||||
void kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
||||
VOID kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
||||
{
|
||||
BOOLEAN status;
|
||||
kernelmode::DRIVER_INITIATION_INFORMATION information;
|
||||
|
@ -230,7 +230,7 @@ void kernelmode::Driver::NotifyDriverOnProcessLaunch()
|
|||
LOG_ERROR( "DeviceIoControl failed with status code 0x%x", GetLastError() );
|
||||
}
|
||||
|
||||
void kernelmode::Driver::DetectSystemVirtualization()
|
||||
VOID kernelmode::Driver::DetectSystemVirtualization()
|
||||
{
|
||||
BOOLEAN status;
|
||||
HYPERVISOR_DETECTION_REPORT report;
|
||||
|
@ -259,7 +259,7 @@ void kernelmode::Driver::DetectSystemVirtualization()
|
|||
/* shutdown the application or smth lmao */
|
||||
}
|
||||
|
||||
void kernelmode::Driver::CheckHandleTableEntries()
|
||||
VOID kernelmode::Driver::CheckHandleTableEntries()
|
||||
{
|
||||
BOOLEAN status;
|
||||
DWORD bytes_returned;
|
||||
|
@ -284,22 +284,80 @@ void kernelmode::Driver::CheckHandleTableEntries()
|
|||
LOG_ERROR( "CheckHandleTableEntries failed with status %x", status );
|
||||
}
|
||||
|
||||
void kernelmode::Driver::RequestModuleExecutableRegions()
|
||||
VOID kernelmode::Driver::RequestModuleExecutableRegions()
|
||||
{
|
||||
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;
|
||||
std::shared_ptr<global::Client> report_interface;
|
||||
|
||||
void QueryReportQueue();
|
||||
void RequestTotalModuleSize();
|
||||
VOID QueryReportQueue();
|
||||
ULONG RequestTotalModuleSize();
|
||||
|
||||
public:
|
||||
|
||||
Driver(LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface );
|
||||
|
||||
void RunNmiCallbacks();
|
||||
void VerifySystemModules();
|
||||
void RunCallbackReportQueue();
|
||||
void NotifyDriverOnProcessLaunch();
|
||||
void DetectSystemVirtualization();
|
||||
void ValidateKPRCBThreads();
|
||||
void CheckDriverHeartbeat();
|
||||
void CheckHandleTableEntries();
|
||||
void RequestModuleExecutableRegions();
|
||||
VOID RunNmiCallbacks();
|
||||
VOID VerifySystemModules();
|
||||
VOID RunCallbackReportQueue();
|
||||
VOID NotifyDriverOnProcessLaunch();
|
||||
VOID DetectSystemVirtualization();
|
||||
VOID ValidateKPRCBThreads();
|
||||
VOID CheckDriverHeartbeat();
|
||||
VOID CheckHandleTableEntries();
|
||||
VOID RequestModuleExecutableRegions();
|
||||
/* todo: driver integrity check */
|
||||
};
|
||||
|
||||
|
|
|
@ -25,3 +25,13 @@ void kernelmode::KManager::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:
|
||||
KManager( LPCWSTR DriverName, std::shared_ptr<global::ThreadPool> ThreadPool, std::shared_ptr<global::Client> ReportInterface);
|
||||
|
||||
void RunNmiCallbacks();
|
||||
void VerifySystemModules();
|
||||
void MonitorCallbackReports();
|
||||
void DetectSystemVirtualization();
|
||||
VOID RunNmiCallbacks();
|
||||
VOID VerifySystemModules();
|
||||
VOID MonitorCallbackReports();
|
||||
VOID DetectSystemVirtualization();
|
||||
VOID EnumerateHandleTables();
|
||||
VOID RequestModuleExecutableRegionsForIntegrityCheck();
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
|
|||
//kmanager.MonitorCallbackReports();
|
||||
//kmanager.RunNmiCallbacks();
|
||||
//kmanager.VerifySystemModules();
|
||||
kmanager.DetectSystemVirtualization();
|
||||
kmanager.RequestModuleExecutableRegionsForIntegrityCheck();
|
||||
|
||||
//umanager.ValidateProcessModules();
|
||||
//umanager.ValidateProcessMemory();
|
||||
|
|
Loading…
Reference in a new issue