Hunting for suspicious Windows LNK files with Wazuh XDR

| by | Wazuh 4.4
Post icon

LNK files, also known as Shell links, are Windows shortcut files that point to an original file, folder, or application. They have the “LNK” file extension and use the Shell Link Binary File Format to hold metadata to access another data object.

We notice a significant rise in the abuse of LNK files. Part of the reason for this increase is that Microsoft is now blocking macros in files from the internet [1], pushing threat actors to look for alternatives. Microsoft applied this measure to improve the security of its Office applications as threat actors exploited VBA (Visual Basic Application) macros to gain unauthorized access and deploy malware on endpoints. Advanced Persistent Threat (APTs) groups heavily misuse the command-line feature of LNK files for initial access, persistence, malware execution, and credential harvesting on endpoints. You can see LNK file abuse in prevalent malware families like Emotet, Bumblebee, Qbot, Icedid, and Quantum ransomware.

This blog post shows how to use Wazuh with other open source tools to detect the presence of malicious LNK files in Windows endpoints.

Shell Link Binary File Format

A Shell link binary has five structures, namely SHELL_LINK_HEADER, LINKTARGET_IDLIST, LINKINFO, STRING_DATA, and EXTRA_DATA. We highlight the specific structures malicious actors focus on to abuse LNK files.

  • SHELL_LINK_HEADER: This is the main and mandatory structure that contains key information about the target file, attributes, and other structures, such as LinkFlags that identify other optional structures.
  • LINKTARGET_IDLIST: Specifies pointers to the location of the link target (data object) based on ItemID. This structure holds information only if the HasLinkTargetIDList flag is set under LinkFlags in the SHELL_LINK_HEADER.
  • LINKINFO: Stores references to link target locations, including volume, serial number, and local paths. This structure gets populated if the HasLinkInfo flag is set under LinkFlags in the SHELL_LINK_HEADER.
  • STRING_DATA: Contains a set of structures that holds information about paths and interfaces for the link target. Example structures include RELATIVE_PATH and COMMAND_LINE_ARGUMENTS, which are our points of interest as threat actors use these structures to exploit legitimate Windows programs to execute malicious code.
    • RELATIVE_PATH specifies the location of the link target relative to the file that contains the shell link. This structure is present if the HasRelativePath flag is set.
    • COMMAND_LINE_ARGUMENTS specifies the command-line argument the link executes. This structure contains information if the HasArguments flag is set.
  • EXTRA_DATA: Holds additional information about a link target.

Environment setup

We use the following endpoints and prerequisites to demonstrate how to emulate and detect misuse of Windows LNK files.

Endpoint Description
CentOS 7This endpoint hosts the Wazuh central components (Wazuh server, Wazuh indexer, and Wazuh dashboard). Install Wazuh 4.4.1 using the Quickstart installation guide. You can also follow the installation alternatives guide.
Windows 11Install Wazuh agent 4.4.1 on this endpoint and enroll it to the Wazuh server. Follow the Wazuh Windows agent installation guide to achieve this.

Data flow of the setup

This setup synchronizes the Wazuh File Integrity Monitoring (FIM) and active response capabilities to detect suspicious and malicious LNK files. The figure below illustrates the flow of events between the different Wazuh modules responsible for detecting, parsing, and alerting suspicious and malicious LNK files.

setup data flow
Figure 1: Overview of data flow of the setup.

The following steps explain the flow of events in the figure above:

1. We use the Wazuh FIM module to monitor the addition and modification of files with the .lnk extension in a specified folder on a Windows endpoint. After a .lnk file is added or modified in a monitored folder, the FIM module generates an event.

2. The FIM event triggers a rule on the Wazuh server generating an FIM alert.

3. The FIM alert shows on the Wazuh dashboard. 

4. Simultaneously, the FIM alert automatically triggers the Wazuh active response module to execute the lnkparser.bat script on the Windows endpoint.

5. The lnkparser.bat script runs LnkParse3 and jq executables to parse, extract, and format data from the .lnk file. It then writes the formatted data to the active-responses.log file on the Windows endpoint.

6. The active-responses.log file stores the parsed data from the .lnk file.

7. The Wazuh agent forwards the extracted data from the active-responses.log file to the Wazuh server for analysis, correlation, and alerting.

8. The Wazuh server finally reports the generated alert on the Wazuh dashboard for further analysis and investigation.

Configuration

This section outlines the steps to configure the Windows endpoint to monitor .lnk file intrusion. We also show how to add rules on the Wazuh server to detect the presence of suspicious and malicious Windows shortcuts in the monitored endpoint.

Windows endpoint

Perform all the commands on this endpoint using PowerShell with Administrator privileges.

