Archive for January, 2008

Hashing: The Iterative Hash

Jan 31

One great technique out there is what is known as the iterative hash. This is simply taking the hash of some data and hashing the resulting hash and then hashing that hash again.

pseudo-code example of this:
string hash = sha256(‘data’ + ‘salt’);
hash = sha256(hash);
hash = sha256(hash);
…etc.

By doing this many times (1,000-10,000 times maybe) makes the hash incredibly hard to crack. If an attacker steals your hash and finally cracks it all they have is a new hash to crack. Then this process has to be repeated again and again and again. Even if it only takes 2 days to crack a hash it would take 2,000-20,000 days now to crack that hash. I will take that any day.

Now their is a performance hit to this of course. I did a bit of benchmarking a while back and found that 1,000 iterations took 0.36 seconds and by jumping up to 10,000 seconds I actually got better performance at 0.19 seconds (original post on this here). So tune how many iterations to what your system will handle (and someone tell me why I get the unexpected result).

Basic Implementation using SHA512.

byte[] data = Encoding.UTF8.GetBytes(dataToHash.Trim() + salt.Trim());
HashAlgorithm algorithm = new SHA512Managed();
for (int i = 0; i < iterations; i++)
{
     data = algorithm.ComputeHash(data);
}

Of course you can use whichever hashing algorithm you want here. If you wanted to get crazy you could mix and match your algorithms to prevent any future weakness in an algorithm from making your hashes vulnerable. While it is nice to have that protection it adds many more failure points which makes it hard to debug issues.

There is also a builtin class in the .NET framework that can be used to generate iterative hashes. It is called Rfc2898DeriveBytes (catchy hey!). Here is a quick code sample of it.

Rfc2898DeriveBytes db;
String data = "HashMe";
int iterations = 1000;
byte[] salt;

if (_salt.Length == 0)
    db = new Rfc2898DeriveBytes(data, _saltSize, iterations);
else
    db = new Rfc2898DeriveBytes(data, _salt, iterations);

byte[] result = db.GetBytes(200);

One of the nice features is that the Rfc2898DeriveBytes class has an overload that we could just pass in the salt size and it will generate the salt for us. Alternatively we can supply our own salt. The hardcoded 200 in the example is how many characters we want our hash to be. I am unsure of what is going on internally inside of this class still as far as algorithms to do all of this work. I have also not been able to find out how hard it is to crack the generated hash either so I have leaned towards using the SHA iterative hasher from before as I have more data on it.

Filed Under: Security

It is not a great day to look for work in Edmonton

Jan 30

Well back in e-town we have hit our cold spell like we always do. I decided to check the weather out and saw a great add from workopolis above the weather. I will leave it for you to decide if “It’s a great day to look for a new job in Edmonton”

Filed Under: General

Victoria Code Camp Materials

Jan 26

Here is the website and slides used in both talks (Cryptography So Easy A Goat Could Do It and Website Hacking 101 – SQL Injection Attacks and Cross Site Scripting). Both presentations used the same site and database so I have included everything as one bundle (including the slides).

Injection Attacks And Cryptography.zip

Filed Under: Speaking

HTML 5 Draft Released

Jan 22

The long awaited HTML5 draft is out. I had a quick look at it looks to be more of depreciating old things than anything else.

Some absent tags of note: center, u, strike, frame, frameset, and noframes (frames are removed due to accessability issues…. and they were always a pain to work with too)

A lot of other attributes have been removed that are now handled (and handled better) by CSS. Some of these are things like bgcolor, align, valign, background, cellpadding, and cellspacing to note a few.

A lot of the new stuff revolves around media. There is the addition of a  videa and audio for media files. As well there has been a 2D drawing API added too which is pretty vague but may allow users to draw onto the page. There are lots of other APIs added as well but details are not outlined yet.

The working draft can be found here: http://www.w3.org/TR/2008/WD-html5-diff-20080122/

Filed Under: General

