Monthly Archives: August 2014

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 6 will be released eventually 😉

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 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.