Are you aware of the MIME/File Upload Security Issue?

This post is more than 2 years old.

I had heard a few rumblings of this recently but had not really paid it much attention. Mike emailed me today and described how he was hacked pretty badly by it. I'll share his email and then add some notes to the end.

Over the last week we have had 3 Coldfusion servers hit by a hacker who is uploading .cfm files using upload form fields that are set to accept only images.

As a long-term Coldfusion user, I never knew that it is possible to spoof Coldfusion into uploading executable (.cfm) files when it was set to only allow images. This post by Brent Fry explains more: http://www.cfexecute.com/post.cfm/spoofing-mime-types-with-coldfusion-and-cfhttp

This has major implications for any web site that allows users to upload images (like dating sites or community sites). You MUST take precautions like adding code to verity the mime type after an upload as discussed by Peter Freitag in this post: http://www.petefreitag.com/item/701.cfm

In our case, the hacker was able to upload an index.cfm file that provided them with COMPLETE control of our server (I'll send you the hackers page if you'd like -- it is truly impressive). They were able to install trojans that, among other things, would email China with our username and password every time we logged onto the server.

We could not find a scanning program that could identify and remove these trojans. All the Google search results about it were in Chinese. Our servers were so thoroughly compromised that we had no choice but to completely rebuild them.

I am hoping that you can warn others about this issue. I am not aware of any information from Adobe about this, and I have heard very little on the blogs. I'm surprised because I know of MANY other sites who have experienced the same attacked over the past week.

I'm hoping that people can learn from our experience and protect themselves now. I have no doubt that this will become a much more common attack in the very near future. The message is clear: if people are able to use an upload file form field on your web site, you too may be vulnerable.

Nice (and by nice I mean it in the snarky, oh crap, why can't people be nice version). So, I strongly encourage folks to read both of the linked too articles above. They nicely describe the issue as well as talk about solutions.

I'll add to Peter's post that you can sniff a file for being a valid image by using the new isImageFile(). Ditto for isPDFFile(). Of course, if you are working with something besides images and PDFs then you will need to use another mechanism.

I especially like the suggestion of pushing static files to something like Amazon S3. Not only does this help reduce your security risk, but it also means you don't have to worry about drive space (as long as you can afford it of course).

I decided not to post the code of the attack script. I don't think it's a risk to post it - I mean, it's not the code that's bad but the fact that someone uploaded it and used it to attack, but I'll err on the side of paranoia here and just not post it. (Although I did not that the hacker didn't properly var scope. Tsk Tsk.)

I think every software project contains red flags - things that you must have but have (potentially) negative side effects in terms of performance and security. Certainly any file upload ability should be considered a red flag and should be documented/reviewed/checked to ensure it can't be abused.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Jason Brookins posted on 6/30/2009 at 8:16 PM

Wow. I don't do a whole lot of file uploading (esp. to public-facing sites), but I will for sure mark this one down and pass it around to my other developers.

Comment 2 by Pete Freitag posted on 6/30/2009 at 8:17 PM

Thanks Ray, I've been meaning to update the post to mention using isImageFile, I will get around to it, but thanks for mentioning it.

Comment 3 by Jules Gravinese posted on 6/30/2009 at 8:20 PM

So how does this work? The hacker uploads a .jpg that is really a plain text file with cfml in it? If so... then what? I don't understand how anything.jpg would get parsed by cf.

Comment 4 by Sid Wing posted on 6/30/2009 at 8:25 PM

Added this to the "Security Checklist" for my dev team - along with var scoping and queryparams.

Comment 5 by Chad posted on 6/30/2009 at 8:25 PM

With image upload we store them in a folder that is secured with a login/password. Then use ImageCR to generate images off of them in a different folder.

Comment 6 by Chad posted on 6/30/2009 at 8:29 PM

@Jules they spoof the mime type so that CFFile thinks it is an image but really it is a text file with CFM code in it. Then they can browse to the upload folder and run the CFM file.

IE. http://foo.com/imageUPloads...

