Module: Rex::Exploitation::Powershell::Parser
Constant Summary collapse
- RESERVED_VARIABLE_NAMES =
Reserved special variables Acquired with: Get-Variable | Format-Table name, value -auto
[ '$$', '$?', '$^', '$_', '$args', '$ConfirmPreference', '$ConsoleFileName', '$DebugPreference', '$Env', '$Error', '$ErrorActionPreference', '$ErrorView', '$ExecutionContext', '$false', '$FormatEnumerationLimit', '$HOME', '$Host', '$input', '$LASTEXITCODE', '$MaximumAliasCount', '$MaximumDriveCount', '$MaximumErrorCount', '$MaximumFunctionCount', '$MaximumHistoryCount', '$MaximumVariableCount', '$MyInvocation', '$NestedPromptLevel', '$null', '$OutputEncoding', '$PID', '$PROFILE', '$ProgressPreference', '$PSBoundParameters', '$PSCulture', '$PSEmailServer', '$PSHOME', '$PSSessionApplicationName', '$PSSessionConfigurationName', '$PSSessionOption', '$PSUICulture', '$PSVersionTable', '$PWD', '$ReportErrorShowExceptionClass', '$ReportErrorShowInnerException', '$ReportErrorShowSource', '$ReportErrorShowStackTrace', '$ShellId', '$StackTrace', '$true', '$VerbosePreference', '$WarningPreference', '$WhatIfPreference' ].map(&:downcase).freeze
Instance Method Summary collapse
-
#block_extract(idx) ⇒ String
Extract block of code inside brackets/parenthesis.
-
#get_func(func_name, delete = false) ⇒ String
Extract a block of function code.
-
#get_func_names ⇒ Array
Get function names from code.
-
#get_string_literals ⇒ Array
Attempt to find string literals in PSH expression.
-
#get_var_names ⇒ Array
Get variable names from code, removes reserved names from return.
-
#match_start(char) ⇒ String
Return matching bracket type.
-
#scan_with_index(str, source = code) ⇒ Array[String,Integer]
Scan code and return matches with index.
Instance Method Details
#block_extract(idx) ⇒ String
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
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 135 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 |
#get_func(func_name, delete = false) ⇒ String
Extract a block of function code
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 164 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_func_names ⇒ Array
Get function names from code
77 78 79 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 77 def get_func_names code.scan(/function\s([a-zA-Z\-\_0-9]+)/).uniq.flatten end |
#get_string_literals ⇒ Array
Attempt to find string literals in PSH expression
85 86 87 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 85 def get_string_literals code.scan(/@"(.+?)"@|@'(.+?)'@/m) end |
#get_var_names ⇒ Array
Get variable names from code, removes reserved names from return
68 69 70 71 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 68 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 |
#match_start(char) ⇒ String
Return matching bracket type
110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 110 def match_start(char) case char when '{' '}' when '(' ')' when '[' ']' when '<' '>' else fail ArgumentError, 'Unknown starting bracket' end end |
#scan_with_index(str, source = code) ⇒ Array[String,Integer]
Scan code and return matches with index
96 97 98 99 100 101 102 |
# File 'lib/rex/exploitation/powershell/parser.rb', line 96 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 |