Friday, June 21, 2013

What I learned from the Defcon CTF

So if anyone follows me on Twitter, they might've caught that I tried the Defcon CTF challenge a week or so ago. I didn't place on the finalist list; most of that stuff is waaaaaaay out of my league.

But the one category I thought was pretty interesting - and I ought to do well in - was the Web one. So I tried to get at least one point in that category, so I could prove to myself that I could do this type of stuff. I'm not a security guy; I'm a web developer.

The result? I got all five questions :) The last one I got with just an hour to spare.

And it really got me to thinking - as a developer, 'engineer' or architect or whatever I am - about some of the security things that I haven't really thought that deeply about before.

Here's what I came up with:

#1) Don't ever use dictionary passwords. Not even with your cl3v3r subst1tut10ns of punctuation or numbers for letters.


Why? Because I tried to brute force a password that was very strongly hashed (SHA-512). I was grinding through 3 and 4 character passwords with a custom-built script I put together. It had been running overnight and I got nothing from it.

But when the lovely and talented Snipeyhead pointed me over towards a password cracker tool, I decided to give that a shot.

The tool spat out the password I needed in probably about 60 seconds.

And the tool had a ruleset - built in to it - that allowed it to automatically test out numeric and punctuation substitutions. So your clever password that's based on a dictionary word might get cracked - and maybe not with today's ruleset, but definitely with tomorrow's.

The password length is actually *less* of a big deal. Of course, if you try and brute-force a password (as I did), a longer one will take longer to force than a shorter one. But if your super duper long password is just a dictionary word - then, no, you're still fucked.

If I were building something from scratch? I would definitely use a very strong hashing method (SHA-512? Bcrypt?) for password storage, but I would play around with different types of password requirements. If the user wants a super duper short password? Maybe it has to have lots of different types of characters. One that has just letters in it? Better be pretty damned long. Who knows? Maybe I'd just stick with what we're doing now.

But regardless of that - if your password can be cracked with a dictionary, then you can't use it. End of story.

(edit) And try not to expose usernames, maybe?


If you don't know what username to dictionary-attack (or brute-force attack) - you don't know what you're going after. You can guess - but if you're at least not exposing "valid username, but invalid password!" (and, holy crap, I hope you aren't!) then you make their job just a liiiiittle bit harder. And that's worth doing, if you can.

#2) Hashing (to prevent message alteration or tampering) and crypto (confidentiality) are completely orthogonal concepts.


If you want to hide the contents of the message, encrypt it. But someone clever can still mess with the contents a little bit. In fact, that's just what I did in challenge number 5 :)

If you want to ensure that a message is not altered in any way, present a hash of it (salted with a secret salty thing). This way if you change one tiny bit anywhere on the message, the resulting salt should change substantially.

So if you need both? DO BOTH. The two functions have nothing to do with each other.

#3) Error Messages in production


This one is probably the most embarrassing for me. I have, on plenty of occasions, allowed apps to go into production with full error messaging intact.

This is usually because I write shitty software that breaks. So when it does, I like to be able to quickly see what happened. So my heart's in the right place, even if my code isn't.

But this is a ridiculously fucking terrible fucking idea.

More than half of the challenges I was going after started to give me hints on how to break in once I was able to fingerprint what type of app they were (this year? Lots of Sinatra. Feel bad for those guys, like they got 'picked on' - but I guess, considering some of their bláse attitudes about security (calling hashed stuff 'encrypted'?), maybe it's warranted). Maybe it's a wakeup call. Or maybe it's just because Sinatra is fun to write? Who knows.

But, seriously - trying to figure what type of thing I was going after really took a lot of time away from trying to figure out how to break in. So the harder you can make those first couple of steps for an attacker (like me) - maybe the easier it might be to get him to go look at somebody else instead.

1 comment:

  1. I'm so glad you participated and wrote up your results. It's great to see that you got something really useful out of it as a developer, and I think it's important to share that. Yes, security weenies are a pain in the ass to deal with, but I think if more devs went through the exercise you went through, they would start to understand why we make them jump through these hoops. A lot of security stuff is pointless security theater, but some of it actually matters.

    Go team Buttfaces!

    ReplyDelete