Now that's security!



  • In light of today's nasty WTF about the banking software security, I'd like to share something that I'd discovered this last week - the best security you've ever seen!

    In brief, I've inherited a mobile app that runs on a PDA and talks to a website. Fine. But I was having trouble logging on, so I start delving into the code. What it does is encrypt the password you enter on the PDA with a salted hash, then for good measure it hashes the result before POSTing it to the website. The site then reads back the hash to get the original salted hash (this bit works fine), then looks up your password from the database, runs the same salted hash algorithm over it and compares it against the one sent from the PDA. If they match, it lets you in.

    But, here's the clever bit... the salted hash returned on the website is different to the one sent from the PDA. I think there's some difference in the encoding the hashing algorithm does (it's c# and both web and PDA are using the same assembly so it's not a different algorithm or anything). So, basically, you can never log on, ever. Don't get much more secure than that!

    And somehow this has been in production for about a year.
     



  • That is a lesson about how desperately the users have been waiting for that application all their lives!

    No one uses it? Who cares, we're live!



  • What? Logging on? Dude who the F*** wants to log on? I want it to read my mind (MINDTAKER!)

     

    Its like the i.beat blaxx mp3 player, you would THINK that SOMEONE would notice this during development/testing/product demos/production, but i guess no one used it so w/e. 



  • @valerion said:

    ...The site then reads back the hash to get the original salted hash (this bit works fine), then looks up your password from the database, runs the same salted hash algorithm over it and compares it against the one sent from the PDA. If they match, it lets you in

    I hope you meant "looks up your salted hash from the database" instead of "looks up your password from the database, then salts and hashes it."

    THAT would be a WTF.



  • @BradC said:

    @valerion said:

    ...The site then reads
    back the hash to get the original salted hash (this bit works fine),
    then looks up your password from the database, runs the same salted
    hash algorithm over it and compares it against the one sent from the
    PDA. If they match, it lets you in

    I hope you meant "looks up your salted hash from the database" instead of "looks up your password from the database, then salts and hashes it."

    THAT would be a WTF.

    I'm quite interested in how the site "reads back the hash to get the original salted hash".  The hash functions that I know of are very decidedly one-way.  If that bit "works fine", it's either not a hash, or the real WTF is that this application was designed by an unrecognized genius of cryptanalysis and has re-written the rule book on how mathematics works...




  • This sounds a lot like a challenge-response algorithm - either misimplemented, or cargo-culted by somebody who had no comprehension of how such algorithms work.



  • @DaveK said:

    @BradC said:

    @valerion said:

    ...The site then reads
    back the hash to get the original salted hash (this bit works fine),
    then looks up your password from the database, runs the same salted
    hash algorithm over it and compares it against the one sent from the
    PDA. If they match, it lets you in

    I hope you meant "looks up your salted hash from the database" instead of "looks up your password from the database, then salts and hashes it."

    THAT would be a WTF.

    I'm quite interested in how the site "reads back the hash to get the original salted hash".  The hash functions that I know of are very decidedly one-way.  If that bit "works fine", it's either not a hash, or the real WTF is that this application was designed by an unrecognized genius of cryptanalysis and has re-written the rule book on how mathematics works...

    Maybe they just brute-force it to get the original salted hash -- or something that hashes to the same value.  No wonder it doesn't work...



  • @BradC said:

    I hope you meant "looks up your salted hash from the database" instead of "looks up your password from the database, then salts and hashes it."

    THAT would be a WTF.

    Seconded. Motherfuckers need to stop putting my plaintext password in their databases. And before you jackasses start getting clever, symmetrically encrypting the passwords in the database is also a WTF.

     In this particular case, however, I think asuffield hit the nail on the head -- sounds like authentication with cargo cult security.



  • @asuffield said:

    This sounds a lot like a challenge-response algorithm - either misimplemented, or cargo-culted by somebody who had no comprehension of how such algorithms work.

    To expand, here's the standard correct algorithm:

    A password is salted and hashed, then stored in that form in the server-side database.

    When the client wishes to authenticate, it requests a challenge from the server. The server extracts the salt from the database, and generates a new random nonce, and sends both to the client. The client takes the password from the user, and hashes it using the salt from the server - at this point, both the client and server should know the value that is stored in the server's database, and the client now just need to prove it (without ever transmitting that value over the network). The client appends the nonce to the first hash, hashes the result again, and sends this second hash to the server. The server performs the same operation, and checks to see if the two hashes match - if they do, then the client has proven that it started with the right password.

    This algorithm is completely secure against eavesdroppers, although still vulnerable to MITM attacks. It can be combined with Diffie-Helman to eliminate those (you simply include the session key in the nonce, so that responses are not portable between sessions). It is also immune to the rainbow table attack.

    In an ideal implementation, the server never sees the true password supplied by the user, so the system is secure on both ends - although that's not common, since server operators are rarely concerned with the security of user passwords.

    Unfortunately this algorithm is too complicated for stupid people to understand, and so they often cargo-cult it, with bizarre and hopelessly ineffective results.


  • And a note of caution for implementing the process outlined by asuffield:

     Don't use the username/actual name of the person as their password salt. This still leaves your database open to slightly more sophisticated rainbow table attacks that have common names/usernames concatenated with common passwords. Using a GUID or two as a salt should add a sufficient amount of entropy to stop any precomputed table attacks.



  • @bobday said:

    And a note of caution for implementing the process outlined by asuffield:

     Don't use the username/actual name of the person as their password salt. This still leaves your database open to slightly more sophisticated rainbow table attacks that have common names/usernames concatenated with common passwords. Using a GUID or two as a salt should add a sufficient amount of entropy to stop any precomputed table attacks.

    GUIDs are just a Microsoft function for generating UUIDs, and are often predictable, so they're no use here. The words 'salt' and 'nonce' are cryptographic concepts; they carry with them the implication of true cryptographic randomness. Failure to make them sufficiently random is just one of the many ways to screw up the algorithm. 

    Don't ever try to implement it from my description. Look it up in a proper source. I didn't even try to cover all the details, it's just a sketch of the concept.



  • Well, the bad news is that the passwords are indeed stored as plaintext (quick point - I did NOT design this!!!).

    By the "hashing before it transmits" what I mean is it turns the text into a byte array (with a function that has "hash" in the name hence me calling it that, then does a bit of encoding - not a proper hash - so it can be reconstructed at the other end but is marginally more secure whilst transmitting). Sadly the guy wasn't a crypto genius.

    I actually found the root of the problem - for some reason the compact framework encodes UTF8 differently to the full framwork. There's another WTF for you. I'm guessing CF1 did it Ok but since it got ported to CF2 it's never been given to anyone to actually use. 


Log in to reply