Like most bots these days this example loads it's tool modules from a remote Command and Control server. The difference is: it uses a completely RAM based file system to store it's tools. This means there is little forensic trace of those tools when they are not directly loaded into memory. I should note that this is not an original idea. According to the ICIT briefing on Advanced Persistent Threats, Uroburos (also known as Epic Turla) uses an Encrypted Virtual File System as part of it's Rootkit.
First let's look at the primary Module we will be using: PyFilesystem. You can check the documentation out at http://docs.pyfilesystem.org There is a second module I use for managing the zip file in the script (so I do not need to rely on the OS unzip functions). You can find the documentation on zipfile here https://docs.python.org/2/library/zipfile.html
Design
There are a lot of possible options for how one could load the tools remotely into the RAM file system (MemoryFS). My first extension was an HTTP based File System API. While that provided a good starting point it was heavy on the CnC side. It required a special server-side component to translate requests for files. Next, I chose to load the tools from a zip File System retrieved across the network. In an actual deployment this maybe as simple as a base64-encoded, encrypted, byte string copied off of a pseudo-anonymous source (like Pastebin or Gists). This turned out to be the much simpler option.Creating the Virtual FS
The first thing we need is a File System we want to import onto a machine. I created one for testing which mirrored what an attacker might want to include.As you might imagine you can add any Binary tools, Python packages, etc. to this. The one constraint I would recommend is to keep it small. There are two reasons for this stance. One being the initial transfer across the network is more likely to cause issues with larger core file systems. This may cause network timeouts or worse (from an attackers perspective) set off alerts. The other reason being memory hogging. Loading too many files into the RAM FS will cause the program to eat up RAM. Keep it lean.
The last file on the list, vfs.zip, contains all the files and directories above it. This is the file we use to transfer the data. To format it I created a script which read the files binary data and converted it to a base64 encoded string. I wrote the string to a file, which I then uploaded to GitHub. I set the BASE_URL to the file's raw data URL (You can look at GitHub tutorials on finding this information).
Using the Virtual FS in RAM
Using the Modules
The Filesystem module comes with a handy class designed to help with this very function. It is the FSImportHook class. It takes, as an argument to to it's constructor, a Filesystem object. Here is what the Source Code has to say about the class:
"Expose an FS object to the python import machinery, via a PEP-302 loader.
The short-hand of that is now the call from syshelp import PrinterFuncs will also look inside the RAM FS for modules. The call to get_application_version() uses this module to print information about the version of the RAM FS. This is the result of running the bot.This module allows you to import python modules from an arbitrary FS object, by placing FS urls on sys.path and/or inserting objects into sys.meta_path. The main class in this module is FSImportHook, which is a PEP-302-compliant module finder and loader. If you place an instance of FSImportHook on sys.meta_path, you will be able to import modules from the exposed filesystem"
No comments:
Post a Comment