At the end of last month, McAfee published a fix for a remote code execution vulnerability in its Security Scan Plus software. Beyond Security, who we worked with for vulnerability coordination published the details of the issue and our PoC exploit on their blog. While the vulnerability itself got some attention due to its frightening simplicity, this is not the first time SSP contained similarly dangerous problems, and it’s certainly not the last. In this post, I’d like to share some additional notes about the wider context of the issue.
Last year we published a proof-of-concept tool to demonstrate bypasses against security products that still rely on the obsolete MD5 cryptographic hash function.
Summary: The method allows bypassing malicious executable detection and whitelists by creating two executables with colliding MD5 hashes. One of the executables (“sheep”) is harmless and can even perform some useful task and is expected to be categorized as goodware by the victim. After the sheep is accepted by the victim, the colliding malicious version (“wolf”) is sent. Because affected products rely solely on the MD5 fingerprints to identify known good executables, wolf is already whitelisted and can run.
Although the reception of the research was generally positive, some were skeptical about the extent and even the validity of the issue. Although in the meantime we received information about more affected products, NDA’s prevented us from further demonstrating that the problem indeed exists and affects multiple vendors.
Today we are able to share a demonstration of the problem affecting Panda Adaptive Defense 360. The issue is demonstrated against the stricter “Lock mode” of the product meaning that the Panda agent only allows known good executables to run (application whitelisting). For the sake of this video we manually unblock the harmless executable version (sheep4.exe) to speed up the process, as otherwise the analysis could take several hours to complete (it was confirmed that the “sheep” executables aren’t detected as malicious by the cloud scanner in case they are not manually unblocked):
(You can skip 01:00-01:55 if you are not interested in the policy update)
We notified Panda Security about this issue through their Hungarian partner (see the timeline at the end of this post). Panda responded that this is a known issue that is expected to be fixed in the next major version, but no ETA was provided. Panda stated that MD5 was used because of performance reasons. We informed Panda that the BLAKE2 hash function can provide higher level of security at better performance than MD5 (thanks to Tony Arcieri for this update!).
We’d like to stress that this research is not about individual vendors but about bad practices prevalent in the security industry. We now know of at least four vendors affected by the above problem and several others still provide MD5 fingerprints only in their tools and public reports. It is shameful that while hard work is put into phasing out SHA-1, in the security industry it is still generally accepted to use MD5, even after it was exploited in a real-world incident. We understand that there are more straightforward ways for evasion, but think that this issue is a good indicator of how security product development is often approached.
We should do better than this!
2016.08.30: Sending technical information to vendor.
2016.09.05: Vendor requests more information, including PCOPInfo logs collected during retest.
2016.09.06: Sending demo video and identification information about product instance. Requesting more information about PCOPInfo usage.
2016.09.06: Vendor responds with instructions about PCOPInfo.
2016.09.08: Sending PCOPInfo logs to vendor.
2016.09.19: Vendor responds that this is a known issue, replacement algorithm is expected to be implemented in the next version.
2016.09.27: Requesting negotiation about issue publication date.
2016.10.12: Requesting negotiation about issue publication date. Including notification about 90-day disclosure deadline in case no agreement would be achieved.
2016.10.19: Vendor responds, internal discussion is still in progress.
2016.11.16: Requesting information about acceptance of publication date.
2016.11.28: Public release.
This week a Polish bank was breached through its online banking interface. According to the reports the attacker stole 250.000 USD and now uses the personal information of 80.000 customers to blackmail the bank. Allegedly the attacker exploited a remote code execution vulnerability in the online banking application to achieve all this.
We at Silent Signal performed penetration tests on numerous online banking applications, and can say that while these systems are far from flawless, RCE vulnerabilities are fairly rare. Accordingly, the majority of the in-the-wild incidents can be traced back to the client side, to compromised browsers or naive users.
But from time to time we find problems that could easily lead to incidents similar to the aforementioned Polish banks. In this case-study we’re describing a remote code execution vulnerability we discovered in an online banking application. The vulnerability is now fixed, the affected institution was not based in Poland (or our home country, Hungary).
The online bank testing account had access to an interface where users could upload various files (pictures, HTML files, Office documents, PDFs etc.). The upload interface checked the MIME type of the uploaded documents only (from the Content-Type header), but not the extension. The Content-Type header is user controlled, so uploading a public ASPX shell was an obvious way to go; but after the upload completed I got an error message that the uploaded file was not found and the message revealed the full path of the missing file on the servers filesystem. I was a bit confused because I could not reproduce this error with any other files I tried to upload. I thought it was possible that an antivirus was in place that removes the malicious document before the application could’ve handled it.
I uploaded a simple text file with the EICAR antivirus test string with .docx extension(so I could make sure that the extension wasn’t the problem) that verified this theory. The antivirus deleted the file before the application could parse it that resulted in an error message revealing the full path:
This directory was reachable from the web and the prefix of the file name was based on the current “tick count” of the system. The biggest problem was that the application removed the uploaded files after a short period of time because this was only a temporary directory. I could also only leak the names of deleted files but not the ones that remained on the system for a longer time. So exploitation required a bit more effort.
Before going into the details of the exploit, let’s see what “primitives” I had to work with:
- I can upload a web shell (antivirus evasion is way too easy…)
- I can leak the tick count by uploading an EICAR signature
- I can access my web shell if I’m fast enough and know the tick count of the server at the moment the shell was uploaded
Unfortunately I can’t do these three things at the same time, so this is a kind of a race condition situation. According to the documentation “a single tick represents one hundred nanoseconds or one ten-millionth of a second” so guessing the tick count on a remote system through the Internet seems like a really though job. Luckily, I don’t always trust the documentation ;)
I built a simple test application that models the primitives described and implemented a simple time synchronization algorithm that I used before to predict time on remote servers with seconds precission. The algorithm works basically by making guesses and adjusting them based on the differentials to the actual reported server times.
While this algorithm wasn’t effective on the 100ns scale, the results were really interesting! I could observe that:
- Parallel requests result in identical tick counts with high probability
- The lower bits of the tick counts tend to represent the same few values
The reason for this is probably that the server processes are not truly parallel, just the OS scheduler makes you believe they are and that the resolution of the tick counter is imperfect. I also found out, that since the filenames are only dependent on the time my requests arrive to the application, the delays of the responses introduce avoidable uncertainty.
My final solution is based on grequests that is an awesome asynchronous HTTP library for Python. This allows me to issue requests very fast without having to wait for the answers in between. I’m using two parallel threads. The first uploads a number of web shells as fast as it can, while the other issues a number of requests with the EICAR string and then tries to access the web shells at constant offsets from the retrieved tick counts. The following chart shows the average hit rates (%) as the server side delays between the creation and deletion of the uploads changes:
And although a few percent doesn’t seem high, don’t forget that I had to only be lucky once! As you can see there is a limit for exploitability (with this setup) between 300 ms and 400 ms but as we later found out the uploads were transferred to a remote host, so the lifetime of the temporary files was above this limit turning the application exploitable.
The model application and the test exploit is available on GitHub.
In this case-study we demonstrated how a low impact information leak and a (seemingly) low exploitability file upload bug could be chained together to an attack that can result in significant financial and reputation loss.
For application developers we have the following advises:
- If you’re in doubt, use cryptographicaly secure random number generators.
- Never assume that your software will be deployed to an environment similar to your test machine. A conflicting component (like the antivirus in this case) can and will cause unexpected behavior.
- File uploads are always fragile parts of web applications, OWASP has some good guidelines about securely handling them.
And for those who are responsible for online banks or similar systems here are some thought-provoking questions:
- Do your development teams follow a security focused development methodology? Because a good methodology is the base of a quality product.
- Do you perform regular, technical security tests on your financial applications? Because people make mistakes.
- Do you fix the discovered vulnerabilities on your production systems in reasonable time? Because tests worth nothing if it takes forever to fix the findings.
- Do you have an incident response plan? Because despite all effort, incidents will eventually happen.
- Would you notice an incident? Because IR doesn’t get started by itself.
- Could you determine what the exploited vulnerabilities were and which users exploited (or tried to exploit) them? Because an incident is an opportunity to learn.
Analyzing the security of security software is one of my favorite research areas: it is always ironic to see software originally meant to protect your systems open a gaping door for the attackers. Earlier this year I stumbled upon the OfficeScan security suite by Trend Micro, a probably lesser known host protection solution (AV) still used at some interesting networks. Since this software looked quite complex (big attack surface) I decided to take a closer look at it. After installing a trial version (10.6 SP1) I could already tell that this software will worth the effort:
- The server component (that provides centralized management for the clients that actually implement the host protection functionality) is mostly implemented through binary CGIs (.EXE and .DLL files)
- The server updates itself through HTTP
- The clients install ActiveX controls into Internet Explorer
And there are possibly many other fragile parts of the system. Now I would like to share a series of little issues which can be chained together to achieve remote code execution. The issues are logic and/or cryptographic flaws, not standard memory corruption issues. As such, they are not trivial to fix or even decide if they are in fact vulnerabilities. This publication comes after months of discussion with the vendor in accordance with the disclosure policy of the HP Zero Day Initiative.