During an audit of ColdFusion 10 and 11’s administration panel, I discovered a reflected, DOM-based cross-site scripting flaw, and in this blog post, I will show you how to leverage that vulnerability to gain remote code execution on the ColdFusion application server.
After discovering this vulnerability, I participated in the responsible disclosure process with the Adobe Security Team. The CVE assigned to this vulnerability is CVE-2015-0345.
To remediate this vulnerability, please patch your ColdFusion installation via the administration panel itself and ensure that the panel is not external facing. If business needs dictate that this panel is exposed, please patch your ColdFusion installation via the administration panel.
Note: This vulnerability is only exploitable to users who have authenticated to the administration panel. Hence, to obtain remote command execution through the exploits documented below, a person who is authenticated to this panel must execute the final XSS vector.
Analysis
ColdFusion’s administration panel is the central interface for configuring its server. It contains functionalities including but not limited to user management, database provisioning, and server management. The JavaScript library jqFileTree.js
is used in conjunction with server-side APIs when ColdFusion administration pages display files or folders in a dynamic view.
Visiting the following ColdFusion administration page reveals the use of the jqFileTree.js
library:
/CFIDE/administrator/filedialog/index.cfm?type=dir&fromjscript=true&dialogStyle=selectDirectory&formelem=ORMSearchIndexDirectory&defaultPath=
A ColdFusion API feeds the paths of folders and files located on the system into the fileTree function.
You can directly access the AJAX API that returns the paths for these folders and files in a list format by visiting the following URL:
/CFIDE/administrator/ajaxtree/jqueryFileTree.cfm?type=dir
By combining these factors together, the paths are requested through JavaScript and then displayed as seen in Image 1.
$('#fileTreeDemo_1').fileTree({ script: '../../administrator/ajaxtree/jqueryFileTree.cfm?type=dir', expanded: '\x2F' }, function(file) { path = file; document.getElementById("pathbox").value = path; });
The script value provided to the file tree is not hard coded but rather is placed in the JavaScript context on page load. This is dynamically generated based on the user-entered URL.
The string is inserted into the page’s HTML source through the ColdFusion server-side script itself, not through the client side:
The value inserted in the above JavaScript source code was:
'../../administrator/ajaxtree/jqueryFileTree.cfm?type=dir'
The ?type=dir portion of the string originates from the user input (URL) and can hence be considered user input.
Through some testing, I found that this type parameter was not properly encoded for a JavaScript context.
Entering a traditional XSS vector was ineffective since ColdFusion's cross-site scripting filter stripped and encoded special characters. Additionally, a blacklist is used to filter out HTML tags and angle brackets (<, >). All invalid characters as defined by this blacklist are completely removed from the page’s HTML source.
Hence, the best option was to create a payload suited for the JavaScript scope.
XSS Proof of Concept
After some tampering, I produced the below payload that triggers a prompt with document.location;
',expanded:'x2F'},function(file){path = file;document.getElementById("pathbox").value = path;});prompt(document.location);$('#fileTreeDemo_1').fileTree({script:'../../administrator/ajaxtree/jqueryFileTree.cfm?type=dir
The above payload escapes out of the existing function and then executes the malicious JavaScript. In this case, the JavaScript that has been injected and will be executed is prompt(document.location);.
The remaining part of the payload reinitiates the fileTree function with the correct configuration. This is to ensure that the file/folder browser for ColdFusion still works on that page, thus reducing suspicion from the victim.
The exploit then URL-encodes the above payload and replaces the value of the type parameter in the original URL:
http://127.0.0.1:8500/CFIDE/administrator/filedialog/index.cfm?type=dir%27%2c%65%78%70%61%6e%64%65%64%3a%27%5c%78%32%46%27%7d%2c%66%75%6e%63%74%69%6f%6e%28%66%69%6c%65%29%7b%70%61%74%68%20%3d%20%66%69%6c%65%3b%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%70%61%74%68%62%6f%78%22%29%2e%76%61%6c%75%65%20%3d%20%70%61%74%68%3b%7d%29%3b%70%72%6f%6d%70%74%28%64%6f%63%75%6d%65%6e%74%2e%6c%6f%63%61%74%69%6f%6e%29%3b%24%28%27%23%66%69%6c%65%54%72%65%65%44%65%6d%6f%5f%31%27%29%2e%66%69%6c%65%54%72%65%65%28%7b%73%63%72%69%70%74%3a%27%2e%2e%2f%2e%2e%2f%61%64%6d%69%6e%69%73%74%72%61%74%6f%72%2f%61%6a%61%78%74%72%65%65%2f%6a%71%75%65%72%79%46%69%6c%65%54%72%65%65%2e%63%66%6d%3f%74%79%70%65%3d%64%69%72&fromjscript=true&dialogStyle=selectDirectory&formelem=ORMSearchIndexDirectory&defaultPath=
When the above URL is visited by the victim, the arbitrary JavaScript, inserted by me in this case, prompt(document.location); is executed in the browser. Below is an image demonstrating this:
XSS-to-RCE Proof of Concept
I created two payloads for compromising the system. The first payload disabled the requirement of a password for the ColdFusion administrator panel. The second payload uploaded a web-backdoor shell to the ColdFusion installation.
For the sake of keeping this blog post succinct, I will focus on the more effective one of the two. However, both payloads and examples of how to use them can be found at our GitHub.
The Payload
Payload #2, as provided in the above GitHub repository, performs the following actions in order to upload a shell once an administrator has executed it:
- GET request made to a CFIDE administration page to obtain the CSRF Token
- POST request made to /CFIDE/administrator/scheduler/scheduleedit.cfm with the relevant parameters put in
- POST request to run the now added task. A CFML shell is uploaded to /CFIDE/update_cf.log
- POST request to change the 404 template and 500 template to execute /CFIDE/update_cf.log
Once the payload has been executed successfully, you can now visit your ColdFusion shell on /404.cfm, /500.cfm or by forcing 404/500 errors on the ColdFusion server.
The payload outputs information such as the CSRF token, the full path of the ColdFusion installation, and the shell’s location upon execution for debugging purposes. Below is a screenshot showing the JavaScript developer console after the PoC has been executed by an administrator:
Visiting the URLs /404.cfm or <span style="font-family:'courier new', courier, monospace;">/500.cfm</span>
will then return the login page for the fuZE web backdoor shell. The web backdoor shell is configured to have the username “god” and the password “default.” After logging into the shell, it is possible to perform functions such as executing arbitrary commands, running SQL queries, editing files, starting a reverse shell, and uploading or downloading files from the server. A screenshot of the backdoor’s interface can be seen below:
Conclusion
As of April 14, 2015, Adobe has successfully patched the DOM-based XSS vulnerability. I’d like to thank the Adobe Security Team for their quick work resolving this issue for ColdFusion 10 and 11 in the 90-day disclosure period.
Adhering to company recommendations when it comes to setting up applications is important, and this ColdFusion vulnerability demonstrates why. Follow Adobe’s best practices and keep the ColdFusion web administration panel internal facing; failure to do so could expose your system to future vulnerabilities.
Any questions or comments concerning this vulnerability? Tell us on Twitter.
The official Bishop Fox advisory for this vulnerability can be found here.
Subscribe to Bishop Fox's Security Blog
Be first to learn about latest tools, advisories, and findings.
Thank You! You have been subscribed.