add shell support for registry methdos, thanks kernelsmith!
git-svn-id: file:///home/svn/framework3/trunk@11784 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
72ffa260c2
commit
e71cd9b524
|
@ -0,0 +1,139 @@
|
|||
|
||||
module Msf
|
||||
class Post
|
||||
module Windows
|
||||
|
||||
module CliParse
|
||||
#
|
||||
# Parses output of some windows CLI commands and returns hash with the keys/vals detected
|
||||
# if the item has multiple values, they will all be returned in the val separated by commas
|
||||
#
|
||||
#--- sc.exe example (somewhat contrived)
|
||||
# SERVICE_NAME: dumbservice
|
||||
# DISPLAY_NAME: KernelSmith Dumb Service - User-mode
|
||||
# TYPE : 20 WIN32_SHARE_PROCESS
|
||||
# STATE : 4 RUNNING
|
||||
# (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
|
||||
# START_TYPE : 2 AUTO_START
|
||||
# BINARY_PATH_NAME : C:\Windows\system32\svchost.exe -k LocalSystemNetworkRestricted
|
||||
# DEPENDENCIES : PlugPlay
|
||||
# : DumberService
|
||||
# SERVICE_START_NAME : LocalSystem
|
||||
# PID : 368
|
||||
# FLAGS :
|
||||
#--- END sc.exe example
|
||||
#
|
||||
# Example would return:
|
||||
# {
|
||||
# 'SERVICE_NAME' => "dumbservice",
|
||||
# 'DISPLAY_NAME' => "KernelSmith Dumb Service - User-mod",
|
||||
# 'STATE' => "4 RUNNING",
|
||||
# 'START_TYPE' => "2 AUTO_START",
|
||||
# 'BINARY_PATH_NAME' => "C:\Windows\system32\svchost.exe -k LocalSystemNetworkRestricted",
|
||||
# 'DEPENDENCIES' => "PlugPlay,DumberService"
|
||||
# <...etc...>
|
||||
# }
|
||||
#
|
||||
def win_parse_results(str)
|
||||
#print_status "Parsing results string: #{str}" if $blab
|
||||
tip = false
|
||||
hashish = Hash.new(nil)
|
||||
lastkey = nil
|
||||
str.each_line do |line|
|
||||
line.chomp!
|
||||
line.gsub!("\t",' ') # lose any tabs
|
||||
if (tip == true && line =~ /^ + :/)
|
||||
# then this is probably a continuation of the previous, let's append to previous
|
||||
# NOTE: this will NOT pickup the (NOT_STOPPABLE, NOT_PAUSABLE), see next, but it
|
||||
# will pickup when there's multiple dependencies
|
||||
#print_status "Caught line continuation with :" if $blab
|
||||
arr = line.scan(/\w+/)
|
||||
val = arr.join(',') # join with commas, tho there is probably only one item in arr
|
||||
hashish[lastkey] << ",#{val}" # append to old val with preceding ','
|
||||
# if that's confusing, maybe: hashish[lastkey] = "#{hashish[lastkey]},#{val}"
|
||||
tip = false
|
||||
elsif (tip == true && line =~ /^ + \(/)
|
||||
# then this is probably a continuation of the previous, let's append to previous
|
||||
# NOTE: this WILL pickup (NOT_STOPPABLE, NOT_PAUSABLE) etc
|
||||
#print_status "Caught line continuation with (" if $blab
|
||||
arr = line.scan(/\w+/) # put each "word" into an array
|
||||
val = arr.join(',') # join back together with commas in case comma wasn't the sep
|
||||
hashish[lastkey] << ",#{val}" # append to old val with preceding ','
|
||||
# if that's confusing, maybe: hashish[lastkey] = "#{hashish[lastkey]},#{val}"
|
||||
tip = false
|
||||
elsif line =~ /^ *[A-Z]+[_]*[A-Z]+.*:/
|
||||
tip = true
|
||||
arr = line.split(':')
|
||||
#print_status "Array split is #{arr.inspect}" if $blab
|
||||
k = arr[0].strip
|
||||
# grab all remaining fields for hash val in case ':' present in val
|
||||
v = arr[1..-1].join(':').strip
|
||||
# now add this entry to the hash
|
||||
#print_status "Adding the following hash entry: #{k} => #{v}" if $blab
|
||||
hashish[k] = v
|
||||
lastkey = k
|
||||
end
|
||||
end
|
||||
return hashish
|
||||
end
|
||||
|
||||
#
|
||||
# Parses error output of some windows CLI commands and returns hash with the keys/vals detected
|
||||
# always returns hash as follows but :errval only comes back from sc.exe using 'FAILED' keyword
|
||||
#
|
||||
# Note, most of the time the :errval will be nil, it's not usually provided
|
||||
#
|
||||
#
|
||||
#--- sc.exe error example
|
||||
# [SC] EnumQueryServicesStatus:OpenService FAILED 1060:
|
||||
#
|
||||
# The specified service does not exist as an installed service.
|
||||
#--- END sc.exe error example
|
||||
# returns:
|
||||
# {
|
||||
# :error => "The specified service does not exist as an installed service",
|
||||
# :errval => 1060
|
||||
# }
|
||||
#
|
||||
#
|
||||
#--- reg.exe error example
|
||||
# ERROR: Invalid key name.
|
||||
# Type "REG QUERY /?" for usage.
|
||||
#--- END reg.exe error example
|
||||
# returns:
|
||||
# {
|
||||
# :error => "INVALID KEY NAME."
|
||||
# :errval => nil
|
||||
# }
|
||||
#
|
||||
def win_parse_error(str)
|
||||
hashish = {
|
||||
:error => "Unknown Error",
|
||||
:errval => nil
|
||||
}
|
||||
if ma = /^error:.*/i.match(str) # if line starts with Error: just pass to regular parser
|
||||
hashish.merge!(win_parse_results(ma[0].upcase)) #upcase required to satisfy regular parser
|
||||
# merge results. Results from win_parse_results will override any duplicates in hashish
|
||||
elsif ma = /FAILED +[0-9]+/.match(str) # look for 'FAILED ' followed by some numbers
|
||||
#print_status "Found FAILED, ma is #{ma.inspect}" if $blab
|
||||
sa = ma[0].split(' ')
|
||||
#print_status "sa is #{sa.inspect}" if $blab
|
||||
hashish[:errval] = sa[1].chomp.to_i
|
||||
# above intended to capture the numbers after the word 'FAILED' as [:errval]
|
||||
ma = /^[^\[\n].+/.match(str)
|
||||
#print_status "ma is #{ma.inspect}" if $blab
|
||||
hashish[:error] = ma[0].chomp.strip
|
||||
# above intended to capture first non-empty line not starting with '[' or \n into [:error]
|
||||
else
|
||||
# do nothing, defaults are good
|
||||
end
|
||||
#print_error "Error hash: #{hashish.inspect}" if $blab
|
||||
print_error "This error hash is optionally available: #{hashish.pretty_inspect}"
|
||||
return hashish
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,52 +1,21 @@
|
|||
|
||||
require 'msf/core/post/windows/cli_parse'
|
||||
|
||||
module Msf
|
||||
class Post
|
||||
|
||||
module Registry
|
||||
|
||||
#
|
||||
# Return the data and type of a given registry key and value
|
||||
#
|
||||
def registry_getvalinfo(key,valname)
|
||||
value = {}
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
|
||||
v = open_key.query_value(valname)
|
||||
value["Data"] = v.data
|
||||
value["Type"] = v.type
|
||||
open_key.close
|
||||
end
|
||||
return value
|
||||
end
|
||||
include Msf::Post::Windows::CliParse
|
||||
|
||||
#
|
||||
# Return the data of a given registry key and value
|
||||
# Create the given registry key
|
||||
#
|
||||
def registry_getvaldata(key,valname)
|
||||
value = nil
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
|
||||
v = open_key.query_value(valname)
|
||||
value = v.data
|
||||
open_key.close
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the data for a given value and type of data on the target registry
|
||||
#
|
||||
# returns true if succesful
|
||||
#
|
||||
def registry_setvaldata(key,valname,data,type)
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_WRITE)
|
||||
open_key.set_value(valname, session.sys.registry.type2str(type), data)
|
||||
open_key.close
|
||||
return true
|
||||
def registry_createkey(key)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_createkey(key)
|
||||
else
|
||||
shell_registry_createkey(key)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -55,13 +24,35 @@ module Registry
|
|||
#
|
||||
# returns true if succesful
|
||||
#
|
||||
def registry_deleteval(key,valname)
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_WRITE)
|
||||
open_key.delete_value(valname)
|
||||
open_key.close
|
||||
return true
|
||||
def registry_deleteval(key, valname)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_deleteval(key, valname)
|
||||
else
|
||||
shell_registry_deleteval(key, valname)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Delete a given registry key
|
||||
#
|
||||
# returns true if succesful
|
||||
#
|
||||
def registry_deletekey(key)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_deletekey(key)
|
||||
else
|
||||
shell_registry_deletekey(key)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Return an array of subkeys for the given registry key
|
||||
#
|
||||
def registry_enumkeys(key)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_enumkeys(key)
|
||||
else
|
||||
shell_registry_enumkeys(key)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -69,6 +60,283 @@ module Registry
|
|||
# Return an array of value names for the given registry key
|
||||
#
|
||||
def registry_enumvals(key)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_enumvals(key)
|
||||
else
|
||||
shell_registry_enumvals(key)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Return the data of a given registry key and value
|
||||
#
|
||||
def registry_getvaldata(key, valname)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_getvaldata(key, valname)
|
||||
else
|
||||
shell_registry_getvaldata(key, valname)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Return the data and type of a given registry key and value
|
||||
#
|
||||
def registry_getvalinfo(key,valname)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_getvalinfo(key, valname)
|
||||
else
|
||||
shell_registry_getvalinfo(key, valname)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Sets the data for a given value and type of data on the target registry
|
||||
#
|
||||
# returns true if succesful
|
||||
#
|
||||
def registry_setvaldata(key, valname, data, type)
|
||||
if session_has_registry_ext?
|
||||
meterpreter_registry_setvaldata(key, valname, data, type)
|
||||
else
|
||||
shell_registry_setvaldata(key, valname, data, type)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Determines whether the session can use meterpreter registry methods
|
||||
#
|
||||
def session_has_registry_ext?
|
||||
(session.sys and session.sys.respond_to?(:registry))
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Generic registry manipulation methods based on reg.exe
|
||||
##
|
||||
|
||||
def shell_registry_createkey(key)
|
||||
key = normalize_key(key)
|
||||
boo = false
|
||||
begin
|
||||
# REG ADD KeyName [/v ValueName | /ve] [/t Type] [/s Separator] [/d Data] [/f]
|
||||
cmd = "cmd.exe /c reg add \"#{key}\""
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if results =~ /The operation completed successfully/
|
||||
boo = true
|
||||
elsif results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def shell_registry_deleteval(key, valname)
|
||||
key = normalize_key(key)
|
||||
boo = false
|
||||
begin
|
||||
# REG DELETE KeyName [/v ValueName | /ve | /va] [/f]
|
||||
cmd = "cmd.exe /c reg delete \"#{key}\" /v \"#{valname}\" /f"
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if results =~ /The operation completed successfully/
|
||||
boo = true
|
||||
elsif results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
return boo
|
||||
end
|
||||
|
||||
def shell_registry_deletekey(key)
|
||||
key = normalize_key(key)
|
||||
boo = false
|
||||
begin
|
||||
# REG DELETE KeyName [/v ValueName | /ve | /va] [/f]
|
||||
cmd = "cmd.exe /c reg delete \"#{key}\" /f"
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if results =~ /The operation completed successfully/
|
||||
boo = true
|
||||
elsif results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
return boo
|
||||
end
|
||||
|
||||
def shell_registry_enumkeys(key)
|
||||
key = normalize_key(key)
|
||||
subkeys = []
|
||||
reg_data_types = 'REG_SZ|REG_MULTI_SZ|REG_DWORD_BIG_ENDIAN|REG_DWORD|REG_BINARY|'
|
||||
reg_data_types << 'REG_DWORD_LITTLE_ENDIAN|REG_NONE|REG_EXPAND_SZ|REG_LINK|REG_FULL_RESOURCE_DESCRIPTOR'
|
||||
begin
|
||||
bslashes = key.count('\\')
|
||||
cmd = "cmd.exe /c reg query \"#{key}\""
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if results
|
||||
if results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
else # would like to use elsif results =~ /#{key}/ but can't figure it out
|
||||
results.each_line do |line|
|
||||
# now let's keep the ones that have a count = bslashes+1
|
||||
# feels like there's a smarter way to do this but...
|
||||
if (line.count('\\') == bslashes+1 && !line.ends_with?('\\'))
|
||||
#then it's a first level subkey
|
||||
subkeys << line.split('\\').last.chomp # take & chomp the last item only
|
||||
end
|
||||
end
|
||||
#else
|
||||
# error_hash = win_parse_error("ERROR:Unrecognizable results from #{cmd}")
|
||||
end
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
return subkeys
|
||||
end
|
||||
|
||||
def shell_registry_enumvals(key)
|
||||
key = normalize_key(key)
|
||||
values = []
|
||||
reg_data_types = 'REG_SZ|REG_MULTI_SZ|REG_DWORD_BIG_ENDIAN|REG_DWORD|REG_BINARY|'
|
||||
reg_data_types << 'REG_DWORD_LITTLE_ENDIAN|REG_NONE|REG_EXPAND_SZ|REG_LINK|REG_FULL_RESOURCE_DESCRIPTOR'
|
||||
begin
|
||||
# REG QUERY KeyName [/v ValueName | /ve] [/s]
|
||||
cmd = "cmd.exe /c reg query \"#{key}\""
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
elsif values = results.scan(/^ +.*[#{reg_data_types}].*/)
|
||||
# yanked the lines with legit REG value types like REG_SZ
|
||||
# now let's parse out the names (first field basically)
|
||||
values.collect! do |line|
|
||||
t = line.split(' ')[0].chomp #chomp for good measure
|
||||
# check if reg returned "<NO NAME>", which splits to "<NO", if so nil instead
|
||||
t = nil if t == "<NO"
|
||||
t
|
||||
end
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
return values
|
||||
end
|
||||
|
||||
def shell_registry_getvaldata(key, valname)
|
||||
value = nil
|
||||
begin
|
||||
a = shell_registry_getvalinfo(key, valname)
|
||||
value = a["Data"] || nil
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
def shell_registry_getvalinfo(key, valname)
|
||||
key = normalize_key(key)
|
||||
value = {}
|
||||
value["Data"] = nil # defaults
|
||||
value["Type"] = nil
|
||||
begin
|
||||
# REG QUERY KeyName [/v ValueName | /ve] [/s]
|
||||
cmd = "cmd.exe /c reg query \"#{key}\" /v \"#{valname}\""
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if match_arr = /^ +#{valname}.*/i.match(results)
|
||||
# pull out the interesting line (the one with the value name in it)
|
||||
# and split it with ' ' yielding [valname,REGvaltype,REGdata]
|
||||
split_arr = match_arr[0].split(' ')
|
||||
value["Type"] = split_arr[1]
|
||||
value["Data"] = split_arr[2]
|
||||
# need to test to ensure all results can be parsed this way
|
||||
elsif results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
def shell_registry_setvaldata(key, valname)
|
||||
key = normalize_key(key)
|
||||
boo = false
|
||||
begin
|
||||
# REG ADD KeyName [/v ValueName | /ve] [/t Type] [/s Separator] [/d Data] [/f]
|
||||
# /f to overwrite w/o prompt
|
||||
cmd = "cmd.exe /c reg add \"#{key}\" /v \"#{valname}\" /t \"#{type}\" /d \"#{data}\" /f"
|
||||
results = session.shell_command_token_win32(cmd)
|
||||
if results =~ /The operation completed successfully/
|
||||
boo = true
|
||||
elsif results =~ /^Error:/
|
||||
error_hash = win_parse_error(results)
|
||||
else
|
||||
error_hash = win_parse_error("ERROR:Unknown error running #{cmd}")
|
||||
end
|
||||
end
|
||||
return boo
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
# Meterpreter-specific registry manipulation methods
|
||||
##
|
||||
|
||||
|
||||
def meterpreter_registry_createkey(key)
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
|
||||
open_key = session.sys.registry.create_key(root_key, base_key)
|
||||
open_key.close
|
||||
return true
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def meterpreter_registry_deleteval(key, valname)
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_WRITE)
|
||||
open_key.delete_value(valname)
|
||||
open_key.close
|
||||
return true
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def meterpreter_registry_deletekey(key)
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
deleted = session.sys.registry.delete_key(root_key, base_key)
|
||||
return deleted
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
print_status "curses, foiled again"
|
||||
end
|
||||
end
|
||||
|
||||
def meterpreter_registry_enumkeys(key)
|
||||
subkeys = []
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
|
||||
keys = open_key.enum_key
|
||||
keys.each { |subkey|
|
||||
subkeys << subkey
|
||||
}
|
||||
open_key.close
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
return subkeys
|
||||
end
|
||||
|
||||
def meterpreter_registry_enumvals(key)
|
||||
values = []
|
||||
begin
|
||||
vals = {}
|
||||
|
@ -79,53 +347,51 @@ module Registry
|
|||
values << val.name
|
||||
}
|
||||
open_key.close
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
return values
|
||||
end
|
||||
|
||||
#
|
||||
# Return an array of subkeys for the given registry key
|
||||
#
|
||||
def registry_enumkeys(key)
|
||||
subkeys = []
|
||||
def meterpreter_registry_getvaldata(key, valname)
|
||||
value = nil
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
|
||||
keys = open_key.enum_key
|
||||
keys.each { |subkey|
|
||||
subkeys << subkey
|
||||
}
|
||||
v = open_key.query_value(valname)
|
||||
value = v.data
|
||||
open_key.close
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
return subkeys
|
||||
return value
|
||||
end
|
||||
|
||||
#
|
||||
# Create the given registry key
|
||||
#
|
||||
def registry_createkey(key)
|
||||
def meterpreter_registry_getvalinfo(key, valname)
|
||||
value = {}
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.create_key(root_key, base_key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
|
||||
v = open_key.query_value(valname)
|
||||
value["Data"] = v.data
|
||||
value["Type"] = v.type
|
||||
open_key.close
|
||||
return true
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
#
|
||||
# Delete a given registry key
|
||||
#
|
||||
# returns true if succesful
|
||||
#
|
||||
def registry_delkey(key)
|
||||
def meterpreter_registry_setvaldata(key, valname, data, type)
|
||||
begin
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.delete_key(root_key, base_key)
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_WRITE)
|
||||
open_key.set_value(valname, session.sys.registry.type2str(type), data)
|
||||
open_key.close
|
||||
return true
|
||||
rescue Rex::Post::Meterpreter::RequestError => e
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue