A Curious Case of CVE-2019-19781 Palware: remove_bds

Vulnerability in Citrix Application Delivery Controller and Citrix Gateway (CVE-2019-19781) – updated

Published on December 17 2019, CVE-2019-19781 is a vulnerability in the Citrix Application Delivery Controller (ADC) and Gateway that, if exploited, allows an unauthenticated attacker to perform arbitrary Remote Code Execution (RCE). Based on the proposed mitigations for the problems, the root cause of the vulnerability stems from how the clients handle SSL VPN requests. While Citrix has provided their clients with information on how to mitigate the issue, a permanent fix has yet to be published.

Due to its severity, the vulnerability has been followed closely by both security and business professionals since its initial disclosure. With Germany among the many countries whose business interests are at risk of being affected by malicious actors exploiting CVE-2019-19781, the CERT-Bund is actively notifying German enterprises who they have determined to be vulnerable.

From Malware to Palware? DCSO Encounters an Interesting Case

During DCSO’s own efforts to evaluate the risk that the Citrix vulnerability poses to its clients, our technical experts encountered an interesting case in which the malware appeared to mitigate the vulnerability on the affected system.

After its deployment, the malware initially spawns a new thread calling main.remove_bds. The program remove_bds then calls main.doFile on files in /netscaler/portal/scripts which have been recently modified, effectively destroying any artifacts left over from prior exploit attempts. Next the malware calls main.install_itself which copies the executable over to /var/nstmp/.nscache/httpd. If the malware was not started from /var/nstmp/.nscache/httpd, then a new process is started from /var/nstmp/.nscache/httpd and the current process terminates.

The new process starts two new threads with main.xrun and main.install_cron.
Afterwards the malware starts walking the filesystem down from the current working directory with main.main.func1. searching .xml files (regex “\.xml$”). This is done in an infinite loop.
Matched files are processed with main.doFile which in turn uses the regular expressions “block|BLOCK” and “d474a8de77902851f96a3b7aa2dcbb8e” to search for specific .xml files.
The string “d474a8de77902851f96a3b7aa2dcbb8e” is present in the malware binary itself because it is part of the file path of the compile go file (/root/backup/sources/d474a8de77902851f96a3b7aa2dcbb8e.go).
The regular expressions (REs) are compiled in main.init, and the function is executed prior to main.main. This behavior indicates that the malware is watching for further exploitation of this vulnerability and prevents any such attempts by deleting any malicious files.
The function main.xrun opens a global (ipv4 & ipv6) UDP listener on port 18634. The malware, however, does not process the received input. Instead this UDP listener acts like a mutex – if this program is already running, every second instance will immediately terminate (the program will be started via cron once per minute, which is necessary to prevent multiple instances from running at the same).

The function main.install_cron is empty and does not implement any usable code. The missing functionality in main.xrun and main.install_cron could indicate that the development process was not yet completed.

What do you call malware that isn’t really malicious?

This case was particularly interesting for our technical experts because of the malware’s seemingly innocent functionality. While its stubcode elements suggest the sample is a work in progress, at its current stage it prioritizes preventing any affected systems from being exploited by other attackers seeking to deploy their own malware.

Because the attacker delivered this seemingly-innocent payload by means of a severe vulnerability, it can’t quite be considered a case of responsible behavior. But it’s certainly not malicious in nature at this stage, making it perhaps a contender for a softer, more considerate term – like palware. It’s not really at the level you would expect from a MSP response, but gets the job done like any good friend would.

Update

As noted by our friends at FireEye, the actor behind this malware is certainly not a “white knight”. While, according to our investigation, the sample itself is not providing direct backdoor capabilities, it is apparently used by the actor to maintain exclusive access to a compromised system. This is achieved by monitoring and deleting foreign payloads from /netscaler/portal/scripts while ignoring payloads that contain a specific marker, in this case d474a8de77902851f96a3b7aa2dcbb8e.

The samples listed in the Appendix contain and search for different markers, thus there is no universal key.

Appendix

Sample SHA-256 hashes

034a283aab5e8255f87842f8ac3eb5426f61365de85cb06eda71441c11d5108f
8dc6e678fe9453f5489c97e46edc560762491e83c6c2bccd5cf64a091775dab7
80b414ac955c30e5ddc3c2a4ba28c7be9ed6ac138e26d16499f3cb2ee52291da
fa7e73d2ff52f8f4ed6f84ac188969405eb14b9ce443c758d13c4b1ec8213d16
436a20803dc20a2f87948c17eb529dc6d1a61d067b9e27ab8b546d0ec9b4b236
751e0aef609a43168ca80ab560fe0bbee51f51baa3505903207209b5af5213e2
686258d0c5020156bcacd982e3959e04e8d0c3e091659aff473e5e7b96165df1
c5a6e599aab2cecac8845d37e604ff13a2c4e2e88aba545c28ea3c6d1f1b04bb
903a592494932a9d3c75d613cd2e14e2dc39a8572bba23aea0fec418fec96b3a
fca9e2eb673bba542df3e289c2a86809eb4be78e05c366029c51c989502170e8
68a4b0c2463d8e003bd6c20ece639547b4272f741fd2c6b452b246e89d71108b

Yara rule

rule dcso_citrix_remove_bds {
meta:
date = "2020-01-15"
reference = "internal research"
sample = "68a4b0c2463d8e003bd6c20ece639547b4272f741fd2c6b452b246e89d71108b"
strings:
$f_0 = "main.doFile"
$f_1 = "main.remove_bds"
$f_2 = "main.xrun"
$f_3 = "main.main.func1"
$p = "/root/backup/sources/"
condition:
2 of ($f_*) and $p
}