Hashing For Passwords

Jan 21

As mentioned in “Hashing – The Basics” I felt that a separate post on hashing for passwords was required.

Principal

The principal of storing hashed passwords is fairly simple and can be described in these steps:

  1. When an account is created the plain text password is entered
  2. The password is run through a hashing algorithm
  3. The output of the hash is stored

 

  1. When the user logs in they enter their plain text password again
  2. The password is run through the hashing algorithm
  3. The hash just generated is checked against the stored one. If the two match then the user has entered the same password as the account was created with

Salting

One of the most important techniques with hashing is salting. Salting is the process of injecting random data into a string before it is hashed. There are a few reasons for this.

  1. Collision avoidance. If two users have the same password they will have the same hash in the database. This means if we crack one password then we have easily cracked the other.
  2. Additional complexity. By adding good random data into a string we can no longer brute force a hash. So we could try a brute force and easily get “mypass” as the password or by using salting we would have to brute force mypass#$^q∩gwjoεai←cyuw3b5asdφ♂

One of the things here to note is to add good random data. Math.Random() does not supply strong random numbers. Instead use the RNGCryptoServiceProvider instead.

public static string GenerateSalt(int sizeInBits)
{
    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
    byte[] salt = new byte[size/8];
    provider.GetBytes(salt);
    return Convert.ToBase64String(salt);
}

By adding salting techniques makes the account creating steps a little more involved. The reason for this is when the user logs in we need the original salt data that the hash was created with. Normally we store this along with our data but there are some other techniques.

