From f7f7c451d3fc0abedcae00d5259b266d15baf102 Mon Sep 17 00:00:00 2001 From: Vlatko Kosturjak Date: Thu, 15 Nov 2012 22:35:35 +0100 Subject: [PATCH] Initial import of Nexpose aux scripts --- .../scanner/nexpose/nexpose_api_login.rb | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 modules/auxiliary/scanner/nexpose/nexpose_api_login.rb diff --git a/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb b/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb new file mode 100644 index 0000000000..820ef0c469 --- /dev/null +++ b/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb @@ -0,0 +1,123 @@ +## +# nexpose_api_login.rb +## + +## +# This file is part of the Metasploit Framework and may be subject to +# redistribution and commercial restrictions. Please see the Metasploit +# web site for more information on licensing and terms of use. +# http://metasploit.com/ +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'NeXpose API Interface Login Utility', + 'Description' => 'This module simply attempts to login to a NeXpose API interface using a specific user/pass.', + 'Author' => [ 'Vlatko Kosturjak ' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(3780), + OptString.new('URI', [true, "URI for NeXpose API. Default is /api/1.1/xml", "/api/1.1/xml"]), + OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false]) + ], self.class) + + register_advanced_options( + [ + OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true]) + ], self.class) + end + + def run_host(ip) + begin + res = send_request_cgi({ + 'uri' => "#{datastore['URI']}", + 'method' => 'GET' + }, 25) + http_fingerprint({ :response => res }) + rescue ::Rex::ConnectionError => e + vprint_error("#{msg} #{datastore['URI']} - #{e}") + return + end + + if not res + vprint_error("#{msg} #{datastore['URI']} - No response") + return + end + if res.code != 200 + vprint_error("#{msg} - did not get 200 for API XML interface") + return + end + + each_user_pass { |user, pass| + do_login(user, pass) + } + end + + def do_login(user='nxadmin', pass='nxadmin') + vprint_status("#{msg} - Trying username:'#{user}' with password:'#{pass}'") + headers = { + 'Content-Type' => 'text/xml' + } + data = '' + begin + res = send_request_cgi({ + 'encode' => true, + 'uri' => "#{datastore['URI']}", + 'method' => 'POST', + 'headers' => headers, + 'data' => data + }, 25) + + rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT + print_error("#{msg} HTTP Connection Failed, Aborting") + return :abort + end + + if not res + print_error("#{msg} HTTP Connection Error - res, Aborting") + return :abort + end + + if res.code != 200 + vprint_error("#{msg} FAILED LOGIN. '#{user}' : '#{pass}'") + return :skip_pass + end + + if res.code == 200 + if res.body =~ /LoginResponse.*success="1"/ + print_good("#{msg} SUCCESSFUL LOGIN. '#{user}' : '#{pass}'") + + report_hash = { + :host => datastore['RHOST'], + :port => datastore['RPORT'], + :sname => 'nexpose', + :user => user, + :pass => pass, + :active => true, + :type => 'password'} + + report_auth_info(report_hash) + return :next_user + end + end + vprint_error("#{msg} FAILED LOGIN. '#{user}' : '#{pass}'") + return :skip_pass + end + + def msg + "#{vhost}:#{rport} NeXpose API -" + end +end