LNK (shortcut) files are a common starting point for many phishing campaigns. Threat actors abuse the unique properties of LNK files to deceive users and evade detection and prevention countermeasures, making them potent tools for compromising systems and networks.
In this blog, we'll provide an in-depth analysis of recent LNK phishing campaigns, examining the tactics, techniques, and procedures (TTPs) employed by threat actors. We'll also introduce tools and techniques for simulating these phishing campaigns, helping defenders test their defenses against malicious LNK usage.
Furthermore, we'll present a list of indicators of compromise (IOCs) associated with recent campaigns and discuss relevant Splunk detections for LNK files.
By the end of this post, you will:
Let's get started by understanding what LNK files are and how they can be abused for phishing.
First, let’s understand LNK files. A LNK (pronounced as "link") file is a type of shortcut file used in the Windows operating system (OS) to create a convenient way to access files, folders, applications, or websites.
These files are typically created automatically when a user creates a shortcut to a file, folder, or application in Windows Explorer or on the desktop.
LNK files appear as small icons with a curved arrow overlay, indicating that they are shortcuts. When a user right-clicks on a LNK file and selects "Properties," they can view and modify properties such as the:
In addition to these properties, LNK files contain supplementary — and you can leverage this info for threat intelligence purposes. This includes details such as the:
Interestingly, in Windows OS, the LNK file extension is not directly visible, even if you have configured Windows to show file extensions in folder options settings. Users may not easily identify LNK files unless they are familiar with their appearance or use command-line queries.
The properties of LNK files make them potent tools in phishing campaigns. Their unique characteristics deceive users and also make it alarmingly easy to slip past detection measures that may be in place.
A variety of threat actors and campaigns have exploited LNK files in their phishing endeavors, including:
These deceptive shortcuts, often camouflaged as legitimate executables or PDF files, entice unsuspecting users to click, ultimately leading to the compromise of their systems or networks.
This video demonstrates how LNK files can be effective for creating deceptive file types due to the inherent behavior of Windows OS in hiding file extensions.
With that background covered, let’s delve into several active campaigns we've observed, each leveraging the .LNK file format as the initial trigger for initiating the infection chain on targeted hosts or systems.
Let’s look at the TTPs that threat actors in these campaigns use. This helps us to:
In a typical phishing campaign, threat actors deploy a straightforward yet impactful strategy by employing malicious LNK files to distribute malware. Crafted with a script or command line argument, these LNK files prompt a specific action upon user interaction.
For instance, clicking the deceptive LNK file — often disguised as a legitimate document titled 'INVOICE#BUSAPOMKDS03' — initiates a chain of events.
Upon execution, the LNK file triggers a command that copies a malicious file.bat from a remote domain to the %USERPROFILE%\Music\file.bat directory on the targeted host. This seemingly innocuous action culminates in the deployment of malware, notably AsyncRAT, potentially compromising the victim's system. Figure 01 illustrates the deceptive LNK file at the heart of this phishing scheme.
Figure 01: AsyncRAT LNK Phishing Campaign
Rhadamanthys (1)(2), a Trojan Stealer, is another example of malware leveraging .LNK files in its phishing campaign. These specially crafted LNK files contain an embedded Base64-encoded PowerShell script designed to download a file from a malicious Command and Control (C2) URL, serving as the initial step in its attack chain.
Figure 02 illustrates how this deceptive .LNK file employs a notepad icon to entice users into clicking the malicious file, thereby initiating the attack.
Figure 02: Rhadamathys LNK Phishing Campaign
After decoding the Base64 string, we unveil a straightforward PowerShell script. This script is responsible for downloading another PowerShell script, which is subsequently executed using Invoke-Expression.
Figure 03: Rhadamathys LNK Decoded Powershell
Another technique we saw commonly used in phishing .LNK campaigns is the obfuscation of scripts it tries to execute, such as PowerShell or batch script.
Figure 04 shows a ducktail LNK campaign that uses a caret “^” symbol as an obfuscation technique to break up commands or expressions to hinder readability and evade detection by security tools.
Figure 04: Ducktail LNK phishing campaign
Using CyberChef once more, we can decode the encoded string to reveal its contents, which include a command to download another file from its C2 server, thereby extending its attack chain.
Figure 05: Ducktail LNK Decode Powershell
Furthermore, threat actors have devised .LNK samples tailored to conduct reconnaissance on target hosts or systems. Upon execution, these .LNK files trigger PowerShell scripts designed to collect extensive system information. This includes details such as:
Such reconnaissance activities enable threat actors to gather valuable intelligence for malicious activities.
Figure 06: LNK Recon
The reconnaissance operation saves all gathered system information, converts it into JSON format, and then transmits it to the C2 server controlled by the threat actor.
Figure 07: Recon Information
In addition, this .LNK file incorporates the PDF icon and embeds a dummy PDF file within its file structure. This tactic makes the LNK file seem legitimate, effectively disguising it as a PDF document. This deceptive appearance increases the likelihood of the target user inadvertently compromising the host system by clicking the LNK file.
Figure 08: Embedded PDF file
Malicious .LNK files can abuse Windows utilities to evade security restrictions around command-line interpreter usage. This lets adversaries execute malicious commands discreetly, bypassing detection mechanisms that typically monitor command execution. This can lead to unauthorized system access or data compromise.
Figure 09 depicts a malicious LNK file observed in the wild. This LNK file uses a Living Off the Land Binary (LOLBIN) technique known as forfiles, a legitimate Windows utility, to execute PowerShell script, which initiates the download of a malicious payload in ZIP file format. Upon successful execution, this payload is deployed onto the compromised host, thereby facilitating further malicious activities by the threat actor.
Figure 09: LNK uses Forfiles LOLBIN
In this section, we’ve analyzed and reverse engineered a more intricate form of malicious LNK files compared to the four examples previously explored. We will dissect all the tactics and techniques employed by this malicious LNK file upon execution by the user.
When executed, this LNK file triggers a PowerShell script that employs obfuscation techniques such as the caret (^) symbol and string comments. These tactics are used to obscure the script's functionality and evade detection during static analysis.
Figure 10: LNK Obfuscated Powershell
After reverse engineering and de-obfuscating the script, we discovered the PowerShell component extracts a series of bytes from the LNK code, which are then decrypted using XOR encryption. The decrypted data is then used to create two files:
Figure 11 illustrates the encrypted data within the payload and its decrypted form after XOR decryption.
Figure 11: Decrypted Files
Next, the PowerShell component extracts the contents of the .CAB file by executing “expand.exe”, a built-in command line tool in Windows OS used to expand and extract compressed files.
Below is a comparison of the partly deobfuscated function versus the renamed function of the LNK PowerShell script responsible for extracting the decrypted .CAB file:
partly deobfuscated function
##
function koMIoWakvBvW
{
param($FMGlWEFVsTs, $esLEposvvv);
expand $FMGlWEFVsTs -F:* $esLEposvvv;
};
the deobfuscated and renamed version
function mw_expand_cab_file
{
param($param_src_cab_file_path, $param_dest_cab_file_path);
expand $param_src_cab_file_path -F:* $param_dest_cab_file_path;
};
After extracting the .CAB file, you'll notice several incorporated files within it. The .LNK PowerShell script will locate the 'start.vbs' file and execute it to proceed with its malicious activities on the compromised host. Below is a brief overview of each file and its intended purpose:
unzip.exe:
This is an extraction utility for archives compressed in .zip file format.
Start.vbs:
This VBScript will execute 49120862.bat using CLSID .COM “ShellWindows” object.
49120862.bat:
This batch file adds the registry run key “svchostno2” in "HKCU\Software\Microsoft\Windows\CurrentVersion\Run" and executes several other batch files: 78345839.bat, 47835693.bat, and 30440211.bat
78345839.bat:
This batch file uses unzip.exe to download and extract another zip file named “di3726.zip” from one of its C2 servers hxxps[:]//goosess[.]com/read/get[.]php.
After the zip archive extraction, the batch file will delete the archive file from the host using the following command : del /f /q %~dp0%fn%.zip > null
47835693.bat:
This batch file collects, encrypts, and sends system information and a list of files from the user's Downloads, Documents, and Desktop folders to one of its C2 servers. Figure 12 depicts a screenshot of the relevant code snippet.
Figure 12: Collect data
30440211.bat:
This batch file downloads, decrypts, and extracts another .CAB file from one of its C2 servers hxxp[:]//stuckss[.]com/list[.]php?f=%COMPUTERNAME%[.]txt Then, it deletes the downloaded .CAB file.
60712945.bat:
This batch file executes a PowerShell script that takes two parameters: the first parameter is a URL link from which it downloads an encrypted RC4 file, and the second is the filename to which the decrypted content will be saved.
99548182.bat:
This batch file triggers a PowerShell script, and with RC4-encryption, encodes and sends a file path passed as a parameter to the specified C2 server parameter via HTTP POST.
30606240.bat:
This batch file changes the current working directory to the directory containing the batch file, retrieves the first item found in the specified first parameter, and saves that output to the file specified in its second parameter.
Figure 13 illustrates the attack chain of this malicious LNK file.
Figure 13: LNK Attack Chain (For a larger resolution of this diagram visit this link)
As organization defenders, we need to be able to test our defenses — whether that be analytics, XDR or AV products — to ensure they are properly tuned and detecting or preventing malicious LNK usage.
In this section, we’ll share how you can test your detections in three ways:
Let’s dive into the Atomic Red Team and check out T1547.009 Test Number 2. This particular test uses PowerShell to create a .LNK file and place it in the Startup directory. Upon startup, cmd.exe will spawn.
$Shell = New-Object -ComObject ("WScript.Shell")
$ShortCut = $Shell.CreateShortcut("$env:APPDATA\Microsoft\Windows\Start Menu\Programs\Startup\T1547.009.lnk")
$ShortCut.TargetPath="cmd.exe"
$ShortCut.WorkingDirectory = "C:\Windows\System32";
$ShortCut.WindowStyle = 1;
$ShortCut.Description = "T1547.009.";
$ShortCut.Save()
Using Invoke-AtomicTest we can view the test running:
Invoke-AtomicTest T1547.009 -ShowDetails -TestNumbers 2
Figure 14: Invoke Atomic test in Splunk Attack Range
Next, we can run the Atomic:
Invoke-AtomicTest T1547.009 -TestNumbers 2
Figure 15: T1547.009 (Invoke Atomic test in Splunk Attack Range, Splunk 2024)
As simple as that, we have written a LNK to the startup folder, which will run and start cmd.exe the next time a user logs on.
Now, we can run Atomic Red Team tests all day and write LNKs and run them, but what if we want to go a bit above and beyond using the Atomic Execution Framework? With that, we present to you two utilities to assist with testing your defenses against more interesting LNK behaviors:
LNK Generator is a tool that simplifies creating desktop shortcuts via an HTA file. This utility demonstrates the versatility of shortcuts in Windows, enabling actions from launching command lines to executing scripts.
We will highlight two functionalities:
These examples show how shortcuts can range from simple utilities to complex operations, making the LNK Generator a practical tool for defenders looking to test their defenses.
Simply click on the desired button to lay down a corresponding LNK on your desktop. Then click the created LNK to observe its action. This process helps you understand how shortcuts can be dynamically created and used in a Windows environment.
You can retrieve the LNK Generator utility here.
Save and run the .HTA file in your lab environment. Once opened, you will see the interface:
Figure 16: LNK Generator (Splunk 2024)
We will demo two of the options.
First, click “Create CMD Shortcut” to write a .LNK to the desktop. Then click the .LNK.
Figure 17: LNK shortcut (Splunk 2024)
Next, double-click the CmdShortcut file. A new Command Prompt window will appear. Right-click and open the properties to the LNK, and you’ll see the Target was cmd.exe, as expected.
Figure 18: LNK shortcut (Splunk 2024)
Now, let’s check out the “Create PowerShell Script Shortcut”. This test will create the LNK, and the Target will be to run a PowerShell encodedcommand that downloads a MSI package from Atomic Red Team.
Figure 19: LNK shortcut (Splunk 2024)
Right click the LNK and review the Target:
Figure 20: LNK shortcut (Splunk 2024)
We can see here the Target includes the PowerShell encodedcommand. Below, in Notepad++, we see the full command and the non-Base64 version.
With that, double-click the LNK and an MSI will appear and run.
Figure 21: LNK shortcut (Splunk 2024)
Another Atomic Test we will share simulates the behavior of a malicious .LNK file that incorporates an encrypted CAB file alongside a dummy document.
The brief video demonstration below showcases how the Splunk Threat Research Team applied reverse engineering techniques to a particularly intriguing .LNK file. This analysis allowed us to replicate a broad spectrum of notable TTPs observed during our investigation. By examining this malicious LNK file, which contained embedded files, we gained critical insights that were vital for our detection, development, and testing efforts.
If you would like to check out a similar Atomic Simulation, here is the link to send down range.
Hashes | Description |
e86017b846165690bcaf38242e09df96651aec60e9c2dae4bf50de8ace77f029 | AsyncRat LNK |
5fb0518c2ced3e2556da039dae3cfe846cbf667ef2556c6d75b1487da75ef15f | DuckTail LNK |
375ac09d5f44849e9c888e86adc50069cdb019e3de3216264f61868bef12ca4d | Rhadamathys LNK |
2e7aa640b2da6d9350afba1b8ad0b65bc85ac335dde42f08cd540da8580e2a78 | Remcos LNK |
4613810c0daf6abb2449de0816ef6c868620bc66318cc927d2ce06752a5fc19e | Recon LNK |
27cd090cf83877750416d37dc6ddd8ff319b4854414e4275d67f96652376bcf0 | FATLNK |
9566099319b9649f49501121f789e7e387e2dd49750d348d5f914d79252c4353 | Forfiles LNK |
The following is a list of Splunk detections triggered during the testing of these malicious LNK files.
This detection looks for modifications or alterations made to registry keys that have the potential to initiate the launch of an application or service during system startup.
By monitoring and detecting modifications in these registry keys, we can identify suspicious or unauthorized changes that could indicate malicious activity. This proactive approach helps in safeguarding the system's integrity and security by promptly identifying and mitigating potential threats that aim to gain persistence or execute malicious actions during the startup process.
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime FROM datamodel=Endpoint.Registry where (Registry.registry_path=*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce
OR Registry.registry_path=*\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartupApproved\\Run
OR Registry.registry_path= "*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User
Shell Folders\\*" OR Registry.registry_path= "*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell
Folders\\*" OR Registry.registry_path=*\\currentversion\\run* OR Registry.registry_path=*\\currentVersion\\Windows\\Appinit_Dlls*
OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Shell* OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Notify*
OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\Userinit* OR Registry.registry_path=*\\CurrentVersion\\Winlogon\\VmApplet*
OR Registry.registry_path=*\\currentversion\\policies\\explorer\\run* OR Registry.registry_path=*\\currentversion\\runservices*
OR Registry.registry_path=HKLM\\SOFTWARE\\Microsoft\\Netsh\\* OR Registry.registry_path=
"*\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Common
Startup" OR Registry.registry_path= *\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SharedTaskScheduler
OR Registry.registry_path= *\\Classes\\htmlfile\\shell\\open\\command OR (Registry.registry_path="*Microsoft\\Windows
NT\\CurrentVersion\\Image File Execution Options*" AND Registry.registry_key_name=Debugger)
OR (Registry.registry_path="*\\CurrentControlSet\\Control\\Lsa" AND Registry.registry_key_name="Security
Packages") OR (Registry.registry_path="*\\CurrentControlSet\\Control\\Lsa\\OSConfig"
AND Registry.registry_key_name="Security Packages") OR (Registry.registry_path="*\\Microsoft\\Windows
NT\\CurrentVersion\\SilentProcessExit\\*") OR (Registry.registry_path="*currentVersion\\Windows"
AND Registry.registry_key_name="Load") OR (Registry.registry_path="*\\CurrentVersion"
AND Registry.registry_key_name="Svchost") OR (Registry.registry_path="*\\CurrentControlSet\Control\Session
Manager"AND Registry.registry_key_name="BootExecute") OR (Registry.registry_path="*\\Software\\Run"
AND Registry.registry_key_name="auto_update")) by Registry.dest Registry.user Registry.registry_path
Registry.registry_value_name Registry.registry_value_data Registry.process_guid
Registry.registry_key_name | `drop_dm_object_name(Registry)` | `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)` | `registry_keys_used_for_persistence_filter`
Figure 22: Registry Keys Used For Persistence
(Learn more about this detection: Registry Keys Used for Persistence.)
The following detection utilizes PowerShell Script Block Logging (EventCode=4104) to identify suspicious PowerShell execution. Script Block Logging captures the command sent to PowerShell, the full command to be executed. Upon enabling, logs will output to Windows event logs. Depending on volume, you can choose to enable this on only critical endpoints or all endpoints.
This detection identifies FromBase64String within the script block. A typical malicious instance will include additional code, for example:
[Byte[]]$var_code = [System.Convert]::FromBase64String(38uqIyMjQ6rG....
During triage, review parallel processes using an EDR product or 4688 events. It will be important to understand the timeline of events around this activity. Review the entire logged PowerShell script block.
`powershell` EventCode=4104 ScriptBlockText = "*frombase64string*" OR ScriptBlockText
= "*gnirtS46esaBmorF*" | stats count min(_time) as firstTime max(_time) as lastTime
by EventCode ScriptBlockText Computer UserID | rename Computer as dest |rename UserID as user | `security_content_ctime(firstTime)`
| `security_content_ctime(lastTime)` | `powershell_fileless_script_contains_base64_encoded_content_filter`
Figure 23: Powershell Fileless Script Contains Base64 Encoded Content
(Learn more about this detection: Powershell Fileless Script Contains Base64 Encoded Content.)
The following detection identifies suspicious PowerShell via EventCode 4104, where WMI is performing an event query looking for running processes or running services.
This technique is commonly found where the adversary will identify services and system information on the compromised machine. During triage, review parallel processes within the same timeframe. Review the full script block to identify other related artifacts.
`powershell` EventCode=4104 (ScriptBlockText= "*SELECT*" OR ScriptBlockText="*Get-WmiObject*") AND ScriptBlockText IN ( "*Win32_Bios*", "*Win32_OperatingSystem*", "*Win32_Processor*",
"*Win32_ComputerSystem*", "*Win32_PnPEntity*", "*Win32_ShadowCopy*", "*Win32_DiskDrive*", "*Win32_PhysicalMemory*", "*Win32_Registry*", "*Win32_LogicalDisk*", "*Win32_NetworkAdapterConfiguration*")
| stats count min(_time) as firstTime max(_time) as lastTime by EventCode ScriptBlockText
Computer UserID | rename Computer as dest | rename UserID as user| `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
Figure 24: Recon Using WMI Class
(Learn more about this detection: Recon Using WMI Class.)
This detection identifies instances where a process initiates a `*.lnk` file from potentially malicious locations, such as:
These locations are frequently targeted by attackers using spear phishing tools to execute malicious shortcuts.
| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time)
as lastTime FROM datamodel=Endpoint.Filesystem where Filesystem.file_name="*.lnk"
AND (Filesystem.file_path="C:\\Users\\*" OR Filesystem.file_path="*\\Temp\\*") by
_time span=1h Filesystem.process_guid Filesystem.file_name Filesystem.file_path
Filesystem.file_hash Filesystem.user | `drop_dm_object_name(Filesystem)` | rename
process_guid as lnk_guid | join lnk_guid, _time [| tstats `security_content_summariesonly`
count FROM datamodel=Endpoint.Processes where Processes.process_name=* by _time
span=1h Processes.parent_process_guid Processes.process_id Processes.process_name
Processes.dest Processes.process_path Processes.process | `drop_dm_object_name(Processes)`
| rename parent_process_guid as lnk_guid | fields _time lnk_guid process_id dest
process_name process_path process] | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)`
| table firstTime, lastTime, lnk_guid, process_id, user, dest, file_name, file_path,
process_name, process, process_path, file_hash
Figure 25: Process Creating LNK file in Suspicious Location
(Learn more about this detection: Process Creating LNK file in Suspicious Location.)
This blog post provides an in-depth analysis of LNK (shortcut) files and their potential for abuse in phishing campaigns. It examines several active campaigns that employ malicious LNK files, detailing the tactics, techniques, and procedures used by threat actors. The post also introduces two utilities to help defenders test their defenses against malicious LNK usage and presents a list of Splunk detections triggered during the testing of these malicious files.
By offering valuable insights into the landscape of LNK-based phishing campaigns, this blog equips readers with the knowledge and tools necessary to strengthen their defenses against these attacks.
Visit research.splunk.com to view the Splunk Threat Research Team's complete security content repository. You can implement this content using the Enterprise Security Content Updates app or the Splunk Security Essentials app.
We would like to thank Teoderick Contreras and Michael Haag for authoring this post and the entire Splunk Threat Research Team for their contributions.
The Splunk platform removes the barriers between data and action, empowering observability, IT and security teams to ensure their organizations are secure, resilient and innovative.
Founded in 2003, Splunk is a global company — with over 7,500 employees, Splunkers have received over 1,020 patents to date and availability in 21 regions around the world — and offers an open, extensible data platform that supports shared data across any environment so that all teams in an organization can get end-to-end visibility, with context, for every interaction and business process. Build a strong data foundation with Splunk.