Pulling the Curtains on Azov Ransomware – Not a Skidsware but Polymorphic Wiper

The abundance of samples has allowed analysts to distinguish two different versions of Azov, one older and one slightly newer.
These two versions share most of their capabilities, but the newer version uses a different ransom note, as well as a different file extension for destroyed files (.azov).

Technical Analysis: Highlights
Manually crafted in assembly using FASM
Using anti-analysis and code obfuscation techniques
Multi-threaded intermittent overwriting (looping 666 bytes) of original data content
Polymorphic way of backdooring 64-bit “.exe” files across the compromised system
“logic bomb” set to detonate at a certain time. The sample analyzed below was set to detonate at 10-27-2022 10:14:30 AM UTC
No network activity and no data exfiltration
Using the SmokeLoader botnet and trojanized programs to spread
Effective, fast, and unrecoverable data wiper

The focus is on the original sample of the newer Azov version (SHA256: 650f0d694c0928d88aeeed649cf629fc8a7bec604563bca716b1688227e0cc7e — as pointed out above, there is no major difference in functionality compared to the older version). This is a 64-bit portable executable file that has been assembled with FASM (flat assembler), with only 1 section .code (r+x), and without any imports.

The .code section has three parts, which are most easily seen by looking at its entropy. First, there is a high-entropy part containing the encrypted shellcode. It is followed by plain code implementing the unpacking routine, and then the last part, with very low entropy, appears to consist of plain strings used to construct the ransom note.

The unpacking routine in the function AllocAndDecryptShellcode() is intentionally created to look more sophisticated than it is. But in reality, it is a simple seeded decryption algorithm using a combination of xor and rol, where key = 0x15C13.

The wiping routine begins by creating a mutex (Local\\azov) to verify that two instances of the malware are not running concurrently.

If the mutex handle is successfully obtained, Azov creates persistence by trojanizing (similar to the backdooring routine) the 64-bit Windows system binary msiexec.exe or perfmon.exe and saving it as rdpclient.exe. A registry entry at SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run is created pointing to the newly created file.

The wiping procedure uses a trigger time – there is a loop where the analyzed sample checks system time, and if it is not equal to or larger than the trigger time, it sleeps 10s and loops again.

Once this logic bomb triggers, the wiper logic iterates over all machine directories and executes the wiping routine on each one, avoiding certain hard-coded system paths and file extensions.
Each file is wiped “intermittently”, by which analysts mean a block of 666 bytes is overwritten with random noise, then an identically-sized block is left intact, then a block is overwritten again, and so on — until the hard limit of 4GB is reached, at which point all further data is left intact.

Once the wiping is finished, the new file extension .azov is added to the original filename.

Backdooring Routine
Before traversing the filesystem to search for files to be backdoored, a mutex named Local\\Kasimir_%c is created, with the %c replaced with the letter of the drive being processed.

The function TryToBackdoorExeFile() is responsible for backdooring 64-bit “.exe” files that meet certain conditions.

These specific conditions could be simplified as follows:

Pre-processing conditions:
It is not a part of the exclude list of filesystem locations
The file extension is “.exe”
The file size is less than 20MB
Processing conditions:
The file is a 64-bit executable file
The PE section containing the Entry Point has enough space for the shellcode implant to be injected in the way of preserving the original Entry Point of PE (the shellcode start address will be placed at the address of the original Entry Point)
File size == PE size (PE size is manually calculated)
The processing conditions are all checked in the function TryToBackdoorExeFile().

Once the file meets all pre-processing and processing conditions, it is considered suitable for backdooring and pushed to function BackdoorExeFile().
The function BackdoorExeFile() is responsible for the polymorphic backdooring of executable files.
It first obtains the address of the original code section (usually the .text section) and randomly modifies its content in several locations. Before injecting the main blob of shellcode into the modified code section, certain constant values are changed, and the whole shellcode is re-encrypted with the same encryption algorithm and key as used during the unpacking of the malware, described earlier.
After the backdoored file is written back to disk, three encoded data structures are appended to its end, which are effectively resources needed for the ransomware to function (for instance, an obfuscated form of the ransom note).

