MosaicRegressor: Lurking in the Shadows of UEFI. We present an extremely detailed analysis and mechanism of action of this APT.

MosaicRegressor is a multi-stage and modular framework aimed at espionage and data gathering. It consists of downloaders, and occasionally multiple intermediate loaders, that are intended to fetch and execute payload on victim machines. In two known cases, the initial stage of the framework was installed in the victim’s UEFI firmware, achieving the above-OS level of persistence.

UEFI Bootkit

When inspecting the compromised UEFI firmware, we noticed four components that had unusual proximity in their assigned GUID values. These were two DXE drivers and two UEFI applications. Upon closer analysis, we could conclude that those were compiled from the source code of a Hacking Team bootkit named VectorEDK, that was leaked in 2015 and is now available online.

umair-akbar-EMaNW9P 1024x373 - US Indicts Sandworm, Russia's Most Destructive Cyberwar Unit
Rogue components found within the compromised UEFI firmware

Following is an outline of the revealed components:

F5B320F7E87CC6F9D02E28350BB87DE6 (SmmInterfaceBase)

0C136186858FD36080A7066657DE81F5 (SmmAccessSub)

91A473D3711C28C3C563284DFAFE926B (SmmReset)

DD8D3718197A10097CD72A94ED223238 (Ntfs)

  • SmmInterfaceBase: a DXE driver intended to deploy the bootkit itself on the system by registering a callback that willbe invoked upon an event of type EFI_EVENT_GROUP_READY_TO_BOOT. The event occurs at a point when control can be passed to the operating system’s bootloader, effectively allowing the callback to take effect before it. The callback will, in turn, load and invoke further components of the bootkit, in this case ‘SmmAccessSub’. This is equivalent to Hacking Team’s ‘rkloader’ component, and is built using its source code.
  • Ntfs: a driver used to parse the NTFS file system to allow reading or writing to disk.
  • SmmReset: a UEFI application intended to mark the execution of the bootkit. This is done by setting the value of avariable named ‘fTA’ to a hard-coded GUID. The same is done by the original Vector-EDK bootkit as part of the bootkit’s main business logic. In this case, it’s not invoked and it seems to be a residue from the open source code that was not properly leveraged by the developers.


umair-akbar-image 1 - US Indicts Sandworm, Russia's Most Destructive Cyberwar Unit
Setting of the fTA variable with a predefined GUID to mark the execution of the bootkit


  • SmmAccessSub: the main bootkit component that serves as a persistent dropper for user-mode malware. It is executed bythe callback registered during the execution of ‘SmmInterfaceBase’, and takes care of writing a binary embedded within it as a file named ‘IntelUpdate.exe’ to the startup directory on disk. This allows the binary to run when Windows accomplishes the boot process.

This is the only proprietary component amongst the ones we inspected, which doesn’t rely on Vector-EDK code. It conducts the following actions to drop the intended file to disk:

– Bootstraps pointers for SystemTable, BootServices and RuntimeServices global structures.

– Tries to get a handle to the currently loaded image by invoking the HandleProtocol method with the EFI_LOADED_ IMAGE_PROTOCOL_GUID argument.

– If it succeeds, it attempts to find the root drive with Windows installation by enumerating all drives and checking that the ‘\Windows\System32’ directory exists. A global EFI_FILE_PROTOCOL object that corresponds to the drive will be created at this point and referenced to open any further directories or files on this drive.

– If the root drive is found, it looks for a marker file named ‘setupinf.log’ under the Windows directory and proceeds only if it doesn’t exist. In the absence of this file, it is created.

– If the creation of ‘setupinf.log’ succeeds, it goes on to check if the ‘Users’ directory exists on the same drive.

– If the ‘Users’ directory exists, it writes the ‘IntelUpdate.exe’ file (embedded in the UEFI application’s binary) under the ‘\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup’ directory.

umair-akbar-image 2 - US Indicts Sandworm, Russia's Most Destructive Cyberwar Unit
Code from ‘SmmAccessSub’ used to write the embedded ‘IntelUpdate.exe’ binary to the Windows startup directory

RAR SFX droppers for the Curl-based downloaders

These are several SFX droppers with decoy documents that were sent to victims by e-mail. Each contains a document and a variant of a Curl-based downloader or a Winhttp-based downloader


This file is a plain RAR archive with one EXE file inside.

2214612018-03-27Health and Ageing on the occasion of the World Health Date_180326.exe0efb785c75c3030c438698c77f6e960e

The EXE file in turn is also a RAR SFX archive with the following contents:


umair-akbar-EMaNW9P 1 1024x373 - US Indicts Sandworm, Russia's Most Destructive Cyberwar Unit

RAR SFX script:

umair-akbar-cc7z3kC 1024x130 - US Indicts Sandworm, Russia's Most Destructive Cyberwar Unit

Mechanism of Action

Mutex name: “FindFirstFile Message Bi”

Enumerates all BITS jobs. For a job whose display name contains the substrings “first_tf” or “second_tf” and overall display name is five or six characters (this never happens since the conditions are contradictory), it cancels the job, effectively interrupting the transfer and removing temporary files. Then the module follows its business logic in a separate thread while running an empty window message loop in the startup thread.

Main thread

The program contains four blocks of data encrypted with a simple one-byte XOR algorithm. Three of those blocks contain URL strings and the fourth contains a unique string, “D22”.