The CFM file runs and they can do what ever they want.

Comment 7 by Pete Freitag posted on 6/30/2009 at 8:40 PM

@Jules there is a code example in my blog entry of how that works: http://www.petefreitag.com/...

Comment 8 by Jules Gravinese posted on 6/30/2009 at 8:51 PM

Oh, I see. Then isn't the simple solution to make sure the file ends in a proper extension? I think you can then prety much ignore the mime type. Is that right?
And if a file manager is in use, make sure files cannot be renamed with as anything.cfm?

Comment 9 by Joshua Cyr posted on 6/30/2009 at 9:14 PM

Just so people know. This is an active attack on CF applications. They are targeting a well known shopping cart and probably other applications. I have seen multiple servers on different hosts go down because of this. If you offer software commercial or open source be sure to check it and inform your clients/users if they need to upgrade.

As for what it does beyond just the basics... it creates a web service, uploads executables, and reinfects periodically. I hadn't heard about the login recording, but not a surprise. This is what I got from one web host.

--

The Windows service name appeared to be randomized. I believe it started with a “w”, though. That’s probably to ensure that it ended up at the bottom of the list. The service pointed to the following file:

C:\windows\system32\wjqpoo.kll

The older version of Computer Associates eTrust which had been on the server did not catch it, but ESET anti-virus did. It identified it as “Win32/PcClient.NEF”. Unfortunately, the ESET site doesn’t provide much information about this threat. It appears to be a back door Trojan. This write-up on Symantec’s site seems to describe a similar variant:

http://www.symantec.com/sec...

It appeared to poll a remote host periodically. It received a binary from the remote host which it downloaded to the Windows temp folder. The binary had a random name which appeared to be a signed integer. The service would then execute the binary. The binary deleted all Web log files, disabled logging on the Web sites, and appended the malicious JavaScript to the bottom of HTML and JS pages.

Comment 10 by Tom Mollerus posted on 6/30/2009 at 11:16 PM

I think the most basic, essential security requirement about accepting files via upload is NEVER to store them inside the web root. This is more important than checking the extension, mime type, or size.

If you need to serve the file back to the user somehow, then just deliver it via CFCONTENT to make sure that it's not executed on the server.

Comment 11 by tony petruzzi posted on 6/30/2009 at 11:54 PM

not for nothing, but this is a HUGE security hole and bug in CF.

Comment 12 by Joshua Cyr posted on 6/30/2009 at 11:56 PM

@Tony How is this a CF bug?

Comment 13 by Raymond Camden posted on 6/30/2009 at 11:56 PM

I respectfully disagree Tony. The MIME type is sent by the browser. Pete's blog entry details that. Therefore CF has no other choice but to trust the MIME type. You told CF, "Check for mime type X", and it did that, exactly. CF can't be held responsible for the browser (requestor) lying about the mime type. Ditto for the user agent.

Comment 14 by papichulo posted on 6/30/2009 at 11:59 PM

Is this all happening on Hostmysite shared servers? I've had many Coldfusion associates for months talking about hostmysite servers being hacked. Nobody I know has had it happen anywhere else.

Comment 15 by tony petruzzi posted on 7/1/2009 at 12:03 AM

@ray,

so you're saying that Adobe shouldn't address this?

Comment 16 by Raymond Camden posted on 7/1/2009 at 12:06 AM

Tony, based on what I said above, can you explain how this is Adobe's responsibility?

That being said, a security note on the Adobe site wouldn't hurt. But again, this is not their responsibility.

Comment 17 by Tony Petruzzi posted on 7/1/2009 at 12:31 AM

@ray,

for the sake of argument, i'll give in and say that you're right: it's not an adobe issue, a security hole or a bug.

that out of the way.

you can't tell me it wouldn't make sense for adobe to write a patch or issue a hotfix that checks that the mimetype of an uploaded file conforms to the specified mimetype(s) listed in the accept attribute after it has been written to the server.

Comment 18 by Raymond Camden posted on 7/1/2009 at 12:33 AM

