Sodin - also known as Sodinokibi or REvil - is a successful ransomware family which often employs advanced evasion techniques to avoid notice until the right time. It is developed and operated as ransomware-as-a-service (RaaS), meaning that threat actors can pay to make use of the software to run their campaigns.
Active from early 2019, Sodin has rapidly become a dominant force in ransomware activity, quickly filling the gap left by the end of Gandcrab being available as a service. There are many good writeups of the Sodin family available online, and in this blog post, we are not doing a full analysis of the sample. Instead, we will breakdown the main ways in which Sodin is detectable and identifiable within a dynamic sandbox environment, aiming to give examples of some of the techniques covered in part 1 of this miniseries.
Analyzed Samples
SHA256 | tria.ge Analysis |
---|---|
e5d23a3bb61b99e227bb8cbfc0e7f1e40fe a34aac4dcb80acc925cfd7e3d18ec | https://tria.ge/reports/191216-pg5st7zccj/ |
06b323e0b626dc4f051596a39f52c46b35f 88ea6f85a56de0fd76ec73c7f3851 | https://tria.ge/reports/191216-4zdx1n374x/ |
0fa207940ea53e2b54a2b769d8ab033a6b2 c5e08c78bf4d7dade79849960b54d | https://tria.ge/reports/191216-8bfljdyw2s/ |
139a7d6656feebe539b2cb94b0729602f62 18f54fb5b7531b58cfe040f180548 | https://tria.ge/reports/191216-4rcmytrrka/ |
Ransomware Information
Ransomware is unusual among malware as it has no interest in hiding its infection from the user once it has carried out its task. Sodin is no exception to this, dropping ransom notes to the directories in which it has encrypted files and changing the wallpaper to point the victim towards these files.
Ransom Note
We took a look at ransom notes in the last blog post in this series so we won’t go over the details again here, but in summary, they contain instructions for the victim on how to pay the ransom and decrypt their files.
In the case of the Sodin family, this note contains several URLs which the victim is meant to visit to receive the instructions and see how much is being demanded in ransom. No bitcoin address or information regarding the ransom is available directly in this file, which is unfortunate (extracting these can be useful for tracking campaigns/threat actors), but these URLs are still worth extracting for further investigation.
The name of the ransom note is defined by the nname
field within the
configuration discussed later in this blog post and will include the file
extension given to all encrypted files. For example, where {"EXT"}
is
replaced by the extension {"EXT"}.info.txt
.
Analyzing Ransom Notes via tria.ge
The tria.ge sandbox includes detections for many aspects of ransomware but there will always be data we don’t include in the final report for one reason or another. However, our kernel driver maintains a record of almost all activity on the VM which can be accessed directly via the Triage API, enabling users to run custom parsers/extractors over the data. In this section, we will do a quick example on fetching and processing this information to extract basic information from a Sodin ransom note - although many other uses are also possible.
Documentation for the API can be found at https://tria.ge/docs/.
Onemon, the kernel driver used in Triage, records a log of system events for each task within an analysis (a ’task’ is a specific VM instance run during analysis - for example a sample run on Windows 7 and Windows 10 will have 2 tasks, 1 for each VM). This data can be downloaded in JSON format via the following command
curl -H ‘Authorization: Bearer <YOUR_API_KEY>’
‘https://api.tria.ge/v0/samples/{sampleID}/{taskID}/logs/onemon.json'
Note that you must pass your API key to access Triage endpoints. This can be found on your [account page][acount].
The taskID
field should simply be replaced by a string like task1
referencing the exact analysis you would like to access - for reference, the
taskID value can be seen in the final part of the URL when viewing a report
online.
As an example, requesting the onemon.json
file for the first sample
linked in this blogpost looks as follows:
curl -H 'Authorization: Bearer <YOUR_API_KEY>' \
'https://api.tria.ge/v0/samples/191216-pg5st7zccj/task1/logs/onemon.json'
The file received from the API contains 1 JSON object per line, each representing an event within the system. The results below have been prettified for readability.
{
"kind": "onemon.File",
"event": {
"dstpath": "",
"flags": "NoFileFlags",
"id": 844424930209781,
"kind": "CreateModify",
"pid": 1444,
"srcpath": "C:\\Users\\Admin\\AppData\\Local\\Temp\\st748h0795z.bmp",
"status": 0,
"ts": 36769
}
}
{
"kind": "onemon.Registry",
"event": {
"kind": "SetValueKeyStr",
"path": "\\REGISTRY\\USER\\S-1-5-21-1774239815-1814403401-2200974991-1000\\Control Panel\\Desktop\\Wallpaper",
"pid": 1444,
"status": 0,
"ts": 36769,
"valued": null,
"valuei": 0,
"values": "C:\\Users\\Admin\\AppData\\Local\\Temp\\st748h0795z.bmp"
}
}
{
"kind": "onemon.NetworkFlow",
"event": {
"dstip": 134744072,
"dstport": 53,
"pid": 284,
"proto": 17,
"srcip": 285214474,
"srcport": 60531,
"ts": 36894
}
}
Example events in onemon.json
Each line includes a ‘kind’ tag which defines the structure contained within
the following ’event’ tag. There are many different ‘kind’ definitions, but
likely the main ones which will be of interest are onemon.Registry
,
onemon.Process
, and onemon.File
. We can combine the ‘kind’ tag
and the ‘status’ tag within the event structure to form filters using grep,
e.g., to show only events where a write operation took place in the registry,
we could use grep onemon.Registry | grep SetValueKeyStr
.
In this example, we are interested in the ransom notes dropped by Sodin during analysis. By default, Triage dumps the contents of all .txt files created by a sample so that automated processing can be carried out on the files, e.g., to extract URLs. These dumps are (currently) stored as FileContents blocks within the onemon log:
{
"kind": "onemon.FileContents",
"event": {
"buf": "SABlAGwAbABvACAAZABlAGEAcgAgAGYAcgBpAGUAbgBkACEADQAKAA0ACgBZAG8AdQByACAAZgBpAGwAZQBzACAAYQByAGUAIABlAG4AYwByAHkAcAB0AGUAZAAsACAAYQBuAGQALAAgAGEAcwAgAHIAZQBzAHUAbAB0ACAAeQBvAHUAIABjAGEAbgAnAHQAIAB1AHMAZQAgAGkAdAAuACAAWQBvAHUAIABtAHUAcwB0ACAAdgBpAHMAaQB0ACAAbwB1AHIAIABwAGEAZwBlACAAdABvACAAZwBlAHQAIABpAG4AcwB0AHIAdQBjAHQAaQBvAG4AcwAgAGEAYgBvAHUAdAAgAGQAZQBjAHIAeQBwAHQAaQBvAG4AIABwAHIAbwBjAGUAcwBzAC4ADQAKAEEAbABsACAAZQBuAGMAcgB5AHAAdABlAGQAIABmAGkAbABlAHMAIABoAGEAdgBlACAAZwBvAHQAIAA0ADMAcwA0ADAAaQA3ADEAbAAgAGUAeAB0AGUAbgBzAGkAbwBuAC4ADQAKAA0ACgBJAG4AcwB0AHIAdQBjAHQAaQBvAG4AcwAgAGkAbgB0AG8AIAB0AGgAZQAgAFQATwBSACAAbgBlAHQAdwBvAHIAawANAAoALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAA0ACgBJAG4AcwB0AGEAbABsACAAVABPAFIAIABiAHIAbwB3AHMAZQByACAAZgByAG8AbQAgAGgAdAB0AHAAcwA6AC8ALwB0AG8AcgBwAHIAbwBqAGUAYwB0AC4AbwByAGcALwANAAoAVgBpAHMAaQB0ACAAdABoAGUAIABmAG8AbABsAG8AdwBpAG4AZwAgAGwAaQBuAGsAOgAgAGgAdAB0AHAAOgAvAC8AYQBwAGwAZQBiAHoAdQA0ADcAdwBnAGEAegBhAHAAZABxAGsAcwA2AHYAcgBjAHYANgB6AGMAbgBqAHAAcABrAGIAeABiAHIANgB3AGsAZQB0AGYANQA2AG4AZgA2AGEAcQAyAG4AbQB5AG8AeQBkAC4AbwBuAGkAbwBuAC8AQgA0AEQAMQBDADcAQQAxAEIAMAAwAEQANgBEAEYARgANAAoADQAKAEkAbgBzAHQAcgB1AGMAdABpAG8AbgBzACAAaQBuAHQAbwAgAFcAVwBXACAAKABUAGgAZQAgAGYAbwBsAGwAbwB3AGkAbgBnACAAbABpAG4AawAgAGMAYQBuACAAbgBvAHQAIABiAGUAIABpAG4AIAB3AG8AcgBrACAAcwB0AGEAdABlACwAIABpAGYAIAB0AHIAdQBlACwAIAB1AHMAZQAgAFQATwBSACAAYQBiAG8AdgBlACkAOgANAAoALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAA0ACgBWAGkAcwBpAHQAIAB0AGgAZQAgAGYAbwBsAGwAbwB3AGkAbgBnACAAbABpAG4AawA6ACAAaAB0AHQAcAA6AC8ALwBkAGUAYwByAHkAcAB0AG8AcgAuAHQAbwBwAC8AQgA0AEQAMQBDADcAQQAxAEIAMAAwAEQANgBEAEYARgANAAoADQAKAFAAYQBnAGUAIAB3AGkAbABsACAAYQBzAGsAIAB5AG8AdQAgAGYAbwByACAAdABoAGUAIABrAGUAeQAsACAAaABlAHIAZQAgAGkAdAAgAGkAcwA6AA0ACgB3ADkAQQB1AHQAeQB1ADcAOQAxAGcARABjAGcAdgBKAGEAOAA4AGIAWgBFAE0AZwAwAHQAWQBRAFgANABzAEkAYgBVAGYAYwBIAGsARwBRAFUATQBlAFcARgBsAEsANgBOADkAVgBQAC8AUABnAG0ASQBwAEUAMwBZAHgAUgBNAA0ACgBvAGgAegBsAHUAbgBDADEAagBIAFAARgBCAE8AZABHADgAUgBRAEgANQBNAEYAZQBTAHAAYQBZAEoAYgBmAGYANwBkAG0AcgBwADAAUwBhAC8AQQBNAHgAcwAzAFoANQA4AEEAdABmAFQAeAB4AHQAcABlAEEAUwBFAFgASgBhAA0ACgBZAFMAdQB0AGUAQwBjADAAYwByAHIAWgBNAFYAUgByAGwAYQA5AHIASABkAHUAegBzAEEALwBIAHgAYgA5AFoARAAxADUAegBMAFMAawBHAFoAbwBEAEgAMQBUADkAYgBjAFkAaABsAEQATgA0AGMAWAA2AGIATABKAHMARgBsAA0ACgBFAHUAYQBwADYAWABXAFcASQBRAE0ATgBJAFgAeQBTAFkAbgBHAC8ATQBVAHkAbAB5AEYAUABrAHEALwBMAGEAMgBCAEEAdwBtAGQAcQBMAHMAbQBYAFYAbgB0AGcALwByAFIAdgBmAFcARQBXAGoAMgBXAGsAYgBGAEgASwBRAA0ACgBkAFgARwBpADMAZgBrAHAAcgBVAGEATQBoADYAQwA1AGsAaQB5AEwAUwA4AEwAcgA0AHUAWQAzAHAAeQBtAGMAUgBsAFAARAA0AEoAcwA0ADUAZgA4ADgAcQA0AFgAWABLAG8AWQBkAFgANABRAGkARgB2ADIARgB1ADQAcABGAA0ACgAwAEcAaQBRAEIAeQBzAGwAQwBBAHcAdwA1ADcAVwBZAEwAWABGADgAeABEAFQAcAArAGMARwBVAFUASQBNAGkASwBWAGMAVQBEAFgAagAzADUAQgBnAFoARQBXAG8AMgBWAHcAaQBpADkATABzAHQAVABiAEkAMABEAGEARABMAA0ACgA4AEgAcABBAFoANQByAGkAcgB0AFYAOABHAHkAUQBzAFMAdwBqAGcAMgBxAHQAWgArAEYAdQBFADgAQQBNADUAWQBRADYAbwB3AEMAMgB2AEMARwBLAHEASwBHAC8AQwA1ADgAMgBnAGwAMwBkAEIASAB0AGYAUAAvADYAZwB2AA0ACgBZAFkAYgA1AE4ASwBMAG4AagBZADIAaABpADYATgA4AEsAMwBIAEoAbgBXAEkAcQBqADcAYgA3AFQAOABkAFcARwBJAE8AbQBrADEAcQBuAG0ANwBCAGwATAB6AFIAdQBtAE0AawB6AFgAdgAzAFEAVABiAHQATgBIADEAQwAwAA0ACgA1ADgAZwA2AEoALwBiAHUANgBaAG4AbABFAG4AcgB1ADYAVgBDAEoARQAvAGQASQB6ADYAUwBCAHgAVQA5ADcAdQB6AHgAdgBsAFMALwBoAHUAaQBlADIAZABEAEsAMQBKAFAAcAB6AFMAaABCAFcAQQA3AHQAegAzAHEAQgB4AA0ACgA1AEEAVABGAFYAUgA1AHUAVwA4AE4AYQAyAGQASgA3AHoASgBlAEoASQB0AE8AUABEAGEAUwBIAHkANgAvAHQAcQB4AGkANQBBAHcARQAzADYAeABvAHMASQBJAE0AaAA0AEEAUgBKAGgAKwBnAGIASQA0AEwAVABjAGQASgA1AA0ACgArADIAQQBtAHQASQBVAGYANQBLADEAUwBXADYAdgBhAHQAcAAyAFMASgBTAEUAUQBxAFUATwBBAGoAaABhAGcAeQBWAGIAMgBNAHgAYQBVADAATQByAEgAcABUAGMAMABhADIAYwBtAEwASgBBAHYARgBlADUAcQBGAG4AWgB2AA0ACgB3AHAAMQBmAGIAdQBGAFQAQwBOAHYARABDAEwAWgBrAE4AWAB4ADcANQA2AGkAcwAvAHEAbgBLAHMAWAA3AFUAYgB6AEkARABGAFoALwB0AHoANgBpADUANABLAGYAcgA3AFIAZABMAGkAawBBAGYAMwBWAG8ASwBmAEUAMQBuAA0ACgA4AEMASAA0AFcATQAzAFIAVgB5ADYAdwAzAHIAVgA2AHgALwB6AFEAUgBmAEkAawAzAHIAVABwAHIAYwBHAGkAcABiAG4AQwBCAEwAeQBWADQAawBUAEEAMQBHADUAYwB0AGEARABwAFMAagA4ADIANQBGAFMAVABRAC8AZwB
"id": 844424930209780,
"pid": 1444,
"ts": 33462
}
}
Sodin ransom note in onemon.json
The onemon.FileContents
blocks are linked to standard onemon.File
events where the sample performed a CreateFile operation for a .txt file. These
blocks contain metadata useful for relating the file dumps to their original
file names and paths, the ID value shown above acts as the reference. Note the
"flags": "DumpContents"
field in this event type
{
"kind": "onemon.File",
"event": {
"dstpath": "",
"flags": "DumpContents",
"id": 844424930209780,
"kind": "CreateModify",
"pid": 1444,
"srcpath": "C:\\Users\\Public\\Videos\\Sample Videos\\43s40i71l.info.txt",
"status": 0,
"ts": 33462
}
}
If we are looking for a specific file, we can grep through the json for the file name and then pick out the specific FileContents block that we were looking for based on the ID value.
The "buf"
section of the FileContents block shown above is a base64-encoded
representation of the data written to the file, extracted by intercepting the
API call for the file write and dumping the buffer contents. In order to
retrieve the original contents, simply decode the value.
At this point the entire contents of the file are available in plaintext for any further processing desired - extracting contact URLs/email addresses, bitcoin wallets, personal identifier codes etc.
We have produced a simple Python script which, when passed a Triage analysis ID
and your API key, will perform the process outlined above and dump every .txt
file found in the onemon.json to the current directory. It will generate a
number of .txt
files. You can find the script here.
To use it, you’ll need the Triage ID,
the task ID of the analysis you want to examine, and your API key for tria.ge.
Usage may look as follows:
python3 triage-ransomnote.py <API-Key> 191216-4rcmytrrka task1
Ransom Portal Overview
The URLs contained within the ransom note lead to a web portal customized to the victim based on a generated ID value, which is the final part of the address (see ransom note above). To make it harder for analysts to use automated tools to gather information, victims must enter some basic information when accessing their portal - a generated ‘key’ visible in the ransom note and the extension used when encrypting files (this can differ based on the configuration settings).
After submitting this information, the victim can then access payment details and other information, including guides on using Bitcoin; a trial decryptor that can be used on a single file; and even a chat support feature to get assistance from the malware operators.
The most useful information on this page is the ransom price and the Bitcoin address which is to be used for payment - using a framework like Selenium it would be possible to automate the gathering of these addresses for tracking.
Desktop Wallpaper Change
To make sure the victim is aware of the infection, Sodin also generates a new desktop background image and makes it active via the registry.
The image is a bitmap created through the DrawTextW function in User32.dll. The text to be written is defined within the malware’s JSON config section (discussed later in this post).
The image is saved to the user’s Local AppData directory with a random file
name, and the registry key HKCU\\Control Panel\\Desktop\\Wallpaper
is set to
point to the new file.
Preventing System Recovery
Like many other ransomware families, Sodin attempts to make recovery of the
infected machine more difficult by disabling or removing some Windows features.
It achieves this using common vssadmin
and bcdedit
commands.
Brief descriptions of these commands are provided below for reference. In a dynamic analysis environment, these are reasonably clear indicators of maliciousness, as there are few legitimate reasons for an application to delete backups or interfere with boot settings.
Command | Description |
---|---|
vssadmin Delete Shadows /All /Quiet | Delete system shadow copies |
bcdedit /set {default} recoveryenabled No | Disables Windows Error Recovery on startup |
bcdedit /set {default} bootstatuspolicy ignoreallfailures | Sets system to ignore errors and boot as normal (NB: this is also the default Windows setting) |
Configuration
To enable threat actors to customize their Sodin campaign, the family includes a configuration file embedded within the executable. This is packaged as a PE section with a distinct name - the 2 variants we have examined for this blogpost used .grrr
and .zeacl
.
PE sections from unpacked Sodin samples
These sections are a JSON configuration file encrypted using RC4 which contain a large amount of information about the particular campaign the sample belongs to
{
"pk": "GadtWz2QBTacskL+55Wpo65IkwY28qJOxHoe4Xte81M=",
"pid": "10",
"sub": "7",
"dbg": false,
"fast": true,
"wipe": true,
"wht": {
"fld": ["appdata", "google", "msocache", "mozilla", "program files", "windows", "perflogs", "application data", "windows.old", "system volume information", "program files (x86)", "$windows.~ws", "intel", "$recycle.bin", "$windows.~bt", "programdata", "boot", "tor browser"],
"fls": ["ntuser.dat.log", "bootsect.bak", "ntuser.dat", "iconcache.db", "ntldr", "autorun.inf", "boot.ini", "bootfont.bin", "desktop.ini", "thumbs.db", "ntuser.ini"],
"ext": ["ldf", "msi", "nomedia", "msu", "wpx", "ani", "shs", "theme", "386", "adv", "icns", "lnk", "ico", "ics", "rom", "sys", "mod", "cur", "com", "scr", "cpl", "diagcfg", "lock", "diagcab", "msstyles", "idx", "msc", "icl", "rtp", "exe", "drv", "hta", "nls", "deskthemepack", "cmd", "hlp", "themepack", "dll", "mpa", "msp", "ps1", "prf", "ocx", "bat", "diagpkg", "cab", "bin", "spl", "key"]
},
"wfld": ["backup"],
"prc": ["mysql.exe"],
"dmn": "lyricalduniya.com;theboardroomafrica.com;chris-anne.com;ownidentity.com;web865.com;[...]",
"net":true,
"nbody ":"SABlAGwAbABvACAAZABlAGEAcgAgAGYAcgBpAGUAbgBkACEADQAKAA0ACgBZAG8AdQByACAAZgBpAGwAZQBzACAAYQByAGUAIABlAG4AYwByAHkAcAB0AGUAZAAsACAAYQBuAGQALAAgAGEAcwAgAHIAZQBzAHUAbAB0ACAAeQBvAHUAIABjAGEAbgAnAHQAIAB1AHMAZQAgAGkAdAAuACAAWQBvAHUAIABtAHUAcwB0ACAAdgBpAHMAaQB0ACAAbwB1AHIAIABwAGEAZwBlACAAdABvACAAZwBlAHQAIABpAG4AcwB0AHIAdQBjAHQAaQBvAG4AcwAgAGEAYgBvAHUAdAAgAGQAZQBjAHIAeQBwAHQAaQBvAG4AIABwAHIAbwBjAGUAcwBzAC4ADQAKAEEAbABsACAAZQBuAGMAcgB5AHAAdABlAGQAIABmAGkAbABlAHMAIABoAGEAdgBlACAAZwBvAHQAIAB7AEUAWABUAH0AIABlAHgAdABlAG4AcwBpAG8AbgAuAA0ACgANAAoASQBuAHMAdAByAHUAYwB0AGkAbwBuAHMAIABpAG4AdABvACAAdABoAGUAIABUAE8AUgAgAG4AZQB0AHcAbwByAGsADQAKAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQANAAoASQBuAHMAdABhAGwAbAAgAFQATwBSACAAYgByAG8AdwBzAGUAcgAgAGYAcgBvAG0AIABoAHQAdABwAHMAOgAvAC8AdABvAHIAcAByAG8AagBlAGMAdAAuAG8AcgBnAC8ADQAKAFYAaQBzAGkAdAAgAHQAaABlACAAZgBvAGwAbABvAHcAaQBuAGcAIABsAGkAbgBrADoAIABoAHQAdABwADoALwAvAGEAcABsAGUAYgB6AHUANAA3AHcAZwBhAHoAYQBwAGQAcQBrAHMANgB2AHIAYwB2ADYAegBjAG4AagBwAHAAawBiAHgAYgByADYAdwBrAGUAdABmADUANgBuAGYANgBhAHEAMgBuAG0AeQBvAHkAZAAuAG8AbgBpAG8AbgAvAHsAVQBJAEQAfQANAAoADQAKAEkAbgBzAHQAcgB1AGMAdABpAG8AbgBzACAAaQBuAHQAbwAgAFcAVwBXACAAKABUAGgAZQAgAGYAbwBsAGwAbwB3AGkAbgBnACAAbABpAG4AawAgAGMAYQBuACAAbgBvAHQAIABiAGUAIABpAG4AIAB3AG8AcgBrACAAcwB0AGEAdABlACwAIABpAGYAIAB0AHIAdQBlACwAIAB1AHMAZQAgAFQATwBSACAAYQBiAG8AdgBlACkAOgANAAoALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAC0ALQAtAA0ACgBWAGkAcwBpAHQAIAB0AGgAZQAgAGYAbwBsAGwAbwB3AGkAbgBnACAAbABpAG4AawA6ACAAaAB0AHQAcAA6AC8ALwBkAGUAYwByAHkAcAB0AG8AcgAuAHQAbwBwAC8AewBVAEkARAB9AA0ACgANAAoAUABhAGcAZQAgAHcAaQBsAGwAIABhAHMAawAgAHkAbwB1ACAAZgBvAHIAIAB0AGgAZQAgAGsAZQB5ACwAIABoAGUAcgBlACAAaQB0ACAAaQBzADoADQAKAHsASwBFAFkAfQAAAA==",
"nname": {"EXT"}.info.txt,
"exp":false,
"img":"WQBvAHUAcgAgAGYAaQBsAGUAcwAgAGEAcgBlACAAZQBuAGMAcgB5AHAAdABlAGQAIQAgAE8AcABlAG4AIAB7AEUAWABUAH0ALgBpAG4AZgBvAC4AdAB4AHQAIQAAAA=="
}
There are quite a few useful fields in here - these are outlined in the table below.
Field Name | Description |
---|---|
pk | Base64-encoded public key used for file encryption |
pid | Only used if net field is also set, sent to C2 servers. Likely related to campaign identifier etc. |
sub | See pid |
dbg | Enable/disable debug mode (for the malware author) |
fast | Boolean value which changes how large files are encrypted |
wipe | Boolean. If set, sample will try to erase contents of folders blacklisted in the wfld field |
wht | Defines whitelists for encryption process. Contains 3 sections: |
1. fld : folders to ignore |
|
2. fls : specific files to ignore |
|
3. ext : whitelisted file extensions |
|
wfld | List of folder names. If the wipe field is set to true then the malware will attempt to erase the contents of all folders |
prc | List of process names the malware will try to terminate before carrying out file encryption |
dmn | List of domain names which the malware will attempt to contact to use as C2 |
net | Boolean value. Sets whether sample should send host information to C2 servers listed in dmn key |
nbody | Base64-encoded version of the ransom note dropped to the file system after encryption |
nname | Filename of the ransom note |
exp | Boolean value. Defines whether or not the malware will use an exploit to try and escalate privileges on the system |
img | Base64-encoded version of the text shown in the wallpaper background set by the malware. |
Configuration field details
When delivered to a new system Sodin samples are packed using a custom algorithm, hiding the existence of the specially named resource sections. The malware uses a PE overwrite approach to its unpacking mechanism - it allocates heap space using LocalAlloc, writes the unpacker stub to it, and then passes execution to that area after marking it RWX with VirtualProtect.
Create and call unpacker stub
The unpacker stub then writes the new PE to the address space in which the original file was mapped, clearing the content of the entire region before writing the new executable and jumping back to the updated Entry Point. We can now dump the executable and examine the sections, as shown previously.
The configuration itself is still encrypted at this stage, but in its unpacked form it is possible to analyze the decryption process and recreate it. The algorithm is RC4 - we can clearly see the SBox creation and swapping operations
- but some minor changes have been made to prevent easy decryption with standard RC4 tools.
Examining the executable we can see that the key for the decryption is the first 32 bytes of the resource section.
With this information and analysis of the decryption function, it was possible to build a configuration extractor to parse and report details from these configurations during dynamic analysis of the samples. In Hatching Triage, we have implemented a system that enables taking process memory dumps when particular conditions are met during an analysis. Using this, we can obtain the unpacked executable and run processing on it to include the information in the analysis report and enable easy identification of particular campaigns or actors.
The Sodin extractor is not available on Triage yet while testing and improvements to the memory dumping methodology are implemented, but keep an eye on our Twitter account for updates when that is released.
File Encryption
Sodin can encrypt files on local storage or any mapped network shares,
overwriting the original files and renaming them with an extension generated on
a per-infection basis. This process is highly customizable through the embedded
configuration section, allowing for certain files/folders to be whitelisted and
protected from the encryption process. The Sodin executable also accepts a
command-line parameter - by passing the value -nolan
, one can disable the
encryption of mapped network shares and limit the effects to only the infected
machine.
"wht": {
"fld": ["appdata", "google", "msocache", "mozilla", "program files", "windows", "perflogs", "application data", "windows.old", "system volume information", "program files (x86)", "$windows.~ws", "intel", "$recycle.bin", "$windows.~bt", "programdata", "boot", "tor browser"],
"fls": ["ntuser.dat.log", "bootsect.bak", "ntuser.dat", "iconcache.db", "ntldr", "autorun.inf", "boot.ini", "bootfont.bin", "desktop.ini", "thumbs.db", "ntuser.ini"],
"ext": ["ldf", "msi", "nomedia", "msu", "wpx", "ani", "shs", "theme", "386", "adv", "icns", "lnk", "ico", "ics", "rom", "sys", "mod", "cur", "com", "scr", "cpl", "diagcfg", "lock", "diagcab", "msstyles", "idx", "msc", "icl", "rtp", "exe", "drv", "hta", "nls", "deskthemepack", "cmd", "hlp", "themepack", "dll", "mpa", "msp", "ps1", "prf", "ocx", "bat", "diagpkg", "cab", "bin", "spl", "key"]
}
Whitelist configuration section
The keys specify whitelists for:
fld
- folder namesfls
- specific file namesext
- file extensions
The malware iterates through every directory and file on the system, checking them against these configuration values and queuing them up for encryption if they are not excluded. Once encrypted, the files are renamed with a new extension.
Encrypted File Extension
Before starting the encryption process, Sodin generates the random file extension which is applied to every encrypted file. The extension is a string of letters and numbers from 5 to 10 characters long, which is generated and saved to the registry along with other information gathered at various stages (discussed below).
The extension itself is tricky to accurately identify as Sodin-related due to the generic nature of it, but the registry path is relatively specific and is readily detectable in a sandbox.
Other Registry Changes
As well as the file extension, Sodin saves a few other bits of data to the Software\\Wow6432Node\\recfg registry key
.
None of the values assigned to these keys are static, but all of the key names are common across Sodin samples. We won’t go into the details of these here, but the image above gives a basic outline of the contents.
In a dynamic environment, this sort of registry structure is ideal for identifying a family.
Conclusion
Sodin is a complex family with far more functionality than we have covered here, but this has outlined the main indicators which are useful for identifying samples within a dynamic environment like Triage. References to a number of samples used as source material for this post can be found in the header at the top of the page.
We’ll be continuing to expand coverage over the coming weeks for ransomware families with ransom note and configuration extractors. In the next post in this mini-series we’ll cover another family which poses some different challenges to analysis and present ways to solve them.
Until next time, Happy Holidays!