1. Download the official Python executable installer.

2. Run the Python installer and select the following checkboxes during installation:

  • Use admin privileges when installing py.exe launcher for all users.
  • Add python.exe to PATH.

3. Install the jq tool using the Chocolatey Windows package manager. Jq is a lightweight and open source tool used to parse JSON logs.

> Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
> choco install jq -y

4. Install LnkParse3 using the following command. LnkParse3 is a simple open source Python package that extracts data from Windows shortcut files.

> pip install LnkParse3

5. Obtain the installation path of the LnkParse3 executable. This path is required in the active response script in the next step. Use the following command:

> (Get-Command lnkparse.exe).Path
C:\Users\vagrant\AppData\Local\Programs\Python\Python310\Scripts\lnkparse.exe

6. Create a batch script named lnkparser.bat in the C:\Program Files (x86)\ossec-agent\active-response\bin\ folder and add the following content. The script extracts data from Windows shortcut files and logs it to the C:\Program Files (x86)\ossec-agent\active-response\active-responses.log file on the Windows endpoint.

Replace <lNKPARSE3_PATH> with the path to the LnkParse3 executable obtained in step 5 above.

setlocal enableDelayedExpansion

reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /i "x86" > NUL && SET OS=32BIT || SET OS=64BIT

if %OS%==32BIT (
	SET log_file_path="%programfiles%\ossec-agent\active-response\active-responses.log"
)

if %OS%==64BIT (
	SET log_file_path="%programfiles(x86)%\ossec-agent\active-response\active-responses.log"
)

for /f "delims=" %%# in ('powershell get-date -format "{dd-MMM-yyyy HH:mm:ss}"') do @set _date=%%#

set input=
for /f "delims=" %%a in ('PowerShell -command "$logInput = Read-Host; Write-Output $logInput"') do (
	set input=%%a
)

set json_file_path="C:\Program Files (x86)\ossec-agent\active-response\stdin.txt"
set syscheck_file_path=
echo %input% > %json_file_path%

for /F "tokens=* USEBACKQ" %%F in (`Powershell -Nop -C "(Get-Content 'C:\Program Files (x86)\ossec-agent\active-response\stdin.txt'|ConvertFrom-Json).parameters.alert.syscheck.path"`) do (
set syscheck_file_path=%%F
)

del /f %json_file_path%
set lnkparse_exe_path="<lNKPARSE3_PATH>"

:: Extracting an LNK file data with the LnkParse3 program and structuring output with the jq tool.
echo %syscheck_file_path% >> %log_file_path%
for /f "delims=" %%a in ('powershell -command "& \"%lnkparse_exe_path%\" -j \"%syscheck_file_path%\" | jq -c ."') do (
	Set str=%%a
)

:: Replacing single \ with double \\ in the file path for proper parsing.
set syscheck_file_path=!syscheck_file_path:\=\\!

