Uploading dangers

A few weeks ago I was reading a forum thread about file upload scripts in the PHP scripting language. The people in the thread were discussing different ways of handling different file types when allowing users on their websites to upload files to the server. Security wasn’t really on the topic here, but there were still mentions of it. The most common problem that is mentioned when it comes to file uploading is that there is a need to somehow restrict what kind of files the users are allowed to upload, how to handle them once they are on the server and so on.

In this case their solution was to disallow users from uploading files with the php extension, and then by using a PHP function called ImageJpeg they would verify that the users were uploading valid pictures (The forum user in question was making an image upload script for his community website). Now, as a developer I can see why this seems like a pretty nice idea, since the data would be verified and changed in the ImageJpeg function. If the file was not a valid image then the function would return false and the file would not be properly uploaded. And even if a malicious user were to put code within the data part of the image, that data would always be changed when the ImageJpeg function has finished and saved the file to disc.

The so called “black listing” of file extensions is usually not a good idea since there exists many different alternatives to one executable extension. If we take the example above where they prevented users from uploading files with the php extension. PHP has 5 alternative extensions, these being .php3, .php4, .php5, .phtml and .phps. And if a developer of a script only restricts .php, then the other 5 can be used instead to upload malicious code to the server.

I found it an interesting topic and decided to see if I can somehow bypass their protection and upload executable code to my test server using their upload scripts. The first thing that came to mind was that jpeg images allow so called “exif” data that can hold comments for image viewers and editors to display in different ways. Although this bubble burst rather quickly as I discovered that the ImageJpeg function always overwrites the exif data with its own, including the comments.

So now I had to fire up a hex editor and get to work, and see if I can insert data into the image itself, while making sure it’s still a valid image that would pass through the ImageJpeg function. The difficulty with this, just as discussed in the thread, was that the data was always changed and thus my code was not intact when the file was saved to disc. The image would in almost all cases be a valid one, although a bit distorted due to my meddling.

After hours of playing around with this I managed to get an image that when injected with code and run through the function, the code would still be intact and executable on my server.


So after even more hours of trying to perfect this method, making sure the image is always a valid one and that it’s not too distorted from the changes, I wrote a script that injects the code automatically and makes sure that the code will still be there after being changed with different image handling tools, like the ImageJpeg function (It was also tested with tools that performs resize on the picture, and although this worked in many cases it was significantly harder to retain the code after processing).

Below is the picture before the injection


Followed by the picture after the injection (notice how in this example, the picture got a little bit distorted at the end. This varies from case to case). Don’t worry, the code can’t execute in its current form.


So to summarize. After a few days I did manage to bypass their protection followed by writing a script to automate it all. Some example output from the script can be seen below.

[+] Jumping to end byte
[+] Searching for valid injection point
[+] Injection completed successfully
[+] Filename: result.phtml

And to top it up I also made a small script to send commands to the file once it has been uploaded to a server, parse the results out of the image data once returned and display it.

uname -a
Linux truesechp01 3.13.0-29-generic #53-Ubuntu SMP Wed Jun 4 21:00:20 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

And this shows how very easy it is for things to go wrong with file upload functionality. There are so very many ways to do bad things with it, and a motivated attacker can in many cases spend days, months or even years to find a way around your protection mechanisms. The trick I have showed you in this article today is not limited to PHP, but can be applied in other environments as well. There are a few measures that can be good enough depending on the situation when handling uploaded files to a server, but there’s no silver bullet as there are in many cases ways to circumvent them as well, the best example being that the developer who implements it simply does it wrongly (classic one is that they only check for the presence of .jpg in a filename, which would then allow the uploading of a file.jpg.php).

For those who decide to solve all this by using blacklisting and block file extensions like .php,.phtml,.php4,.php4,.php5. Be aware, PHP 7 will be released eventually 😉

UPDATE: And PHP 7 is here, and the vulnerability is back 🙂

Your passwords are never really safe

There have been a lot of user credential leaks lately according to media.
Some of them involve whole user databases with all kinds of credentials, and some involve “only” credit card numbers and so on.
It usually depends what the attacker is after when he/she/they break into the servers of the targeted company.

The thing that people don’t always know about this is that there are passwords being leaked all the time from hundreds of websites without
us even knowing about it. Some really huge leaks will never see daylight because the people behind the site never detects the intrusion, and the people behind the attack wants to keep it to themselves. Personally I have a unique email for every account I create, so that if they give out my details to a third party or if someone breaks into their systems, I’ll know.

Fresh databases with user credentials are worth a lot to many people on the black market for several reasons.

  • The email addresses can be used for spam
  • The email and password combination can be tried against different services like Facebook or Twitter and used for a number of things (spam being one of them)
  • The passwords can be put into a wordlist and used for cracking other passwords in the future

