Path: blob/master/modules/post/windows/gather/enum_dirperms.rb
19758 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::Windows::Accounts78def initialize(info = {})9super(10update_info(11info,12'Name' => 'Windows Gather Directory Permissions Enumeration',13'Description' => %q{14This module enumerates directories and lists the permissions set15on found directories. Please note: if the PATH option isn't specified,16then the module will start enumerate whatever is in the target machine's17%PATH% variable.18},19'License' => MSF_LICENSE,20'Platform' => ['win'],21'SessionTypes' => ['meterpreter'],22'Author' => [23'Kx499',24'Ben Campbell',25'sinn3r'26],27'Notes' => {28'Stability' => [CRASH_SAFE],29'SideEffects' => [],30'Reliability' => []31},32'Compat' => {33'Meterpreter' => {34'Commands' => %w[35stdapi_fs_stat36]37}38}39)40)4142register_options(43[44OptString.new('PATH', [ false, 'Directory to begin search from', '']),45OptEnum.new('FILTER', [ false, 'Filter to limit results by', 'NA', [ 'NA', 'R', 'W', 'RW' ]]),46OptInt.new('DEPTH', [ true, 'Depth to drill down into subdirs, O = no limit', 0]),47]48)49end5051def enum_subdirs(perm_filter, dpath, maxdepth, token)52begin53dirs = session.fs.dir.foreach(dpath)54rescue Rex::Post::Meterpreter::RequestError55# Sometimes we cannot see the dir56dirs = []57end5859if (maxdepth >= 1) || (maxdepth < 0)60dirs.each do |d|61next if d =~ /^(\.|\.\.)$/6263realpath = dpath + '\\' + d64next unless session.fs.file.stat(realpath).directory?6566perm = check_dir_perms(realpath, token)67if perm_filter && perm && perm.include?(perm_filter)68print_status(perm + "\t" + realpath)69end70enum_subdirs(perm_filter, realpath, maxdepth - 1, token)71end72end73end7475def get_paths76p = datastore['PATH']77return [p] if !p.nil? && !p.empty?7879begin80p = cmd_exec('cmd.exe', '/c echo %PATH%')81rescue Rex::Post::Meterpreter::RequestError => e82vprint_error(e.message)83return []84end85print_status("Option 'PATH' isn't specified. Using system %PATH%")86if p.include?(';')87return p.split(';')88else89return [p]90end91end9293def get_token94print_status('Getting impersonation token...')95begin96t = get_imperstoken97rescue StandardError => e98# Failure due to timeout, access denied, etc.99t = nil100vprint_error("Error #{e.message} while using get_imperstoken()")101vprint_error(e.backtrace)102end103return t104end105106def enum_perms(perm_filter, token, depth, paths)107paths.each do |path|108next if path.empty?109110path = path.strip111112print_status("Checking directory permissions from: #{path}")113114perm = check_dir_perms(path, token)115next if perm.nil?116117# Show the permission of the parent directory118if perm_filter && perm.include?(perm_filter)119print_status(perm + "\t" + path)120end121122# call recursive function to loop through and check all sub directories123enum_subdirs(perm_filter, path, depth, token)124end125end126127def run128perm_filter = datastore['FILTER'] == 'NA' ? nil : datastore['FILTER']129130paths = get_paths131if paths.empty?132print_error('Unable to get the path')133return134end135136depth = -1137if datastore['DEPTH'] > 0138depth = datastore['DEPTH']139end140141t = get_token142143if t144print_status("Got token: #{t}...")145enum_perms(perm_filter, t, depth, paths)146else147print_error('Getting impersonation token failed')148end149end150end151152153