Here are the steps again with salting involved:

  1. When an account is created the plain text password is entered
  2. A random salt is generated and appended onto the password (i.e. “mypass” + “#$^q∩gwjoεai←cyuw3b5asdφ♂”)
  3. The password+salt is run through a hashing algorithm
  4. The output of the hash is stored
  5. The salt used is also stored

 

  1. When the user logs in they enter their plain text password again
  2. The salt is loaded
  3. The plain text password + salt is run through the hashing algorithm
  4. The hash just generated is checked against the stored one. If the two match then the user has entered the same password as the account was created with.

Now it does not always have to be ‘password’ + ‘salt’ we could reverse it to be ‘salt’ + ‘password’ or even ‘salt’ + ‘password’ + ‘salt’. As long as the way we create the hash is the same procedure we use to check the hash then the possibilities are endless. In fact as I write this I would say that ‘password’ + ‘salt’ is the common pattern that to add more security to your hashes mix the salt in differently (i.e. the ‘salt’ + ‘password’ + ‘salt’)

IMPORTANT: Do not use the same salt for each record. Having random data thrown in to each unique record will make each record harder to crack. I will discuss this idea a bit more in my next post on attacking hashed passwords.

Drawbacks

Hashing passwords does have its drawbacks like anything else:

1. Passwords can not be retrieved for a user. This is because hashes are just a fingerprint of the data; they never actually contain the password inside of them. The way to get around this is to have the ability to reset a users password (i.e. generate a new hash/salt and overwrite it in the database)

2. Creation / Login disparities. I had an issue once where when the account was created the password did not get whitespace trimmed off of it. I created an account with a password of “blah ” but the user could not login with “blah” because “blah” and “blah ” result in two totally different hashes. This took quite a while to debug.

3. Database/Code truncation. It is easy to spot that a users password exceeds the size of a database column as it would look like this “HelloMyNameIsSi” but a truncated hash would look like “A56FY#SDFH^(EU”. These are hard issues to spot and debug sometimes

4. Performance. The performance impact is not that large but it is still higher than a plain text login system. I would never sacrifice security for performance myself and there are usually better places to improve performance of a system.

Filed Under: Security

Common Home Router Exploit (UPNP enabled routers only)

Jan 15

The concept of Universal Plug and Play (UPNP) is a great idea but for some reason always frightened me…. and now I see why.

For a bit of background UPNP is a protocol that is meant to allow network devices to seamlessly connect and configure. A good example of this is on home routers when you use the file sharing feature in MSN. When you to send someone a file your computer opens a port up and instructs the recipient to connect to your computer on port x and download that file. If you are behind a home router you would actually have to login to it and say forward requests on port x to my computer internally on port x. That is quite the pain but with UPNP the computer talks to the router and does this all for you automatically and the file transfer is completed. This is all done without the user having to confirm the action and the commands are trusted because it is coming from inside the network.

This is how routers can be exploited. The current proof of concept has the user visit a website with a flash application on it. The flash application runs on your local computer which is behind the router. This allows the flash application to issue UPNP commands inside your network. So now by visiting a website you could possibly emit UPNP commands from within your network without you knowing (not that you ever knew what commands UPNP was executing in the first place)

Some of the things that could be done with this attack

-Open a port forward to your internal network.
-Change the DNS server on the router. This could be tragic as it could route www.yourbank.com to a fake site that looks just like www.yourbank.com and you would never know… well until your account got emptied out.
-Resetting credentials (yes this can be done over UPNP).
-Potentially open a port forward to the internal router web server to the outside world.

Mitigation Techniques

-Number one is to disable PNP on your router/other devices. Most routers have this turned on by default.
-In order to carry out this attack the software needs to guess the routers IP address. The common address is 192.168.1.1 so changing it to something else (but still in the private range) makes the attack harder but may only be a matter of time if a brute force methodology is used.
-Disable flash on your internal computers (not very practical and all it would take would be for someone to create a Java app or some other app that runs on the client to exploit this)

Not a Flash Issue

Reading this most people have felt that this is an issue with Flash and should be fixed there. Really Flash is just a convenient vector. In theory anything that is downloaded and executed on your computer could be used to do this (i.e. javascript, activeX, Java, silverlight, etc.) could perform the same exploit. The only thing limiting those technologies is the language feature to do a HTTP post to any IP it wants to (some languages will only allow you to talk back to where you got the file from in the first place). Flash actually has this protection in that it will allow you to send data to any server but not read the response back.

Filed Under: Security

Speaking at Victoria Code Camp

Jan 11

I will be doing two talks at the Victoria Code Camp on January 26th.

My first talk is titled “Cryptography So Easy A Goat Could Do It”. This is an intro into cryptography including hashing, symmetric, and asymmetric encryption. I will be talking about a lot of best practices and comparing the differences between algorithms available in the .NET framework.

My second talk has the much more boring title of “Common Web Site Exploits and How To Protect Against Them”. In this one we will hack a sample site using common techniques and then look at how to lock the site down to help mitigate these attacks.

Hope to see you there!

Filed Under: Speaking

Hashing – The Basics

Jan 11

Hashing has been a long used technique to store and validate information. Hashing is the function of applying a translation to a string to generate a unique (and replicable) fingerprint of the data (often referred to as a checksum).

String Hash
Hello World b10a8db164e0754105b7a99be72e3fe5
Hello Worlds 9f0d0cd67d27414d0ae8f5eca41a1a36

As you can see, even a minor change to the string results in a completely different hash. This is why hashes are often used to verify that data has been unmodified. Another great feature of hashes is that they are just a fingerprint of the data. There is no way to reconstitute the original data from a hash*.

Hashing for Verifying the Authenticity of Data

hashing

As you can see in the document the author generates an SHA512 hash of his/her document and places that document on the Internet. The client then downloads the document and runs it through the same algorithm on their own. If the hash we generate matches the authors then the document has been unmodified. If the hashes don’t match then the document may have been tampered with and should not be trusted.

Storing the hash right next to the document really defeats the purpose. If an attacker gained access to the document, that attacker could then modify the document, generate a new hash for the modified document and overwrite the original. From a client point of view there is a document and a hash that work out. So it passes the verification. This is why it is really important to store the hash separately from the data you are trying to authenticate. Optimally the hash should be stored with a third party or be given out upon request directly from the author.

Hashing for Passwords

The most common way operating systems store passwords is in a hashed format. I actually don’t know of a modern operating system that does not do this. The premise is quite simple. When your account is created your password is hashed and stored on the disk. When you login, you type in your password which then gets hashed. The operating system compares the hash it just generated (based on you entering your password into the login screen) with the hash it has on disk. If the two hashes match then you entered the same password your account was created with and so you are successfully logged in. If properly implemented this is a great way to authenticate users without having to ever store their passwords (I think properly implementing this is a post to itself).

Algorithms

For us in the .NET world there are 5 hashing functions available to us:

Acronym Name Output Size (bit) Recommended
MD5 Message-Digest algorithm 5 128 No (collision can be created in less than one minute on a standard computer)
SHA1 Secure Hash Algorithm 160 No (collisions are possible to create but much harder than MD5)
SHA256 Secure Hash Algorithm 256 Yes
SHA384 Secure Hash Algorithm 384 Yes
SHA512 Secure Hash Algorithm 512 Yes

 

The SHA256-SHA512 are often referred to as SHA2 and are the preferred choice currently. The main reason for this is the lack of collisions which have been created on the MD5, SHA0, and SHA1 protocols. The SHA2 protocols are relatively new but have not been shown to have collisions (yet).

Collisions

A hash collision occurs when two different values produce the same hash. In theory this could mean that two totally different documents could yield the same hash. Worse yet that two separate passwords could yield the same hash. This would reduce the time taken to brute force a system as it would be possible to enter a password that collides against a hashed password in the system thus reducing the number of guesses required to force our way into a system. The use of salting is a great way to help protect against this (more on this later) but I prefer to use a stronger algorithm (and salting) when designing a system.

Code

The code is actually quite simple. All you have to do is convert your input data to a byte array and run it through one of the classes that derives from HashAlgorithm (MD5, SHA1, SHA256Managed, SHA384Managed, or SHA512Managed) and call the ComputeHash method on it. Here is a quick sample using the SHA512 Managed class:

public string CreateHash(string input)
{
       HashAlgorithm sha = new SHA512Managed();
       byte[] inputData = Convert.FromBase64String(input);
       byte[] hashedBytes = sha.ComputeHash(inputData);
       return Convert.ToBase64String(hashedBytes);
}

 

That is the basics of hashing. Next up I will write some posts on properly implementing hashing and salting for password systems.

 

 

*Well besides brute forcing the hash. This is done by throwing data at the hash function until the same hash is generate as the one you are trying to get. If the hashes match then you probably (see collisions) have the original data.

Filed Under: Security

New Year – New Direction

Jan 11

I have always tried to write my blog towards the common developer (aka the intermediate programmer). I feel that this is the often neglected programmers; experienced enough to do some things on their own but not experienced enough to do everything on their own. So I started writing little tips and notes with those developers in mind. I have really enjoyed seeing my readership grow to people all over the world.

In a former life I used to do security work on the networking side and really enjoyed it. I have found that passion with security on the code side. Most of my recent speaking engagements have been around security and I have decided to really focus on that area and that includes my blogging. Over the next few months I am going to be putting a lot of the things I do in my speaking engagements into digestible posts. While security is not the only thing I will be blogging/speaking on it will be my primary focus.

Happy New Year!

Filed Under: General

Tortoise Global Ignore

Jan 4

One of the annoying things with using Tortoise SVN I have found was that I always have to exclude the bin, obj, and .suo files that are unique to each machine. Even if I did that someone else on my team might forget which just makes it a huge pain. I thought there must be a better way and sure enough there is a global ignore setting in the tortoise settings panel (just right click on any folder and select TortoiseSvn -> Settings). Right on the front page I noticed the global ignore setting:

Tortise Settings

So far my global pattern is:
    *\bin *\obj *\bin\* *\obj\* *.suo

Filed Under: General