There have been many cases where website owners haven’t encrypted or hashed the passwords of the users, which have made life a lot easier for the intruder who then steals and potentially leaks the information (actually a lot easier, since very long passwords are harder to crack by brute force as it takes an enormous amount of time). But of course, today in most cases we see that they use some sort of encryption or password hashing. And even though this is a very positive thing, it doesn’t always help that much. If your password is too short and the password has been hashed, then it is in most cases lost. If it has been encrypted then there might still be hope, but then the hope lies upon the safety of the encryption key. And if the intruder has gotten access to the database, then the key might not be safe either.

The thing about the mind of a hacker that people don’t think about, is that a determined hacker wont stop just because it’s complicated or a hassle. If it’s a “hard to exploit” vulnerability then it simply means that it’s all a matter of time. And if the hacker thinks it’s worth the trouble, then years can be spent breaking in if needed. It’s the same with these databases. You all probably know about the Adobe intrusion and how all the users information was leaked on the Internet. These passwords were encrypted, although in a way that makes them not unique which has the problem of one password in its encrypted state will look the same for all users with the same password. This database has as of this date (as far as we know), not been completely cracked as the encryption key has not been discovered. But I’m sure that someone somewhere is working on that. Some determined hacker wants to get their hands on the key. Computers are getting faster and faster, so it’s just a matter of time.

I would like to demonstrate the typical process of your password getting in the wrong hands.
I downloaded the published dump of the eharmony.com password list with over 1500000 password hashes from users of the site.
Then I loaded them all into a password cracker called oclHashCat, and within seconds this was the result.

Session.Name...: oclHashcat
Status.........: Running
Input.Mode.....: Mask (?1?1?1?1?1?1) [6]
Hash.Target....: File (/home/cats/eharmony-hashes.txt)
Hash.Type......: MD5
Time.Started...: Wed Aug 13 21:42:11 2014 (4 secs)
Time.Estimated.: Wed Aug 13 22:50:22 2014 (1 hour, 7 mins)
Speed.GPU.#1...: 57925.6 kH/s
Speed.GPU.#2...: 62493.3 kH/s
Speed.GPU.#3...: 63531.4 kH/s
Speed.GPU.#4...: 42643.3 kH/s
Speed.GPU.#*...: 226.6 MH/s
Recovered......: 73454/1513805 (4.85%) Digests, 0/1 (0.00%) Salts
Progress.......: 738197504/735091890625 (0.10%)
Skipped........: 0/738197504 (0.00%)
Rejected.......: 0/738197504 (0.00%)
HWMon.GPU.#1...: 38% Util, 52c Temp, 43% Fan
HWMon.GPU.#2...: 36% Util, 48c Temp, 36% Fan
HWMon.GPU.#3...: 31% Util, 49c Temp, 45% Fan
HWMon.GPU.#4...: 33% Util, 47c Temp, 36% Fan

As you can see, 73454 passwords were recovered within 5 seconds. After 2 minutes the status is “388429/1513805 (25.66%)”. And this is by sheer brute force (I usually start with brute force when cracking MD5 since it’s so fast anyway). I haven’t even started to use my wordlists yet. By getting all these passwords in clear text I expand my database of wordlists with more user passwords that can be used in attacks later on. After about 1 hour I decided to stop the brute forcing process and try with a wordlist instead.

As you can see on this result there is one GPU less. This is because one graphics card broke during the brute forcing of the passwords. I have disconnected the damaged card for now until I can take a closer look later to see if it can still be used or not. Anyway as you can see, after only 5 minutes we have cracked 106794 passwords with the wordlist, leaving about 676732 still unsolved. Now, this list of passwords has already been cracked once my someone else, so I wont go for 100%.

Session.Name...: oclHashcat
Status.........: Exhausted
Input.Mode.....: File (../dics/crackstation.txt)
Hash.Target....: File (/home/cats/eharmony-hashes.txt)
Hash.Type......: MD5
Time.Started...: Thu Aug 14 08:30:44 2014 (5 mins, 51 secs)
Time.Estimated.: 0 secs
Speed.GPU.#1...: 3204.3 kH/s
Speed.GPU.#2...: 2937.5 kH/s
Speed.GPU.#3...: 2942.3 kH/s
Speed.GPU.#*...: 9084.1 kH/s
Recovered......: 106794/783526 (13.63%) Digests, 0/1 (0.00%) Salts
Progress.......: 1167547735/1167547735 (100.00%)
Skipped........: 0/1167547735 (0.00%)
Rejected.......: 14082514/1167547735 (1.21%)
HWMon.GPU.#1...: 29% Util, 49c Temp, 40% Fan
HWMon.GPU.#2...: 64% Util, 48c Temp, 35% Fan
HWMon.GPU.#3...: 64% Util, 45c Temp, 37% Fan