But it isn't a mime type on the file - it is a value sent by the requestor. (Pete, or anyone else, correct me if I'm wrong.) To me, this is like asking CF to 'fix' a bad user agent. It can't. It is what it is based on the info sent.

Comment 19 by tony petruzzi posted on 7/1/2009 at 12:39 AM

http://www.coldfusionmuse.c...

this post has some information on getting the mimetype of file that has been written to the server.

Comment 20 by Pete Freitag posted on 7/1/2009 at 12:40 AM

@Ray that's correct the mime-type is sent in the http request.

Most web servers have a huge list of mime-type to file extension mappings, it would be possible to create such a list and put it in a config file, and throw an exception if the uploaded file extension is not corresponding to the mime-type mappings. But at that point you might as well just add an attribute for allowed file extensions.

Comment 21 by Pete Freitag posted on 7/1/2009 at 1:06 AM

@papichulo From what I have heard (second hand) many of the attacks on hostmysite have been from a virus that grabs saved FTP passwords from local FTP clients, and then uploads a cross site scripting attack to the files on the web sites.

There isn't anything in particular that would make a hosting company more at risk for this attack, except perhaps hosting companies that force you to upload into the web root. And those that don't allow file uploads would not be at risk.

Comment 22 by papichulo posted on 7/1/2009 at 1:30 AM

@pete Thanks for the tidbit of info. I was asking because my upload form is in my admin panel behind SSL, and uses encrypted password just to get in the admin to upload. Our sites were getting owned, and people were saying it was because the hackers were using an upload form. That didn't make sense to me, because my form was only in my admin panel. Then I changed my admin password and asp,php,js,and cf pages were being written to the sites within 10 minutes of changing the admin password. Hostmysite acknowledge the problems, but when I saw this post it caught my attention because they had told me about upload forms. Now what you heard makes more sense than what I was thinking. Thanks.

Comment 23 by Christopher posted on 7/1/2009 at 2:28 AM

So I'm confused.

How was ColdFusion executing the .cfm file that was being uploaded? Was it being uploaded directly to a folder the user could instantly access and execute? Or are you saying somehow ColdFusion invoked the uploaded .cfm file itself?

Because if Mike was uploading directly to a user-accessible folder, this exploit is certainly not news.

Comment 24 by Brent Frye posted on 7/1/2009 at 3:13 AM

As has been mentioned this is a direct attack on a shopping cart, according to the makers the newest version does not have this vulnerability, yet another reason to keep yourself patched and updated. On most of the servers I've seen, unless you have proper sandboxing and have disabled cfexecute, these attackers are creating local users and also uploading key loggers to track your passwords. The web shell their using also allows them to wipe your web logs, execute programs directly on your server, and inject malicious JavaScript into all the files on your server.

Comment 25 by Brent Frye posted on 7/1/2009 at 3:20 AM

@Christopher

The cffile accept argument implicitly trusts the MIME types sent by the browser, so having image/jpeg in there, the attacker would simply send a .cfm file to the action page, but say its a jpeg with the MIME type. In this application, it directly uploads to an images folder, obviously not the best option - as you'd want to upload somewhere not accessible on the web and then perform additional checks on the file before moving it somewhere publicly accessible.

Comment 26 by Christopher posted on 7/1/2009 at 3:31 AM

@Brent Frye,

So, this is a case of uploading to a public directory. I thought someone found a way to upload a .cfm file and have the server execute the file, no matter where it was stored.

I crapped myself for nothing.

I was always under the impression that filtering out file types on the browser side was like validating form input with JavaScript, it's more for the user than for security.

That said, I don't bother with client-side restrictions.

Comment 27 by Brent Frye posted on 7/1/2009 at 3:41 AM

@Christopher

Yeah - if you already upload outside of the web root and take extra precautions to validate those files prior to making them public you should be fine. As has been stated, this is the client side telling the server that its uploading something it isn't. When its public - that allows the attacker to execute the code like it were any other cfm file on the server. In this case, look up the C99 php web shell - they are using essentially the same thing, only written in ColdFusion.

