password storage and attacking in php

Post on 01-Sep-2014

7.807 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

These slides are from a talk that I did at PHP Benelux 2013 ( http://conference.phpbenelux.eu/2013/ ). In this talk, I go over the progression of password storage techniques, and weaknesses of each method. Eventually, we build up to the final secure implementations, and the current methods used to attack them.

TRANSCRIPT

Password Storage(And Attacking)

In PHP

Anthony Ferrara

Github URL

Follow Along:

github.com/ircmaxell/password-bad-web-app

A "Bad Web App" - Has Known Vulnerabilities - Only Use For Education!!! - Requires only Apache + PHP - Has Composer Dependencies

Let's StartFrom The Beginning

Plain-Text Storagegit checkout plaintext

Stores passwords in Plain-Text

What's wrong with this picture?

Plain-Text Storage

What happens if we have a SQL-Injection Vulnerability?

localhost/sqli

Simulates:

?offset=0'+UNION+SELECT+*+FROM+users

Plain-Text Storage

Problem!

Any attack vector results in leakage of ALL credentials!

We Can Do Better

MD5git checkout md5

Uses the MD5 Cryptographic Hash function.

md5($password)

hash('md5', $password)

Wait,What Is A Hash?

What's A Cryptographic Hash?

Like a fingerprint.

One-way. - Easy and efficient to compute - Very inefficient to reverse - (Practically impossible) - Very hard to create collision - (new input with same output)

MD5

What's the problem now?

SQL-Injection still gives us hash

But the hash is one-way, how can we attack it?

Enter:Lookup Tables

Lookup Table

Google is a great example

Maps hash to password directly

Database Table:hash | password--------------+-----------"5f4dcc3b..." | "password""acbd18db..." | "foo"

Lookup Table

Lookups are CPU efficient.

Require a LOT of storage space - (Very space inefficient)

All passwords <= 7 chars (95^7, 70 Trillion)Requires 1.5 PetaBytes - In Most Optimal Storage Format

We Can Do Better

Rainbow Table

Seed

Hash

Reduce

Hash

Rainbow Table

Seed

Hash

Reduce

Hash

a4fef...

Reduce

NewPassword

Rainbow Table

Seed 1 Hash Reduce Hash Reduce Hash Reduce Hash

Seed 2 Hash Reduce Hash Reduce Hash Reduce Hash

Seed 3 Hash Reduce Hash Reduce Hash Reduce Hash

Seed 4 Hash Reduce Hash Reduce Hash Reduce Hash

Seed 5 Hash Reduce Hash Reduce Hash Reduce Hash

Seed 6 Hash Reduce Hash Reduce Hash Reduce Hash

Rainbow Table

Time/Space Tradeoff - Slower than a Lookup Table - Uses Much less storage

Most (99.9%) passwords <= 7 charsRequires only 64 GB - Chain length of 71,000

Defense!

Salted MD5git checkout salted-md5

Uses the MD5 Cryptographic Hash function.But adds a random salt UNIQUE per user.

md5($salt . $password)

hash('md5', $salt . $password)

Salts

Must be unique! - Per Hash - Globally

Should be random - Strong!!! - Reasonably long (at least 64 bits)

Salted MD5

What's the problem now?

SQL-Injection still gives us hash - And the salt

But the salt defeats rainbow tables...

Can Anyone See The Problem?

What's A Cryptographic Hash?

Like a fingerprint.

One-way. - Easy and efficient to compute - Very inefficient to reverse - (Practically impossible) - Very hard to create collision - (new input with same output)

What's A Cryptographic Hash?

Like a fingerprint.

One-way.

- Easy and efficient to compute - Very inefficient to reverse - (Practically impossible) - Very hard to create collision - (new input with same output)

Hash FunctionsAre Made To Be

FAST

Brute Forcing

Several Tools Available - John The Ripper - OCIHashCat

A Lot Faster Than You May Think

Brute Forcing

Multiple Ways To Attack - Mask Based (permutations) - Dictionary Based - Combinator Based - Combinations of dictionary words - Fingerprint Based - Combinators applied with permutations - Rule Based - Takes input password and transforms it

Brute ForcingSalted MD5

2012 Macbook Pro: - md5: 33 million per second - sha256: 20 million per second

Mask Attack:6 char passwords: 5 hours7 char passwords: 22 daysEntire English Language: 1.8 seconds"LEET" Permutations: 1 hour

We Can Do Better

Brute ForcingSalted MD5

25 GPU Cluster - md5: 180 Billion per second - < $50,000

6 char passwords: 4 seconds7 char passwords: 6 minutes8 char passwords: 10 hoursEntire English Language:"LEET" Permutations:

Brute ForcingSalted MD5

25 GPU Cluster - md5: 180 Billion per second - < $50,000

6 char passwords: 4 seconds7 char passwords: 6 minutes8 char passwords: 10 hoursEntire English Language: yeah..."LEET" Permutations: 0.7 seconds

But Wait,I Thought MD5 Was Broken?

MD5 IS Broken!

But No Other Primitive Hash Is Not!!!

sha1≈ md5 sha256 ≈ md5sha512 ≈ md5whirlpool ≈ md5

ALL raw primitive hashes are broken for password storage.

So, How Can We Combat Such

Hardware?

Iterated MD5git checkout iterated-md5

Uses the MD5 Cryptographic Hash function.But adds a random salt UNIQUE per user.And iterates a lot of times

do { $h = md5($h . $salt . $password)} while($i++ < 1000);

We're Intentionally

Slowing It Down

Brute ForcingIterated MD5

25 GPU Cluster - md5: 70 million per second

6 char passwords: 17 minutes7 char passwords: 1 day8 char passwords: 124 days

Entire English Language: 0.8 seconds

We Can Do Better

PBKDF2git checkout pbkdf2

Uses the standard PBKDF2 algo - With SHA512 primitive

Slower, and harder to use on GPU

pbkdf2($pass, $salt, 10000, 40)

Brute ForcingPBKDF2

25 GPU Cluster - PBKDF2(sha512): 300,000 per second

6 char passwords: 28 days7 char passwords: 7 years8 char passwords: 700 years

Entire English Language: 3 minutes

We Can StillDo Better

BCryptgit checkout bcrypt

Uses the standard BCrypt algo - based on Blowfish cipher

Same execution time,Much harder to run on GPU

crypt $2a$

Brute ForcingBCrypt

25 GPU Cluster - BCrypt: 70,000 per second

6 char passwords: 120 days7 char passwords: 31 years8 char passwords: 3000 years

Entire English Language: 14 minutes

A Note On Cost

BCrypt accepts a "cost" parameter

Must be tuned per server! - Target about 0.25 to 0.5 second runtime - Cost of 10 is a good baseline - Cost of 11 or 12 is better - If you have decent hardware.

PHP 5.5 Password Hashing APIgit checkout password-compat

A thin wrapper over crypt() - Simplifies implmentation - Strong random salt generation - Can specify cost as int option

password_hash($pass, $algo, $opts)password_verify($pass, $hash)

github.com/ircmaxell/password_compat

We Can DoEven Better!

Let's Encrypt Instead!

Encrypted BCryptgit checkout bcrypt-with-encryption

Hash with BCrypt,Then encrypt result with AES-128.

Requires key storage for the app. - Not trivial

Use only if needed! - BCrypt alone is typically sufficient

Brute ForcingEncrypted BCrypt

Attack requires low level server compromise! - SQL Injection is not enough!

localhost/codeinject - Simulates code injection that reads source

Any low level compromiseIs No Worse than raw BCrypt - BCrypt is the baseline.

The Future

The Future

scrypt - Sequential Memory Hard - Uses a LOT of memory (32mb / hash) - Harder to brute-force than bcrypt

But it's VERY new - In cryptography terms at least - Not proven enough for use (yet)

The Future

Password Hashing Competition - Currently being setup - Aims to pick "standard" password hashing algorithm - A community effort

The Future

Brute Forcing Word Lists - Complex combinations of words - "horse correct battery staple"

Brute Forcing Grammar - "I don't want no cookies"

Brute Forcing Structures - URLs, Email Addresses, URLs, etc

Anthony Ferrarajoind.in/7792@ircmaxell

ircmaxell@php.netblog.ircmaxell.comyoutube.com/ircmaxell

top related