Attack Chain Déjà-vu: The infection vector used by SVCReady, Gozi and IcedID
Early June 2022, HP Threat Research published a blog post about a newly discovered malware named SVCReady, notable for using Word document properties to store shellcode used in its attack chain.
DCSO CyTec has been observing similar attack chains since the beginning of March 2022 at the earliest, previously used to deliver IcedID instead of the later discovered SVCReady malware. In addition, a tweet by Cert AgID in April 2022 seems to document a very similar attack chain resulting in the distribution of Gozi (aka Ursnif) malware.
It thus appears the attack chain, common to all 3 instances, predates the appearance of the SVCReady malware itself and is independent of the distributed malware. This implies that the same attack chain may be utilized to distribute other malware in the future, which is why we decided to investigate and take a closer look.
This blogpost was authored by Johann Aydinbas
Layer 1 — Word Macros
As is often the case, the attack chain starts with a lure document using macros in order to infect a client. The macro code varies slightly between samples, sometimes employing minor obfuscation techniques such as reversing strings or storing them in document properties instead of hardcoding them into the macro code.
In general the macro:
- defines environment variables to communicate with the final stage of the attack chain
- extracts and decodes appropriate (32/64bit) shellcode from document properties
- executes the shellcode via
SetTimer
API call
All macros use two fixed environment variables for communicating with RemoteDllLoader, an as of now undocumented (though mentioned by Cert AgID) component appearing later in the execution chain.
RemoteDllLoader has two execution modes. It can either be supplied a URL from where to fetch the final payload, or it can be pointed to a custom archive format file from which to extract the final payload.
For this purpose, the macro signals which mode to operate in by setting one or both environment variables. The variable names itself resemble a GUID and have remained unchanged since the beginning.
If the macro sets both, {FCF2382A-4DD7–4FBE-9E77–0EE3DD66379A}
specifies the full path to the Word document itself, which contains the embedded custom archive, while {1F79AEE7–7F65–4B80-A1C6-E5C90A7BE6CF}
contains the name of the embedded archive file.
Otherwise, the macro only sets {FCF2382A-4DD7–4FBE-9E77–0EE3DD66379A}
which will contain a URL to fetch the payload from.
Finally, the shellcode embedded in the document properties is executed using the SetTimer
API.
Layer 2 — Shellcode Decoder
The shellcode extracted from the document properties is encrypted. It is prefixed by a small custom decoding routine which appears multiple times throughout the attack chain and involved components.
The decoder expects the trailing encrypted payload in the following format:
[DWORD type]
[DWORD xor key length]
[DWORD payload length]
[* xor key]
[* payload]
It then proceeds with decrypting the payload with a cyclic xor using the embedded key. After decryption, the decoder checks if the “type” DWORD is set to 0xE8
— if this is the case, the decoder executes the decrypted data as code, otherwise it just returns.
At this point, the type is set to 0xE8
and thus the decoder continues with executing the just decoded code.
This stage is a result of the ongoing development process. It was missing in the earliest sample used to drop IcedID, and later samples also started to include minor variations such as adding a fixed key (xor 0xAA) on top.
Layer 3 — DLL Loader
The DLL loader consists of another shellcode stub and payload.
Here, the code stub is responsible for loading the appended RemoteDllLoader
DLL file via manual mapping. Manual mapping is the process of loading a PE file without using common API functions like LoadLibrary
in order to stay under the radar of security products.
Once the PE file has been mapped, the code executes the entry point as specified in the image header, to which it passes a magic number 0x54E1C0DE as the first argument (in place of fdwReason
as expected for DLL entry points).
At its entry point, RemoteDllLoader
verifies the presence of this magic number. This prevents sandboxes from properly executing the malware. If the magic number is not supplied, as would be the case in a sandbox loading the DLL the normal way, the DLL quits without further action.
Layer 4 — RemoteDllLoader
RemoteDllLoader finally is the component responsible for either fetching and executing the final payload, or extracting it from a previously specified custom archive format before execution.
URL Mode
In URL mode, RemoteDllLoader fetches the URL as specified in the environment variable {FCF2382A-4DD7–4FBE-9E77–0EE3DD66379A}
by the Word macro, using the API URLDownloadToFileA
to a temporary path.
If the downloaded file is a DLL, a copy of rundll32.exe
is used to execute its DllRegisterServer
export whereas EXE files are executed using the WinExec
API.
Archive Mode
Despite its name, RemoteDllLoader does not have to fetch its payload from a URL.
The initial Word macro can point RemoteDllLoader to a zip file and a file name of a custom archive contained in that zip file, from where the payload will be extracted.
As .docx
files are essentially zip files, the custom archive is distributed embedded inside the .docx
itself, and the initial macro points RemoteDllLoader to a specific file inside the lure document via environment variables.
The custom archive uses the same format as used in Layer 2 with the same shellcode stub responsible for decrypting the payload.
In this case the “type” is set to 0xEA
so the decoder stub does not execute the decrypted payload directly. Execution then proceeds as documented for URL mode, concluding the attack chain with the execution of the payload.
IoCs
You can grab the raw IoCs from our GitHub.
MISP
If you prefer MISP, you can find the IoCs in form of a MISP event on our GitHub as well.
MITRE ATT&CK
T1027 Obfuscated Files or Information
T1566 Phishing
T1001 Data Obfuscation
T1059.005 Visual Basic
T1497 Virtualization/Sandbox Evasion