This commit is contained in:
lhodges1 2023-09-08 03:49:36 +10:00
parent 4a0bdc262f
commit ea36f16703
20 changed files with 306 additions and 23 deletions

16
dblayout.drawio Normal file
View file

@ -0,0 +1,16 @@
<mxfile host="app.diagrams.net" modified="2023-09-07T11:40:22.850Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" etag="zxLKc88AkFicnfjyOcSN" version="21.7.2" type="device">
<diagram name="Page-1" id="lGA2o3BVWdjGpJAT47dB">
<mxGraphModel dx="1434" dy="790" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="3Gc6Ea0flFLE_1pXqOZ2-15" value="&lt;div style=&quot;box-sizing:border-box;width:100%;background:#e4e4e4;padding:2px;&quot;&gt;User&lt;/div&gt;&lt;table style=&quot;width:100%;font-size:1em;&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;PK&lt;/td&gt;&lt;td&gt;UserId&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FK1&lt;/td&gt;&lt;td&gt;HardwareId&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Steam64Id&lt;br&gt;Banned&lt;br&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="60" y="290" width="180" height="145" as="geometry" />
</mxCell>
<mxCell id="3Gc6Ea0flFLE_1pXqOZ2-16" value="&lt;div style=&quot;box-sizing:border-box;width:100%;background:#e4e4e4;padding:2px;&quot;&gt;User&lt;/div&gt;&lt;table style=&quot;width:100%;font-size:1em;&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;PK&lt;/td&gt;&lt;td&gt;UserId&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;FK1&lt;/td&gt;&lt;td&gt;HardwareId&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Steam64Id&lt;br&gt;Banned&lt;br&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;" style="verticalAlign=top;align=left;overflow=fill;html=1;whiteSpace=wrap;" vertex="1" parent="1">
<mxGeometry x="360" y="290" width="180" height="145" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View file

