[ad_1]
MoustachedBouncer is a cyberespionage group discovered by ESET Research and first publicly disclosed in this blogpost. The group has been active since at least 2014 and only targets foreign embassies in Belarus. Since 2020, MoustachedBouncer has most likely been able to perform adversary-in-the-middle (AitM) attacks at the ISP level, within Belarus, in order to compromise its targets. The group uses two separate toolsets that we have named NightClub and Disco.
Key points of this report:
- MoustachedBouncer has been operating since at least 2014.
- We assess with medium confidence that they are aligned with Belarus’s interests.
- MoustachedBouncer specializes in the espionage of foreign embassies in Belarus.
- MoustachedBouncer has used the adversary-in-the-middle technique since 2020 to redirect captive portal checks to a C&C server and deliver malware plugins via SMB shares.
- We believe that MoustachedBouncer uses a lawful interception system (such as SORM) to conduct its AitM operations.
- We assess with low confidence that MoustachedBouncer is closely cooperating with Winter Vivern, another group targeting European diplomats but using different TTPs.
- Since 2014, the group has been operating a malware framework that we have named NightClub. It uses the SMTP and IMAP (email) protocols for C&C communications.
- Starting in 2020, the group has been using, in parallel, a second malware framework we have named Disco.
- Both NightClub and Disco support additional spying plugins including a screenshotter, an audio recorder, and a file stealer.
The group’s intricate tactics, techniques and procedures were also discussed on the ESET Research Podcast. Just press play to learn more from ESET’s Director of Threat Research Jean-Ian Boutin and ESET Distinguished Researcher Aryeh Goretsky.
Victimology
According to ESET telemetry, the group targets foreign embassies in Belarus, and we have identified four different countries whose embassy staff have been targeted: two from Europe, one from South Asia, and one from Africa. The key dates are shown in Figure 1.
![Figure 1. Timeline of MoustachedBouncer activities MoustachedBouncer_Timeline_edited](https://web-assets.esetstatic.com/wls/2023/2023-8/moustachedbouncer-timeline-edited.png)
Attribution
While we track MoustachedBouncer as a separate group, we have found elements that make us assess with low confidence that they are closely collaborating with another group known as Winter Vivern. The latter was discovered in 2021 and is still active as of 2023. In March 2023, Winter Vivern used a known XSS vulnerability (CVE-2022-27926) in the Zimbra mail portal in order to steal webmail credentials of diplomats of several European countries. This campaign was publicly disclosed by Proofpoint researchers.
MoustachedBouncer’s activity spans from 2014 to 2022 and the TTPs of the group have evolved over time. For example, we have first seen them use AitM attacks only in 2020. However, the targeted vertical has stayed the same.
Table 1 shows the characteristics of each campaign. Given these elements, we assess with high confidence that they are all linked to MoustachedBouncer.
Table 1. Connections between the MoustachedBouncer campaigns
|
VirusTotal |
Victim A (2017) |
Victim B |
Victim C |
Victim D |
NightClub implant |
X |
X |
|
X |
|
NightClub plugins |
|
X |
X |
X |
|
Disco implant |
|
|
X |
|
X |
SharpDisco dropper |
|
|
X |
|
|
Compromise via AitM |
? |
? |
? |
? |
X |
Malware delivery via AitM on SMB shares |
|
|
X |
|
X |
Victims: foreign embassies in Belarus |
? |
X |
X |
X |
X |
Compromise vector: AitM
In this section, we detail the initial access for Disco. We don’t yet know the initial access method MoustachedBouncer uses to install NightClub.
Fake Windows Update
To compromise their targets, MoustachedBouncer operators tamper with their victims’ internet access, probably at the ISP level, to make Windows believe it’s behind a captive portal. Windows 10 checks whether it’s able to access the internet with an HTTP request to http://www.msftconnecttest.com/connecttest.txt. In case the answer is not Microsoft Connect Test, a browser window is opened to http://www.msftconnecttest.com/redirect . For IP ranges targeted by MoustachedBouncer, the network traffic is tampered at the ISP level, and the latter URL redirects to a seemingly legitimate, but fake, Windows Update URL, http://updates.microsoft[.]com/. Hence, the fake Windows Update page will be displayed to a potential victim upon network connection. The fake update page is shown in Figure 2. The text we observed is in Russian, most likely because that is the main language used in Belarus, but it is possible that versions in other languages exist. The page indicates that there are critical system security updates that must be installed.
![Figure 2. Fake Windows Update page Figure 2. Fake Windows Update page](https://web-assets.esetstatic.com/wls/2023/2023-8/picture1.png)
Note that it is using unencrypted HTTP and not HTTPS, and that the updates.microsoft[.]com subdomain does not exist on Microsoft’s nameservers, so it does not resolve on the open internet. During the attack, this domain resolved to 5.45.121[.]106 on the target’s machine. This IP address is used for parking domains and is unrelated to Microsoft. Although this is an internet-routable IP address, traffic to this IP never reaches the internet while the AitM attack is ongoing. Both the DNS resolutions and the HTTP replies were injected in transit, probably at the ISP level.
An important point is that the adversary-in-the-middle (AitM) technique only occurs against a few selected organizations (perhaps just embassies), not countrywide. It is not possible to reproduce the redirection by simply exiting from a random IP address in Belarus.
Malware delivery
The HTML page, shown in Figure 2, loads JavaScript code from http://updates.microsoft[.]com/jdrop.js. This script first calls setTimeout to execute the function jdrop one second after the page has loaded. That function (see Figure 3) displays a modal window with a button named Получить обновления (translation: Get updates).
![Figure 3. jdrop function Figure 3. jdrop function](https://web-assets.esetstatic.com/wls/2023/2023-8/jdrop.png)
A click on the button executes the update function, shown in Figure 4.
![Figure 4. update function Figure 4. update function](https://web-assets.esetstatic.com/wls/2023/2023-8/update-js.png)
This function triggers the download of a fake Windows Update installer from the legitimate-seeming URL http://updates.microsoft[.]com/MicrosoftUpdate845255.zip. It also displays some instructions to install the update: Для установки обновлений, скачайте и запустите “MicrosoftUpdate845255.msi”. (translation: To install updates, download and run “MicrosoftUpdate845255.msi”).
We were unable to retrieve the downloaded MicrosoftUpdate845255.zip file but our telemetry shows it contains a malicious executable named MicrosoftUpdate845255.exe.
Written in Go, it creates a scheduled task that executes \\35.214.56[.]2\OfficeBroker\OfficeBroker.exe every minute. Like the path suggests, it fetches the executable via SMB from 35.214.56[.]2. This IP address belongs to a Google Cloud customer, but just like the HTTP server, we believe that SMB replies are injected on the fly via AitM and that the attackers don’t control the actual internet-routable IP address.
We have also observed the following SMB servers, intercepted via AitM:
- \\209.19.37[.]184
- \\38.9.8[.]78
- \\59.6.8[.]25
We have observed this behavior in two separate ISP networks: Unitary Enterprise A1 and Beltelecom. This suggests that those ISPs may not provide full data confidentiality and integrity. We strongly recommend that foreign organizations in Belarus use an end-to-end encrypted VPN tunnel, ideally out-of-band (i.e., not from the endpoint), providing internet connectivity from a trusted network.
Figure 5 depicts our hypothesis about the compromise vector and the traffic interception.
![Figure 5. Compromise via AitM scenario Figure 5. Compromise via AitM scenario](https://web-assets.esetstatic.com/wls/2023/2023-8/slide1.jpeg)
AitM – General thoughts
The AitM scenario reminds us of the Turla and StrongPity threat actors who have trojanized software installers on the fly at the ISP level.
Usually, this initial access method is used by threat actors operating in their own country because it requires significant access inside the internet service providers, or their upstream providers. In many countries, security services are allowed to perform so-called “lawful interception” using special devices installed on the ISPs’ premises.
In Russia, a law from 2014 requires ISPs to install devices called SORM-3 that enable the Federal Security Service (FSB) to conduct targeted surveillance. The devices have deep packet inspection (DPI) capabilities and were likely used by Turla in its Mosquito campaign.
In 2018, the Citizen Lab revealed that DPI devices developed by the Canadian company Sandvine were used to modify HTTP traffic in Turkey and Egypt. In Turkey, the devices were allegedly used to redirect internet users to a malicious server when they tried to download certain Windows applications, which is in line with StrongPity activities. In Egypt, those devices were allegedly used to inject ads and cryptocurrency mining scripts in order to generate money.
In 2020, a Bloomberg article revealed that Belarus’s National Traffic Exchange Center bought the same Sandvine DPI equipment, but according to a Cyberscoop article the contract was cancelled in September 2020.
According to a report by Amnesty International published in 2021, “Under Belarusian law, all telecommunications providers in the country must make their hardware compatible with the SORM system”. They also state that “The SORM system allows the authorities direct, remote-control access to all user communications and associated data without notifying the provider”. We assess with low confidence that MoustachedBouncer uses this SORM system to conduct its operations.
While the compromise of routers in order to conduct AitM on embassy networks cannot be fully discarded, the presence of lawful interception capabilities in Belarus suggests the traffic mangling is happening at the ISP level rather than on the targets’ routers.
Implants: NightClub and Disco
Since 2014, the malware families used by MoustachedBouncer have evolved, and a big change happened in 2020 when the group started to use AitM attacks. At the same time, it started to use much simpler tools developed in .NET and Go. In reference to NightClub, we named this new toolset Disco.
MoustachedBouncer operates the two implant families in parallel, but on a given machine, only one is deployed at a time. We believe that Disco is used in conjunction with AitM attacks while NightClub is used for victims where traffic interception at the ISP level isn’t possible because of a mitigation such as the use of an end-to-end encrypted VPN where internet traffic is routed outside of Belarus.
Disco
As mentioned in the previous section, a fake Windows Update page delivers the first stage (SHA-1: E65EB4467DDB1C99B09AE87BA0A964C36BAB4C30). This is a simple dropper written in Go that creates a scheduled task to execute \\35.214.56[.]2\OfficeBroker\OfficeBroker.exe every minute. OfficeBroker.exe is downloaded over the SMB protocol via AitM attack. The dropper’s main function is shown in Figure 6.
![Figure 6. Main function of the Go dropper Figure 6. Main function of the Go dropper](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-6.png)
Finally, the dropper does a DNS query for windows.system.update[.]com. This domain does not exist but the DNS request is probably intercepted via AitM, and is likely a beacon to notify the operators that the machine has been successfully compromised.
We were unable to retrieve the OfficeBroker.exe file, but it is very likely that it acts as a downloader, since we have observed further plugins being executed from SMB shares. The plugins are developed in Go and are rather simple because they mostly rely on external Go libraries. Table 2 summarizes the different plugins.
Table 2. Go plugins used by MoustachedBouncer in 2021–2022
Download URL / Path on disk |
Description |
\\209.19.37[.]184\driverpack\aact.exe |
Takes screenshots using the kbinani/screenshot library. Screenshots are saved in .\AActdata\<d>_<s>.dat (on the SMB share) where <d> is the active display number and <s> the date. It sleeps 15 seconds between each screenshot. |
C:\Users\Public\driverpack\driverpackUpdate.exe |
Executes PowerShell scripts with powershell.exe -NoProfile -NonInteractive <command>, where <command> is read from the file .\idata. The output is written in .\odata. |
C:\Users\Public\driverpack\sdrive.exe |
Executes C:\Users\Public\driverpack\driverpackUpdate.exe (the plugin above) using elevated rights via CVE-2021-1732. The code was likely inspired by a PoC on GitHub and uses the zydis code generation library. |
\\209.19.37[.]184\driverpack\officetelemetry.exe |
A reverse proxy strongly inspired by the GitHub repository revsocks. We were unable to retrieve the command line parameters with the proxy IP address. |
\\38.9.8[.]78\driverpack\DPU.exe |
Another sample of the PowerShell plugin. |
%userprofile%\appdata\nod32update\nod32update.exe |
Another sample of the reverse proxy plugin. |
\\59.6.8[.]25\outlooksync\outlooksync.exe |
Takes screenshots; it is similar to the first plugin. Images are saved in ./logs/${DATETIME}.dat. |
\\52.3.8[.]25\oracle\oracleTelemetry.exe |
Screenshot plugin packed with Themida. |
Interestingly, the plugins also use SMB shares for data exfiltration. There is no C&C server outside the attackers’ premises to look at or to take down. There also seems to be no way to reach that C&C server from the internet. This gives high resiliency to the attackers’ network infrastructure.
SharpDisco and NightClub plugins
In January 2020 we observed a MoustachedBouncer dropper, which we named SharpDisco, being downloaded from https://mail.mfa.gov.<redacted>/EdgeUpdate.exe by a Microsoft Edge process. It is not clear how attackers were able to tamper with HTTPS traffic, but it is possible an invalid TLS certificate warning was shown to the victim. Another possibility is that MoustachedBouncer compromised this governmental website.
SharpDisco (SHA-1: A3AE82B19FEE2756D6354E85A094F1A4598314AB)
SharpDisco is a dropper developed in C#. It displays a fake update window, shown in Figure 7, while creating two scheduled tasks in the background.
![Figure 7. Fake Microsoft Edge update window Figure 7. Fake Microsoft Edge update window](https://web-assets.esetstatic.com/wls/2023/2023-8/edge-update.png)
These scheduled tasks are:
WINCMDA.EXE and WINCMDB.EXE are probably just cmd.exe renamed. Every minute, the task reads what is in \\24.9.51[.]94\EDGEUPDATE\EDGEAIN (on the SMB share), pipes it to cmd.exe, and writes the output to \\24.9.51[.]94\EDGEUPDATE\EDGEAOUT. It is the same for the second task, but with the EDGEBIN and EDGEBOUT files. From a higher viewpoint, those tasks are reverse shells with a one-second latency.
Then, as shown in Figure 8, the dropper sends a DNS request for an unregistered domain, edgeupdate-security-windows[.]com. This is similar to what the 2022 Disco dropper does.
![Figure 8. Dropper used in 2020 Figure 8. Dropper used in 2020](https://web-assets.esetstatic.com/wls/2023/2023-8/dropper-2020.png)
ESET telemetry shows that the reverse shell was used to drop a genuine Python interpreter in C:\Users\Public\WinTN\WinTN.exe. We then observed two plugins being dropped on disk by cmd.exe, which means they were likely dropped by the reverse shell as well. The two plugins are:
- A recent-files stealer in C:\Users\Public\WinSrcNT\It11.exe
- An external drive monitor in C:\Users\Public\It3.exe
It is interesting to note that those plugins share code with NightClub (described in the section NightClub – 2017 (SHA-1: F92FE4DD679903F75ADE64DC8A20D46DFBD3B277) below). This allowed us to link the Disco and NightClub toolsets.
Recent-files stealer (SHA-1: 0DAEA89F91A55F46D33C294CFE84EF06CE22E393)
This plugin is a Windows executable named It11.exe. We believe it was executed via the reverse shell mentioned above. There is no persistence mechanism implemented in the plugin.
It gets the files recently opened on the machine by reading the content of the folder %USERPROFILE%\Recent (on Windows XP) or of %APPDATA%\Microsoft\Windows\Recent (in newer Windows versions). Those folders contain LNK files, each pointing to a recently opened file.
The plugin embeds its own LNK format parser in order to extract the path to the original file.
We were unable to make this plugin work, but static analysis shows that the files are exfiltrated to the SMB share \\24.9.51[.]94\EDGEUPDATE\update\. The plugin maintains a list of already exfiltrated files, and their CRC-32 checksum, in %TEMP%\index.dat. This likely avoids retransmitting the same file more than once.
External drive monitor (SHA-1: 11CF38D971534D9B619581CEDC19319962F3B996)
This plugin is a Windows executable named It3.exe. As with the recent-files stealer, it doesn’t implement any persistence mechanism.
The plugin calls GetLogicalDrives in a loop to get a list of all connected drives, including removable ones such as USB keys. Then, it does a raw copy of the NTFS volume of each removable drive and writes it in the current working directory, C:\Users\Public\ in our example. The filename is a randomly generated string of six to eight alphanumeric characters, for example heNNYwmY.
It maintains a log file in <working directory>\index.dat with the CRC-32 checksums of the copied disks.
The plugin doesn’t appear to have any exfiltration capabilities. It is likely that the staged drive dumps are later retrieved using the reverse shell.
NightClub
Since 2014, MoustachedBouncer has been using a malware framework we named NightClub because it contains a C++ class named nightclub. We found samples from 2014, 2017, 2020, and 2022. This section describes the evolution of NightClub from a simple backdoor to a fully modular C++ implant.
In summary, NightClub is an implant family using emails for its C&C communications. Since 2016, additional modules could be delivered by email to extend its spying capabilities.
NightClub – 2014
This is the oldest known version of NightClub. We found a dropper and an orchestrator.
The dropper (SHA-1: 0401EE7F3BC384734BF7E352C4C4BC372840C30D) is an executable named EsetUpdate-0117583943.exe, and it was uploaded to VirusTotal from Ukraine on 2014-11-19. We don’t know how it was distributed at that time.
The main function, illustrated in Figure 9, loads the resource MEMORY and writes its content in %SystemRoot%\System32\creh.dll. It is stored in cleartext in the PE resource.
![Figure 9. Main function of the dropper Figure 9. Main function of the dropper](https://web-assets.esetstatic.com/wls/2023/2023-8/2014-main-dropper.png)
Then, the dropper modifies the Creation, Access, and Write timestamps of creh.dll to those of the genuine Windows DLL user32.dll.
Finally, it creates a Windows service named WmdmPmSp and sets, in the registry, its ServiceDll to %SystemRoot%\System32\creh.dll – see Figure 10.
![Figure 10. Modification of the value ServiceDll Figure 10. Modification of the value ServiceDll](https://web-assets.esetstatic.com/wls/2023/2023-8/2014-servicedll.png)
The previously dropped DLL, creh.dll (SHA-1: 5B55250CC0DA407201B5F042322CFDBF56041632) is the NightClub orchestrator. It has a single export named ServiceMain and its PDB path is D:\Programming\Projects\Work\SwampThing\Release\Win32\WorkingDll.pdb.
It is written in C++ and the names of some methods and classes are present in the RTTI data – see Figure 11.
![Figure 11. Method and class names from the RTTI data Figure 11. Method and class names from the RTTI data](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-11.png)
Some of the strings are encrypted using the following linear congruential generator (LCG): staten+1 = (690069 × staten + 1) mod 232. For each encrypted string, a seed (state0) between 0 and 255 is provided. To decrypt a string, the staten is subtracted from each encrypted byten. An example of an encrypted string structure is shown in Figure 12.
![Figure 12. Encrypted string format Figure 12. Encrypted string format](https://web-assets.esetstatic.com/wls/2023/2023-8/2014-encrypted-string.png)
A non-encrypted log file is present in C:\Windows\System32\servdll.log. It contains very basic information about the initialization of the orchestrator – see Figure 13.
![Figure 13. Log file Figure 13. Log file](https://web-assets.esetstatic.com/wls/2023/2023-8/2014-log-file.png)
NightClub has two main capabilities:
• Monitoring files
• Exfiltrating data via SMTP (email)
File monitor
Functionality implemented here is very close to that of the recent file monitor plugin seen in 2020 and described above. It also browses the directories %USERPROFILE%\Recent on Windows XP, and in newer Windows versions %APPDATA%\Microsoft\Windows\Recent, and implements the same LNK parser – see Figure 14 and Figure 15.
![Figure 14. LNK parser (2014 sample – 5B55250CC0DA407201B5F042322CFDBF56041632) Figure 14. LNK parser (2014 sample – 5B55250CC0DA407201B5F042322CFDBF56041632)](https://web-assets.esetstatic.com/wls/2023/2023-8/2014-lnk-parser.png)
Figure 14. LNK parser (2014 sample – 5B55250CC0DA407201B5F042322CFDBF56041632)
![Figure 15. LNK parser (2020 sample – 0DAEA89F91A55F46D33C294CFE84EF06CE22E393) Figure 15. LNK parser (2020 sample – 0DAEA89F91A55F46D33C294CFE84EF06CE22E393)](https://web-assets.esetstatic.com/wls/2023/2023-8/2020-lnk-parser-1.png)
Figure 15. LNK parser (2020 sample – 0DAEA89F91A55F46D33C294CFE84EF06CE22E393)
The files retrieved from the LNK files are copied to %TEMP%\<original filename>.bin. Note that unlike the 2020 variant, only files with extensions .doc, .docx, .xls, .xslx, or .pdf are copied.
It also monitors removable drives in a loop, in order to steal files from them.
SMTP C&C communications
NightClub uses the SMTP protocol to exfiltrate data. Even if C&C communication by email is not unique to MoustachedBouncer and is also used by other adversaries such as Turla (see LightNeuron and the Outlook backdoor), it is quite rare. The code is based on the CSmtp project available on GitHub. The email accounts’ information is hardcoded, encrypted with the LCG algorithm. In the sample we analyzed, the mail configuration is:
• SMTP server: smtp.seznam.cz
• Sender address: glen.morriss75@seznam[.]cz
• Sender password: <redacted>
• Recipient address: SunyaF@seznam[.]cz
seznam.cz is a Czech web portal offering a free webmail service. We believe the attackers created their own email accounts, instead of compromising legitimate ones.
NightClub exfiltrates the files previously copied to %TEMP% by the file monitor functionality (FileMonitor in Figure 11). They’re encoded in base64 and added as an attachment. The attachment name is the original filename with the .bin extension.
Figure 16 shows the exfiltration of a file via SMTP. NightClub authenticates using the credentials for the glen.morriss75@seznam[.]cz account and sends an email to SunyaF@seznam[.]cz with the stolen file attached.
![Figure 16. TCP stream of the SMTP communication from our test machine Figure 16. TCP stream of the SMTP communication from our test machine](https://web-assets.esetstatic.com/wls/2023/2023-8/figure16.png)
Figure 16. TCP stream of the SMTP communication from our test machine
Note that some headers that might look suspicious at first sight are the defaults from the CSmtp project, so they are probably not distinctive. These include:
• X-Mailer: The Bat! (v3.02) Professional
• Content-Type: multipart/mixed; boundary=”__MESSAGE__ID__54yg6f6h6y456345″
The Bat! is an email client widely used in Eastern Europe. As such, the X-Mailer header likely blends in with email traffic in Belarus.
NightClub – 2017 (SHA-1: F92FE4DD679903F75ADE64DC8A20D46DFBD3B277)
In 2017, we found a more recent version of NightClub, which was compiled on 2017-06-05. On the victim’s machine, it was located at C:\Windows\System32\metamn.dll. Its filename in the DLL export directory is DownloaderService.dll, and it has a single export named ServiceMain. It contains the PDB path D:\AbcdMainProject\Rootsrc\Projects\MainS\Ink\Release\x64\EtfFavoriteFinder.pdb.
To persist, it creates a Windows service named WmdmPmSp, as in previous versions. Unfortunately, we have not been able to recover the dropper.
This NightClub version also includes a few C++ class and method names, including nightclub, in the RTTI data – see Figure 17.
![Figure 17. Method and class names from the RTTI data of the 2017 NightClub version Figure 17. Method and class names from the RTTI data of the 2017 NightClub version](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-17.png)
Figure 17. Method and class names from the RTTI data of the 2017 NightClub version
As in previous versions, C&C communications use the SMTP protocol, via the CSmtp library, with hardcoded credentials. In the sample we analyzed, the mail configuration is:
• SMTP server: smtp.mail.ru
• Sender address: fhtgbbwi@mail[.]ru
• Sender password: [redacted]
• Recipient address: nvjfnvjfnjf@mail[.]ru
The main difference is that they switched the free email provider from Seznam.cz to Mail.ru.
This NightClub version uses external plugins stored in the folder %APPDATA%\NvmFilter\. They are DLLs named <random>.cr (e.g., et2z7q0FREZ.cr) with a single export named Starts. We have identified two plugins: a keylogger and a file monitor.
Keylogger (SHA-1: 6999730D0715606D14ACD19329AF0685B8AD0299)
This plugin was stored in %APPDATA%\NvmFilter\et2z7q0FREZ.cr and is a DLL with one export, Starts. It contains the PDB path D:\Programming\Projects\Autogen\Kh\AutogenAlg\Release\x64\SearchIdxDll.pdb and was developed in C++. RTTI data shows a few class names – see Figure 18.
![Figure 18. Method and class names from the RTTI data of the NightClub keylogger plugin Figure 18. Method and class names from the RTTI data of the NightClub keylogger plugin](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-18.png)
Figure 18. Method and class names from the RTTI data of the NightClub keylogger plugin
The keylogger implementation is rather traditional, using the Windows GetKeyState API function – see Figure 19.
![Figure 19. NightClub keylogger Figure 19. NightClub keylogger](https://web-assets.esetstatic.com/wls/2023/2023-8/keylogger.png)
The keylogger maintains a cleartext log file in %TEMP%\uirtl.tmp. It contains the date, the title of the application, and the logged keystrokes for this specific application. An example, which we generated, is provided in Figure 20.
![Figure 20. Example of the output of the keylogger (generated by us) Figure 20. Example of the output of the keylogger (generated by us)](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-20.png)
Figure 20. Example of the output of the keylogger (generated by us)
File monitor (SHA-1: 6E729E84C7672F048ED8AE847F20A0219E917FA)
This plugin was stored in %APPDATA%\NvmFilter\sTUlsWa1.cr and is a DLL with a single export named Starts. Its PDB path, D:\Programming\Projects\Autogen\Kh\AutogenAlg\Release\x64\FileMonitoringModule.pdb, has not been stripped, and it reuses code from the 2014 and 2020 file monitors, described above. It monitors drives and recent files, and copies files for exfiltration to %TEMP%\AcmSym\rm. Its log file is stored in %TEMP%\indexwti.sxd.
NightClub – 2020–2022
In 2020-11, we observed a new version of NightClub deployed in Belarus, on the computers of the diplomatic staff of a European country. In 2022-07, MoustachedBouncer again compromised some of the same computers. The 2020 and 2022 versions of NightClub are almost identical, and the compromise vector remains unknown.
Its architecture is slightly different from the previous versions, as the orchestrator also implements networking functions. The second component, which its developers call the module agent, is only responsible for loading the plugins. All samples were found in the folder %APPDATA%\microsoft\def\ and are written in C++ with statically linked libraries such as CSmtp or cpprestsdk. As a result, the executables are quite large – around 5MB.
Orchestrator
On the victims’ machines, both orchestrator variants (SHA-1: 92115E21E565440B1A26ECC20D2552A214155669 and D14D9118335C9BF6633CB2A41023486DACBEB052) were named svhvost.exe. We believe MoustachedBouncer tried to masquerade as the name of the legitimate executable svchost.exe. For persistence, it creates a service named vAwast.
Contrary to previous versions, to encrypt the strings they simply add 0x01 to each byte. For example, the string cmd.exe would be encrypted as dne/fyf. Another difference is that the configuration is stored in an external file, rather than hardcoded in the binary. It is stored in the hardcoded path %APPDATA%\Microsoft\def\Gfr45.cfg and the data is decrypted with a private 2048-bit RSA key (see Figure 21) using the function BCryptImportKeyPair and BCryptDecrypt.
![Figure 21. Hardcoded private RSA key Figure 21. Hardcoded private RSA key](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-21.png)
The config is formatted in JSON, as shown in Figure 22.
![Figure 22. NightClub external configuration format Figure 22. NightClub external configuration format](https://web-assets.esetstatic.com/wls/2023/2023-8/figure-22.png)
The most important keys are transport and modules. The former contains information about the mailbox used for C&C communications, as in the previous versions. The latter contains the list of modules.
Module agent
The two variants of the module agent (SHA-1: DE0B38E12C0AF0FD63A67B03DD1F8C1BF7FA6128 and E6DE72516C1D4338D7E45E028340B54DCDC7A8AC) were named schvost.exe, which is another imitation of the svchost.exe filename.
This component is responsible for starting the modules that are specified in the configuration. They are DLLs, each with an export named Start or Starts. They are stored on disk unencrypted with the .ini extension, but actually are DLLs.
Modules
Over the course of our investigation, we found five different modules: an audio recorder, two almost identical screenshotters, a keylogger, and a DNS backdoor. For all of them: their configuration, which is formatted in JSON, is passed as an argument to the Start or Starts function.
By default, the output of the plugin is written in %TEMP%\tmp123.tmp. This can be changed using the config field file. Table 3 shows the different plugins.
Table 3. NightClub plugins
DLL export name |
Configuration |
Description |
NotifyLoggers.dll |
{ “name”:”<value>”, “enabled”:”<value>”, “max_size”:”<value>”, “file”:”<value>”, “chk_t”:”<value>”, “r_d”:”<value>”, “f_hs”:”<value>”, “t_hs”:”<value>” } |
An audio recorder that uses the Lame library, and mciSendStringW to control the audio device. The additional configuration fields are likely used to specify options for Lame. |
MicroServiceRun.dll |
{ “name”:”<value>”, “enabled”:”<value>”, “max_size”:”<value>”, “file”:”<value>” “period_in_sec”:”<value>”, “quality”:”<value>”, “app_keywords”:”<value>” } |
A screenshotter that uses CreateCompatibleDC and GdipSaveImageToStream and writes captured images in file to disk. If app_keywords is not empty, it uses GetForegroundWindow to check the name of the active Window and capture it only if it matches app_keywords. |
JobTesterDll.dll |
{ “name”:”<value>”, “enabled”:”<value>”, “max_size”:”<value>”, “file”:”<value>” } |
A keylogger that uses the GetKeyState API. It writes the log in file to disk and the format is <Date><Title bar><content>. |
ParametersParserer.dll |
{ “name”:”<value>”, “enabled”:”<value>”, “max_size”:”<value>”, “file”:”<value>”, “cc_server_address”:”<value>” } |
A DNS-tunneling backdoor. cc_server_address specifies the IP address of a DNS server to which requests are sent. More details follow. |
The DNS-tunneling backdoor (ParametersParserer.dll) uses a custom protocol to send and receive data from a malicious DNS server (cc_server_address). Figure 23 shows that the DNS request is sent to the IP address provided in the configuration, using the pExtra parameter of DnsQuery_A.
![Figure 23. DNS request to the C&C server Figure 23. DNS request to the C&C server](https://web-assets.esetstatic.com/wls/2023/2023-8/2022-plugin-dns-request.png)
The plugin adds the data to exfiltrate as part of the subdomain name of the domain that is used in the DNS request (pszName above). The domain is always 11.1.1.cid and the data is contained in the subdomain. It uses the following format, where x is the letter, not some variable:
x + <modified base64(buffer)> + x.11.1.1.cid
For example, the first DNS request the plugin sends is xZW1wdHkx.11.1.1.cid, where ZW1wdHk decodes to empty.
Note that the base64 function is not standard. It removes the =, if any, from the result of the base64 encoding, and also replaces / characters with -s and + characters with -p. This is to create valid subdomains, because standard base64 encoding output can include +, / and = characters, all of which are invalid in domain names and could be detected in network traffic.
Then, the plugin reads the result that should be one or many TXT DNS records, since the flag DNS_TYPE_TEXT is passed to DnsQuery_A. Microsoft names the underlying structure DNS_TXT_DATAA. It contains an array of strings, which are concatenated to compute the output buffer.
![Figure 24. The plugin reads the TXT record Figure 24. The plugin reads the TXT record](https://web-assets.esetstatic.com/wls/2023/2023-8/2022-dns-data-txt-1.png)
Figure 24. The plugin reads the TXT record
The expected format of the reply is:
x + <argument encoded with modified base64> + x.<cmd_id>.<unknown integer>.1.<cmd_name>
This is similar to the format of the requests. The <argument encoded with modified base64> also uses the custom base64 encoding without = and with -p for + and -s for /. <cmd_name> is an arbitrary string that is not used by the backdoor; it’s likely used by the operators to keep track of the different commands. <cmd_id> is an integer that corresponds to a command in the backdoor switch statement.
For example, if the operators wanted to execute calc.exe, the DNS C&C server would send the reply xYzpcd2luZG93c1xzeXN0ZW0zMlxjYWxjLmV4ZQx.27.2.1.calc, where Yzpcd2luZG93c1xzeXN0ZW0zMlxjYWxjLmV4ZQ decodes to c:\windows\system32\calc.exe and 27 is the command ID to create a new process. All commands supported by this backdoor are detailed in Table 4.
Table 4. Commands implemented by the DNS backdoor
ID |
Description |
0x15 (21) |
Copy a directory (from a source to a destination) |
0x16 (22) |
Move a file (from a source to a destination) |
0x17 (23) |
Remove a file or a directory |
0x18 (24) |
Search a file for a given pattern (Note: we are unsure about the exact behavior of this command) |
0x19 (25) |
Write a buffer to a file |
0x1A (26) |
Read a file |
0x1B (27) |
Create a process |
The result of the commands is exfiltrated back to the attacker using DNS requests, as detailed above. The only difference is that 11 is replaced by 12 in the domain name, as shown in this example: xdGltZW91dAx.12.1.1.cid. In this case, the plugin sent the message timeout to the C&C server.
Conclusion
MoustachedBouncer is a skilled threat actor targeting foreign diplomats in Belarus. It uses quite advanced techniques for C&C communications including network interception at the ISP level for the Disco implant, emails for the NightClub implant, and DNS in one of the NightClub plugins.
The main takeaway is that organizations in foreign countries where the internet cannot be trusted should use an end-to-end encrypted VPN tunnel to a trusted location for all their internet traffic in order to circumvent any network inspection devices.
For any inquiries about our research published on WeLiveSecurity, please contact us at threatintel@eset.com.
ESET Research offers private APT intelligence reports and data feeds. For any inquiries about this service, visit the ESET Threat Intelligence page.
ESET Research Podcast
If you want to know how ESET researchers named MoustachedBouncer and its tools Disco and NightClub, what makes this group worthy of the “advanced” label, or if employees of the targeted embassies could have brought the malware home from work, then listen to the latest episode of the ESET Research podcast. ESET’s Director of Threat Research Jean-Ian Boutin explains the intricacies of MoustachedBouncer to our host and ESET Distinguished Researcher Aryeh Goretsky. If you enjoy listening to cybersecurity topics, subscribe to our ESET Research podcast on Spotify, Google Podcasts, Apple Podcasts, or PodBean.
IoCs
Files
SHA-1 |
Filename |
Detection |
Description |
02790DC4B276DFBB26C714F29D19E53129BB6186 |
index.html |
JS/TrojanDownloader.Agent.YJJ |
Fake Windows update webpage. |
6EFF58EDF7AC0FC60F0B8F7E22CFE243566E2A13 |
jdrop.js |
JS/TrojanDownloader.Agent.YJJ |
JavaScript code that triggers the download prompt of the fake Windows update. |
E65EB4467DDB1C99B09AE87BA0A964C36BAB4C30 |
MicrosoftUpdate845255.exe |
WinGo/Agent.ET |
Disco dropper. |
3A9B699A25257CBD0476CB1239FF9B25810305FE |
driverpackUpdate.exe |
WinGo/Runner.B |
Disco plugin. Executes PowerShell scripts. |
19E3D06FBE276D4AAEA25ABC36CC40EA88435630 |
DPU.exe |
WinGo/Runner.C |
Disco plugin. Executes PowerShell scripts. |
52BE04C420795B0D9C7CD1A4ACBF8D5953FAFD16 |
sdrive.exe |
Win64/Exploit.CVE-2021-1732.I |
Disco plugin. LPE exploit for CVE-2021-1732. |
0241A01D4B03BD360DD09165B59B63AC2CECEAFB |
nod32update.exe |
WinGo/Agent.EV |
Disco plugin. Reverse proxy based on revsocks. |
A01F1A9336C83FFE1B13410C93C1B04E15E2996C |
aact.exe |
WinGo/Spy.Agent.W |
Disco plugin. Takes screenshots. |
C2AA90B441391ADEFAA3A841AA8CE777D6EC7E18 |
officetelemetry.exe |
WinGo/Agent.BT |
Disco plugin. Reverse proxy based on revsocks. |
C5B2323EAE5E01A6019931CE35FF7623DF7346BA |
oracleTelemetry.exe |
WinGo/Spy.Agent.W |
Disco plugin packed with Themida. Takes screenshots. |
C46CB98D0CECCB83EC7DE070B3FA7AFEE7F41189 |
outlooksync.exe |
WinGo/Spy.Agent.W |
Disco plugin. Takes screenshots. |
A3AE82B19FEE2756D6354E85A094F1A4598314AB |
kb4480959_EdgeUpdate.exe |
MSIL/TrojanDropper.Agent.FKQ |
Disco .NET dropper. |
4F1CECF6D05571AE35ED00AC02D5E8E0F878A984 |
WinSrcNT.exe |
Win32/Nightclub.B |
NightClub plugin used by Disco. Steals recent files. |
0DAEA89F91A55F46D33C294CFE84EF06CE22E393 |
It11.exe |
Win32/Nightclub.B |
NightClub plugin used by Disco. Steals recent files. |
11CF38D971534D9B619581CEDC19319962F3B996 |
It3.exe |
Win32/Nightclub.B |
NightClub plugin used by Disco. Makes raw dumps of removable drives. |
F92FE4DD679903F75ADE64DC8A20D46DFBD3B277 |
metamn.dll |
Win64/Nightclub.B |
NightClub (2017 version). |
6999730D0715606D14ACD19329AF0685B8AD0299 |
et2z7q0FREZ.cr |
Win64/Nightclub.B |
NightClub plugin. Keylogger. |
6E729E84C7672F048ED8AE847F20A0219E917FA3 |
sTUlsWa1.cr |
Win64/Nightclub.A |
NightClub plugin. File stealer. |
0401EE7F3BC384734BF7E352C4C4BC372840C30D |
EsetUpdate-0117583943.exe |
Win32/Nightclub.C |
NightClub dropper. |
5B55250CC0DA407201B5F042322CFDBF56041632 |
creh.dll |
Win32/Nightclub.C |
NightClub (2014). |
D14D9118335C9BF6633CB2A41023486DACBEB052 |
svhvost.exe |
Win32/Nightclub.D |
Orchestrator (NightClub). |
E6DE72516C1D4338D7E45E028340B54DCDC7A8AC |
schvost.exe |
Win32/Nightclub.D |
Module agent (NightClub). |
3AD77281640E7BA754E9B203C8B6ABFD3F6A7BDD |
nullnat.ini |
Win32/Nightclub.D |
Backdoor with DNS tunneling (NightClub plugin). |
142FF0770BC6E3D077FBB64D6F23499D9DEB9093 |
soccix.ini |
Win32/Nightclub.D |
Keylogger (NightClub plugin). |
FE9527277C06D7F986161291CE7854EE79788CB8 |
oreonion.ini |
Win32/Nightclub.D |
Screenshotter (NightClub plugin). |
92115E21E565440B1A26ECC20D2552A214155669 |
svhvost.exe |
Win32/Nightclub.D |
Orchestrator (NightClub). |
DE0B38E12C0AF0FD63A67B03DD1F8C1BF7FA6128 |
schvost.exe |
Win32/Nightclub.D |
Module agent (NightClub). |
D2B715A72BBA307CC9BF7690439D34F62EDF1324 |
sysleg.ini |
Win32/Nightclub.D |
Records audio (NightClub plugin). |
DF8DED42F9B7DE1F439AEC50F9C2A13CD5EB1DB6 |
oreonion.ini |
Win32/Nightclub.D |
Takes screenshots (NightClub plugin). |
C&C servers
IP |
Domain |
First seen |
Comment |
185.87.148[.]86 |
centrocspupdate[.]com |
November 3, 2021 |
Suspected NightClub C&C server. |
185.87.151[.]130 |
ocsp-atomsecure[.]com |
November 11, 2021 |
Suspected NightClub C&C server. |
45.136.199[.]67 |
securityocspdev[.]com |
July 5, 2022 |
NightClub C&C server. |
45.136.199[.]129 |
dervasopssec[.]com |
October 12, 2022 |
Suspected NightClub C&C server. |
“Fake” domains used in AitM
Note: These domains are used in a context where DNS queries are intercepted before reaching the internet. They do not resolve outside the context of the AitM attack.
windows.network.troubleshooter[.]com
updates.microsoft[.]com
SMB share IP addresses while AitM is ongoing
Note: These IP addresses are used in a context where traffic to them is intercepted before reaching the internet. These internet-routable IP addresses are not malicious outside the context of the AitM attack.
24.9.51[.]94
35.214.56[.]2
38.9.8[.]78
52.3.8[.]25
59.6.8[.]25
209.19.37[.]184
Email addresses
fhtgbbwi@mail[.]ru
nvjfnvjfnjf@mail[.]ru
glen.morriss75@seznam[.]cz
SunyaF@seznam[.]cz
MITRE ATT&CK techniques
This table was built using version 13 of the MITRE ATT&CK framework.
Tactic |
ID |
Name |
Description |
Reconnaissance |
Gather Victim Network Information: IP Addresses |
MoustachedBouncer operators have collected IP addresses, or address blocks, of their targets in order to modify network traffic for just those addresses. |
|
Initial Access |
Drive-by Compromise |
Disco is delivered via a fake Windows Update website. |
|
Execution |
User Execution: Malicious File |
Disco needs to be manually executed by the victim. |
|
Persistence |
Scheduled Task/Job: Scheduled Task |
Disco persists as a scheduled task that downloads an executable from a “fake” SMB share every minute. |
|
Create or Modify System Process: Windows Service |
NightClub persists as a ServiceDll of a service named WmdmPmSp. |
||
Privilege Escalation |
Exploitation for Privilege Escalation |
Disco has a plugin to exploit the CVE-2021-1732 local privilege escalation vulnerability. |
|
Defense Evasion |
Deobfuscate/Decode Files or Information |
Since 2020, NightClub has used an external configuration file encrypted with RSA. |
|
Collection |
Data from Local System |
NightClub steals recent files from the local system. |
|
Data from Removable Media |
NightClub steals files from the local system. |
||
Input Capture: Keylogging |
NightClub has a plugin to record keystrokes. |
||
Screen Capture |
NightClub and Disco each have a plugin to take screenshots. |
||
Audio Capture |
NightClub has a plugin to record audio. |
||
Command and Control |
Application Layer Protocol: File Transfer Protocols |
Disco communicates via the SMB protocol. |
|
Application Layer Protocol: Mail Protocols |
NightClub communicates via the SMTP protocol. |
||
Application Layer Protocol: DNS |
One of the NightClub plugins is a backdoor that communicates via DNS. |
||
Data Encoding: Standard Encoding |
NightClub encodes files, attached to email, in base64. |
||
Data Encoding: Non-Standard Encoding |
NightClub encodes commands and responses sent via its DNS C&C channel with a modified form of base64. |
||
Encrypted Channel: Symmetric Cryptography |
NightClub receives plugins in email attachments, encrypted using AES-CBC. |
||
Adversary-in-the-Middle |
MoustachedBouncer has performed AitM at the ISP level to redirect its targets to a fake Windows Update page. It has also done AitM on the SMB protocol to deliver malicious files from “fake” servers. |
||
Exfiltration |
Exfiltration Over C2 Channel |
NightClub and Disco exfiltrate data over the C&C channel (SMTP, SMB, and DNS). |
|
Impact |
Data Manipulation: Transmitted Data Manipulation |
MoustachedBouncer has modified the HTTP traffic from specific IP addresses at the ISP level in order to redirect its targets to a fake Windows Update page. |
[ad_2]