-
Notifications
You must be signed in to change notification settings - Fork 14k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
32 changed files
with
2,430 additions
and
203 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# -*- coding: binary -*- | ||
|
||
require 'rex/exploitation/powershell/output' | ||
require 'rex/exploitation/powershell/parser' | ||
require 'rex/exploitation/powershell/obfu' | ||
require 'rex/exploitation/powershell/param' | ||
require 'rex/exploitation/powershell/function' | ||
require 'rex/exploitation/powershell/script' | ||
require 'rex/exploitation/powershell/psh_methods' | ||
|
||
module Rex | ||
module Exploitation | ||
module Powershell | ||
# | ||
# Reads script into a PowershellScript | ||
# | ||
# @param script_path [String] Path to the Script File | ||
# | ||
# @return [Script] Powershell Script object | ||
def self.read_script(script_path) | ||
Rex::Exploitation::Powershell::Script.new(script_path) | ||
end | ||
|
||
# | ||
# Insert substitutions into the powershell script | ||
# If script is a path to a file then read the file | ||
# otherwise treat it as the contents of a file | ||
# | ||
# @param script [String] Script file or path to script | ||
# @param subs [Array] Substitutions to insert | ||
# | ||
# @return [String] Modified script file | ||
def self.make_subs(script, subs) | ||
if ::File.file?(script) | ||
script = ::File.read(script) | ||
end | ||
|
||
subs.each do |set| | ||
script.gsub!(set[0], set[1]) | ||
end | ||
|
||
script | ||
end | ||
|
||
# | ||
# Return an array of substitutions for use in make_subs | ||
# | ||
# @param subs [String] A ; seperated list of substitutions | ||
# | ||
# @return [Array] An array of substitutions | ||
def self.process_subs(subs) | ||
return [] if subs.nil? or subs.empty? | ||
new_subs = [] | ||
subs.split(';').each do |set| | ||
new_subs << set.split(',', 2) | ||
end | ||
|
||
new_subs | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# -*- coding: binary -*- | ||
|
||
module Rex | ||
module Exploitation | ||
module Powershell | ||
class Function | ||
FUNCTION_REGEX = Regexp.new(/\[(\w+\[\])\]\$(\w+)\s?=|\[(\w+)\]\$(\w+)\s?=|\[(\w+\[\])\]\s+?\$(\w+)\s+=|\[(\w+)\]\s+\$(\w+)\s?=/i) | ||
PARAMETER_REGEX = Regexp.new(/param\s+\(|param\(/im) | ||
attr_accessor :code, :name, :params | ||
|
||
include Output | ||
include Parser | ||
include Obfu | ||
|
||
def initialize(name, code) | ||
@name = name | ||
@code = code | ||
populate_params | ||
end | ||
|
||
# | ||
# To String | ||
# | ||
# @return [String] Powershell function | ||
def to_s | ||
"function #{name} #{code}" | ||
end | ||
|
||
# | ||
# Identify the parameters from the code and | ||
# store as Param in @params | ||
# | ||
def populate_params | ||
@params = [] | ||
start = code.index(PARAMETER_REGEX) | ||
return unless start | ||
# Get start of our block | ||
idx = scan_with_index('(', code[start..-1]).first.last + start | ||
pclause = block_extract(idx) | ||
|
||
matches = pclause.scan(FUNCTION_REGEX) | ||
|
||
# Ignore assignment, create params with class and variable names | ||
matches.each do |param| | ||
klass = nil | ||
name = nil | ||
param.each do |value| | ||
if value | ||
if klass | ||
name = value | ||
@params << Param.new(klass, name) | ||
break | ||
else | ||
klass = value | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
# -*- coding: binary -*- | ||
|
||
require 'rex/text' | ||
|
||
module Rex | ||
module Exploitation | ||
module Powershell | ||
module Obfu | ||
MULTI_LINE_COMMENTS_REGEX = Regexp.new(/<#(.*?)#>/m) | ||
SINGLE_LINE_COMMENTS_REGEX = Regexp.new(/^\s*#(?!.*region)(.*$)/i) | ||
WINDOWS_EOL_REGEX = Regexp.new(/[\r\n]+/) | ||
UNIX_EOL_REGEX = Regexp.new(/[\n]+/) | ||
WHITESPACE_REGEX = Regexp.new(/\s+/) | ||
EMPTY_LINE_REGEX = Regexp.new(/^$|^\s+$/) | ||
|
||
# | ||
# Remove comments | ||
# | ||
# @return [String] code without comments | ||
def strip_comments | ||
# Multi line | ||
code.gsub!(MULTI_LINE_COMMENTS_REGEX, '') | ||
# Single line | ||
code.gsub!(SINGLE_LINE_COMMENTS_REGEX, '') | ||
|
||
code | ||
end | ||
|
||
# | ||
# Remove empty lines | ||
# | ||
# @return [String] code without empty lines | ||
def strip_empty_lines | ||
# Windows EOL | ||
code.gsub!(WINDOWS_EOL_REGEX, "\r\n") | ||
# UNIX EOL | ||
code.gsub!(UNIX_EOL_REGEX, "\n") | ||
|
||
code | ||
end | ||
|
||
# | ||
# Remove whitespace | ||
# This can break some codes using inline .NET | ||
# | ||
# @return [String] code with whitespace stripped | ||
def strip_whitespace | ||
code.gsub!(WHITESPACE_REGEX, ' ') | ||
|
||
code | ||
end | ||
|
||
# | ||
# Identify variables and replace them | ||
# | ||
# @return [String] code with variable names replaced with unique values | ||
def sub_vars | ||
# Get list of variables, remove reserved | ||
get_var_names.each do |var, _sub| | ||
code.gsub!(var, "$#{@rig.init_var(var)}") | ||
end | ||
|
||
code | ||
end | ||
|
||
# | ||
# Identify function names and replace them | ||
# | ||
# @return [String] code with function names replaced with unique | ||
# values | ||
def sub_funcs | ||
# Find out function names, make map | ||
get_func_names.each do |var, _sub| | ||
code.gsub!(var, @rig.init_var(var)) | ||
end | ||
|
||
code | ||
end | ||
|
||
# | ||
# Perform standard substitutions | ||
# | ||
# @return [String] code with standard substitution methods applied | ||
def standard_subs(subs = %w(strip_comments strip_whitespace sub_funcs sub_vars)) | ||
# Save us the trouble of breaking injected .NET and such | ||
subs.delete('strip_whitespace') unless get_string_literals.empty? | ||
# Run selected modifiers | ||
subs.each do |modifier| | ||
send(modifier) | ||
end | ||
code.gsub!(EMPTY_LINE_REGEX, '') | ||
|
||
code | ||
end | ||
end # Obfu | ||
end | ||
end | ||
end |
Oops, something went wrong.