Because Ransomware attacks are currently number one cyber threat — techniques, tools and procedures for their detection and response become more and more important. There are a lot of ways how you can start detecting ransomware activity on your endpoint or network. For example catching creation of thousands DECRYPT_ME.txt on the file system or bunch of suspicious WinAPI calls collected with Sysmon. And today I would like to share my experience building ransomware detection tool.
Before we dive into code, let’s try to describe how ransomware works. In general, ransomware is simple program which enumerates files on your system, encrypts them and sends encryption keys to malicious server. More advanced samples will also escalate privileges, obtain persistence and start lateral movement. But we will focus on simple one, and stage we will be looking at is where ransomware enumerates files and starts encryption.
Concept of ransomware honeypots isn’t new [https://ieeexplore.ieee.org/document/7600214]. Main idea is to create honeypot files and folders and monitor them for changes. While it is simple task it becomes CPU nightmare when you have thousands of such honeypots. But what if I tell you that you can monitor only one file and still catch ransomware before it encrypts all your fancy memes?
On Linux we can use symbolic links to point to our honeypot file and only track read/write access to this file. And because on Linux file extension is almost irrelevant we can name our symbolic link as we want for example finance.docx
Now, we can start coding!
At first we need to generate our decoy file. I wrote simple function which takes two arguments - path where to store decoy and size. It returns absolute path to decoy.
After that we need to create a bunch of symbolic links which should point to our decoy. Function Deploy_decoy takes two arguments — path to decoy and path where it will recursively create symbolic links to our decoy. I have used name “.007-decoy-finance.docx” for two reasons:
- it will be hidden so user wouldn’t accidentally open it
- it will be among the first to be encrypted because digits and special symbols are first in directory listing
We should be ready to start monitoring our honeypot file. There are multiple options we can use for this task:
- Watchdogs - is python library which uses watchdogs to monitor files and directories and generates events. But it doesn’t log process related information so we need another candidate.
- fuser — utility on Linux which identifies processes using files or sockets. With “-kw” flags it will find all processes which are writing to our honeypot and kill them. Disadvantages of using this tool is it takes some time to enumerate all processes and their opened files, so we need to find more reliable monitoring tool.
3. Last option I had was using auditd which is Linux Audit Daemon that generates events based on syscalls. This looks promising!
Using auditd we have successfully logged write access to honeypot file.
Now we can write our monitoring routine using python.
First of all we need to configure auditd rule to track read/write/access to our honeypot.
Main routine looks following:
- Check if there are triggered events with aureport
- Get appropriate events with ausearch
- Filter out events triggered by our own code
- Parse results to extract pid and executable name
- Kill process by pid
Here is python code.
Here is script which generates random files and folders within provided path to make testing slightly easier.
For testing I have picked up following Ransomware PoCs from github:
GonnarCry was able to encrypt 8 files before termination
JavaRansomware showed 30 (27 of them were decoys) encrypted files before termination
RAASNet showed best results with 21 encrypted files
Today we built Ransomware prevention system using only python and auditd which was able to catch all our testing samples. Of course there are more options we can add to our tool to make it more “Enterprise level” like adding logging, creating daemon and adding more rules to auditd policy, but I think it is good enough for PoC. So don’t hesitate and test it by yourself!
Repository with code is here.