It builds an identification string following the format: %Computer name%-D22_32 or 64

The 32 or 64 suffix is chosen based on system identification. The system is supposed to be 64 if the program is able to locate the file or directory named %WINDIR%\SysWOW64

The program then follows into an infinite C&C communication loop. It delays for a hardcoded period of 20 minutes between each attempt.

C&C Communication

The module compiles a final URL string following the format: URL from the decrypted buffer/identification string/on.z

It then attempts to download the contents of that URL to the file %TEMP%\on.dat using its BITS transfer routine. The contents of the file areignored and the file is deleted immediately after transfer. This initial download is used to determine the valid C&C server. The module iterates through all three URLs hardcoded in its body and uses the first one that responds without error for further communication.

In case any of the C&C servers provided a valid response, the program sends another download request for: URL of the

valid C&C server/identification string/BeFileA.z The downloaded contents are then saved to: %TEMP%\BeFileA.dll

It also tries to fetch the file using the URL: URL of the valid C&C server/identification string/BeFileC.z and save it to:


The file “BeFileA.dll” is downloaded only once during the duration of the program’s instance and is loaded in a separate thread.

The attempts to download the file “BeFileC.dll” occur in every communication period. The file is loaded in the same thread.

BITS Transfer

The program creates a new BITS job. For a download job it names the job “first_tf” and for the upload tasks it uses the name “second_tf”. Other versions use slightly different strings as job names but they all start with “first” and “second” correspondingly, and are always identical to the names of the jobs that are cancelled during the startup. The job is started with the priority setting “BG_JOB_PRIORITY_FOREGROUND”. It also toggles the security options “BG_SSL_IGNORE_ CERT_CN_INVALID”, “BG_SSL_IGNORE_CERT_DATE_INVALID”, “BG_SSL_IGNORE_UNKNOWN_CA”, to accept invalid HTTPS certificates.

It then waits for up to about five minutes for the BITS job to complete, also extending the wait if the actual transfer is in progress.

Loading the DLL modules

The module expects the files provided by the C&C server to be PE DLLs. They are loaded normally using the LoadLibrary API function. Each DLL may have one or more exported functions named “CallA”, “CallB”, “CallC”, “CallD”, “CallE”.

All exported functions are supposed to have the same ABI: cdecl calling convention, five arguments all passed by pointers. Following the execution of each function the program delays for one second and then processes the results returned in these arguments. Depending on the data returned by the exported function, the program may then download or upload arbitrary files from/to arbitrary URLs using its BITS transfer routine. Also, depending on the returned data, it may delete or leave the DLLs file on disk.

Then it checks if a corresponding “dat” file exists in the %TEMP%directory. In case the file exists it uploads it to the C&C server using the BITS transfer routine, the same URL except the last component is identical to the actual filename. The “dat” file is deleted if the upload succeeds.

umair-akbar-image 3 - US Indicts Sandworm, Russia's Most Destructive Cyberwar Unit

This module is similar to the “BITS Downloader” and appears to be based on the same code. The differences follow. It uses a different mutex name: “set instance state”.

After starting the C&C communication thread, the program sets the registry value HKEY_CURRENT_USER\Software\ Microsoft\Windows\CurrentVersion\Run, value name qwinstd, to the location of its own executable. It also overwrites the value if it is not equal to the location of the executable. This ensures the program’s automatic startup. Also the program sets up a timer callback routine to be called every second. The routine looks for the file %APPDATA%\Microsoft\Internet Explorer\ When such a file is found it acts as a kill switch: the file deleted, the BITS Jobs are cancelled and the program exits.

Instead of the %TEMP% directory this version uses the directory %APPDATA%\Microsoft\Internet Explorer to store its temporary files.

System information

The module creates a text file %APPDATA%\Microsoft\Internet Explorer\%Computername%.dat and fills it with system information. Note the non-ASCII symbols 0xA3 and 0xBE used in the string literals. These were replaced with a colon character (See “Language artifacts”).

Host Infomation:

EXE ID: %Unique ID, see table%

Host Name: %Computername%

Current User Name: %USERNAME%

PRIVILEGE: %User privilege%

OS: Windows NT %Major%.%Minor%\t%Service pack string%\t%Product type%\tSystemMetrics:

%Build number for Windows 5.2%\tSuiteMask hex: %Suite mask%

OS BITS: %32 or 64%

Host Power ON Time: %04d-%02d-%02d %02d:%02d

Power ON Time: %d Hours %2d Minutes %2d Seconds *or*Power ON Time: %2d Minutes %2d Seconds

Installed Programe List 32:

*the following list is the contents of registry keys from HKLM\SOFTWARE\Microsoft\Windows\ CurrentVersion\Uninstall*

*%Item number%* *%Registry key last write timestamp in format %04d-%02d-%02d %02d:%02d%* %Display Name%

*optional, when the program determines that it is running on a 64-bit OS, it disables 64/32 registry reflection and enumerates the installed program list again, generating a similar list with a header “Installed Programe List 64”*


Stay tuned for part 2: We discuss the actual payload.

About the Author


Umair Akbar | Cloud Engineer

Umair Akbar is a Senior Information Security Engineer with over 5 years of experience leading the development and daily management of InfoSec systems.

View All Articles