{
	"id": "46a34a21-08ff-404c-8b50-462511d5fed3",
	"created_at": "2026-04-06T01:31:53.298661Z",
	"updated_at": "2026-04-10T03:22:01.075138Z",
	"deleted_at": null,
	"sha1_hash": "5ad270dd080f0a9a33e27a22a55842a1ffa98ce1",
	"title": "Hatching - Automated malware analysis solutions",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 3159153,
	"plain_text": "Hatching - Automated malware analysis solutions\r\nBy Written by Pete Cowman\r\nPublished: 2019-12-18 · Archived: 2026-04-06 00:16:53 UTC\r\nSodin - also known as Sodinokibi or REvil - is a successful ransomware family which often employs advanced\r\nevasion techniques to avoid notice until the right time. It is developed and operated as ransomware-as-a-service\r\n(RaaS), meaning that threat actors can pay to make use of the software to run their campaigns.\r\nActive from early 2019, Sodin has rapidly become a dominant force in ransomware activity, quickly filling the\r\ngap left by the end of Gandcrab being available as a service. There are many good writeups of the Sodin family\r\navailable online, and in this blog post, we are not doing a full analysis of the sample. Instead, we will breakdown\r\nthe main ways in which Sodin is detectable and identifiable within a dynamic sandbox environment, aiming to\r\ngive examples of some of the techniques covered in part 1 of this miniseries.\r\nAnalyzed Samples\r\nSHA256 tria.ge Analysis\r\ne5d23a3bb61b99e227bb8cbfc0e7f1e40fe\r\na34aac4dcb80acc925cfd7e3d18ec\r\nhttps://tria.ge/reports/191216-\r\npg5st7zccj/\r\n06b323e0b626dc4f051596a39f52c46b35f\r\n88ea6f85a56de0fd76ec73c7f3851\r\nhttps://tria.ge/reports/191216-\r\n4zdx1n374x/\r\n0fa207940ea53e2b54a2b769d8ab033a6b2\r\nc5e08c78bf4d7dade79849960b54d\r\nhttps://tria.ge/reports/191216-\r\n8bfljdyw2s/\r\n139a7d6656feebe539b2cb94b0729602f62\r\n18f54fb5b7531b58cfe040f180548\r\nhttps://tria.ge/reports/191216-\r\n4rcmytrrka/\r\nRansomware Information\r\nRansomware is unusual among malware as it has no interest in hiding its infection from the user once it has\r\ncarried out its task. Sodin is no exception to this, dropping ransom notes to the directories in which it has\r\nencrypted files and changing the wallpaper to point the victim towards these files.\r\nRansom Note\r\nWe 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\r\nsummary, they contain instructions for the victim on how to pay the ransom and decrypt their files.\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 1 of 14\n\nExample ransom note created by Sodin infection\r\nIn the case of the Sodin family, this note contains several URLs which the victim is meant to visit to receive the\r\ninstructions and see how much is being demanded in ransom. No bitcoin address or information regarding the\r\nransom is available directly in this file, which is unfortunate (extracting these can be useful for tracking\r\ncampaigns/threat actors), but these URLs are still worth extracting for further investigation.\r\nThe name of the ransom note is defined by the nname field within the configuration discussed later in this blog\r\npost and will include the file extension given to all encrypted files. For example, where {\"EXT\"} is replaced by\r\nthe extension {\"EXT\"}.info.txt .\r\nAnalyzing Ransom Notes via tria.ge\r\nThe tria.ge sandbox includes detections for many aspects of ransomware but there will always be data we don’t\r\ninclude in the final report for one reason or another. However, our kernel driver maintains a record of almost all\r\nactivity on the VM which can be accessed directly via the Triage API, enabling users to run custom\r\nparsers/extractors over the data. In this section, we will do a quick example on fetching and processing this\r\ninformation to extract basic information from a Sodin ransom note - although many other uses are also possible.\r\nDocumentation for the API can be found at https://tria.ge/docs/.\r\nOnemon, the kernel driver used in Triage, records a log of system events for each task within an analysis (a ’task’\r\nis a specific VM instance run during analysis - for example a sample run on Windows 7 and Windows 10 will\r\nhave 2 tasks, 1 for each VM). This data can be downloaded in JSON format via the following command\r\ncurl -H ‘Authorization: Bearer \u003cYOUR_API_KEY\u003e’\r\n‘https://api.tria.ge/v0/samples/{sampleID}/{taskID}/logs/onemon.json'\r\nNote that you must pass your API key to access Triage endpoints. This can be found on your [account page]\r\n[acount].\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 2 of 14\n\nThe taskID field should simply be replaced by a string like task1 referencing the exact analysis you would\r\nlike to access - for reference, the taskID value can be seen in the final part of the URL when viewing a report\r\nonline.\r\nAs an example, requesting the onemon.json file for the first sample linked in this blogpost looks as follows:\r\ncurl -H 'Authorization: Bearer \u003cYOUR_API_KEY\u003e' \\\r\n 'https://api.tria.ge/v0/samples/191216-pg5st7zccj/task1/logs/onemon.json'\r\nThe file received from the API contains 1 JSON object per line, each representing an event within the system. The\r\nresults below have been prettified for readability.\r\n{\r\n \"kind\": \"onemon.File\",\r\n \"event\": {\r\n \"dstpath\": \"\",\r\n \"flags\": \"NoFileFlags\",\r\n \"id\": 844424930209781,\r\n \"kind\": \"CreateModify\",\r\n \"pid\": 1444,\r\n \"srcpath\": \"C:\\\\Users\\\\Admin\\\\AppData\\\\Local\\\\Temp\\\\st748h0795z.bmp\",\r\n \"status\": 0,\r\n \"ts\": 36769\r\n }\r\n}\r\n{\r\n \"kind\": \"onemon.Registry\",\r\n \"event\": {\r\n \"kind\": \"SetValueKeyStr\",\r\n \"path\": \"\\\\REGISTRY\\\\USER\\\\S-1-5-21-1774239815-1814403401-2200974991-1000\\\\Control Panel\\\\Desktop\\\\Wallp\r\n \"pid\": 1444,\r\n \"status\": 0,\r\n \"ts\": 36769,\r\n \"valued\": null,\r\n \"valuei\": 0,\r\n \"values\": \"C:\\\\Users\\\\Admin\\\\AppData\\\\Local\\\\Temp\\\\st748h0795z.bmp\"\r\n }\r\n}\r\n{\r\n \"kind\": \"onemon.NetworkFlow\",\r\n \"event\": {\r\n \"dstip\": 134744072,\r\n \"dstport\": 53,\r\n \"pid\": 284,\r\n \"proto\": 17,\r\n \"srcip\": 285214474,\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 3 of 14\n\n\"srcport\": 60531,\r\n \"ts\": 36894\r\n }\r\n}\r\nExample events in onemon.json\r\nEach line includes a ‘kind’ tag which defines the structure contained within the following ’event’ tag. There are\r\nmany different ‘kind’ definitions, but likely the main ones which will be of interest are onemon.Registry ,\r\nonemon.Process , and onemon.File . We can combine the ‘kind’ tag and the ‘status’ tag within the event\r\nstructure to form filters using grep, e.g., to show only events where a write operation took place in the registry, we\r\ncould use grep onemon.Registry | grep SetValueKeyStr .\r\nIn this example, we are interested in the ransom notes dropped by Sodin during analysis. By default, Triage dumps\r\nthe contents of all .txt files created by a sample so that automated processing can be carried out on the files, e.g.,\r\nto extract URLs. These dumps are (currently) stored as FileContents blocks within the onemon log:\r\n{\r\n \"kind\": \"onemon.FileContents\",\r\n \"event\": {\r\n \"buf\": \"SABlAGwAbABvACAAZABlAGEAcgAgAGYAcgBpAGUAbgBkACEADQAKAA0ACgBZAG8AdQByACAAZgBpAGwAZQBzACAAYQByAGUA\r\n \"id\": 844424930209780,\r\n \"pid\": 1444,\r\n \"ts\": 33462\r\n }\r\n}\r\nSodin ransom note in onemon.json\r\nThe onemon.FileContents blocks are linked to standard onemon.File events where the sample performed a\r\nCreateFile operation for a .txt file. These blocks contain metadata useful for relating the file dumps to their\r\noriginal file names and paths, the ID value shown above acts as the reference. Note the \"flags\":\r\n\"DumpContents\" field in this event type\r\n{\r\n \"kind\": \"onemon.File\",\r\n \"event\": {\r\n \"dstpath\": \"\",\r\n \"flags\": \"DumpContents\",\r\n \"id\": 844424930209780,\r\n \"kind\": \"CreateModify\",\r\n \"pid\": 1444,\r\n \"srcpath\": \"C:\\\\Users\\\\Public\\\\Videos\\\\Sample Videos\\\\43s40i71l.info.txt\",\r\n \"status\": 0,\r\n \"ts\": 33462\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 4 of 14\n\n}\r\n}\r\nIf we are looking for a specific file, we can grep through the json for the file name and then pick out the specific\r\nFileContents block that we were looking for based on the ID value.\r\nThe \"buf\" section of the FileContents block shown above is a base64-encoded representation of the data written\r\nto the file, extracted by intercepting the API call for the file write and dumping the buffer contents. In order to\r\nretrieve the original contents, simply decode the value.\r\nAt this point the entire contents of the file are available in plaintext for any further processing desired - extracting\r\ncontact URLs/email addresses, bitcoin wallets, personal identifier codes etc.\r\nWe have produced a simple Python script which, when passed a Triage analysis ID and your API key, will perform\r\nthe process outlined above and dump every .txt file found in the onemon.json to the current directory. It will\r\ngenerate a number of .txt files. You can find the script here. To use it, you’ll need the Triage ID, the task ID of\r\nthe analysis you want to examine, and your API key for tria.ge. Usage may look as follows:\r\npython3 triage-ransomnote.py \u003cAPI-Key\u003e 191216-4rcmytrrka task1\r\nRansom Portal Overview\r\nThe URLs contained within the ransom note lead to a web portal customized to the victim based on a generated\r\nID value, which is the final part of the address (see ransom note above). To make it harder for analysts to use\r\nautomated tools to gather information, victims must enter some basic information when accessing their portal - a\r\ngenerated ‘key’ visible in the ransom note and the extension used when encrypting files (this can differ based on\r\nthe configuration settings).\r\nRansom portal landing page\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 5 of 14\n\nAfter submitting this information, the victim can then access payment details and other information, including\r\nguides on using Bitcoin; a trial decryptor that can be used on a single file; and even a chat support feature to get\r\nassistance from the malware operators.\r\nMain elements of Sodin ransom portal\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 6 of 14\n\nMain elements of Sodin ransom portal\r\nThe most useful information on this page is the ransom price and the Bitcoin address which is to be used for\r\npayment - using a framework like Selenium it would be possible to automate the gathering of these addresses for\r\ntracking.\r\nDesktop Wallpaper Change\r\nTo make sure the victim is aware of the infection, Sodin also generates a new desktop background image and\r\nmakes it active via the registry.\r\nThe image is a bitmap created through the DrawTextW function in User32.dll. The text to be written is defined\r\nwithin the malware’s JSON config section (discussed later in this post).\r\nSample passes string into DrawTextW to create background image\r\nThe image is saved to the user’s Local AppData directory with a random file name, and the registry key\r\nHKCU\\\\Control Panel\\\\Desktop\\\\Wallpaper is set to point to the new file.\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 7 of 14\n\nPreventing System Recovery\r\nLike many other ransomware families, Sodin attempts to make recovery of the infected machine more difficult by\r\ndisabling or removing some Windows features. It achieves this using common vssadmin and bcdedit\r\ncommands.\r\nBrief descriptions of these commands are provided below for reference. In a dynamic analysis environment, these\r\nare reasonably clear indicators of maliciousness, as there are few legitimate reasons for an application to delete\r\nbackups or interfere with boot settings.\r\nCommand Description\r\nvssadmin Delete Shadows /All /Quiet Delete system shadow copies\r\nbcdedit /set {default} recoveryenabled\r\nNo\r\nDisables Windows Error Recovery on startup\r\nbcdedit /set {default} bootstatuspolicy\r\nignoreallfailures\r\nSets system to ignore errors and boot as normal (NB: this is also\r\nthe default Windows setting)\r\nConfiguration\r\nTo enable threat actors to customize their Sodin campaign, the family includes a configuration file embedded\r\nwithin the executable. This is packaged as a PE section with a distinct name - the 2 variants we have examined for\r\nthis blogpost used .grrr and .zeacl .\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 8 of 14\n\nPE sections from unpacked Sodin samples\r\nThese sections are a JSON configuration file encrypted using RC4 which contain a large amount of information\r\nabout the particular campaign the sample belongs to\r\n{\r\n \"pk\": \"GadtWz2QBTacskL+55Wpo65IkwY28qJOxHoe4Xte81M=\",\r\n \"pid\": \"10\",\r\n \"sub\": \"7\",\r\n \"dbg\": false,\r\n \"fast\": true,\r\n \"wipe\": true,\r\n \"wht\": {\r\n \"fld\": [\"appdata\", \"google\", \"msocache\", \"mozilla\", \"program files\", \"windows\", \"perflogs\", \"application\r\n \"fls\": [\"ntuser.dat.log\", \"bootsect.bak\", \"ntuser.dat\", \"iconcache.db\", \"ntldr\", \"autorun.inf\", \"boot.in\r\n \"ext\": [\"ldf\", \"msi\", \"nomedia\", \"msu\", \"wpx\", \"ani\", \"shs\", \"theme\", \"386\", \"adv\", \"icns\", \"lnk\", \"ico\"\r\n },\r\n \"wfld\": [\"backup\"],\r\n \"prc\": [\"mysql.exe\"],\r\n \"dmn\": \"lyricalduniya.com;theboardroomafrica.com;chris-anne.com;ownidentity.com;web865.com;[...]\",\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 9 of 14\n\n\"net\":true,\r\n \"nbody \":\"SABlAGwAbABvACAAZABlAGEAcgAgAGYAcgBpAGUAbgBkACEADQAKAA0ACgBZAG8AdQByACAAZgBpAGwAZQBzACAAYQByAGUAIA\r\n \"nname\": {\"EXT\"}.info.txt,\r\n \"exp\":false,\r\n \"img\":\"WQBvAHUAcgAgAGYAaQBsAGUAcwAgAGEAcgBlACAAZQBuAGMAcgB5AHAAdABlAGQAIQAgAE8AcABlAG4AIAB7AEUAWABUAH0ALgBpA\r\n}\r\nThere are quite a few useful fields in here - these are outlined in the table below.\r\nField\r\nName\r\nDescription\r\npk Base64-encoded public key used for file encryption\r\npid Only used if net field is also set, sent to C2 servers. Likely related to campaign identifier etc.\r\nsub See pid\r\ndbg Enable/disable debug mode (for the malware author)\r\nfast Boolean value which changes how large files are encrypted\r\nwipe Boolean. If set, sample will try to erase contents of folders blacklisted in the wfld field\r\nwht Defines whitelists for encryption process. Contains 3 sections:\r\n1. fld : folders to ignore\r\n2. fls : specific files to ignore\r\n3. ext : whitelisted file extensions\r\nwfld\r\nList of folder names. If the wipe field is set to true then the malware will attempt to erase the\r\ncontents of all folders\r\nprc List of process names the malware will try to terminate before carrying out file encryption\r\ndmn List of domain names which the malware will attempt to contact to use as C2\r\nnet\r\nBoolean value. Sets whether sample should send host information to C2 servers listed in dmn\r\nkey\r\nnbody Base64-encoded version of the ransom note dropped to the file system after encryption\r\nnname Filename of the ransom note\r\nexp\r\nBoolean value. Defines whether or not the malware will use an exploit to try and escalate\r\nprivileges on the system\r\nimg Base64-encoded version of the text shown in the wallpaper background set by the malware.\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 10 of 14\n\nConfiguration field details\r\nWhen delivered to a new system Sodin samples are packed using a custom algorithm, hiding the existence of the\r\nspecially named resource sections. The malware uses a PE overwrite approach to its unpacking mechanism - it\r\nallocates heap space using LocalAlloc, writes the unpacker stub to it, and then passes execution to that area after\r\nmarking it RWX with VirtualProtect.\r\nCreate and call unpacker stub\r\nThe unpacker stub then writes the new PE to the address space in which the original file was mapped, clearing the\r\ncontent of the entire region before writing the new executable and jumping back to the updated Entry Point. We\r\ncan now dump the executable and examine the sections, as shown previously.\r\nThe configuration itself is still encrypted at this stage, but in its unpacked form it is possible to analyze the\r\ndecryption process and recreate it. The algorithm is RC4 - we can clearly see the SBox creation and swapping\r\noperations\r\nbut some minor changes have been made to prevent easy decryption with standard RC4 tools.\r\nExamining the executable we can see that the key for the decryption is the first 32 bytes of the resource section.\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 11 of 14\n\nPreparing keylength and ciphertext parameters and passing them to the configuration\r\ndecryption function\r\nWith this information and analysis of the decryption function, it was possible to build a configuration extractor to\r\nparse and report details from these configurations during dynamic analysis of the samples. In Hatching Triage, we\r\nhave implemented a system that enables taking process memory dumps when particular conditions are met during\r\nan analysis. Using this, we can obtain the unpacked executable and run processing on it to include the information\r\nin the analysis report and enable easy identification of particular campaigns or actors.\r\nThe Sodin extractor is not available on Triage yet while testing and improvements to the memory dumping\r\nmethodology are implemented, but keep an eye on our Twitter account for updates when that is released.\r\nFile Encryption\r\nSodin can encrypt files on local storage or any mapped network shares, overwriting the original files and\r\nrenaming them with an extension generated on a per-infection basis. This process is highly customizable through\r\nthe embedded configuration section, allowing for certain files/folders to be whitelisted and protected from the\r\nencryption process. The Sodin executable also accepts a command-line parameter - by passing the value -nolan ,\r\none can disable the encryption of mapped network shares and limit the effects to only the infected machine.\r\n\"wht\": {\r\n \"fld\": [\"appdata\", \"google\", \"msocache\", \"mozilla\", \"program files\", \"windows\", \"perflogs\", \"application dat\r\n \"fls\": [\"ntuser.dat.log\", \"bootsect.bak\", \"ntuser.dat\", \"iconcache.db\", \"ntldr\", \"autorun.inf\", \"boot.ini\",\r\n \"ext\": [\"ldf\", \"msi\", \"nomedia\", \"msu\", \"wpx\", \"ani\", \"shs\", \"theme\", \"386\", \"adv\", \"icns\", \"lnk\", \"ico\", \"i\r\n}\r\nWhitelist configuration section\r\nThe keys specify whitelists for:\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 12 of 14\n\nfld - folder names\r\nfls - specific file names\r\next - file extensions\r\nThe malware iterates through every directory and file on the system, checking them against these configuration\r\nvalues and queuing them up for encryption if they are not excluded. Once encrypted, the files are renamed with a\r\nnew extension.\r\nEncrypted File Extension\r\nBefore starting the encryption process, Sodin generates the random file extension which is applied to every\r\nencrypted file. The extension is a string of letters and numbers from 5 to 10 characters long, which is generated\r\nand saved to the registry along with other information gathered at various stages (discussed below).\r\nFile extension saved to SOFTWARE\\\\WOW6432Node\\\\recfg\\\\rnd_ext\r\nThe extension itself is tricky to accurately identify as Sodin-related due to the generic nature of it, but the registry\r\npath is relatively specific and is readily detectable in a sandbox.\r\nOther Registry Changes\r\nAs well as the file extension, Sodin saves a few other bits of data to the Software\\\\Wow6432Node\\\\recfg registry\r\nkey .\r\nValues within the recfg registry key\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 13 of 14\n\nNone of the values assigned to these keys are static, but all of the key names are common across Sodin samples.\r\nWe won’t go into the details of these here, but the image above gives a basic outline of the contents.\r\nIn a dynamic environment, this sort of registry structure is ideal for identifying a family.\r\nTria.ge signature output for registry keys\r\nConclusion\r\nSodin is a complex family with far more functionality than we have covered here, but this has outlined the main\r\nindicators which are useful for identifying samples within a dynamic environment like Triage. References to a\r\nnumber of samples used as source material for this post can be found in the header at the top of the page.\r\nWe’ll be continuing to expand coverage over the coming weeks for ransomware families with ransom note and\r\nconfiguration extractors. In the next post in this mini-series we’ll cover another family which poses some different\r\nchallenges to analysis and present ways to solve them.\r\nUntil next time, Happy Holidays!\r\nSource: https://hatching.io/blog/ransomware-part2\r\nhttps://hatching.io/blog/ransomware-part2\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://hatching.io/blog/ransomware-part2"
	],
	"report_names": [
		"ransomware-part2"
	],
	"threat_actors": [],
	"ts_created_at": 1775439113,
	"ts_updated_at": 1775791321,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/5ad270dd080f0a9a33e27a22a55842a1ffa98ce1.pdf",
		"text": "https://archive.orkl.eu/5ad270dd080f0a9a33e27a22a55842a1ffa98ce1.txt",
		"img": "https://archive.orkl.eu/5ad270dd080f0a9a33e27a22a55842a1ffa98ce1.jpg"
	}
}