On this page:
Threat Detection
December 11, 2024
An in-depth analysis of Xloader malware delivered via spoofed SharePoint notifications.
Sublime recently prevented a malicious SharePoint impersonation attempting to deliver malware via a link in the message.
Our analysis led us through a complex chain of obfuscation, zip files, AutoIT, shellcode, and multiple rounds of process injection. We believe with high confidence that the final deployed payload is Xloader (Formbook), an information stealer that primarily harvests user credentials, keystrokes and screenshots, and with moderate confidence that the initial loading component is related to Trickgate.
In this post, we’ll walk through the details of our analysis starting with the detection of the SharePoint impersonation.
This attack starts with the target receiving a message that looks like a legitimate SharePoint share with an Open files link, including the standard “share” logo and the Microsoft brand logo.
This message was caught by Sublime after triggering multiple Detection Rules and earning an Attack Score Verdict of malicious
.
Sublime's AI-powered detection engine prevented this attack. The top signals in these attacks are:
See the full Message Query Language (MQL) that detected these attacks in these publicly available Detection Rules in the Core Feed:
The Open files button led to a .zip file hosted on a non-SharePoint URL. Within a safe environment, we downloaded and extracted its contents for further analysis: document.exe
.
To obtain more information on the file, we used Detect It Easy to provide an initial overview and determine how to proceed with analysis. Detect It Easy was able to recognize the file as AutoIT
, which is a scripting language that allows for automation of windows tasks and systems management. AutoIT has many legitimate purposes, but it is often utilized by malicious actors due to its relative simplicity, flexibility, and ability to be turned into executable files.
Standard analysis tools don’t handle AutoIT well, so we grabbed an AutoIT decompiler from GitHub and deployed it to our analysis machine. When we decompiled document.exe
, we got the original AutoIT script used to create the binary file.
The script begins with a large blob of obfuscated text stored in a single parameter.
After the large blob of text is assigned to the $vwcpaypcs
variable, the script contains logic to decode the blob as well as other smaller obfuscated pieces. Each piece of obfuscated text contains the string "eocs29" repeated multiple times for each string.
After removing the eocs29
string with find/replace, we determined that the code was a loader for the initial blob of text. Based on the presence of VirtualProtect
and DllCallAddress
, we made the safe assumption that it was executable code, likely in the form of shellcode.
Close inspection of the code also revealed that the decoded content executes from an offset of 0x23b0
. This will become more important later when we execute and analyze the code.
Next, we used CyberChef to extract the encoded text and remove any references to eocs29
. This resulted in a large blob of hex characters with initial bytes resembling valid x86 instructions.
We ran a Disassemble x86
operation to confirm that the hex characters were valid x86 instructions.
We then saved the resulting data and tried to execute it using the Speakeasy emulator by Mandiant. Speakeasy confirmed that the code would execute, but it terminated immediately after calling GetTickCount
and Sleep
. This is a common anti-analysis trick used by malware to defeat emulators and sandboxes.
So far, we had identified that document.exe
contained a malicious AutoIT script that featured shellcode for further execution. Initial attempts to execute the shellcode inside a sandbox had failed, so we then moved the data into Ghidra in order to work out what it was doing and which malware family it might belong to.
Starting at the execution offset of 0x23b0
, we noticed that the code contained numerous stack strings and quickly redirected the shellcode to an offset of 0
(indicated by FUN_00000000
).
We decoded the initial stack string and obtained a character sequence followed by "lecheries".
Following the redirection (FUN_00000000
) to the beginning of the shellcode, we saw additional stack strings and references to possible API hashes (a method of locating necessary windows APIs without referencing them directly by name).
API hashes can be resolved manually, but this is often a significant effort, and largely unnecessary if the same hashing logic is already documented. Leveraging OSINT sources, we confirmed that these hash values matched with a shellcode-based loader (potentially TrickGate).
The first hash value from our shellcode corresponds to the CRC32 hash of CreateProcessW
. This meant that we could use the documented values to label our code, and revealed that the hashing is extremely likely to be CRC32.
We were also able to locate the hashing algorithm within the shellcode, with constant values confirming the CRC32 usage.
The usage of CRC32 alone was not enough to confirm that our malware was the same TrickGate, but the fact that these hashes were seen on another shellcode-based file added to the theory that we were looking at a similar loader or an updated variant. In addition to this, TrickGate has been known to utilize AutoIT and deliver the same payload (more later in the post).
The process of static reverse engineering with Ghidra is valuable but time consuming, and at this point, not completely necessary since our primary goal was to identify the malware. Our previous analysis suggested that the shellcode may be a loader designed to deliver the payload onto the system.
In order to save time and prevent unnecessary analysis, we decided to debug the code and look for any additional clues as to what we were dealing with. We could always jump back into static analysis if debugging failed.
We began the dynamic process by loading the extracted shellcode into x32dbg using BlobRunner by OALabs.
This enabled us to easily view remaining stack strings, which largely contained DLL names later used for resolving APIs.
Additional analysis allowed us to deploy breakpoints at the location of API hashing. This meant that we could apply a logging condition and simply print the resolved hashes to the log window. This is often far easier than fully reversing the hashes.
Here we have a simple conditional breakpoint that allowed us to monitor all APIs resolved via hashing.
This revealed many of the APIs that the shellcode was resolving. Of particular interest was the presence of CreateProcessW
, VirtualAlloc
and ReadProcessMemory
, as well as GetThreadContext
and SetThreadContext
. These APIs are commonly associated with process injection and further suggested we were dealing with a loader and not a final payload.
Below is a short list of APIs that the shellcode was resolving via hashing. Note the usage of many common injection APIs.
Allowing the code to execute further, we saw attempts to access a "lecheries" file located in the users temp
directory. This isn’t particularly interesting, but provided a unique string that we could later search to identify the malware.
We also observed attempts to spawn an svchost.exe
process via CreateProcessW
. Given the presence of injection APIs, this is likely the injection target and where we’ll find the next stage of malware.
We also observed the shellcode attempting to load a second copy of ntdll.dll
. This is often performed by malware in order to obtain a "clean" version for execution and is commonly used to evade detection with variants of syscalls or DLL unhooking.
Continuing the execution, we observed and investigated the newly spawned svchost
, and confirmed a second copy of ntdll
present in the module listing. There are few legitimate reasons for two ntdll
modules to be loaded, so we knew something strange was going on inside of this svchost
.
Shortly after spawning, the new svchost.exe
terminated and spawned a suspicious instance of netsh.exe
.
The netsh
was created without any command line parameters, which is unusual and suspicious. So we decided to investigate the process further.
By closely inspecting the memory regions of netsh.exe, we noticed a suspicious area of memory with RWX (read/write/execute) permissions and what appeared to be shellcode.
Disassembling the region inside of a debugger, we confirmed that the bytes disassembled correctly and followed a sequence typical of shellcode. Namely, immediately calling a nearby instruction and using a pop to obtain the address.
This typically enables shellcode to determine its position in memory when that position is not predictable. It’s also a sequence that would rarely be seen in legitimate code.
Portions of the code did not execute and raised exceptions, so we decided to perform a more extensive scan of our analysis machine using hollows_hunter. Specifically, we wanted to use hollows_hunter to search for indications of shellcode present in any process that was currently running.
Much to our surprise, it had flagged explorer.exe
as suspicious. This was unusual as there was no obvious new execution of explorer.exe
.
Inspecting the explorer.exe
process further, we noticed another suspicious area of RWX memory.
Luckily, hollows_hunter had flagged this same section and saved it for analysis.
We then used Detect It Easy to search for strings in that saved region. We quickly discovered a domain, partial URL, user agent, and base64 data prepended with the string "PKT2". These are all strings that would be expected in code that is attempting to make an external connection. Since these strings were present in the dump (and located in an RWX section), we suspected that this was linked to our malware.
Since we were primarily interested in identifying the malware we were dealing with, we investigated the strings for any links to documented activity. This led to the strong suggestion that we were dealing with Xloader (aka Formbook).
While researching PKT2 malware, we found two blogs specifically detailing Xloader (Zscaler and Baglai Vlad).
The Zscaler blog calls out Xloader registration packets using base64 appended to the string "PKT2", which aligned with the string seen in our extracted data.
We also saw similarities documented in the Baglai Vlad blog.
The Baglai Vlad blog also calls out Xloader as utilizing a second copy of ntdll.dll
for resolving hashes and evading detection. This aligned with our observation of the second loading of ntdll.dll
inside of our svchost
process, as there are few legitimate reasons for two copies to be loaded.
The Baglai Vlad blog also called out Xloader as utilizing process injection specifically into explorer.exe
, after first injecting into another process. This aligned with our observation of injection into svchost.exe, followed by netsh.exe
and activity inside of explorer.exe
.
Due to these and other similarities covered within the blogs, we were fairly confident that we were looking at a similar sample.
We believe with moderate confidence that the initial AutoIT and shellcode components are related to Trickgate. Trickgate has been documented specifically deploying Xloader (Formbook) and utilizing techniques with high similarity to the initial AutoIT component of our sample.
If you’re interested in checking out Sublime and how we detect and prevent attempts to deliver malware via email originating attacks, you can create a free account today or request a demo.
Sublime releases, detections, blogs, events, and more directly to your inbox.
The latest research, attack spotlights, and product updates.
Experience Sublime’s adaptable email security platform and take control of your email environment today.