Comment 28 by Steve Glachan posted on 7/1/2009 at 4:25 AM

This is crazy interesting. Thanks for the notice.

I've been trying to read through this while at work so forgive me if this has already been brought up but, is this exclusive to CF? All the comments seem CF related so just wondering if this is specific or experienced across the board with Java, PHP, .NET, etc.?

Comment 29 by Brent Frye posted on 7/1/2009 at 5:17 AM

@Steve,

This could likely be exploited in any language if all you trust for uploads is the MIME type provided by the user and automatically upload to a publicly accessible location. There are web shells written in just about every language (Perl, .Net, PHP, CF, and classic ASP), so most of the discussion is applicable to any language used for web applications where the public can freely upload files.

Comment 30 by tony petruzzi posted on 7/1/2009 at 5:35 AM

i took the time to code an almost drop in replacement for cffile to handle this issue until something could be sorted out. it uses the gettempdirectory() function to upload, performs some checks against and then will move the file to the original destination if it's ok.

http://gist.github.com/138542

if anything, if you can look over the code and tell me what i'm missing, i would appreciate it. i want to implement this into all my sites tomorrow.

Comment 31 by John Whish posted on 7/1/2009 at 2:20 PM

I might be being dense, but when I do file uploads I have a list of allowed file extension and check against that when a file is uploaded so I don't rely on the mime type. That way the server won't execute the script.

Something like:
<cffile action="upload" .../>
<cfif ListFindNoCase( "jpg,png,gif,jpeg", cffile.serverfileext ) EQ 0>
<!--- delete the file --->
<cfelse>
<!--- file has an expected extension so carry on --->
</cfif>

Comment 32 by Joseph Lamoree posted on 7/1/2009 at 3:23 PM

I ran a quick search on some of my applications to see if any files that use CFFILE are accessible by a non-admin user, or if any publicly accessible upload forms place a file in a directly accessible path:

find . -name '*.cfm' -exec grep -Hoi -E '<cffile.*action="upload".*>' {} \;

I might write something more sophisticated, but that does the trick for now.

-joseph

Comment 33 by Sammy Larbi posted on 7/1/2009 at 3:42 PM

Mike says "We could not find a scanning program that could identify and remove these trojans."

If you shared the uploaded file, we could at least write a program that would scan our drives for similar ones, to know if we've been compromised and then decide to rebuild the servers.

If not the whole thing, could you specify some things to look for? Rarely used tags that could be scanned for and examined by hand might be useful, for instance.

Comment 34 by The Innocent posted on 7/1/2009 at 4:17 PM

And here is an example of how easy it can be to have your server pwned if you don't take care.

http://www.coldfusion.tv/vi...

Comment 35 by Jules Gravinese posted on 7/1/2009 at 4:31 PM

@The Innocent

That script looks very familiar. I had to clean that off of a server recently. It was used by EL_MuHaMMeD:
http://www.zone-h.org/archi...

Comment 36 by Matt Osbun posted on 7/1/2009 at 4:57 PM

http://xkcd.com/327/

Not exactly the same thing, but this issue is a lot like putting a hand grenade in a vase simply because it was delivered by FTD.

Comment 37 by DanaK posted on 7/1/2009 at 6:18 PM

This seems like more of a problem for shared hosting folks. I never would put uploaded files in a web accessible folder myself.

Hopefully posts like this makes it's rounds enough for people to be aware and protect themselves!

Comment 38 by Wil Genovese posted on 7/1/2009 at 6:30 PM

This isn't a new thing. It's always been possible to do this with pretty much any web server that allows file uploads. Back in the day I would never let an uploaded file be saved into the accessible web root. I had a locked down 'dump' folder for these files that could not be executed via URL. With today's social media craze we all want our uploaded content visible like now! So, we must take even greater steps to ensure the file uploaded is safe.

Good catch on this and it is always the right time to raise a security concern.

Comment 39 by Pete Freitag posted on 7/1/2009 at 7:05 PM

