Introduction
🎈🎂🎂🎂🎂🎂🎂🎈Six years ago today, on September 12, 2017, Adobe released APSB17-30. Among three other vulnerabilities*, it included a patch for CVE-2017-11286 a Critical XML eXternal entities (XXE) bug in ColdFusion. This vulnerability was found and reported to Adobe by Daniel Lawson of Depth Security. While digging into some ColdFusion internals recently, I walked back through history and stumbled on this vulnerability, and figured it was interesting enough for a detailed write-up.
Over the past six months there has been a lot of ColdFusion security activity related to remote ColdFusion Component (CFC) methods, deserialization, and remote code execution vulnerabilities -- including the wild CFClient-related CVE-2023-26360 and a series of WDDX Java deserialization flaws (CVE-2023-29300, CVE-2023-38203, CVE-2023-38204).
I've spent a lot of time reviewing these vulnerabilities, their corresponding exploits, and the underlying vulnerable codepaths in an effort to better understand the attack surface of ColdFusion environments. I also want to call out and acknowledge the outstanding research, analysis and write-ups for these vulnerabilities from Stephen Fewer of Rapid7 (CVE-2023-26360), and Harsh Jaiswal and Rahul Maini of ProjectDiscovery Research (CVE-2023-38203, CVE-2023-38204). Their work has been tremendously helpful to me.
So What? Why Does This Matter in 2023? "But Brian," you say, "the Only Things I Want to Revisit from 2017 are Amazon Prime's Vastly Underrated Series Patriot, and Cloud Nothings' Life Without Sound..."
So why spend research time and effort digging into a a vulnerability that is old enough to play tee-ball? And why should you, my dear reader, care about it? In my fourth blog post, I winked at George Santayana. In this post, I'll give the people want they want and just say the line:
"Those who cannot remember the past are condemned to repeat it."
Therein lies the value of walking through a six-year-old vulnerability. By studying vulnerable constructs and vulnerable functionality, it can be possible to identify more areas of likely weakness to analyze, secure, and protect. This is pure speculation, but it is possible that detailed, contemporary analysis of CVE-2017-11286 could have led to other ColdFusion vulnerabilities being found and fixed much earlier. May my research inform and and assist future research.
What do CVE-2023-29300, CVE-2023-38203, CVE-2023-38204, and CVE-2017-11286 all have in common? The exploitation technique involves passing malicious data in parameters to remote CFC methods. I suspect there are many other past vulnerabilities that fit this pattern, and that there will be more in the future. Armed with this knowledge, we could take a defensive position and block remote HTTP access to all .cfc files. This may be an extreme position, but it has the potential to provide immediate protection against future, unknown vulnerabilities. Remote CFC methods can provide a quick way to build API-like functionality, but they also appear to expose significant portions of ColdFusion codepaths to user-input, which would otherwise be inaccessible. (And to be clear, this recommendation has no impact on calling public/private/package methods in CFCs.)
Technical Details
Exploiting CVE-2023-29300 involves unsafe deserialization of user-controlled data in a WDDX packet. WDDX (Web Distributed Data eXchange) is an XML data format created by Allaire for ColdFusion in 1998, and is now supported in several other languages.
While looking at some CFC execution flows, the following block of code caught my eye in the WddxDeserializer method in the coldfusion.wddx.WddxDeserializer class:
These are the SAX security settings to prevent XML eXternal Entities (XXE) attacks. This immediately got me wondering if the SAXParser that processed WDDX from in function arguments was vulnerable at some point in the past, and if so, when was it patched.
After reviewing several years of past Adobe Product Security Bulletins and some trial-and-error, I fired up an old version of ColdFusion and confirmed that it was in fact vulnerable to XXE via WDDX packets. After even more testing, I had confirmed that ColdFusion 11 Update 12 and ColdFusion 2016 Update 4 (and earlier) and was pretty sure that this behavior was CVE-2017-11286 from APSB17-30. [ed: I've confirmed with Daniel that the XXE vulnerability that I've reproduced here is his from APSB17-30.]
The vulnerable version of WddxDeserializer lacks the SAX security settings:
A sample exploit with a WDDX packet that contains an XXE payload that will perform a simple HTTP callback is shown below:
Host: some.target.here
If this is sent to a ColdFusion server running a vulnerable version of WddxDeserializer (i.e., pre-ColdFusion 11 Update 13 and pre-ColdFusion 2016 Update 5), our exploit will be successful. Other XXE payloads, such as data exfiltration techniques, can be used in place of a simple HTTP callback.
Similar to other other attacks that leverage a remote ColdFusion component (CFC), the method specified in the request doesn't need to exist. But it gets even crazier. The entire component doesn't even need to exist. You can exploit this by pointing to a blank file with a .cfc extension. This possibility sets up the scenarios where if one vulnerability exists that lets an attacker create an empty filename with an arbitrary extension, he can chain it with a remote CFC vulnerability for a more impactful exploit path. I have not gone back and confirmed that other CFC-based exploits work in a similar fashion, but I suspect that they do.
Recommendations and Conclusion
Does a new article on a six-year-old vulnerability really need recommendations? If you're vulnerable to CVE-2017-11286, you're likely also vulnerable to many more worse things and may already be compromised. So migrating to a secure, patched, current ColdFusion environment is a given. Ideally one where you're blocking remote HTTP access to CFCs. ☺
[*And if you're interested in the other two Critical vulnerabilities from APSB17-30, the researcher who reported them, Nicky Bloor, also published a detailed write-up here in October 2017. They both involve unsafe Java deserialization.]
Thanks, Brian. Helpful stuff as always. I certainly really appreciate the historical and practical perspective.
ReplyDeleteThat said, I think you'd help a lot of people with a discussion or link to a resource discussing how to block those remote cfc calls (in iis, apache, and in the uriworkermap.properties file). :-)
Then also, it could help to suggest how best to look for any such calls in web server logs (to avoid blocking unexpectedly-needed cfc calls).
And some will need to hear that all this has NOTHING TO DO with whether your code calls cfcs as components within cfml but only calls made to CFCs via http/https. (And some will fall into the trap of saying "we don't use that", but as you note the exploit can be used with ANY cfc, and they exist within the cfusion/wwwroot folder, which Is implicitly web accessible--and that's worthy of its own discussion.)
If you may not want to elaborate on any of this here or in another post, let us know and I or others can consider taking it on. I just wanted to get the thoughts out to help other readers here, as they consider your recommendation into action.
It seems worth also mentioning Adobe's Aug 2023 update (for cf2023 and cf2021 only), which itself tries to address another aspect of this cfc-based serialization in a more global way--but where just blocking incoming cfc calls may still be best for some.
Oh, the wicked webs that are woven. Thanks again for helping folks navigate them.
Thanks for the comment, Charlie. All great points. I hadn't planned on going into detail about searching logs and blocking paths -- beyond maybe answering questions here -- because there's bound to be a lot of variation based on individual configurations. I also still wonder if there's some underlying need for remote CFCs in some cases that I'm ignorant of. But since a few of the recent CF remote code execution vulnerabilities were exploited/detected in the wild before a patch was available, that got me thinking about proactive defenses.
ReplyDeleteI suspect that CFAdmin needs remote access to some CFCs for core functionality any blocking should probably happen at least one level above "localhost" access. My gut feeling is that a WAF rule/access control at the edge may the the easiest win with the least risk (depending on your tolerance for internal-network attacks). I haven't thought through all the possible edge cases and I don't have access to enough varied, diverse ColdFusion log stores to take a shot at a one-size-fits-most approach. But if you want to take a crack at it or have great links to share, go for it!
Thanks very much for this write up Brian, have added CFC request blocking via Apache.
ReplyDelete