:: Renaming field name "data" for proper indexing and adding file_path to the data.
set str=!str:{"data":{={"lnk_data":{"file_path":"%syscheck_file_path%",!
echo %_date% wazuh-lnkparse: INFO - Scan result: %str% >> %log_file_path%

exit /b

7. Append the following configuration to the Wazuh agent configuration file C:\Program Files (x86)\ossec-agent\ossec.conf. This configuration enables the FIM module to monitor the \Downloads folder of all users (*) on the Windows endpoint. You can configure other folders of interest.

<ossec_config>
  <syscheck>
    <directories realtime="yes">C:\Users\*\Downloads</directories>
  </syscheck>
</ossec_config>

8. Restart the Wazuh agent to apply the configuration changes:

> Restart-Service -Name wazuh

Wazuh server

1. Add the following rules to the /var/ossec/etc/rules/local_rules.xml file to generate FIM alerts when shortcut files are added or modified in the monitored directory.

<group name="syscheck,">
  <!-- Rule that detects .lnk file intrusion into endpoint. -->
  <rule id="110000" level="7">
    <if_sid>554</if_sid>
    <field name="file" type="pcre2">(?i).lnk$</field>
    <description>Windows shortcut "$(file)" has been added.</description>
    <mitre>
      <id>T1492</id>
    </mitre>
  </rule>

  <!-- Rule that detects .lnk file modification on endpoint. -->
  <rule id="110001" level="7">
    <if_sid>550</if_sid>
    <field name="file" type="pcre2">(?i).lnk$</field>
    <description>Windows shortcut "$(file)" has been modified.</description>
  </rule>
</group>

Where:

  • Rule ID 110000 is triggered when an LNK file is added to a monitored Windows endpoint folder.
  • Rule ID 110001 is triggered when an LNK file is modified in a monitored Windows endpoint folder.

2. Append the following configuration to the /var/ossec/etc/ossec.conf file to enable the Wazuh active response module to automatically execute the lnkparser.bat batch script. This automatic execution only occurs after the FIM module triggers alerts with rule ID 110000 or 110001 on the Windows endpoint.

<ossec_config>
  <command>
    <name>lnkparser</name>
    <executable>lnkparser.bat</executable>
    <timeout_allowed>no</timeout_allowed>
  </command>

  <active-response>
    <command>lnkparser</command>
    <location>local</location>
    <rules_id>110000,110001</rules_id>
  </active-response>
</ossec_config>

3. Append the following decoder to the /var/ossec/etc/decoders/local_decoder.xml file to extract the fields in the log event produced by the lnkparser.bat script:

<decoder name="raw_json">
  <prematch>wazuh-lnkparse: INFO - Scan result: </prematch>
  <plugin_decoder offset="after_prematch">JSON_Decoder</plugin_decoder>
</decoder>

4. Append the following rules to the /var/ossec/etc/rules/local_rules.xml file to trigger alerts when the Wazuh server detects Windows shortcuts with suspicious signatures:

<group name="windows_shortcut,">
  <rule id="110003" level="12">
    <decoded_as>raw_json</decoded_as>
    <field name="lnk_data.command_line_arguments" type="pcre2">(?i)cmd|powershell|psexec|MSHTA|bitsadmin|certutil|vbc|csc|del|echo|tasklist|rundll32|regsvr32|%COMSPEC%|Assembly\.Load|\[Reflection\.Assembly\]::Load|\.dll|\.scr|\.pif|http|https|ftp|ServerXMLHTTP|\.url|cdn.|\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b|\.ps1|invoke|\[Convert\]|FromBase|-exex|-nop|-noprofile|-noni|-enc|-decode|-accepteula|hidden|bypass|javascript|jscript|vbscript|wscript|cscript|\.js|\.vb|\.wsc|\.wsh|\.wsf|\.sct|\.cmd|\.hta|\.bat|ActiveXObject|eval|\.7z|\.zip|\.cab|\.iso|\.rar|\.tar|\.bz2|\.lzh|\.dat|expand|makecab|winword|exel|powerpnt|\.rtf|\.doc|\.dot|\.xls|\.xla|\.csv|\.ppt|\.pps|\.xml|\.pdf|%PDF|\.swf|\.fws|setlocal|EnableExtensions|DisableDelayedExpansion|process call</field>
    <description>Suspicious Windows shortcut "$(lnk_data.file_path)" with malicious artifacts. Possible LNK file abuse.</description>
    <mitre>
      <id>T1547.009</id>
      <id>T1036</id>
    </mitre>
  </rule>

  <rule id="110004" level="12">
    <decoded_as>raw_json</decoded_as>
    <field name="header.link_flags" type="pcre2">(?i)HasRelativePath</field>
    <field name="lnk_data.relative_path" type="pcre2">(?i)cmd|powershell|psexec|MSHTA|bitsadmin|certutil|vbc|csc|del|echo|tasklist|rundll32|regsvr32|%COMSPEC%|Assembly\.Load|\[Reflection\.Assembly\]::Load|\.dll|\.scr|\.pif|http|https|ftp|ServerXMLHTTP|\.url|cdn.|\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b|\.ps1|invoke|\[Convert\]|FromBase|-exex|-nop|-noprofile|-noni|-enc|-decode|-accepteula|hidden|bypass|javascript|jscript|vbscript|wscript|cscript|\.js|\.vb|\.wsc|\.wsh|\.wsf|\.sct|\.cmd|\.hta|\.bat|ActiveXObject|eval|\.7z|\.zip|\.cab|\.iso|\.rar|\.tar|\.bz2|\.lzh|\.dat|expand|makecab|winword|exel|powerpnt|\.rtf|\.doc|\.dot|\.xls|\.xla|\.csv|\.ppt|\.pps|\.xml|\.pdf|%PDF|\.swf|\.fws|setlocal|EnableExtensions|DisableDelayedExpansion|process call</field>
    <description>Suspicious Windows shortcut "$(lnk_data.file_path)" with malicious artifacts. Possible LNK file abuse.</description>
    <mitre>
      <id>T1547.009</id>
      <id>T1036</id>
    </mitre>
  </rule>

  <rule id="110005" level="12">
    <if_sid>110003,110004</if_sid>
    <description>Suspicious Windows shortcut "$(lnk_data.file_path)" with malicious artifacts. Possible LNK file abuse.</description>
    <mitre>
      <id>T1547.009</id>
      <id>T1036</id>
    </mitre>
  </rule>
</group>

Where:

  • Rule ID 110003 is triggered when the command_line_arguments parameter of an LNK file contains executables, scripts, network connections, and compression patterns.
  • Rule ID 110004 is triggered when the relative_path parameter of an LNK file contains executables, scripts, network connections, and compression patterns. This rule is ignored if rule ID 110003 is triggered.
  • Rule ID 110005 is a correlation rule that generates an alert when either rule ID 110003 or 110004 is triggered. This rule shows on the Wazuh dashboard when an LNK file is suspicious or malicious.

5. Restart the Wazuh manager to apply the configuration changes:

$ sudo systemctl restart wazuh-manager

Crafting a suspicious LNK file

We create a suspicious shortcut file called malicious.lnk, using VBScript to test the configuration. VBScript is Microsoft’s Active Scripting language that is modeled on Visual Basic. The shortcut file opens the Windows endpoint’s calculator program and downloads the Wazuh LICENSE file to the \Downloads folder when executed.

Note

You don’t need to execute the file because our rules detect suspicious LNK files once the FIM module detects them on an endpoint.

To craft the malicious shortcut, perform the following steps on the Windows endpoint.

1. Create a VBScript file create_shortcut.vbs on the \Desktop and add the following script:

Set wshell = CreateObject("WScript.Shell")

Dim path
path = wshell.SpecialFolders("Desktop") & "/malicious.lnk"

Set shortcut              = wshell.CreateShortcut(path)
shortcut.IconLocation     = "C:\Windows\System32\shell32.dll,70"
shortcut.WindowStyle      = 7
shortcut.TargetPath       = "powershell.exe"
shortcut.Arguments        = "calc.exe; Invoke-WebRequest -URI 'https://github.com/wazuh/wazuh/blob/master/LICENSE' -OutFile C:\Users\${env:USERNAME}\Downloads\LICENSE"
shortcut.WorkingDirectory = "C:"
shortcut.HotKey           = "CTRL+Z"
shortcut.Description      = "Run calculator and download a file"
shortcut.Save

Note

You might need to disable real-time and cloud-delivered protection in Windows Security settings before compiling the VBScript.

2. Run the following PowerShell command to create the malicious shortcut, malicious.lnk, on the \Desktop:

> cscript C:\Users\${env:USERNAME}\Desktop\create_shortcut.vbs

Triggering the rules and viewing the alerts

In this section, we test the configuration by performing two different actions on the Windows endpoint. 

For the first action, we copy a legitimate shortcut file that only triggers rule ID 110000, detecting the presence of a shortcut. This action does not trigger rule ID 110005, implying that the shortcut is not suspicious.

For the second action, we copy a suspicious shortcut file that triggers rule IDs 110000 and 110005, detecting the presence of a suspicious shortcut.

Perform the following steps to generate and view the alerts.

Using a legitimate shortcut file

1. Copy the Windows administrative tool shortcut, Performance Monitor.lnk, from the C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools folder to the monitored \Downloads folder using the following PowerShell command:

> cp "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools\Performance Monitor.lnk" C:\Users\$env:USERNAME\Downloads\

2. Visit the Wazuh dashboard and navigate to Modules > Security events tab to view the generated alerts.

lnk files
Figure 2: Wazuh dashboard showing a legitimate Windows shortcut security alert.

Using a suspicious shortcut file

1. Run the following PowerShell command to copy the crafted malicious.lnk shortcut file on your \Desktop to the monitored \Downloads folder.

> cp C:\Users\$env:USERNAME\Desktop\malicious.lnk C:\Users\$env:USERNAME\Downloads\

2. Visit the Wazuh dashboard and navigate to Modules > Security events tab to view the generated alerts.

windows lnk files
Figure 3: Wazuh dashboard with Windows shortcut security alerts.

Conclusion

By crafting our payload, we can better understand how threat actors leverage LNK files to compromise Windows endpoints. Threat actors generally use Windows utilities like PowerShell, CMD, and MSHTA in LNK files to download and execute malicious payloads on endpoints.

We have shown how Wazuh detects the presence of suspicious and malicious LNK files in Windows endpoints.

LNK file abuse has become widespread, so we strongly recommend verifying the source and authenticity of LNK files before executing them. Additionally, keep your operating systems and endpoint protection software up-to-date, as compromises can adversely affect your endpoint and organization.

Learn more about the open source Wazuh security platform and its capabilities to protect against malware and gain visibility of your infrastructure. You can also join our Slack community of professionals and enterprises if you have any questions on this blog post or Wazuh in general.

References

  1. Microsoft blocked internet macros for Office suite
  2. Shell Link Binary File Format
  3. How LNK files are abused by threat actors
  4. Generic LNK YARA ruleset
  5. Crafting malicious LNK files