So to summarize. Pick long and complex passwords, and preferably unique ones for every site you register at. Personally I try to make up rules in my head for my passwords, and then I make up phrases for them. “Ch1ldOfL1ght1s@Gre@tG@me” is an example of a good password. Length is better than complexity, but it’s even better if you can mix in both. Also, if a site gets hacked and you have an account there, don’t trust that they have encrypted or hashed your passwords correctly. If it’s an important password that you have used in several places then you should always assume the worst and change it as soon as possible.

Too hot for cracking

A few weeks ago one of the PSUs for my hash cracking rig decided to give up on life.
Luckily I had a few months left on the warranty so I could get it switched for a new one just a week later.
I have decided that I want to make some new wordlists and thus needed the rig to be fully operational again (only 2/4 cards worked when one PSU was gone).

Currently it’s hashing away at a rather okay speed, although using the old unoptimized wordlists that I have.

Session.Name...: oclHashcat
Status.........: Running
Input.Mode.....: File (../dics/full_en.txt)
Hash.Target....: File (testhashes)
Hash.Type......: phpass, MD5(WordPress), MD5(phpBB3), MD5(Joomla)
Time.Started...: Fri Aug 8 18:48:24 2014 (10 hours, 27 mins)
Time.Estimated.: Sun Aug 10 07:37:18 2014 (14 hours, 11 mins)
Speed.GPU.#1...: 2881 H/s
Speed.GPU.#2...: 2869 H/s
Speed.GPU.#3...: 3113 H/s
Speed.GPU.#4...: 2752 H/s
Speed.GPU.#*...: 11614 H/s
Recovered......: 11/15 (6.59%) Digests, 11/167 (6.59%) Salts
Progress.......: 71936802816/164154971801 (43.82%)
Skipped........: 3950772224/71936802816 (5.49%)
Rejected.......: 0/71936802816 (0.00%)
HWMon.GPU.#1...: 90% Util, 71c Temp, 76% Fan
HWMon.GPU.#2...: 89% Util, 70c Temp, 76% Fan
HWMon.GPU.#3...: 88% Util, 74c Temp, 93% Fan
HWMon.GPU.#4...: 90% Util, 72c Temp, 52% Fan

The temperature as you can see is okay right now due an extra fan and an open window.
But the rig has already stopped working once due to high temperatures in the room.
It’s been really hot recently here, even on some of the days when it’s been raining heavily (like today).
Which has made it difficult to run the rig.


I have decided to gather all my wordlists and do the following on them:

* Remove “dirty” ones (some has bad encoding and some are clones of others for some reason)
* Merge smaller lists and categorize the rest in a neatly fashion
* Sort and remove duplicate words (So that every word is unique)

I will make another post soon with a link to two different downloads.
One link will be the categorized and neatly sorted lists, and another link will go to a “super list” with all other lists merged into one large.
The super one will also be cleaned and sorted properly after merging.
I might start releasing my wordlists in different versions since I add new lists once in a while.

More to come.

When security is not taken seriously

So I have this project going on for a while now where I’m trying to track a script kiddie that has been using sqlmap to hack literally hundreds of websites for about half a year now. He then proceeds to publish the information about the sites he has broken into, and while doing so shows a lot of signs of inexperience in the field. I don’t want to go too deep into the details of this little project in fear of alerting the person in question. But I do want to talk shortly about an incident that happened recently that is directly related to this project, that shows what can happen when security is not taken seriously.

A few days ago I checked on the list of websites that the guy has hacked. I noticed that he had added a bunch of new sites to his list and stated on some of them that he had only checked the database names and a list of tables in them. He had, according to what he said, not extracted any other sensitive information. Reading this, I proceeded to quickly contact the affected websites (I always do this, but sometimes I do it faster if I think that the data on the servers haven’t been touched yet) in hope of preventing any further damage. I have a template that I use for all contact with sites in this project, and I have even been reported for spamming by one of the company. Ungrateful as it may sound, I understand their reaction.

Among the sites I contacted, one was especially quick to reply to my E-mail. Stating that this incident had nothing to do with them and did not affect their website or business. I was surprised at first and thought that I might have made some error in contacting them and perhaps had contacted the wrong company. After double and triple checking, I decided to reply to the E-mail and ask if the website (including the link to the affected website) was indeed their website. It should be noted that if their websites address was “verylegitimatewebsite.tld”, then the contact address I was sending my E-mails to, was “info@verylegitimatewebsite.tld”.

This is how I think a lot of people see IT-security consultants these days when we try to tell people that security needs to be taken more seriously.

After a while the person on the other end responded that the site indeed belonged to them.
I’m not sure what brought on the first reply that it had nothing to do with them, but it became clear to me that this person had no idea what I was talking about and didn’t really seem to care either. I wrote a bit more detailed response more directed towards this specific website (instead of just generally direct them to the list of affected sites like I usually do to save time) to try to explain the situation and what all this could lead to, damages etc. I have so far not gotten a response, but I am still eagerly waiting for it.

During the conversation we had over E-mail, their user database was stolen and information regarding it was published.

Take it seriously folks.