MosaicLoader Analysis
We will analyze MosaicLoader.
Summary
In July 2021, BitDefender published a WhitePaper on new Golang malware family “MosaicLoader.”
Golang programs are becoming increasingly popular amongst the adversaries, Pentesters and Red Teamers because it allows them to create malicious program that can support multiple OS platform with single source code. However due to it’s nature, by default it statically link all the libraries and it would not strip the Symbolic Tables. This allows analyst more information then usual, since all the function names and such can be somewhat be seen, unless creator obfuscate the code with packing.
MosaicLoader’s infection vector is known to be cracked softwares and it has four infection stages.
- Downloader
- First stage payload (app.exe)
- Second stage payload(prun.exe)
- Post-exploitation deliveries
We will focus four binaries within 1~3 stages in our analysis.
Downloader (SHA256: 0cdb630f148fe880bd223b6455daa7b6ef1cbe5b7b287920c67ea1cbf0fba91d)P3.exe (SHA256: 05f8948e087d01c9f9616d0ecdbd334372e37b9c212e3be236abeb7f4d1ed1b1)App.exe (SHA256: 1a98cc7728fc729c0947f445051dcacae38b86b4cee29384da22bb2ccc976747)Prun.exe (SHA256: 06550b2257d9e5620e98a2ea91ccce5f8ccf70a1f54197e12df8897b814f3b62)
Downloader
MITRE ATT&CK
Defense Evasion
T1562 Impair Defenses
Execution
T1059 Command and Scripting Interpreter
Command and Control
T1071 Application Layer Protocol
T1105 Ingress Tool Transfer
File Hash (SHA256)
0cdb630f148fe880bd223b6455daa7b6ef1cbe5b7b287920c67ea1cbf0fba91d
Execution Flow
From the static analysis, the file itself can be seen to have many Golang indications.
Golang is known to statically link all the libraries and does not strip symbolic table by default. In addition, this binary is not packed and many of the key information can be seen from static analysis.
As we can see in Figure 3, many of the function names are intact with suggestive names.
When the downloader is executed, it shows the UAC prompt and shows a console in the background.
The downloader appears to have following execution flow
- Configure exclusion setting
Downloader appears to spawn multiple PowerShell commands, which modifies the Microsoft Defender with -Add-MpPreference
cmdlet.
PowerShell command updates the settings for Windows Defender to exclude 12 different files from scheduled and real-time scanning to evade Microsoft Defender.
The command excludes scanning by Microsoft Defender under “C:” or “C:\Program Files(x86)\PublicGaming” with .exe file extesion. Process specifically excluded are appsetup.exe, prun.exe, p1.exe, p2.exe, p3.exe, p4.exe, p5.exe, p6.exe, p7.exe, p8.exe, p9.exe, and p10.exe.
Appsetup.exe and prun.exe are identified as two stager by BitDefender’s whitepaper. The files p1.exe ~ p10.exe are assumed to be additional files that are downloaded from the C2 connection by this downloader and we will specifically look into p3.exe in the next section.
- New directory creation
After configuring exclusion list for Microsoft Defender, downloader creates a directory C:\Program Files (x86)\PublicGaming, which appears to be utilizes later to place downloaded files appsetup.exe and prun.exe.
- Download additional malwares
Downloader attempts to download two zip files from two different locations.
https://source.activedirect[.]xyz/p6-2.zip
https://srv2.checkblanco[.]xyz/update-assets2.zip
After the first download of p6–2.zip, it proceeds to download the second zip file update-assets2.zip from srv2.checkblanco[.]xyz.
After the download is successful, the downloader attempts to place the zip file under the temp folder.
C:\Users\<username>\AppData\Local\Temp\update-assets2.zip
Unfortunately we were not able to retrieve either of the zip files. However p6–2.zip was in VirusTotal and it appears to contain one of the files included in the exclusion list p3.exe.
Other interesting data we can find in this binary :
C:\\Users\\<username>\\AppData\\Local\\Temp\\6198e55c-67f5–4bde-9dfc-155c077eaa9d.zip[HKEY_CURRENT_USER\Software\Asymetrix\Web3d20\FileDialogState]
P6–2.zip(p3.exe)
MITRE ATT&CK
Defense Evasion
T1140 Deobfuscate/Decode Files or Information
Command and Control
T1071 Application Layer Protocol
collection
T1113 Screen Capture
T1560 Archive Collected Data
File hash (SHA256)
05f8948e087d01c9f9616d0ecdbd334372e37b9c212e3be236abeb7f4d1ed1b1
Execution Flow
Downloader downloads additional zip file from the source.activedirect[.]xyz and it is one of excluded files p3.exe. As we can see from Figure 11, the file is masquarading as 7-Zip setup file. The file is not Golang binary.
The file appears to go through the following execution flow.
1. Create directory
The p3.exe creates a directory (C:\Users\<username>\AppData\Roaming\AHLaoTPZpYcd) to prepare dropping files.
2. Drop files
P3.exe prepares file drop by unpacking onto a memroy via VirtualAlloc and WriteFile.
The executable proceeds to create 4 different .dot files.
The dropped file appears to be obfuscated files and AutoIT Scripts
Crepitando.dot: Obfuscated file.
Esistenza.dot: Obfuscated AutoIT Script
Sua.dot: Obfuscated VBS Script
Veduto.dot: Obfuscated PE file.
Since I was getting an error on debugger, I reran it with the procmon and noticed that one of the .dot files were turned into autoit related executable.
After the dropping of the file, one of the files Crepitando.dot was replaced by Getto.exe.com, which appears to be AutoIT executable.
More information on dropped files.
Filename : Getto.exe.com
MD5 : 78ba0653a340bac5ff152b21a83626cc
Reference : https://www.virustotal.com/gui/file/05d8cf394190f3a707abfb25fb44d7da9d5f533d7d2063b23c00cc11253c8be7Filename : Esistenza.dot
MD5 : 48B3E78FE366DC8ADA44269668CCCD57Filename : Sua.dot
Md5 : 1F3DFE860832CB5AAB3469F1467DC470
Reference : https://www.virustotal.com/gui/file/bd70a24dcfa73cc8df03a0c9bbb88607f508d16575cdec99ef3f14a1ef9a0ff7Filename : Veduto.dot
MD5 : A2BD0E0C363AA9CC7B1DC453E25663E6
It appears Sua.dot and Veduto.dot are part of infostealer malware, Taurus Stealer.
3. Possible Exfiltration
After the files are dropped, p3.exe proceeds to create a process makecab.exe in suspended mode and execute the process by calling ShellExecuteExW. Process makecab.exe is a “Cabinet Maker” which allows user to compress the files into .cab file.
There are few techniques by malicious actors to compress a file with makecab.exe and extract the file with extrac32.exe to exfiltrate the data from the infected machine.
However since I was getting an error with the debug, I was not able to obvserve this behavior.
4. Execute files
After p3.exe dropping the file, it proceeds to execute the AutoIT executable Getto.exe.com to start it’s exfiltration.
Getto.exe.com spawns child processes cmd.exe to execute the .dot files.
Later it proceeds to extract the obfuscated code Veduto.dot file by extracting specific strings with findstr command.
Findstr command is using the following params.
/V: Prints only lines that doesn't contain a match/R: Processes search strings as regular expressions. This is the default setting.
In our case, it searches and ouputs all strings that does not match with:
gEBDTrNLizVyhMqQJJHhSQmHPcJFUXlDpKKZOnNDyQtFGaCxfhSqXcvbtTObziRlpsWCwqwlWrowMUwvTgfGtpGNgjUVJfpXZUv
Getto.exe.com proceed to execute the following.
- Checks a file aaa_TouchMeNot_.txt
- Dump system information into text file.
- Checks and dumps cryptocurrency wallet, files, cache/cookie in Browser, and screenshot of Desktop into a dedicated directory.
- Zip the retrieved data.
- C2 connection
Getto.exe.com appears to create connection to the following domains to exfiltrate the retrieved data.
EtRlyZLogOuuBHUl[.]EtRlyZLogOuuBHUlaufxio33[.]top
appsetup.exe
MITRE ATT&CK
Defense Evasion
T1497 Virtualization/Sandbox Evasion
Persistence
T1543 Create or Modify System Process
Command and Control
T1071 Application Layer Protocol
File hash (SHA256)
1a98cc7728fc729c0947f445051dcacae38b86b4cee29384da22bb2ccc976747
Execution Flow
This file is assumed to be downloaded via update-assets2.zip. The zipfile appears to be different name from the whitepaper, but this is due to using different binary.
Again, this binary is Golang.
main_run function is called as soon as it enters main_main, and it appears to contain flag package. According to Go documentation:
Package flag implements command-line flag parsing.
Within the execution flow, this function appears to support command-line flag service
.
appsetup.exe is seen to load a library service
and this allows the executable to manage system services.
As we execute the code, it appears to be creating a new service pubgame-updater
for persistence purposes .
In Go, function args appears to follow the pattern args ptr and the length of the ptr value in assembly.
For example in Figure 32, the first arg at 0x9D6D32 is followed by value 0xF(15). First arg is the ptr to the value the function New receives which is "pubgame-updater" and this appears to have length of 15. This rule applies to other args as well.
Later in the execution flow main_isinstalled is called, which has an indirect call :
The address 0x71CF40 turns out to be function_windowsService__Status, which checks if service pubgame-updater exist within the machine.
This will eventually return ErrNotInstalled, which is an indicator that the given service is not installed within the environment.
After the service status check in main_installed, execution flow goes back to main_run which hits conditional block. It will take the jump(jz) if the service does not exist within the machine.
Once the jump is taken, we can seen that the value prun.exe is seen to be placed.
Within this codeblock, it has main_setupWrapper which calls cryptio’s go-startup. It is a library that manages startup applications in Windows. It appears to enable the startup services:
From the above, it is configuring the following.
Name — prunsas
Executable — “C:\Windows\PublicGaming\prun.exe”
startuptype — CURRENT_USER
runonce — False
This startup setup is also placed for another executable, WinFlow.exe.
Name — WinFlow
Executable — C:\ProgramData\WinFlow.exe
startuptype — CURRENT_USER
runonce — False
After the Startup is enabled, it calls windowsService’s Install function where it appears to call CreateService() to finish creating the Service.
Before program termniates, it will start the service by calling Start() function.
Now we go back to the conditional block from Figure 42, which will not take the jump, if the service already exist.
In this execution flow, it checks if the process is running in interactive mode. If it is, the program will terminate abruptly and it appears this is one of anti-debugging technique, which is essentially checking if the process is being debugged.
In figure 50, call eax on the first block is calling Interactive() function and placing the return value into eax. In the next code block in loc_924FDA, it checks the return value of Interactive().
If the executable returns false for Interactive() function, the execution flow will continue to proceed creating a connection to http://green.cablesparking[.]net/fetch.json
in function main_getHubEndopoint function.
https://green.cablesparking[.]net
is identified as malicious by threat intel, and it appears tobe utilized by NetBounce malware in the past.
Within this malware, it also has similar IP address 195.181.164[.]195
from Twitter post and it may be one of the indicator this malware is related to NetBounce.
When we access the url, it retrieves the netbounce related information.
The executable also has function main_equinoxUpdate, which appears to create an additional C2 connection before the program termination.
The domain spark.lightburst[.]xyz
is identified as malicious by threat intel.
The function main_sendnotification function is only seen in Program_Shutdown and Program_Stop functions.
Prun.exe
MITRE ATT&CK
Defense Evasion
T1055 Process Injection
T1140 Deobfuscate/Decode Files or Information
Command and Control
T1071 Application Layer Protocol
Execution
T1106 Native API
File hash (SHA256)
06550b2257d9e5620e98a2ea91ccce5f8ccf70a1f54197e12df8897b814f3b62
Execution Flow
This executable does not appeared to be Golang executable and it has some suggestions that this is packed by Delphi, Inno Setup.
Looking into the sections, this executable has interesting section VolcaniM
which has executable persmission.
When prun.exe is executed, execution flow will enter section VolcaniM
.
Within VolcaniM section, it scans through each sections within this executable and it tried to read pass the end of file (0xC89000) which triggers an EXCEPTION_ACCESS_VIOLATION.
There’s a conditional that checks the end of the file, however this was set to 0x7FFFFFFF which was causing this exception to occur in the first place. Changing the conditional value to 0xC80000 fixed the issue and bypassed the exception error.
Then executable proceeds to allocate code into memory via VirtualAlloc three times.
1. Unpacked Code
Indirect call to VirtualAlloc can be seen and this appears to be allocating Exeute/Read/Write permission.
After the memory is allocated, it loads the function RtlDecompressBuffer from ntdll.dll by using GetProcAddress and LoadLibraryA.
RtlDecompressBuffer Function defined by msdn as:
The RtlDecompressBuffer function decompresses an entire compressed buffer.
This is assumed to be one of the unpacking mechanism of this executable.
After the GetProcAddress of RtlDecompressBuffer, the execution flow proceeds to move certain amount of data from VolcaniM to allocated memory location by using combination of rep movsb instruction.
REP instruction is a repeat instruction which is used as a prefix written before the actual instruction. In this case, movsb instruction gets repeated , which is an instruction that fetches the byte at address SI(Source) and store it into DI(Destination). This instruction allows the executable to copy part of VolcaniM to allocated memory.
This moves each byte from 0x4BD000(VolcanM) to 0x29947EE(allocated memory) and it loops 15932 times, which is roughly 16kb of data from VolcanM.
※ I was getting an exception “Access Violation Exception” while executing rep movsb
, due to an invalid access permission(according to debugger). This was resolved by resetting the allocated memory’s permission to full access.
As soon as the copy is done, it will proceed and executes RtlDecompressBuffer.
NT_RTL_COMPRESS_API NTSTATUS RtlDecompressBuffer(
USHORT CompressionFormat,
PUCHAR UncompressedBuffer,
ULONG UncompressedBufferSize,
PUCHAR CompressedBuffer,
ULONG CompressedBufferSize,
PULONG FinalUncompressedSize
);
As we can see from the above, the argument four(CompressedBuffer) is pointing to the beginning of the address where the copied data are placed with the same count size as ECX in argument five(CompressedBufferSize). Decompressed data will be pasted onto the beginning of the memory (2931000), which is evident from argument two(UncompressedBuffer).
Once the decompression is done, the execution flow will proceed with direct call to this unpacked memory location.
2. ntdll.dll
Before the execution flow enters the unpacked memory, it proceeds to execute another VirtualAlloc with Execute/Read/Write permission.
This memory allocation is used to dump ntdll.dll within the instructions of decompressed memory.
3. Injection preparation file
The third VirtualAlloc is called and within the unpacked memory instructions, it dumps PE file. This PE file appears to be part of prun.exe, since it asks for the symbol file name by prun.pdb.
Within the unpacked memory, the executable proceeds to execute Process Hollowing and injects this 3rd allocated PE into itself. The process is created via CreateProcess before hand in the suspended mode.
- Unpack the malicious PE to the 3rd VirtualAlloced memory.
- ZwUnmapViewofSection of the unpacked/dumped malicious PE.
3. Writes the unmapped section by using ZwWriteVirtualMemory into child process.
4. Start the hollowed process by using CreateProcessW.
Looking at the PE file, it is evident this PE file will create C2 connections as we can see that it is loading ws2_32.dll for connectivity and we can also see the C2 domain class.checkblanco[.]xyz
listed.
This injected PE file appears to be utilized purely for C2 communication.
Conclusion
Each executables that we covered can be identified as the following.
- Downloader: Loader
- P3: Infostealer (Taurus Infostealer)
- appsetup: Loader (NetBounce)
- prun.exe: Loader
To prevent the infection with this malware, it is always recommended to avoid downloading and installing cracked softwares.
If the machine gets infected by this malware, then it is recommended to re-install the OS however if this is not valid, then following actions can be taken.
- Reset the user credentials of any web applications that was accessed via Browsers.
- Delete service (pubgame-updater)
- Delete all the files under directory (C:\Windows\PublicGaming)
- Remove the exclusion processes set by
Add-MpPreference
- Block the detected domains and IP address. (EtRlyZLogOuuBHUl[.]EtRlyZLogOuuBHUl, aufxio33[.]top, source.activedirect[.]xyz, srv2.checkblanco[.]xyz, green.cablesparking[.]net, class.checkblanco[.]xyz, 195.181.164[.]195)
However assuming that the C2 connections were successful and it reaches prun.exe execution, it is likely that post-exploitation or additional malwares are downloaded and executed. Re-Imaging the OS and recovering from the backup would be the safest approach to disinfect the machine.