VIEW VMRAY’S ANALYSIS REPORT
Overview
First identified in October 2023, Latrodectus malware has since evolved significantly, becoming a key player in the cybercriminal ecosystem. The malware works mainly as a loader/downloader. Latrodectus malware has strong ties with the former, infamous loader IcedID, which was taken down in May 2024, thanks to the efforts of an international operation led by Europol and EC3. Since Operation Endgame, IcedID went under and Latrodectus is seen slowly taking its place in the cybercriminal ecosystem. Interestingly, Latrodectus also includes a specific C2 command, which can download a sample of IcedID loader.
Recently, Latrodectus malware developers released multiple new versions in quick succession, likely to stay ahead in the constant ‘cat-and-mouse’ game between defenders and attackers. As a result of this rapid iteration, these new versions primarily consist of small changes, including the removal of existing features. The previous pace of development would suggest that Latrodectus malware will keep on iterating with new versions. Due to the prevalence of the malware family, we felt that adding malware configuration extraction support for all the recent versions was the best move forward for producing high-quality IoCs for our customers.
Furthermore, in this short blogpost, we would like to go over some of the most important features of the malware.
Figure 1: VMRay Platform’s dynamic analysis reveals the malicious behavior of Latrodectus
VIDEO
How Latrodectus Malware is Distributed and Continually Evolving
Latrodectus malware is distributed in a chain of JavaScript → MSI droppers, finally ending in the core DLL payload. The DLL payload often has four unique-looking exports, using the same address, and eventually running the same main logic when all four exports are tested.
Figure 2: Latrodectus exhibiting 4 exports with the same export address
Over time, the loader has undergone several iterations. At the time of writing, the most up-to-date version is v1.8. Initially, early versions began to surface in late September 2023. In contrast, samples of the most recent version were compiled just by the end of September 2024.
:
Key technical changes in Latrodectus malware versions include:
Initially the family used a PRNG seed with XOR algorithm for string decryption (v1.1a)
Then Latrodectus developers decided to degrade it, and use a simpler rolling XOR method (v1.1b)
Starting with version 1.4, the loader changed to AES-256 (CTR) string decryption with a fixed key and a variable initialization value (IV) for each string
Additional command IDs introduced for the command handler in v1.4, like the possibility of downloading an arbitrary file to %APPDATA%
Some features that were previously incorporated are now removed from recent versions of samples, like the ADS self-deletion technique
Evasion techniques
In summary, Latrodectus malware employs four distinct anti-debugging and sandbox evasion techniques, which are as follows:
Process count check
For this reason, the sanity process count check is most likely aimed at evading sandboxes. Virtualized environments often lack the same number of installed and running applications as a real desktop environment.
a the API call RtlGetVersion or via GetVersionExW, if the Rtl version does not return data. If the routine detects Windows 10 or Windows 11 as the host OS, Latrodectus malware needs at least 75 active processes to launch, otherwise it simply terminates. The other condition does the same check, just for Windows versions v6.3 or less (which would constitute Windows 8.1, Windows 8, Windows 7 and anything  this case, the loader needs at least 50 active processes to launch. This is to account for baseline levels for different versions of Windows OS.
The VMRay Platform allows customers to directly specify the amount of background processes during analysis time, successfully countering such sandbox evasion techniques .
Figure 3: Latrodectus enumerating Windows OS version
MAC address validity
Furthermore, the second evasion check enumerates the _IP_ADAPTER_INFO  structure via the GetAdaptersInfo API function, then all hardware addresses of present network adapters are examined against the argument of 6  the program will simply terminate. While MAC addresses have been standardized to 6 bytes for a long time now, some older networking technologies used different address lengths and certain specialized or proprietary systems might use non-standard MAC address formats. This same evasion check was present in the BumbleBee loader  as well.
Figure 4: A rare network card check to verify validity of MAC addresses
BeingDebugged
A third evasion check is simply walking the Process Environment Block (PEB) data structure to query the BeingDebugged flag to detect any debugging attempts: this is a smarter way without calling the actual Windows API IsDebuggerPresent(), which may trigger some AV/EDR systems.
Figure 5: BeingDebugged flag being checked by walking the PEB
WOW64 process check
The next check is a validation of the current process, whether it is running under WOW64 on Windows, which simply ascertains whether the malware process is running . In this case, the malware will simply exit. Since all Latrodectus DLLs so far have been 64-bit DLLs, it is not fully clear what the intention of the threat actors was with this condition, since it will not return 32-bit in normal circumstances.Â
Figure 6: Checking the running process against IsWow64Process
Encrypted strings
How Latrodectus Malware Encrypts Strings
In order to make reverse engineering process harder, Latrodectus malware employs string encryption. The internal strings hold a significant amount of information on how the malware operates, what behavior it resembles. These internal strings often serve as the base for malware configuration extraction as well. In early versions of samples, the malware family utilized a unique pseudo random generator (PRNG) for Later, Latrodectus malware downgraded this functionality and simply opted to use an increment-based seed variable, which in essence turned the encryption process into a rolling XOR method. As of the most recent versions, the loader is now using AES-256 encryption with a hardcoded key inside the sample and with a variable IV for each of encrypted strings.
While the encryption algorithm has undergone several changes, as described earlier, the storage of encrypted strings has remained largely consistent. The prototype for these structures are simple: the encrypted strings are stored in the .data section of the DLL. In early versions of the loader, the first 4 bytes noted the XOR key and the delimiter bytes as well, the length of each strings are stored in the 5. and 6. bytes, and the remaining bytes are the actual encrypted data.
Storage of Encrypted Data Across Versions
The recent versions, due to introducing the AES algorithm, a hardcoded key is burnt-in into the .text section of the samples. The data length still resides in the .data section in the first two bytes for each chunk, which is followed by the IV, taking up 16 bytes. The remaining data of each chunk is again the actual encrypted data.
String encryption
Versions
Algorithm
Key
Data length
IV
Data
Seed
v1.1a
XOR
chunk[:4]
chunk[4:6]
Not applicable
chunk[6:6+data_length]
PRNG
v1.1b
Rolling XOR
chunk[:4]
chunk[4:6]
Not applicable
chunk[6:6+data_length]
Incrementer
v1.2
Rolling XOR
chunk[:4]
chunk[4:6]
Not applicable
chunk[6:6+data_length]
Incrementer
v1.3
Rolling XOR
chunk[:4]
chunk[4:6]
Not applicable
chunk[6:6+data_length]
Incrementer
v1.4
AES-256 (CTR mode)
hardcoded
chunk[:2]
chunk[2:18]
chunk[18:18+data_length]
Not applicable
v1.5
AES-256 (CTR mode)
hardcoded
chunk[:2]
chunk[2:18]
chunk[18:18+data_length]
Not applicable
v1.7
AES-256 (CTR mode)
hardcoded
chunk[:2]
chunk[2:18]
chunk[18:18+data_length]
Not applicable
v1.8
AES-256 (CTR mode)
hardcoded
chunk[:2]
chunk[2:18]
chunk[18:18+data_length]
Not applicable
Runtime API resolving and API hashing
The loader again utilizes the Process Environment Block (PEB) structure to find the base addresses of kernel32.dll and ntdll.dll. Then Latrodectus continues to resolve other libraries, like user32.dll, wininet.dll, iphlpapi.dllcall the LoadLibraryW function to finally load the library.
Once Latrodectus loaded all DLLs necessary, it continues to resolve the APIs by comparing the CRC32 checksums of the exported functions with the target values. The open-source project HashDB can help and save work here, as its Lookup Service can reverse the hash values and recreate the API names within an analysis. Reference:Â https://github.com/OALabs/hashdb
Figure 8: CRC32-based API hashing in Latrodectus
Setting up persistence
File Placement in %APPDATA% Folder
To ensure persistence, the malware first checks whether it is running from under the %APPDATA% folder. If it is not, it then copies itself to one of the following locations:
%APPDATA%\Custom_update\Update_XXXXXXXX.dll (older versions)
%APPDATA%\falsify_steward\confrontation_XXXXXXXX.dll (newer versions)
The part of the filename noted with XXXXXXXX gets filled up with the hardware ID, generated from the system’s volume serial number and a hardcoded constant described in the Hardware ID section of the blogpost.
Leveraging COM Interfaces for Scheduled Tasks
The creativity of developers is again revealed at the next stage of persistence: Rather than using common APIs or scheduler commands to create a scheduled task, Latrodectus uses the Component Object Model (COM) interface to stay active. . In the past, we have also taken a deep-dive into how the use of COM objects can blind malware analysis .
First, the sample calls the CoCreateInstance API to create and initialize an object, then connects to the ITaskService object. A new task is created inside the root of the scheduler and the job is set to execute whenever the user logs on. The name of the scheduled task is changing between “Updater” or “anxiety” between different versions of Latrodectus samples.
The task will point to the file previously dropped inside the %APPDATA% folder.
Figure 9: VMRay Platform’s Function Log reveals the setup of the scheduled task via the Component Object Model (COM) interface
Mutex
Latrodectus also tracks previously successful infections by creating a mutex on the target system. The hardcoded string “runnung” has been consistent across all Latrodectus versions and it is checked before execution to prevent re-infecting already corrupted systems.
Figure 10: VMRay Platform’s Function log showing the hardcoded mutex “runnung”
Group ID generation
Enumerating the campaign name
So far, we have seen that each new version of the loader also introduces a new group ID. We suspect this may change in the future and there will be unique group IDs per versions, if Latrodectus decides to switch to a “Malware-as-a-Service” model.
The group IDs are present in the initial C2 check-in traffic as &group= parameter and are represented as decimal numbers. They are also present in the malware sample as a string in an encrypted form. Since, we have already discovered that a Fowler–Noll–Vo (FNV1a) hash is created based off of the IDs, . Our approach was to create a word-list of all possible combinations of the English alphabet (26 letters) and try and simply brute-force it. With a high-computing machine, it is also reasonable to try mixed lowercase and uppercase variations, but for this short experiment, we stuck with just capitalizing the first letters.
Keep in mind that – since this is FNV-1a 32-bit space – there could be multiple strings appearing under the same hash due to hash collisions. So in rare cases, there might be a slight chance that the script cannot find the original campaign name.
def generate_words(length):
   Â
alphabet =Â
'abcdefghijklmnopqrstuvwxyz'
   Â
words = []
   Â
for
 combination in itertools.product(alphabet, repeat=length -Â
1
):
       Â
word =Â
''
.join(combination).capitalize()
       Â
words.append(word)
   Â
return
 words
def write_words(words, file_path):
   Â
with open(file_path,Â
'a'
) as f:
       Â
for
 word in words:
           Â
f.write(word +Â
'\n'
)
Once we gave enough time to the script to generate a massive (~ 130MB) wordlist (we kept it up to 7 letters), we can simply call a FNV1a hash generator to iterate through the given words line by line:
fnv_prime_32 =Â
2
**
24
 +Â
2
**
8
 +Â
0x93
offset_basis_32 =Â
0x811c9dc5
def fnv1a_hash_32(bs):
   Â
r = offset_basis_32
   Â
for
 b in bs:
       Â
r = r ^ b
       Â
r = (r * fnv_prime_32) &Â
0xffffffff
   Â
return
 r
if
 __name__ ==Â
'__main__'
:
   Â
with open(
'wordlist.txt'
,Â
'rb'
) as file:
       Â
wordlist = file.readlines()
   Â
for
 words in wordlist:
       Â
print(
"Campaign: "
 + Fore.YELLOW, wordbytes.decode(
'ascii'
),
"| FNV1a: "
, hex(fnv1a_hash_32(wordbytes)),
"| Dec: "
,
int
(hex(fnv1a_hash_32(wordbytes)),Â
16
))
Figure 11: Successfully brute-forcing the campaign name based on the decimal value of the campaign ID
Hardware ID generation
The loader also generates a unique hardware ID for each target host. This ID is based off of the victim’s Serial Volume ID and simply multiplied with a hardcoded constant. This constant is consistent so far in all observed Latrodectus versions: 0x19660D. The generated GUID is present in the initial C2 check-in request as &guid= parameter.
Figure 12: Generating the hardware ID, using the Volume Serial Number and the hardcoded constant (0x19660Dh)
Self-deletion
The loader uses a rather fascinating self-deletion technique: besides Latrodectus, we have previously observed this technique in both DarkSide, Dark Power, HelloXD and other malware families. Ultimately, this method can delete a locked, or a currently running executable from disk. It uses the SetFileInformationByHandle Windows API to rename the executable’s primary data stream and then facilitates the DeleteFile flag in the FileDispositionInfo class to trigger the disposition. There is a publicly available proof-of-concept code for this method on GitHub:Â https://github.com/LloydLabs/delete-self-poc
We have – uniquely in the industry – tried creating a future-proof detection coverage specifically for this technique, which is now observable as a VMRay Threat Identifier (VTI).
Figure 13: The VMRay Platform triggering on ADS self-deletion technique via VTIs
Network C2
Upon successful infection, Latrodectus sends an initial check-in POST request with a hardcoded User-Agent string: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Tob 1.1). This User-Agent header is consistent across all Latrodectus versions so far.
Figure 14: VMRay Platform’s network capture displays POST requests to the C2 server
The POST request data includes parameter values collected from the system and also consists of a few hardcoded values, stored in the sample that identifies the campaign and the sample version. These parameters are originally sent towards the C2 server RC4 encrypted and then base64 encoded, but the VMRay Platform easily captures the decrypted values in the function logs.
Figure 15: VMRay Platform’s Function Log revealing the parameters being filled with values
Each of these parameters serve a specific purpose:
C2 command handler
Once an infection took place, the malicious process can receive further commands from the C2 server, 4 different commands are available:
The COMMAND handler is the most interesting one as it can receive the following further sub-commands from the C2:
Figure 16: Command handler IDs for more functionalities
YARA coverage
We have introduced several forward-looking YARA signatures to detect all versions of the family. We also provide version-based signatures to aid customers with up-to-date information on the exact version of Latrodectus in question.
Figure 17: VMRay Platform’s report showing YARA detection signatures on Latrodectus samples
Malware configuration extraction
The VMRay Platform currently extracts all important malware configuration information from the samples. These would include the C2 URLs, the exact version, mission ID, and any potential encryption keys that are used for the string encryption or C2 communication: namely the RC4 key and the AES key (from v1.4 up to v1.8).
Figure 18: VMRay Platform’s successful malware configuration extraction for Latrodectus v1.8
Conclusion
With its consistent updates and strategic adaptations, Latrodectus malware continues to challenge security measures worldwide.
The threat actors behind the malware family seem to iterate versions in a speedy fashion, perhaps to wear defenders out or potentially to prepare for a substantial major change. Looking ahead, we suspect the prevalent loader will enter version 2.0 soon. Given the previous pace of development, it seems likely that even more updates are on the horizon. We noticed that some subversions even removed features from the loader, likely to reorganize its internal design. As this threat is still prevalent today, we will make sure to follow-up on future changes to aid customers with proper detection coverage and precise malware configuration extraction.
Latrodectus malware exemplifies the ever-evolving threats in the digital landscape. Stay updated on its latest developments by exploring our full malware analysis and detection capabilities: try VMRay Platform to detect all Latrodectus versions up to v1.8 and can acquire malware configuration from all working samples!
References
IoCs
C2 URLs
hxxps://antyparkov[.]site/live/
hxxps://aytobusesre[.]com/live/
hxxps://carflotyup[.]com/live/
hxxps://drifajizo[.]fun/live/
hxxps://coolarition[.]com/live/
hxxps://finjuiceer[.]com/live/
hxxps://grebiunti[.]top/live/
hxxps://grunzalom[.]fun/live/
hxxps://illoskanawer[.]com/live/
hxxps://jertacco[.]com/live/
hxxps://saicetyapy[.]space/live/
hxxps://scifimond[.]com/live/
hxxps://skinnyjeanso[.]com/live/
hxxps://stratimasesstr[.]com/live/
hxxps://stripplasst[.]com/live/
hxxps://titnovacrion[.]top/live/
hxxps://trymeakafr[.]com/live/
hxxps://winarkamaps[.]com/live/
hxxps://workspacin[.]cloud/live/
hxxps://worlpquano[.]com/live/
hxxps://zumkoshapsret[.]com/live/
hxxps://minrezviko[.]com/test/
hxxps://pomaspoteraka[.]com/test/
hxxps://finilamedima[.]com/test/
hxxps://restoreviner[.]com/test/
hxxps://peronikilinfer[.]com/test/
hxxps://rilomenifis[.]com/test/
hxxps://isomicrotich[.]com/test/
Mutex
runnung
Scheduled task name
Updater
anxiety
Persistence location
%APPDATA%\falsify_steward\confrontation_XXXXXXXX.dll
%APPDATA%\Custom_update\Update_XXXXXXXX.dll
RC4 keys
12345
2sDbsEUXvhgLOO4Irt8AF6el3jJ0M1MowXyao00Nn6ZUjtjXwb
u9X7Ogp3IECwtHNBFGa0uMc0fDXhjVnV9SiAiVzqdkoleTZy16
eNIHaXC815vAqddR21qsuD35eJFL7CnSOLI9vUBdcb5RPcS0h6
EhAyPSHvva9CvL6OIddDJvDXHJjoMsqXyjraKyYmXFqDGdAYyO
9edoY7pK6eQfntcLBNU1WSkauwf1sHj4I8vTuAddXvPwYbJPeP
v9JrWM4aDsviWsTfSCgX5Ed98pH6kMpQr1VWWj5LTMiC5C5Lna
k2C0I3yY0ZDMCy4zFZDFnCD3mzc4fFdEMw5uF1n6u59eGG2NDN
xkxp7pKhnkQxUokR2dl00qsRa6Hx0xvQ31jTD7EwUqj4RXWtHwELbZFbOoqCnXl8
Group/Campaign IDs
Alpha (v1.8)
Alpha (v1.7)
Ceres
Compati
Delta (v1.5)
Electrol
Facial
Jupiter
Liniska
Littlehw
Mars
Mercury
Neptun
Novik
Olimp
Supted
Trusted
Venus
Wiski (v1.4)
Versions
v1.1a
v1.1b
v1.2
v1.3
v1.4
v1.5
v1.7
v1.8