Latrodectus: A year in the making
2024-10-21 18:36:57 Author: www.vmray.com(查看原文) 阅读量:0 收藏

VIEW VMRAY’S ANALYSIS REPORT

Overview

Latrodectus was first discovered by researchers in October 2023 and has been in heavy development ever since. The malware works mainly as a loader/downloader. Latrodectus 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, the developers of this malware family have started on an iteration rampage, where multiple new versions were released in a relatively short time, perhaps in an effort to get ahead of the evergreen “cat-and-mouse” game between defenders and threat actors. These new versions only consist of small changes, even removal of existing features. The previous pace of development would suggest that Latrodectus 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.

You can read our analysis report here (see Figure 1 for an overview).


Figure 1: VMRay Platform’s dynamic analysis reveals the malicious behavior of Latrodectus

Distribution and evolution

Latrodectus is distributed in a chain of JavaScript → MSI droppers, finally ending in the core DLL payload. The DLL payload usually has 4 unique-looking exports, utilizing the same export address, eventually running the same core logic when one decides to try all 4 exports.

Figure 2: Latrodectus exhibiting 4 exports with the same export address

The loader has gone through several iterations: at the time of writing this post, the most up-to-date version is v1.8. Early versions have started to surface at the end of September 2023, while samples of the most recent version were just compiled at the end of September 2024. Effectively, we are talking about an evolution spanning over a year now.

We have tracked each version’s earliest PE compiled time to give a rough estimation over its timeline of creation:

Versions

Compiled time for first samples of respective versions

v1.1a 29 Sep 2023 13:29:13 UTC
v1.1b 15 Feb 2024 10:10:37 UTC
v1.2 21 Mar 2024 16:27:39 UTC
v1.3 09 May 2024 11:08:17 UTC
v1.4 29 Jul 2024 10:07:54 UTC
v1.5 30 Jul 2024 17:16:02 UTC
v1.7 16 Sep 2024 08:44:51 UTC
v1.8 25 Sep 2024 11:20:43 UTC

A few major changes worth highlighting across the versions:

  • 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)
  • From v1.4 on, the loader switched to AES-256 (CTR) string decryption with a hardcoded key and variable 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

Overall, Latrodectus utilized 4 different anti-debugging and sandbox evasion techniques, these are as follows:

Process count check

This sanity process count check is most likely aimed at evading sandboxes as virtualized environments may not display the same number of installed and running applications as a real desktop environment would do.

Latrodectus simply enumerates the Windows OS version via 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 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 below). In 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

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. In the event, it does not equal to 6 bytes, 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 as a 32-bit process on the 64-bit OS. 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. This might be an attempt to detect certain emulation scenarios.

Figure 6: Checking the running process against IsWow64Process

Encrypted strings

In order to make reverse engineering process harder, Latrodectus 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 seeding. Later, Latrodectus 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.

Although, the encryption algorithm went through several changes as described previously, the storage of the encrypted strings remained almost similar. 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.

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
Figure 7: Encryption changes across versions

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.dll via finding the files inside the \Windows\System32 folder, calculating the CRC32 checksums of the filenames and then comparing them with the hardcoded hashed values in the sample. The last step is then to call 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

Using a simple condition, the malware verifies if it is running from under the %APPDATA% folder: if that’s not the case, it will copy itself to the location of either:

  • %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.

The creativity of developers is again revealed at the next stage of persistence: instead of calling conventional APIs or scheduler commands, that would simply create a scheduled task, Latrodectus uses the Component Object Model (COM) interface to achieve persistence. Our function log clearly describes the behavior and it is easy to follow the chain of events. 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, we can easily brute-force a reasonable amount of potential group names if we don’t have the decrypted campaign name string. 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:

Parameter

Value description

counter C2 request throttling for evasion, (default = 0)
type Type of the request (check-in = 1)
guid Hardware ID, seeded by the volume serial number, multiplied by the hardcoded value of 0x19660D
os Windows OS version
arch Windows architecture version
username Username of the infected host
group Campaign ID in decimal representation
version Sample version
up Always 1
direction C2 server
mac Network card MAC address
computername Hostname of infected host
domain Host domain

C2 command handler

Once an infection took place, the malicious process can receive further commands from the C2 server, 4 different commands are available:

Directives

Description

CLEARURL Clears the C2 table
URLS Sends a new C2 URL to be stored in the C2 table
COMMAND The command handler to other functionalities
ERROR Sends an error message to the host

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

Command ID

Description

2 Grabs filelist from the Desktop folder
3 Gets host process list
4 Collects sysinfo
12 Downloads and executes a next-stage PE
13 Downloads and executes a next-stage DLL
14 Downloads and executes a next-stage shellcode
15 Updates and restarts the bot
17 Terminates itself
18 Downloads IcedID loader and execute
19 Increases timeout
20 Resets the counter value
21 Executes a stealer module
22 Downloads and executes shellcode via base64 function
25 Downloads a file to %APPDATA%

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

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. We suspect the prevalent loader will enter into version 2.0 soon, as the previous pace of development seems to indicate even more updates incoming. Interestingly, we have seen that subversions even removed certain features from the loader, perhaps in an attempt to refactor some of the internal structures. 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.

The VMRay Platform currently detects 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

文章来源: https://www.vmray.com/latrodectus-a-year-in-the-making/
如有侵权请联系:admin#unsafe.sh