Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Ball and Chain A New Paradigm in Stored Password Security Benjamin Donnelly and Tim Tomes

959e62ab25ff6d97da293785eff676be?s=47 zaeyx
September 26, 2014

Ball and Chain A New Paradigm in Stored Password Security Benjamin Donnelly and Tim Tomes

From Derbycon 4.0 Family Rootz

959e62ab25ff6d97da293785eff676be?s=128

zaeyx

September 26, 2014
Tweet

Other Decks in Technology

Transcript

  1. Ball and Chain A New Paradigm In Stored Password Security

  2. Credits • SDSM&T Math and CS Dept. • Spokane Falls

    Comm. College IS & CS Dept. • John Strand (@strandjs) • Ethan Robish (@EthanRobish) • Mick Douglas (@bettersafetynet) • Joff Thyer (@joff_thyer) • Beau Bullock (@dafthack) • Mark Baggett (@MarkBaggett) • Ian Pickett (graphics) • Others
  3. Benjamin Donnelly - @zaeyx • Security Researcher/Pentester – Black Hills

    Info Sec • I like shapes • 20 Years young – So no beer – I accept protein shakes • Hacker | Dreamer | Idealist • Where? – https://bitbucket.org/Zaeyx/ – http://twitter.com/zaeyx – In your deepest, darkest dreams
  4. Tim Tomes - @lanmaster53 • Christian† | Father | Husband

    | Veteran • Managing Consultant – nVisium, Inc. • SANS / SamuraiWTF Instructor • Security Blogger – www.lanmaster53.com • Open Source Developer • Hacker looking out for users by educating developers.
  5. Overview • The Problem – Why password hashing is broken

    – Why we can’t trust humans to secure things • The Philosophy – Secure by default • The Solution – The logical overview – Technical Implementation • The Future
  6. The Problem • All current implementations are broken • BSides

    Augusta – Stored Password Security… • Plaintext / Encoding – 1 step from disclosure • Encryption – Key must be accessible – Only prevents a one-step attack • Hashing (fast) – Cracking is too easy – Users create minimal complexity passwords • Adaptive Hashing (slow) – Harder, but still possible • Computational power war
  7. The Problem • Current approach to stored password security is

    a seesaw – Between algorithm strength & password strength • Fast hashing requires stronger passwords because the algorithm is weak • Slower hashing allows for weaker passwords – Bad assumption: “This is harder, therefore I win” – Strength comes from computational difficulty algorithm password
  8. The Problem • The attacker’s focus is different • Mom

    and Pop (victim) – Supporting a service that has to compute constantly (logins) – Harder computations result in a greater cost (uptime, resources, etc.) • Russian Mob (attacker) – One objective: crack the hashes – Only has to attack each hash once – Can distribute the cracking – Can build a powerful machines uniquely designed to crack M&P’s algorithm • The attacker will always have the computational advantage
  9. The Problem • We have to make better, more secure,

    assumptions • We have to assume the worst case scenario • We have to assume, the attacker is a dedicated, nation state, ready to handle our hashes • We have to assume that we have limited resources resulting in a system where the hashes and the passwords aren’t that strong (our seesaw is broken) • Then we build up from that terrifying picture.
  10. The Problem • The business doesn’t want to spend more

    money just so you can compute slow algorithm logons for all your users • Users don’t want to use a 25 character alphanumeric + special, passphrase • You don’t want to enter into a computational power war with a nation state or criminal group running botnets
  11. The Problem • To win the war, we need two

    things – We need to identify and exploit a defensive advantage – We need to make passwords easy for users • Well really, three things – People smart enough to figure out need #1 while considering need #2
  12. The Philosophy • Why did I do this? • The

    internet is broken – We are fighting a war – One that we are losing – One that we cannot afford to lose • Without empathy we are just solving puzzles – We need to find and solve issues that matter
  13. The Philosophy (secure by default) • Secure by default –

    We must build our systems to be secure by default – We need to make the users lives easier not harder – We need to stop relying on users for our security • I want to make passwords fun again
  14. The Philosophy (cont) • You want to stop bugs from

    flying through your open window? • Don’t sit there trying to catch them • Just put a screen in!
  15. THE SOLUTION Ball And Chain

  16. The Solution • The defensive advantage does exist! • We

    own the data at rest • We also control the surrounding infrastructure • The attacker needs to download the data – Through our infrastructure
  17. The Solution (cont) • Downloading little bits of data… –

    Is no problem for an attacker – In fact, it’s very hard to stop this • What about downloading a ton of data… – What if the attacker needed terabytes of data? – What if our outbound pipe was only so large? – What if it was monitored for huge downloads? • (note: monitoring isn’t necessary, just helpful)
  18. The Solution (Logical Overview) • We create a huge “file”

    on the network • We tie authentication to this file • To check if a password is valid or invalid – You need the stored password representation – And you need this huge file • If the attacker gets the stored password – He still needs the huge file to make a single guess
  19. The Solution (Logical Conclusion) • Have you ever tried downloading

    a multi- terabyte array? • The attacker will never download it – Not even a significant portion of it • So he cannot perform an offline attack
  20. A Simple Graphical Example Your Network Attacker’s Network Data-Pipeline Big

    Ole’ Fat File Hashes Evil Machines, Waiting to crack your stored passwords f3a173de83c5 Big Ole’ Fat File
  21. Example My home upload speed is 6.14 Mbps If the

    attacker used my entire outbound pipe… (2 terabyte array)
  22. Keep in mind • This is using the entire pipe

    • This is easy to detect and stop • He hasn’t even started cracking yet • This is basically infeasible
  23. The Beauty of It • Secure with minimal human intervention

    – Passwords become easy – It basically protects itself • Offline password attacks will go extinct • It’s cheap to implement • It scales with your business
  24. How It Scales • A Small Startup – 6 Mbps

    Upload – 2 Terabytes (Approx: $100) • Medium Business – 15 Mbps Upload – 5 Terabytes (Approx: $250)
  25. Why It’s Called “Ball and Chain” • It’s like a

    weight tying down the attacker • Because – He has to extract it from the network – Distributing it is a huge pain – Loading it to a cloud cracking service is out – Hosting it for others nets bandwidth issues – It’s loud and clunky and easy to track
  26. TECHNICAL IMPLEMENTATION A template for how to actually do this

  27. Shopping List • A CSPRNG – Optional: Source for True

    Random • Block Cipher (Ex. AES-128_CTR) • Hashing Algorithm (Ex. Sha3) • Data Storage Mechanism (Ex. Multi-TB NAS)
  28. Our Trick • If AES-128_CTR decrypts with an invalid key

    – We get a random output – It’s total gibberish • Our trick will be – Create a plaintext that looks exactly like this • Total random gibberish
  29. How to do this • Build a gigantic file (array)

    of random data • Pull some data from that array • Store that data as our message • Anything that goes into the block cipher – Will be 100% random – Will be delimited by length – Will be deterministically confirmable as ours
  30. Authentication Example • Let me first show you how to

    – Create the array – Store a password – Perform authentication • Once I’ve explained all this – We’ll go over a few specifics and shortfalls – I will be addressing all this in the whitepaper
  31. Creating the array

  32. On Array Creation • Pick a decent size – We’ll

    talk a little about this at the end • Use either true random • Or a CSPRNG with a strong seed – And THROW OUT THE SEED • The attacker must not be able to expand the array from a simple seed
  33. Storing a password

  34. 1) Select Locations In The Array • We need a

    few pointer|data pairs 01101100 01101010 01101000 01100001 01110111 01101011 01100110 01101000 01110001 01101100 01110101 01101000 01110110 01101111 01101001 01100101 01101010 01110110 01101111 01101001 01101010 01110011 01100100 01101011 01101110 01101010 01110001 01101101 00101100 01100101 01101110 01100010 01100001 01101111 01110000 01110011 01110110 01101111 01110000 01110101 01101001 01100101 01110010 01101000 01101011 01110001 01100010 01110111 01100101 01110010 01101101 01101110 01100001 01101011 01110000 Our Random Array
  35. 1) Select Locations In The Array • We need a

    few pointer|data pairs 01101100 01101010 01101000 01100001 01110111 01101011 01100110 01101000 01110001 01101100 01110101 01101000 01110110 01101111 01101001 01100101 01101010 01110110 01101111 01101001 01101010 01110011 01100100 01101011 01101110 01101010 01110001 01101101 00101100 01100101 01101110 01100010 01100001 01101111 01110000 01110011 01110110 01101111 01110000 01110101 01101001 01100101 01110010 01101000 01101011 01110001 01100010 01110111 01100101 01110010 01101101 01101110 01100001 01101011 01110000 Our Random Array Pointer; Row 5 Col 4 Data; 01101011
  36. 2) Concatenate Pointers, Data • Once you have enough pointer|data

    pairs • We need to split by type and concatenate – Pointers together – Data together Ptr_0, Data_0 Ptr_1, Data_1 Ptr_2, Data_2 Ptr_3, Data_3 Ptr_0Ptr_1Ptr_2Ptr_3 Data_0Data_1Data_2Data_3
  37. 3) Hash Concatenated Data • Next we will hash all

    the data – Use a secure hashing function like Sha3 (Keccak) • It can be a fast hashing function though • (Note: for some of this, collisions work in our favor) • Concatenate the pointers and the hash • So now we have: Ptr_0Ptr_1Ptr_2Ptr_3Sha3(Data_0Data_1Data_2Data_3)
  38. 4) Convert to binary format • If your pointers and

    data aren’t already binary • We have to do this because – Invalid decryptions don’t come out just as ASCII – They range the entire character-space • As binary data BinaryOf(Ptr_0Ptr_1Ptr_2Ptr_3Sha3(Data_0Data_1Data_2Data_3)) Warning: This must be done properly, simply translating ASCII to binary isn’t good enough
  39. 5) Encrypt with the user’s password • Encrypt the all

    the binary data with AES – Use the user’s password as the key User’s Password: Sha3(MONSTROSITY) BinaryOf(Ptr_0Ptr_1Ptr_2Ptr_3Sha3(Data_0Data_1Data_2Data_3)) AES-128_CTR Random Nonce
  40. 5) Encrypt with the user’s password • Encrypt the all

    the binary data with AES – Use the user’s password as the key User’s Password: Sha3(MONSTROSITY) BinaryOf(Ptr_0Ptr_1Ptr_2Ptr_3Sha3(Data_0Data_1Data_2Data_3)) AES-128_CTR Random Nonce Password Representation: 8fda158e42aef96062fe1ac0ecd8a83f
  41. 6) How to Store • Shadow format is more than

    fine – Username – Nonce = salt – Ciphertext = hash Turtle:1234567:8fda158e42aef96062fe1ac0ecd8a83f
  42. Authentication

  43. 1) User enters a password • Attempt to decrypt the

    stored data with it User’s Password: Sha3(MONSTROSITY) AES-128_CTR Random Nonce Password Representation: 8fda158e42aef96062fe1ac0ecd8a83f
  44. 1) User enters a password • Attempt to decrypt the

    stored data with it User’s Password: Sha3(MONSTROSITY) Random looking output: 01110011011101000111001001110101011001110110011101101100011001010000110100001010 AES-128_CTR Random Nonce Password Representation: 8fda158e42aef96062fe1ac0ecd8a83f
  45. 2) Split the data • You should have global variables

    for – Length of each pointer – Length of each data section – Length of hashed data – Number of pointers • Use these to split your output into variables Ptr_0, Ptr_1, Ptr_2, Ptr_3, Sha3(Data)
  46. 3) Rebuild the Pointer|Data Pairs • Take each pointer and

    go get its paired data – Obviously you need the array for this – This is the step at which the attacker fails without • Once you have all the data – Throw out the pointers – Concatenate the data Data_0Data_1Data_2Data_3
  47. 4) Hash and compare • Hash the data Data_0Data_1Data_2Data_3 Sha3/Keccak

  48. 4) Hash and compare • Hash the data Data_0Data_1Data_2Data_3 Sha3/Keccak

    Sha3(Data_0Data_1Data_2Data_3)
  49. 4) Hash and compare • Hash the data Data_0Data_1Data_2Data_3 Sha3/Keccak

    Sha3(Data_0Data_1Data_2Data_3) Does Sha3_Output_0 == Sha3_Output_1? If True: authenticate; else: don’t
  50. Authentication Overview • If a valid key gives 100% random

    output – Just like an invalid key • Then the attacker needs the array to confirm • And without the array, he’s SOL
  51. SOME SPECIFICS Trip ups and tricks

  52. Selecting Data Length • Select a data length (128 bits)

    – The data length is the amount of the data to be pulled from the array at the randomly chosen location – You want to choose enough entropy so that the chances of a successful decryption without the proper key is statistically impossible – If your data length is 128 bits, the chance of a collision is 1/(2^128) for every key • Though, that actually stacks really fast when we’re using multiple pointers
  53. When Building Your Array • Decide on a size for

    your array – You want it to be large enough so as to be infeasible to extract any significant portion of it – Pointer considerations must be made • Depending on the format you choose for your pointer • This is because if the amount of viable pointers to the array max out before the pointer-space does the attacker can determine some of what the password IS not. – Allow me to explain
  54. Array Indexes • Take for example, an array with four

    viable indexes 0,1,2,3 • If in your pointer|data pair, you use a single decimal character to represent the pointer.. – You get decryptions that give an pointer outside of the array 4,5,6,7,8,9 • It is infeasible to steal the array • But easy to figure out what the highest index is
  55. So What? • So the attacker can now figure out

    some of what the password isn’t • He does this by making guesses • If the decrypted pointer is outside of the array, he knows that is not the password – Because it’s is impossible to confirmable
  56. Possible Solutions 1. Ignore it – Especially if the difference

    is minimal – It won’t reveal the password 2. Match your pointer-space and array size – Limits your possibilities 3. Use non-sequential indexes – You could create a mapping too large to steal – This could quickly get out of control 4. Make indexes wrap around – Just do pointer = temp_pointer % sizeOf(array)
  57. Why use multiple Pointer|Data Pairs? • It reduces the chances

    an attacker can get away with just stealing part of the array • It’s incredibly important to hash the data though • If you don’t, you make his job easier – Only needs to see one pointer|data pair – Since the chances of a collision are astronomical
  58. For Example • If he can confirm one – Chances

    are, he has the right password 01101100 01101010 01101000 01100001 01110111 01101011 01100110 01101000 01110001 01101100 01110101 01101000 01110110 01101111 01101001 01100101 01101010 01110110 01101111 01101001 01101010 01110011 01100100 01101011 01101110 01101010 01110001 01101101 00101100 01100101 01101110 01100010 01100001 01101111 01110000 01110011 01110110 01101111 01110000 01110101 01101001 01100101 01110010 01101000 01101011 01110001 01100010 01110111 01100101 01110010 01101101 01101110 01100001 01101011 01110000 Our Random Array Pointer; Row 5 Col 4 Data; 01101011 Other Pointer|Data Pairs
  59. The New Reality • Password: 1234 • Online Attacks –

    Anti-automation mitigation – Monitoring and defense – Who has 4 char passwords in their dictionary? • Offline attacks – openBAC • 1234 == *Secure* password
  60. The Future • BAC is complex to understand and implement

    • Our objective isn’t necessarily about convincing everyone to implement BAC • It’s about pushing the industry forward • Market research shows that given several options, people choose the “in between” option because of the perceived “best of both worlds” • Goldilocks Principle
  61. The Future • Current implementation trend – Adaptive Hashing (too

    complex / costly) – Plaintext / Encoding (too insecure) – Fast Hashing (juuuuust right)
  62. The Future • Projected trend after the release of BAC

    – BAC (too complex / costly) – Fast Hashing (too insecure) – Adaptive Hashing (juuuuust right) • This is still a win, but we need to change the trajectory • BAC is a real solution, and a step in the right direction
  63. In Closing It’s not a matter of if. It’s a

    matter of when. Always implement password storage systems that assume eventual compromise.
  64. The Goods • https://bitbucket.org/Zaeyx/openBAC – POC/Example code • https://www.reddit.com/r/openbac –

    Discussion/Development • https://twitter.com/zaeyx – For my latest ramblings on the subject – Watch here for the release of the full whitepaper @zaeyx | @lanmaster53