From be3608309755c4d6b568b1db03b1c0ab54423462 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Mon, 12 Nov 2012 18:29:56 -0600 Subject: [PATCH] Make PATH optional, also correct a filtering bug If the PATH option is not specified, the module will try to enumerate from %PATH%. Also, this commit fixes a bug in the filtering routine (basically the filtering routine didn't really work). --- modules/post/windows/gather/enum_dirperms.rb | 94 ++++++++++++++------ 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/modules/post/windows/gather/enum_dirperms.rb b/modules/post/windows/gather/enum_dirperms.rb index 313eb2fa3d..dee4a4b3c9 100644 --- a/modules/post/windows/gather/enum_dirperms.rb +++ b/modules/post/windows/gather/enum_dirperms.rb @@ -10,16 +10,20 @@ ## require 'msf/core' -require 'rex' +require 'msf/core/post/common' class Metasploit3 < Msf::Post + include Msf::Post::Common + def initialize(info={}) super(update_info(info, 'Name' => "Windows Gather Directory Permissions Enumeration", 'Description' => %q{ This module enumerates directories and lists the permissions set - on found directories. + on found directories. Please note: if the PATH option isn't specified, + then the module will start enumerate whatever is in the target machine's + %PATH% variable. }, 'License' => MSF_LICENSE, 'Version' => '$Revision$', @@ -30,7 +34,7 @@ class Metasploit3 < Msf::Post register_options( [ - OptString.new('PATH', [ true, 'Directory to begin search from', '']), + OptString.new('PATH', [ false, 'Directory to begin search from', '']), 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]), ], self.class) @@ -90,40 +94,46 @@ class Metasploit3 < Msf::Post if w["GrantedAccess"] > 0 then result << "W" end end - def enum_subdirs(dpath, maxdepth, token) + def enum_subdirs(perm_filter, dpath, maxdepth, token) filter = datastore['FILTER'] filter = nil if datastore['FILTER'] == 'NA' + dirs = session.fs.dir.foreach(dpath) + if maxdepth >= 1 or maxdepth < 0 dirs.each do|d| next if d =~ /^(\.|\.\.)$/ realpath = dpath + '\\' + d if session.fs.file.stat(realpath).directory? perm = check_dir(realpath, token) - if !filter or perm.include? filter + if perm_filter and perm.include?(perm_filter) print_status(perm + "\t" + realpath) end - enum_subdirs(realpath, maxdepth - 1,token) + enum_subdirs(perm_filter, realpath, maxdepth - 1,token) end end end end - def run - t = 0 #holds impers token + def get_paths + p = datastore['PATH'] + return [p] if not p.nil? and not p.empty? - #check and set vars - if not datastore['PATH'].empty? - path = datastore['PATH'] + begin + p = cmd_exec("cmd.exe", "/c echo %PATH%") + rescue Rex::Post::Meterpreter::RequestError => e + vprint_error(e.message) + return [] end - - depth = -1 - - if datastore['DEPTH'] > 0 - depth = datastore['DEPTH'] + print_status("Option 'PATH' isn't specified. Using system %PATH%") + if p.include?(';') + return p.split(';') + else + return [p] end + end - #get impersonation token + def get_token print_status("Getting impersonation token...") begin t = get_imperstoken() @@ -133,19 +143,51 @@ class Metasploit3 < Msf::Post vprint_error("Error #{e.message} while using get_imperstoken()") vprint_error(e.backtrace) end + return t + end - #loop through sub dirs if we have an impers token..else error - if t == 0 - print_error("Getting impersonation token failed") - else - print_status("Got token...") - print_status("Checking directory permissions from: " + path) + def enum_perms(perm_filter, token, depth, paths) + paths.each do |path| + next if path.empty? + path = path.strip + + print_status("Checking directory permissions from: #{path}") + + perm = check_dir(path, token) + if not perm.nil? + # Show the permission of the parent directory + if perm_filter and perm.include?(perm_filter) + print_status(perm + "\t" + path) + end - is_path_valid = check_dir(path, t) - if not is_path_valid.nil? #call recursive function to loop through and check all sub directories - enum_subdirs(path, depth, t) + enum_subdirs(perm_filter, path, depth, token) end end end + + def run + perm_filter = datastore['FILTER'] + perm_filter = nil if datastore['FILTER'] == 'NA' + + paths = get_paths + if paths.empty? + print_error("Unable to get the path") + return + end + + depth = -1 + if datastore['DEPTH'] > 0 + depth = datastore['DEPTH'] + end + + t = get_token + + if t == 0 + print_error("Getting impersonation token failed") + else + print_status("Got token: #{t.to_s}...") + enum_perms(perm_filter, t, depth, paths) + end + end end