Many of you may know there is a web server attack going on in the wild that involves appending a JS script to all the htm, php, cfm, js, jsp files found on a server. If you are unfamiliar with this attack see some of my previous posts like this one for more of an explanation. While I have found the script that actually does this dirty deed and I have combated this issue on numerous servers by now, I have never really been confident that I have discovered where the attack actually begins (i.e. how this file gets on the server to begin with). Yesterday I was made aware of a technique that might be the smoking gun. It has been tested by some folks I trust and I want to give a full explanation here to assist all those Muse readers who battle the bad guys at the server level.
If you are a technician or network operations professional who is trying to scan your way out of this attack, I'm afraid you are probably out of luck (but keep reading anyway). This attack specifically targets application code - not just CF but ASP, JSP, PHP and any others. All of them can be subject to this problem because it has to do with insecure coding, not specific platform vulnerabilities. I would add that if you find your code vulnerable don't feel too bad. This exploit is clever enough to get by code that seems secure as we shall see. If you are a web developer of any stripe you should definitely read this post. The examples are in ColdFusion, but you will be able to extrapolate for your own language or technology pretty easily.
Allowing users to upload files is a pretty typical feature on the web these days - and not just with ColdFusion. The ability to add content or resources in the form of a file is a common feature of forums, email applications, galleries, video sites, document sharing sites et al. Naturally it is very important that you are able to secure your server from malicious files uploaded using the tools you provides. In ColdFusion you can use the "accept" attribute to specify MIME types to accept. The browser determines the MIME type on upload using the file extension. Not only is this useless from a security standpoint, developers have found that this is not one hundred percent reliable (depending as it does on the client) so they have taken to writing custom code to filter out pernicious attempts to infiltrate the server. Consider this code for example:
This code checks the extension of the file and excludes any files that don't match a list of allowed extensions. So, for example, if a user wanted to upload a file with a .cfm extension and run it on your server they would be unable to do so - right? That makes this code safe... or does it?
There are a couple of reasons why this code may not be safe - not the least of which is that code could be uploaded with a spurious extension and used in some other way. For example, in my post on the Iframe injection hack a user was able to upload a file using ASP that seemed to be a GIF file, but in actuality was a CDX file which an IIS server in its "default configuration" (and no server should ever be left in it's default configuration!) is set up to handle using the asp.dll. In that case a malicious user was able to fool the upload script into thinking it's handling a gif when in actuality it is handling and executing malicious code. But that is not the exploit we are discussing here. In fact the exploit we are discussing here is even more devious and clever.
The way this works is pretty simple. A malicious user prepares a CFM script that does something naughty like emails your directory structure to himself or downloads additional files to the server via cfftp. He calls his script something random that is not likely to be on your server. Let us suppose he names his .cfm file "bob.cfm". Having his ignoble file in hand he must now figure out how to get it on your server where it can be executed.
Our hacker registers for an account on that site you built for mole lovers (Ilovemoles.com) and pokes around a bit (or should I say "digs" around a bit). Part of your site allows you to upload pictures of moles that you think are cute or unique. He uploads a photograph, and then views it his browser. He takes note that your code is serving the picture from www.ilovemoles.com/userphotos/. That path becomes his target directory. So his first attempt is to simply upload something other than a photo. He tries uploading Bob.cfm. Naturally, because you are not just a mole lover but also a good programmer you have precluded the upload of .cfm files. Our too clever hacker moves on to step 2 - the load test scenario.
Our hacker sets up his load test tool. Load test tools can be made to do different things, but one thing they do well is to simulate a barrage of HTTP requests at a certain level. Our hacker begins by setting up his load tester to test against one URL - www.ilovemoles.com/userphotos/bob.cfm. He sets it to run for 3 or 4 minutes and configures it to simulate a fairly high level of traffic (even a low level might work with repetition).
Now our hacker (I'm starting to feel an avuncular fondness for him) begins his load test. Naturally the load test is returning a boat load of 404 errors which it is dutifully logging. With the load test steaming along he logs into his ilovemoles.com account and uploads bob.cfm as if it were a photo.
Let's stop right here and consider what is happening under the hood with our code.
It is this tiny little window of opportunity that the hacker uses to his advantage. His load test code happily churning out 404 errors is firing off http requests at a rapid clip and one of them can hit the file at the right moment and grab a handle. The file is compiled into a CF class and executed - meanwhile your delete code will simply sit there and wait for the operating system to return a new file handle for it's delete operation. The OS obliges and does exactly that. As soon as CF is done compiling the code to Java Bytecode your excellent validation code happily deletes the evidence that the file was ever there to begin with. In fact, if you eschew web logging because you use something like Google analytics you will never know this file was being probed for or was ever on your disk.
Before we talk about prevention let me reiterate again that this approach is not a "ColdFusion" flaw - even though my example uses ColdFusion. Any web application that allows for upload directly into a web accessible directory that is configured with script permissions will potentially be vulnerable (PHP, ASP, JSP et al). Here's my list of preventative measures:
I'm always looking for a smoking gun. With the recent spate of attacks I have been frustrated by the fact that I am unable to determine the attack vector. I have suspected FTP, FCK Editor and a variety of insecure coding techniques. This explanation comes as close to explaining the "stealth" attacks as any I have run across. I have to say I'm still not completely convinced in spite of how neatly this all fits together. Still, it is one more thing to examine. Finally I would like to express my thanks to a group of ColdFusion developers who shall remain nameless but helped me uncover and vet this attack (thanks Gurus).
2. Just wanted to share a specific case of the lessons learned.
If you're uploading to the same folder as the content, you'll definitely need to change how that works to be protected.
However, if you're uploading to a directory that is accessible by URL but different than the final one the content resides in, you can remove all web access in your web server to the intermediate directory thereby making it inaccessible via a URL.
This is useful for cases where you're supporting legacy code or where making changes to existing code is not feasible.
- Gabriel
to my surprise, i put a test CF file there and it was accessible, suggesting that your hack detailed above is possible. Is there a way i can prevent CF code from being run at all in my upload directory?
how do I set this?
This is a really great post with an awesome explanation. I learned a lot from it. Thank you. This will come in especially handy with a project I will be working on soon.
Yes, you can disable script permissions on that directory. I'm not sure of the exact syntax but I believe it entails adding an option (NOEXEC or IncludesNOEXEC perhaps).
One of my Apache guru readers can perhaps post the correct syntax.
@gabriel, thanks for the additional info!
@Jason - thanks for the kind words
<Directory "/home/protectedDirectory">
Options IncludesNoExec
</Directory>
But i can still execute cfm scripts in there :(
I also have a mapping:
Alias /mappingname /home/protectedDirectory
Is this causing a problem?
the code they used was mainly in chinese, but they used a param "seraph"... I found a couple of instances... if you think something crazy is going on... Do a dreamweaver entire site search for "seraph" and you may find your hole.
The file they upload is .CFM and gets through cffile tags they dont check against limiting that type of extension.
Their file contains script to delete, add, view and edit any file on the server. They start by initialing with a cfdirectory that recurses through the entire server. They then get that list and start plucking away.
Ultimately I spent lots of hours locking down the site and then moving it to a new server. Once they got in through CF, they added things to the registry to launch .vb files and other scripts that were scheduled to append their .js scripts to all files on the server.
Its messy and ultimately you'll need to format the HD and reinstall windows to get back up and running.
That "seems" right to me, but apparently not :) I suspect it has to do with where in the file it's placed (within the site or whatever). As apache has no knowledge of a CF mapping I doubt that is in play.
@steve2 (if you are a different steve),
Thanks for that additional information. I agree with you that in the end, once a server is well and truly compromised, drastic measures are necessary.