@ -97,6 +97,15 @@ VOID GetDriverSymbolicLink(
KeReleaseGuardedMutex( &driver_config.lock );
}
VOID GetDriverConfigSystemInformation(
_In_ PSYSTEM_INFORMATION* SystemInformation
)
{
KeAcquireGuardedMutex( &driver_config.lock );
*SystemInformation = &driver_config.system_information;
KeReleaseGuardedMutex( &driver_config.lock );
}
NTSTATUS RegistryPathQueryCallbackRoutine(
IN PWSTR ValueName,
IN ULONG ValueType,

View file

@ -75,6 +75,9 @@ VOID GetDriverPath(
_In_ PUNICODE_STRING DriverPath
);
VOID GetDriverConfigSystemInformation(
_In_ PSYSTEM_INFORMATION* SystemInformation
);
VOID TerminateProtectedProcessOnViolation();

View file

@ -250,6 +250,27 @@ NTSTATUS DeviceControl(
break;
case IOCTL_REQUEST_HARDWARE_INFORMATION:;
PSYSTEM_INFORMATION system_information = NULL;
GetDriverConfigSystemInformation( &system_information );
if ( system_information == NULL )
{
DEBUG_ERROR( "GetDriverConfigSystemInformation failed" );
goto end;
}
Irp->IoStatus.Information = sizeof( SYSTEM_INFORMATION );
RtlCopyMemory(
Irp->AssociatedIrp.SystemBuffer,
system_information,
sizeof( SYSTEM_INFORMATION )
);
break;
default:
DEBUG_ERROR( "Invalid IOCTL passed to driver" );
break;

View file

@ -20,6 +20,7 @@
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DETECT_ATTACHED_THREADS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2014, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_PROCESS_LOADED_MODULE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2015, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_HARDWARE_INFORMATION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2016, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _DRIVER_INITIATION_INFORMATION
{

View file

@ -0,0 +1,60 @@
using Microsoft.AspNetCore.Routing;
using MySql.Data.MySqlClient;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace server.Database
{
public class DatabaseConnection : IDisposable
{
private MySqlConnection _connection;
public DatabaseConnection()
{
string connectionString = @"server=localhost;userid=root;password=root;database=ac_db";
_connection = new MySqlConnection(connectionString);
}
public void Open()
{
try
{
_connection.Open();
}
catch(MySqlException ex)
{
throw new DatabaseConnectionException("Cannot connect to server.", ex);
}
}
public void Close()
{
try
{
_connection.Close();
}
catch(MySqlException ex)
{
throw new DatabaseConnectionException("Cannot disconnect from server.", ex);
}
}
public void Dispose()
{
Close();
}
}
public class DatabaseConnectionException : Exception
{
internal DatabaseConnectionException(string message, MySqlException inner) : base(message, inner)
{
}
public int ErrorCode => ((MySqlException)InnerException).ErrorCode;
}
}

55
server/Database/Report.cs Normal file
View file

@ -0,0 +1,55 @@
using Microsoft.Extensions.Logging;
using server.Types.Reports;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace server.Database
{
public class Report : DatabaseConnection
{
private ILogger _logger;
private enum ReportCodes
{
MODULE_VERIFICATION_CHECKSUM_FAILURE = 10,
PROCESS_THREAD_START_FAILURE = 20,
PAGE_PROTECTION_FAILURE = 30,
PATTERN_SCAN_FAILURE = 40,
NMI_CALLBACK_FAILURE = 50,
MODULE_VERIFICATION_FAILURE = 60,
MODULE_VERIFICATION_SUCCESS = 70
}
public Report(ILogger<Report> logger)
{
_logger = logger;
}
public void InsertReport<T>(T report, int reportCode)
{
if (report == null)
{
_logger.LogError("Report is null");
return;
}
switch (reportCode)
{
case (int)ReportCodes.MODULE_VERIFICATION_CHECKSUM_FAILURE:
InsertReportWithCode10((MODULE_VERIFICATION_CHECKSUM_FAILURE)Convert.ChangeType(report, typeof(MODULE_VERIFICATION_CHECKSUM_FAILURE)));
break;
default:
_logger.LogError("Unknown report code: {0}", reportCode);
break;
}
}
private void InsertReportWithCode10(MODULE_VERIFICATION_CHECKSUM_FAILURE report)
{
}
}
}

20
server/Database/User.cs Normal file
View file

@ -0,0 +1,20 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace server.Database
{
public class User : DatabaseConnection
{
private ILogger _logger;
public User(ILogger<User> logger)
{
_logger = logger;
}
}
}

View file

@ -8,6 +8,10 @@ using System.Threading.Tasks;
using Serilog;
using server;
using service;
using System.Net;
using System.Net.Sockets;
using server.Types.Reports;
using System.Runtime.InteropServices;
namespace server
{
@ -15,9 +19,9 @@ namespace server
{
private byte[] _buffer;
private int _bufferSize;
private int _messageType;
private ILogger _logger;
private PACKET_HEADER _header;
private NetworkStream _networkStream;
private enum MESSAGE_TYPE
{
@ -26,10 +30,13 @@ namespace server
MESSAGE_TYPE_RECEIVE = 3
}
public struct PACKET_HEADER
[StructLayout(LayoutKind.Sequential)]
public unsafe struct PACKET_HEADER
{
public int message_type;
public Int64 steam64_id;
public fixed char motherboard_serial_number[128];
public fixed char device_drive_0_serial[256];
};
struct REPORT_PACKET_HEADER
@ -37,19 +44,39 @@ namespace server
public int reportId;
}
public Message(byte[] buffer, int bufferSize, ILogger logger)
public Message(NetworkStream networkStream, byte[] buffer, int bufferSize, ILogger logger)
{
_networkStream = networkStream;
_buffer = buffer;
_bufferSize = bufferSize;
_logger = logger;
_header = this.GetMessageHeader();
_logger.Information("SteamID: {0}, Message type: {1}",
char[] string_1 = new char[128];
char[] string_2 = new char[256];
unsafe
{
for (int i = 0; i < 128; i++)
{
string_1[i] = _header.motherboard_serial_number[i];
}
for (int i=0;i<256;i++)
{
string_2[i] = _header.device_drive_0_serial[i];
}
}
_logger.Information("SteamID: {0}, MoboSerial: {3}, DriveSerial: {4}, Message type: {1}",
_header.steam64_id,
_header.message_type
_header.message_type,
string_1,
string_2
);
switch (_messageType)
switch (_header.message_type)
{
case (int)MESSAGE_TYPE.MESSAGE_TYPE_REPORT:
int reportId = GetReportType().reportId;
@ -75,7 +102,8 @@ namespace server
{
_logger.Information("Report id: {0}", reportId);
var openHandleFailure = Helper.BytesToStructure<Types.Reports.OPEN_HANDLE_FAILURE_REPORT>(ref _buffer, sizeof(PACKET_HEADER));
OPEN_HANDLE_FAILURE_REPORT openHandleFailure =
Helper.BytesToStructure<Types.Reports.OPEN_HANDLE_FAILURE_REPORT>(ref _buffer, sizeof(PACKET_HEADER));
_logger.Information("Report code: {0}, Process Name: {4} ProcessID: {1:x}, ThreadId: {2:x}, DesiredAccess{3:x}",
openHandleFailure.ReportCode,

View file

@ -1,4 +1,5 @@
using Serilog;
using server.Database;
using System.Net;
using System.Net.Sockets;
using System.Reflection.Metadata.Ecma335;
@ -14,6 +15,9 @@ namespace server
.WriteTo.Console()
.CreateLogger();
DatabaseConnection database = new DatabaseConnection();
database.Open();
Server server = new Server(logger);
await server.Listen();
}

View file

@ -14,8 +14,6 @@ namespace server
private IPEndPoint _ipEndPoint;
private TcpListener _tcpListener;
private ILogger _logger;
private byte[] _buffer;
private int _bufferSize;
private const int MAX_BUFFER_SIZE = 8192;
@ -23,8 +21,6 @@ namespace server
{
_ipEndPoint = new IPEndPoint(IPAddress.Any, 8888);
_tcpListener = new TcpListener(_ipEndPoint);
_buffer = new byte[MAX_BUFFER_SIZE];
_bufferSize = 0;
_logger = logger;
}
@ -39,15 +35,19 @@ namespace server
using TcpClient _client = await _tcpListener.AcceptTcpClientAsync();
NetworkStream _stream = _client.GetStream();
_bufferSize = _stream.Read(_buffer, 0, MAX_BUFFER_SIZE);
byte[] buffer = new byte[MAX_BUFFER_SIZE];
int bufferSize = 0;
NetworkStream clientStreamReference = _stream;
ThreadPool.QueueUserWorkItem(DispatchMessage);
bufferSize = _stream.Read(buffer, 0, MAX_BUFFER_SIZE);
ThreadPool.QueueUserWorkItem(state => DispatchMessage(state, clientStreamReference, buffer, bufferSize) );
}
}
private void DispatchMessage(Object? stateInfo)
private void DispatchMessage(Object? stateInfo, NetworkStream clientStreamReference, byte[] buffer, int bufferSize)
{
Message message = new Message(_buffer, _bufferSize, _logger);
Message message = new Message(clientStreamReference, buffer, bufferSize, _logger);
}
}
}

View file

@ -17,6 +17,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="MySql.Data" Version="8.1.0" />
<PackageReference Include="Serilog" Version="3.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />

View file

@ -12,6 +12,11 @@ global::Client::Client( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR P
this->pipe = std::make_shared<global::Pipe>( PipeName );
}
void global::Client::UpdateSystemInformation(global::headers::SYSTEM_INFORMATION* SystemInformation)
{
memcpy( &this->system_information, SystemInformation, sizeof( global::headers::SYSTEM_INFORMATION ) );
}
/*
* Request an item from the server
*/
@ -23,13 +28,14 @@ void global::Client::ServerReceive()
/*
* Send an item to the server
*/
void global::Client::ServerSend(PVOID Buffer, SIZE_T Size, INT RequestId)
void global::Client::ServerSend(PVOID Buffer, SIZE_T Size, INT RequestId )
{
mutex.lock();
global::headers::PIPE_PACKET_HEADER header;
header.message_type = SERVER_SEND_PACKET_ID;
header.steam64_id = TEST_STEAM_64_ID;
memcpy( &header.system_information, &this->system_information, sizeof( global::headers::SYSTEM_INFORMATION ) );
memcpy( this->send_buffer, &header, sizeof( global::headers::PIPE_PACKET_HEADER ) );
LONG total_size_of_headers = sizeof( global::headers::PIPE_PACKET_HEADER ) + sizeof( global::headers::PIPE_PACKET_SEND_EXTENSION_HEADER );

View file

@ -25,6 +25,8 @@
#define REPORT_HIDDEN_SYSTEM_THREAD 90
#define REPORT_ILLEGAL_ATTACH_PROCESS 100
#define TEST_STEAM_64_ID 123456789;
enum REPORT_CODES
{
USERMODE_MODULE = 10,
@ -50,6 +52,7 @@ namespace global
std::shared_ptr<global::ThreadPool> thread_pool;
std::shared_ptr<global::Pipe> pipe;
std::mutex mutex;
global::headers::SYSTEM_INFORMATION system_information;
byte report_buffer[ REPORT_BUFFER_SIZE ];
byte send_buffer[ SEND_BUFFER_SIZE ];
@ -58,6 +61,8 @@ namespace global
Client( std::shared_ptr<global::ThreadPool> ThreadPool, LPTSTR PipeName );
void UpdateSystemInformation( global::headers::SYSTEM_INFORMATION* SystemInformation );
/* lock buffer, attach header, copy report, send to service then clear buffer */
template <typename T>
void ReportViolation( T* Report )
@ -66,6 +71,7 @@ namespace global
global::headers::PIPE_PACKET_HEADER header;
header.message_type = REPORT_PACKET_ID;
header.steam64_id = TEST_STEAM_64_ID;
memcpy( this->report_buffer, &header, sizeof( global::headers::PIPE_PACKET_HEADER ) );
memcpy( PVOID( ( UINT64 )this->report_buffer + sizeof( global::headers::PIPE_PACKET_HEADER ) ), Report, sizeof( T ) );

View file

@ -5,6 +5,9 @@
#include "../common.h"
#include <winternl.h>
typedef BOOLEAN( NTAPI* RtlDosPathNameToNtPathName_U )(
PCWSTR DosPathName, PUNICODE_STRING NtPathName, PCWSTR* NtFileNamePart, PVOID DirectoryInfo );
kernelmode::Driver::Driver( LPCWSTR DriverName, std::shared_ptr<global::Client> ReportInterface )
{
this->driver_name = DriverName;
@ -513,9 +516,6 @@ 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;
@ -594,3 +594,33 @@ VOID kernelmode::Driver::VerifyProcessLoadedModuleExecutableRegions()
end:
CloseHandle( process_modules_handle );
}
VOID kernelmode::Driver::RequestHardwareInformation( global::headers::SYSTEM_INFORMATION* SystemInformation )
{
BOOLEAN status;
global::headers::SYSTEM_INFORMATION system_information;
DWORD bytes_returned;
status = DeviceIoControl(
this->driver_handle,
IOCTL_REQUEST_HARDWARE_INFORMATION,
NULL,
NULL,
&system_information,
sizeof( global::headers::SYSTEM_INFORMATION ),
&bytes_returned,
NULL
);
if ( status == NULL || bytes_returned == NULL)
{
LOG_ERROR( "DeviceIoControl failed with status %x", GetLastError() );
return;
}
memcpy(
SystemInformation,
&system_information,
sizeof( global::headers::SYSTEM_INFORMATION )
);
}

View file

@ -20,6 +20,7 @@
#define IOCTL_PERFORM_INTEGRITY_CHECK CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2013, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_DETECT_ATTACHED_THREADS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2014, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_VALIDATE_PROCESS_LOADED_MODULE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2015, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_REQUEST_HARDWARE_INFORMATION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x2016, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define MAX_REPORTS_PER_IRP 20
@ -55,6 +56,7 @@ namespace kernelmode
VOID PerformIntegrityCheck();
VOID CheckForAttachedThreads();
VOID VerifyProcessLoadedModuleExecutableRegions();
VOID RequestHardwareInformation( global::headers::SYSTEM_INFORMATION* SystemInformation );
};
struct DRIVER_INITIATION_INFORMATION

View file

@ -55,3 +55,8 @@ VOID kernelmode::KManager::ValidateProcessModules()
{
this->thread_pool->QueueJob( [ this ]() { this->driver_interface->VerifyProcessLoadedModuleExecutableRegions(); } );
}
VOID kernelmode::KManager::RequestHardwareInformation(global::headers::SYSTEM_INFORMATION* SystemInformation)
{
this->thread_pool->QueueJob( [ this, SystemInformation ]() { this->driver_interface->RequestHardwareInformation(SystemInformation); } );
}

View file

@ -27,6 +27,7 @@ namespace kernelmode
VOID PerformIntegrityCheck();
VOID CheckForAttachedThreads();
VOID ValidateProcessModules();
VOID RequestHardwareInformation( global::headers::SYSTEM_INFORMATION* SystemInformation );
};
}

View file

@ -23,10 +23,15 @@ DWORD WINAPI Init(HINSTANCE hinstDLL)
LPCWSTR driver_name = L"\\\\.\\DonnaAC";
std::shared_ptr<global::ThreadPool> thread_pool = std::make_shared<global::ThreadPool>( 4 );
std::shared_ptr<global::Client> report_interface = std::make_shared<global::Client>( thread_pool, pipe_name );
std::shared_ptr<global::Client> client_interface = std::make_shared<global::Client>( thread_pool, pipe_name );
usermode::UManager umanager( thread_pool, report_interface );
kernelmode::KManager kmanager( driver_name, thread_pool, report_interface);
usermode::UManager umanager( thread_pool, client_interface );
kernelmode::KManager kmanager( driver_name, thread_pool, client_interface);
global::headers::SYSTEM_INFORMATION system_information;
kmanager.RequestHardwareInformation( &system_information );
client_interface->UpdateSystemInformation( &system_information );
while ( !GetAsyncKeyState( VK_DELETE ) )
{

View file

@ -7,6 +7,9 @@
#define SERVER_REQUEST_PACKET_ID 2
#define SERVER_SEND_PACKET_ID 3
#define MOTHERBOARD_SERIAL_CODE_LENGTH 128
#define DEVICE_DRIVE_0_SERIAL_CODE_LENGTH 256
namespace global
{
class Pipe
@ -23,10 +26,17 @@ namespace global
namespace headers
{
struct SYSTEM_INFORMATION
{
CHAR motherboard_serial[ MOTHERBOARD_SERIAL_CODE_LENGTH ];
CHAR drive_0_serial[ DEVICE_DRIVE_0_SERIAL_CODE_LENGTH ];
};
struct PIPE_PACKET_HEADER
{
INT message_type;
UINT64 steam64_id;
SYSTEM_INFORMATION system_information;
};
struct PIPE_PACKET_REQUEST_EXTENSION_HEADER