Despite the polymorphic backdooring, the encryption/decryption algorithm used during the unpacking and backdooring is consistent and can be used for Azov detection.
Anti-analysis and code obfuscation techniques
Preventing usage of software breakpoints – using routines that copy already decrypted and currently executing parts of shellcode to newly allocated memory and later transferring execution to it will sooner or later result in an exception if software breakpoints are set. In such situations, it is necessary to use hardware breakpoints.

Opaque constants – replacing constants with a code routine producing the same resulting constant’s value. (This can be repeatedly seen in routines responsible for calculating constant offsets rather than using them directly so that a direct call can be replaced with an indirect call)

Syntactic confusion – replacing an instruction with semantically equivalent instruction(s) that are not idiomatic, or are outright bloat. One example of this is found in the routine responsible for parsing the export directory; another is the repeated replacement of a call with a direct or indirect jmp.

Dead (junk) code – insertion of garbage bytes which results in no meaningful instructions or even no instructions at all.

Opaque predicates – a jz/jnz that at first sight appears to be a conditional jump in practice has the condition always met (or always not met) and effectively functions as an unconditional jump, confusing static analysis.

These two obfuscations can both be seen in the function FindGetProcAddress().

Sign Up For Threat Alerts

Loading...
Threats Icon

Feb 02, 2023

Ukraine CERT-UA: Compromised Email Address Used To...

An adversary was discovered using a compromised e-mail address to send phishing emails with a...

Threats Icon

Feb 01, 2023

Ukraine Government Sector Targeted With The DolphinCape...

The government sector of Ukraine was targeted with spear-phishing emails with a malicious attachment which...

Threats Icon

Feb 01, 2023

Ukraine Government Sector Targeted With The DolphinCape...

The government sector of Ukraine was targeted with spear-phishing emails with a malicious attachment which...

Threats Icon

Jan 31, 2023

Multiple Malware Variants Distributed Through Microsoft OneNote

Spear-phishing emails with malicious Microsoft OneNote attachments were discovered delivering variants from the AsyncRAT, Formbook¸...

Threats Icon

Jan 30, 2023

Playing Whack-a-Mole With New Dharma Ransomware Variants

The Dharma ransomware family was initially identified in 2016 and operates as a Ransomware-as-a-Service (RaaS)...

Threats Icon

Jan 29, 2023

APT15 Targets Multiple Sectors With Turian Backdoor

APT15, also known as Playful Taurus, is an advanced persistent threat (APT) that conducts a...

Threats Icon

Jan 26, 2023

Vice Society Ransomware Group Targets Manufacturing Companies

The Vice Society threat group was discovered targeting multiple sectors including manufacturing companies in Brazil....

Threats Icon

Jan 26, 2023

US Cert Alert – Alert (AA23-025A) Protecting...

Although this campaign appears financially motivated, the authoring organizations assess it could lead to additional...

Threats Icon

Jan 25, 2023

Emotet Malware Makes a Comeback with New...

The Emotet malware operation has continued to refine its tactics in an effort to fly...

Threats Icon

Jan 25, 2023

DragonSpark

The DragonSpark attacks represent the first concrete malicious activity where Analysts observe the consistent use...

Threats Icon

Jan 25, 2023

PLAY Ransomware

PLAY is simple but heavily obfuscated with a lot of unique tricks that have not...

Threats Icon

Jan 24, 2023

Gamaredon Abuses Telegram To Target Ukrainian Government...

The Gamaredon APT group was discovered targeting Ukrainian government entities using the Telegram messaging service...

Threats Icon

Jan 23, 2023

NeedleDropper: A New Dropper-as-a-Service Uncovered

Avast's Threat Research Team has since October 2022 been observing a new strain of dropper...

Threats Icon

Jan 22, 2023

Aurora Stealer Leverages Shapeshifting Tactics And Popular...

A threat actor was discovered mimicking legitimate websites to host and deliver the 9002 RAT,...

Threats Icon

Jan 19, 2023

Earth Bogle Campaign Targets Entities With Geopolitical...

Middle Eastern geopolitical themed lures were used to distribute njRAT across the Middle East and...