@John Whish - yes checking the file extension as you show is key, the other thing that you must do is upload outside the webroot, otherwise I might be able to write a script that uploads the file and then spawns a fury of requests for the file, there is a chance that I could execute it before you deleted it. That's why you need to upload to a destination outside the web root.

@Wil Genovese - No it certainly is not new, I've been talking about this issue for a long time, I never blogged it until recently unfortunately. I have always found that whenever I talk about this issue, about half of the room has to run and fix their code. So this issue is one that we all need to be vocal about as frequently as possible (just like cfqueryparam, yay!).

Comment 40 by Raymond Camden posted on 7/1/2009 at 7:08 PM

Hey Pete - attending MAX? I think you may be volunteered to speak on this at CF Unconference. If you are attending MAX, consider yourself drafted. ;)

Comment 41 by Pete Freitag posted on 7/1/2009 at 7:16 PM

@Ray - Yeah I'll be at Max Sunday-Wednesday, is the unconference on Sunday?

Comment 42 by Raymond Camden posted on 7/1/2009 at 7:19 PM

Unconference is all week, M-W. See my other post on it (http://www.coldfusionjedi.c.... Thanks for "volunteering" Pete.

Comment 43 by Brett posted on 7/1/2009 at 7:19 PM

Our server was attacked even with sandboxing, cfexecute disabled, service factory calls disabled. I have not yet tried to determine how they got around the sandboxing but
one preventative measure is to run ColdFusion under a user with limited permissions instead of running the service as local system.

Most of the hack (on our particular server) appears to be specific to Windows IIS servers. Some distinguishing features of the hack .cfm file are:
- the name seraph
- references to cmd.exe, adsutil.vbs, MetaBase.xml, cscript.exe
- comments that show up as question marks or gibberish in a text editor (but may be a foreign language)

Other signs of this particular hack:
- Unknown virtual directory (particularly in IIS default web site)
- Registry entry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\wminotify (records server admin passwords)
- Unknown service which is difficult to disable
- Executables (.exe) in C:\windows\temp
- IIS logs deleted and disabled
- Script tag added to html, htm, asp, js, and application.cfm files

Comment 44 by Pete Freitag posted on 7/1/2009 at 7:43 PM

@Brett - your attack may not have come through CF, see my previous comment about the FTP attack as one possibility.

@Ray - Sure, lets schedule it for Monday sometime.

Comment 45 by Mike posted on 7/1/2009 at 7:56 PM

Please note that this is NOT a HostMySite issue. My servers were hacked and they have nothing to do with HostMySite.

I'm sure the hackers (based in China) crawled all the HMS IP addresses looking for Coldfusion sites to hit. This attack may be clustered around HMS at this time, but I am sure it will spread over time.

Comment 46 by Jules Gravinese posted on 7/1/2009 at 8:42 PM

@Mike
Sometimes they do a google search. For instance, "cffm.cfm" to find that particular CF file manager. Then test if it's open. Then test uploading a file, etc etc.
I found that out by looking at the logs around the time EL_MuHaMMeD stopped by. I was able to retrace his every step, watching how he wiggled his way deeper and deeper:

(referring to log line numbers to my client)
(2) It looks like this hacker used our file manager to get a file 'tmpfiles.gif.cfm' onto the server. The file manager is locked so that you can only upload files into the /media/ folder or below. But what this guy did was upload a CFM which is its own file manager.

(4) He accessed that uploaded CFM as a regular web page.

(6-13) He's looking around for a safe place to upload/hide another hack file manager.
(14) He uploads another file manager

(16-21) He deletes the original hack file manager.

(33) He checks to see if he can run PHP code as well. But cannot.

(58) He uploads the defaced home page.
(59) And tests it.
(60) And deletes the real home page.

(61-73) He looks for other weaknesses, finds none, and leaves.

Comment 47 by Hazen posted on 7/1/2009 at 8:50 PM

Hi all, regarding Bret's post about Registry entries, Registry entry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Notify\wminotify (records server admin passwords)

Should this entry be removed and if so is the entire Notify Entry to be removed? or some entries contained with in??? I guess I am asking because we have have had an attack on another server, but just this week recommissioned a new server, and started serving sites again from the new box. I want to be sure that the new box stays safe,(as much as is possible), and so I have checked for this registry and YES, Notify is in the Reg. So what's to be done?

Thanks,

Comment 48 by Paul posted on 7/2/2009 at 6:15 AM

Erg...I think we were just attacked by this at 1:45am 07-01-09.

What we're seeing is essentially every web file (.htm(l),.cfm,.php,.js, etc) being appended with a script code trying to load a swf from "chanm.3322.org/flash/".

We scrubbed all of these files with a massive search and replace and then they just got reinfected again.

We're trying to find the source that is running this attack automatically, but we're having difficulties finding it. Any tips/ideas on how to isolate the malicious program thats causing this and get our servers back online??

Thanks!
Paul

Comment 49 by Jules Gravinese posted on 7/2/2009 at 6:40 AM

Paul, check the server log files during that time period.

Comment 50 by John P posted on 7/2/2009 at 6:16 PM

@Brett - make sure you have JSP on the server disabled. This is how the hacker is able to get around sandboxing.

Comment 51 by Jeff Hubbach posted on 7/2/2009 at 11:56 PM

Who allows users to upload files to a web-accessible folder anymore? Seriously? All uploads go into a non web-accessible directory. To serve them back to the user, use cfcontent.

Comment 52 by Raymond Camden posted on 7/3/2009 at 12:02 AM

@Jeff: Who does? A lot of people. Don't forget - the mere fact that you READ a blog puts you in the minority. The vast majority of devs out there don't do any due diligence, don't spend time researching, etc. They just do their day job.

Comment 53 by CC posted on 7/3/2009 at 12:44 AM

FYI: This vulnerability has been picked up by SANS:

http://isc.sans.org/diary.h...

Comment 54 by Raymond Camden posted on 7/3/2009 at 6:27 AM
Comment 55 by barry.b posted on 7/4/2009 at 6:36 PM

"I had heard a few rumblings of this recently but had not really paid it much attention."

not you're fault, Ray, that "not really paid it much attention" ... where was the flashing red lights from Adobe? Where was the official word so you could pick it up and blog/retweet?

sure it involves a 3rd party product. I'm just shocked that it's a case of the tail (community) wagging the dog (Adobe's psirt).

In the Enterprise space, we're quite happy to pay for CF licencing even when it includes 3rd party products, because they've been tested by Adobe and have their seal of approval on them. But this is an on-going things, not "just a forget it after it's released" - that means being tightly plugged into the 3rd party products and hearing of any issues to see if it has an impact on their use in CF.

how to kill a platform in the Enterprise space - be really sloppy with security responses...

my 2c.

Comment 56 by Jon Cavanaugh posted on 8/5/2009 at 9:23 PM

After applying the patch in advisory APSB09-09, we need to allow uploads via fckeditor. Following these OPTIONAL steps to enable, we're not able to start ColdFusion. The specific step that is applied causing CF to not start is:

Edit jvm.config file and add the JVM argument “–Dcoldfusion.fckupload=true”

I have verfied that the "update" hf800-77218.jar was active and that the default JVM was being used for ColdFusion. Anyone else try enabling the upload and run into this problem?

Thanks for any help,

Jon C.

Comment 57 by Ray Majoran posted on 1/17/2010 at 5:24 AM

The easiest way to get around this is to make sure the directory that you're uploading the files to does not have Script or Executable permissions (i.e in IIS). That way, even if they upload a CFM (or ASP, NET, PHP, EXE, DLL) file, it doesn't really matter -- it can't execute.

Comment 58 by Doug Trojanowski posted on 2/5/2010 at 6:23 AM

@Ray Majoran

Is that true Script/Executable trun off?

Comment 59 by EL_MuHaMMeD posted on 3/22/2010 at 8:35 PM

:)
I'm Turkish Hacker....

Raymond :P