Using Shell Links as zero-touch downloaders and to initiate network connections
Last Updated: 2020-06-24 10:32:50 UTC
by Jan Kopriva (Version: 1)
Probably anyone who has used any modern version of Windows is aware of their file-based shortcuts, also known as LNKs or Shell Link files. Although they were intended as a simple feature to make Windows a bit more user-friendly, over the years, a significant number of vulnerabilities were identified in handling of LNKs. Many of these vulnerabilities lead to remote code execution and one (CVE-2010-2568) was even used in creation of the Stuxnet worm.
It has been known for some time that even on fully patched systems, Windows still handles Shell Link files with externally loaded icons in an interesting (and quite unsafe) way. Specifically, the OS won’t just load external icon files from local drives, but it will try to do so from remote paths specified in a UNC format as well. What is less known is that the OS will try to do the same even for paths specified as URLs. This means that every time Windows tries to load the icon (it will do so when the LNK file is displayed by File Explorer), a remote connection will be initiated by it to a remote machine and if the icon specified by the UNC or URL path exists, it will be downloaded and displayed.
This, by itself, might actually sound like an interesting feature rather than anything else, however since there appear to be nearly no limits on what paths may be specified for the remote icon file, one may cause Windows to do some surprising things by simply browsing to a specially crafted LNK file. Things such as download an arbitrary file to the local drive (there don’t appear to be any checks in place with regards to size or type of the file which Windows is willing to download) or initiate a SMB connection to an arbitrary remote machine. As you can probably imagine, a hypothetical malicious actor might take advantage of this behavior quite easily.
Probably the most straightforward way to misuse it would be to craft a special LNK file, ZIP it and send it out in a phishing e-mail, or upload the LNK to a network file share used by multiple users (if one had access to it). Under such conditions, just browsing to the LNK file might cause the OS of the victim to do something unintended, such as exhaust bandwidth or space on a local drive by downloading a very large file, download a malicious executable, or try to authenticate against a remote server. I’ve mentioned this issue in passing during my SANS@MIC talk last week, but thought I’d try to provide a deeper explanation of what causes it and how it may be leveraged in this diary.
The potential for misuse of LNK icon loading lies in a lack of checks when it comes to the contents of ICON_LOCATION StringData section of the Shell Link structure.
Due to this lack of checks, it is possible to create a LNK file, which specifies a URL or UNC path as the ICON_LOCATION instead of a local path. It seems that the same may be done with the IconEnvironmentDataBlock structure, but for simplicity’s sake, we will demonstrate the principle using ICON_LOCATION section.
If an arbitrary URL/UNC is specified as the ICON_LOCATION, then, when a folder in which the LNK is located is opened in File Explorer, the OS will attempt to download the file specified by the URL using a HTTP GET request or to download the file by accessing the UNC path over SMB. This will happen without the need for a user to click on anything.
In order to demonstrate this behavior, I've created couple of LNK files, which show this issue in practice and illustrate why this might be dangerous. For the sake of simplicity, most of the files only contain the SHELL_LINK_HEADER and STRING_DATA sections, with ICON_LOCATION being the only STRING_DATA section present.
Before we delve into the example shown above, let’s start slowly, and show that a shortcut, which doesn’t point to any target file, will actually “work” in Windows (i.e. that its icon will be loaded). The following picture shows the internal structure of a LNK file normal.lnk, which doesn’t link to any other file and has its icon set to C:\Windows\SysWOW64\OneDrive.ico.
In this case, the following icon will indeed be loaded from the local path and displayed if the folder, in which is LNK is placed, is browsed to using File Explorer (this is conditional upon the two bytes preceding the path being set to its length as this is required by the ICON_LOCATION format).
As we’ve mentioned, the ICON_LOCATION string may contain a URL/UNC instead of local path, and it is therefore possible to use it to point to a remote server. The following picture demonstrates the internal structure of “external-icon.lnk” file, which has the ICON_LOCATION set to the URL https://untrustednetwork.net/images/un1.ico.
In this case, the following icon will be loaded from the remote server and displayed if the folder in which is LNK is placed is opened in File Explorer.
Since the only limitation when it comes to the ICON_LOCATION string seems to be that it has to end in “.ico” in order for Windows to try to access it, it is possible to craft a LNK, which will cause the OS to make an (almost) arbitrary HTTP GET request. One might use this fact in several ways.
One, which comes to mind, is user tracking through monitoring HTTP requests. To achieve this, the malicious actor would only have to ensure that a LNK file, which loads an icon from server under his control, was placed in a folder, which would be opened in File Explorer on a regular basis (such as the Desktop folder). The following picture shows the internal structure of a file, which demonstrates this principle by having the ICON_LOCATION set to the URL https[:]//untrustednetwork[.]net/loggerscript.php?usertrackingid=1&ending=hit.ico.
If a folder containing such a file was opened (or if the LNK was placed on the Desktop), it would indeed result in Windows sending the relevant HTTP GET request. As the following log from a webserver shows, tracking the public IP address of a specific user would be quite simple in such a scenario.
While on the subject of generating arbitrary request to remote servers, a much more useful way to take advantage of the behavior of Windows in context of an attack or pentest/red team engagement would of course be to use a UNC path instead of a URL and capture hashes/use the requests for SMB relay attack.
The last side effect of the way loading of icons for LNKs is handled worth mentioning is the potential to force Windows to download an arbitrary (i.e. potentially malicious) file to the machine, on which a folder containing a specially crafted LNK is opened.
The following picture shows the internal structure of a file “eicar-downloader.lnk”, which demonstrates this principle by having the ICON_LOCATION set to the URL https[:]//untrustednetwork[.]net/misc/eicar.exe?.ico. As you may have guessed, the file it points to is the EICAR test file with an EXE extension.
The resulting HTTP GET request will lead to the download of EICAR test file to somewhere within the path %USERPROFILE%\AppData\Local\Microsoft\Windows\INetCache (on a W10 machine) with the name eicar.exe.
This should of course result in a warning from any anti-malware solution installed on the machine. A malicious actor could however use the same technique to make Windows download a real malicious file, which would not be detected by AV (or any other data).
By itself, this technique can’t lead to the execution of the downloaded file, but since the target path to which the file will be downloaded is known beforehand, it is fairly simple to create a LNK, which will cause Windows to download an executable from a remote server and which will also execute it when launched. This means that one may create a very simple downloader without the need to actually download anything, which has some (though admittedly limited) potential for both malicious actors and red teamers.
To show how easy it may be to craft such a LNK file I’ve created one, which causes the Process Explorer to download from a Microsoft server and which, when “launched”, causes the following command (and therefore the downloaded binary) to execute.
C:\Windows\System32\cmd.exe /c "cd %USERPROFILE%\AppData\Local\Microsoft\Windows\INetCache & dir /s /B procexp*.exe | cmd.exe /k"
If you’d like to try this out yourself, you may download the file and some of the other LNKs mentioned above from https://untrustednetwork.net/files/ISC/2020/iconic_lnks.zip. Since there one of them is the “EICAR downloader”, the archive is encrypted with the usual password (i.e. “infected”).
The last thing I believe is worth mentioning is that Microsoft is aware of the issue and from what I understand, there have even been some mitigations for it implemented into Windows 8 and Windows 10. These were however afterwards negated by later updates.
Since it seems that we’ll be left without a patch for this issue for the foreseeable future (and since malicious LNK files are quite common in malspam attachments), one of the reasonable defenses against attackers misusing the techniques mentioned above as well as others, which are dependent on LNKs, would be a good level of security awareness among end users. Including the concept malicious shortcut files in security awareness trainings might therefore not be a bad idea.
On a technical side, one additional thing which might be used to mitigate risks related to malicious shortcuts would be to block or quarantine any e-mails with attached archives, which contain (only) LNK files.