Module: Msf::Post::Windows::CliParse
- Included in:
- Registry
- Defined in:
- lib/msf/core/post/windows/cli_parse.rb
Defined Under Namespace
Classes: ParseError
Instance Method Summary collapse
-
#win_parse_error(results) ⇒ Object
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.
-
#win_parse_results(str) ⇒ Object
Parses output of some windows CLI commands and returns a hash with the keys/vals detected.
Instance Method Details
#win_parse_error(results) ⇒ Object
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.
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.
returns:
{
:error => "INVALID KEY NAME."
:errval => nil
}
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/msf/core/post/windows/cli_parse.rb', line 140 def win_parse_error(results) hashish = { :error => "Unknown Error", :errval => nil } # parse the results if ma = /^error:.*/i.match(results) # 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(results) # look for 'FAILED ' followed by some numbers sa = ma[0].split(' ') hashish[:errval] = sa[1].chomp.to_i # ^ intended to capture the numbers after the word 'FAILED' as [:errval] ma = /^[^\[\n].+/.match(results) 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 return hashish end |
#win_parse_results(str) ⇒ Object
Parses output of some windows CLI commands and returns a hash with the keys/vals detected. If the item has multiple values, they will all be returned in the val separated by commas. Keys are downcased and symbolized (key.downcase.to_sym)
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
returns:
{
: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...>
}
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/msf/core/post/windows/cli_parse.rb', line 75 def win_parse_results(str) tip = false hashish = {} 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 arr = line.scan(/\w+/) val = arr.join(',') # join with commas, though 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 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(':') k = arr[0].strip.downcase.to_sym # 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 hashish[k] = v lastkey = k end end return hashish end |