module Rex::Exploitation::Powershell::Parser
Constants
- RESERVED_VARIABLE_NAMES
Reserved special variables Acquired with: Get-Variable | Format-Table name, value -auto
Public Instance Methods
Extract block of code inside brackets/parenthesis
Attempts to match the bracket at idx, handling nesting manually Once the balanced matching bracket is found, all script content between idx and the index of the matching bracket is returned
@param idx [Integer] index of opening bracket
@return [String] content between matching brackets
# File lib/rex/exploitation/powershell/parser.rb, line 134 def block_extract(idx) fail ArgumentError unless idx if idx < 0 || idx >= code.length fail ArgumentError, 'Invalid index' end start = code[idx] stop = match_start(start) delims = scan_with_index(/#{Regexp.escape(start)}|#{Regexp.escape(stop)}/, code[idx + 1..-1]) delims.map { |x| x[1] = x[1] + idx + 1 } c = 1 sidx = nil # Go through delims till we balance, get idx while (c != 0) && (x = delims.shift) sidx = x[1] x[0] == stop ? c -= 1 : c += 1 end code[idx..sidx] end
Extract a block of function code
@param func_name [String] function name @param delete [Boolean] delete the function from the code
@return [String] function block
# File lib/rex/exploitation/powershell/parser.rb, line 163 def get_func(func_name, delete = false) start = code.index(func_name) return nil unless start idx = code[start..-1].index('{') + start func_txt = block_extract(idx) if delete delete_code = code[0..idx] delete_code << code[(idx + func_txt.length)..-1] @code = delete_code end Function.new(func_name, func_txt) end
Get function names from code
@return [Array] function names
# File lib/rex/exploitation/powershell/parser.rb, line 76 def get_func_names code.scan(/function\s([a-zA-Z\-\_0-9]+)/).uniq.flatten end
Attempt to find string literals in PSH expression
@return [Array] string literals
# File lib/rex/exploitation/powershell/parser.rb, line 84 def get_string_literals code.scan(/@"(.+?)"@|@'(.+?)'@/m) end
Get variable names from code, removes reserved names from return
@return [Array] variable names
# File lib/rex/exploitation/powershell/parser.rb, line 67 def get_var_names our_vars = code.scan(/\$[a-zA-Z\-\_0-9]+/).uniq.flatten.map(&:strip) our_vars.select { |v| !RESERVED_VARIABLE_NAMES.include?(v.downcase) } end
Return matching bracket type
@param char [String] opening bracket character
@return [String] matching closing bracket
# File lib/rex/exploitation/powershell/parser.rb, line 109 def match_start(char) case char when '{' '}' when '(' ')' when '[' ']' when '<' '>' else fail ArgumentError, 'Unknown starting bracket' end end
Scan code and return matches with index
@param str [String] string to match in code @param source [String] source code to match, defaults to @code
@return [Array] matched items with index
# File lib/rex/exploitation/powershell/parser.rb, line 95 def scan_with_index(str, source = code) ::Enumerator.new do |y| source.scan(str) do y << ::Regexp.last_match end end.map { |m| [m.to_s, m.offset(0)[0]] } end