June 16, 2021
Click your shortcut and... you got pwned
Introducing LnkGen, a GUI tool for crafting malicious LNK shortcut files with bamboozle mode, alternate data streams, and expert options.
Originally published on redteamer.tips
In the light of the fairly recent NOBELIUM ransomware and through some red team experience of my own, I figured it was time to release a tool called LnkGen, available on GitHub.
Preamble
The art of hiding payloads in LNK files is ancient. However, as we have seen recently, the awareness around LNKs is also “ancient” — as in people don’t know about the threat or they simply forgot (or don’t care).
LNK generators have been around for a while on underground forums and from malware-as-a-service (MAAS) providers.
I had written a LNK generator in the past as a CLI tool, and decided it would be a fun little challenge to port it over to a (somewhat) user-friendly GUI. My first thought was to port it over to .NET Core and use Avalonia UI to make it cross-platform. I quickly backed off from that though — Avalonia, although quite cool, is fairly complex for the uninitiated and I could not find a decent file browser dialog binding. (Okay, I was just lazy.)
So I went to another ancient technology instead: Windows Forms. Yes, you read that right. Why? Well it has drag and drop building blocks, and again, I AM LAZY.
Introducing LnkGen
The UI has two modes: normal mode and expert mode. Let’s first talk about normal mode.
Normal mode has two mandatory fields: a target exe and an icon. In normal mode, file checks will be done (even if you type instead of using the file browser) to check if both files exist. This means you will only be able to create LNK files that target binaries you have installed on your system as well — this is an opsec consideration to avoid broken LNKs (as you will be able to test run them on your own system).
Arguments and Description are optional. In case you want to leverage a LOLBIN and need command-line arguments, put them in the arguments field. Description will provide mouseover text should you hover over your LNK file.
Bamboozle will prepend whitespaces so the target exe is obfuscated — you cannot see it in the LNK properties anymore. Keep in mind though that you have MAX_PATH (255 characters) for your command line.
Example: faking MS Teams
In this example, we will create a shortcut that mimics Teams. In reality we will open cmd:
- Set the target to
cmd.exe - Set the icon to the Teams icon
- Generate the LNK
Inspecting the properties, we can clearly see that this LNK will open cmd and not Teams. Let’s generate the same LNK again with the Bamboozle option:
Now the target field appears blank — this is the bamboozling. Running the LNK will still pop cmd.
Expert mode
Expert mode will not enforce file checks on icon or target, which means you can craft LNK files that will only work on your target system (provided you know the absolute path of the target exe and icon).
Additionally, expert mode gives you another interesting option: Alternate Data Streams.
This gives you the possibility to add ADS to your LNK. Yes, ADS can be attached to anything — LNKs are no exception. If you don’t know about ADS, I suggest you don’t use this option.
Important: ADS will not ship with your LNK when it bears the Mark of the Web (MOTW). So be mindful of that.
The tool has an Add button to attach ADS entries and a Check ADS button for sanity checks. Multiple ADS entries can be added as well.
Once again, shipping your LNK will strip the ADS unless you find a MOTW bypass… cough T1553.005 cough
Mitigations
- Mail proxies should be configured to disallow certain filetypes from external (and internal) sources. This is your first line of defense.
- User awareness is your second line of defense — your users should be made aware time and time again to not just click random stuff.
- YARA rules — Florian Roth has a YARA rule for LNK files in case you want to hunt for this stuff.
- Application whitelisting can also help — getting the LNK on a system is one thing, making it execute something malicious is another (very often relies on base64 decoding or a LOLBIN).
Check out SharpLNKGen-UI on GitHub.