Transcript
Page 1: Password Storage and Attacking in PHP

Password Storage(And Attacking)

In PHP

Anthony Ferrara

Page 2: Password Storage and Attacking in PHP

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

Page 3: Password Storage and Attacking in PHP

Let's StartFrom The Beginning

Page 4: Password Storage and Attacking in PHP

Plain-Text Storagegit checkout plaintext

Stores passwords in Plain-Text

What's wrong with this picture?

Page 5: Password Storage and Attacking in PHP

Plain-Text Storage

What happens if we have a SQL-Injection Vulnerability?

localhost/sqli

Simulates:

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

Page 6: Password Storage and Attacking in PHP

Plain-Text Storage

Problem!

Any attack vector results in leakage of ALL credentials!

Page 7: Password Storage and Attacking in PHP

We Can Do Better

Page 8: Password Storage and Attacking in PHP

MD5git checkout md5

Uses the MD5 Cryptographic Hash function.

md5($password)

hash('md5', $password)

Page 9: Password Storage and Attacking in PHP

Wait,What Is A Hash?

Page 10: Password Storage and Attacking in PHP
Page 11: Password Storage and Attacking in PHP

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)

Page 12: Password Storage and Attacking in PHP

MD5

What's the problem now?

SQL-Injection still gives us hash

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

Page 13: Password Storage and Attacking in PHP

Enter:Lookup Tables

Page 14: Password Storage and Attacking in PHP
Page 15: Password Storage and Attacking in PHP

Lookup Table

Google is a great example

Maps hash to password directly

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

Page 16: Password Storage and Attacking in PHP

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

Page 17: Password Storage and Attacking in PHP

We Can Do Better

Page 18: Password Storage and Attacking in PHP

Rainbow Table

Seed

Hash

Reduce

Hash

Page 19: Password Storage and Attacking in PHP

Rainbow Table

Seed

Hash

Reduce

Hash

a4fef...

Reduce

NewPassword

Page 20: Password Storage and Attacking in PHP

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

Page 21: Password Storage and Attacking in PHP

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

Page 22: Password Storage and Attacking in PHP

Defense!

Page 23: Password Storage and Attacking in PHP
Page 24: Password Storage and Attacking in PHP

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)

Page 25: Password Storage and Attacking in PHP

Salts

Must be unique! - Per Hash - Globally

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

Page 26: Password Storage and Attacking in PHP

Salted MD5

What's the problem now?

SQL-Injection still gives us hash - And the salt

But the salt defeats rainbow tables...

Page 27: Password Storage and Attacking in PHP

Can Anyone See The Problem?

Page 28: Password Storage and Attacking in PHP

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)

Page 29: Password Storage and Attacking in PHP

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)

Page 30: Password Storage and Attacking in PHP

Hash FunctionsAre Made To Be

FAST

Page 31: Password Storage and Attacking in PHP

Brute Forcing

Several Tools Available - John The Ripper - OCIHashCat

A Lot Faster Than You May Think

Page 32: Password Storage and Attacking in PHP

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

Page 33: Password Storage and Attacking in PHP

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

Page 34: Password Storage and Attacking in PHP

We Can Do Better

Page 35: Password Storage and Attacking in PHP
Page 36: Password Storage and Attacking in PHP

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:

Page 37: Password Storage and Attacking in PHP

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

Page 38: Password Storage and Attacking in PHP

But Wait,I Thought MD5 Was Broken?

Page 39: Password Storage and Attacking in PHP

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.

Page 40: Password Storage and Attacking in PHP

So, How Can We Combat Such

Hardware?

Page 41: Password Storage and Attacking in PHP

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);

Page 42: Password Storage and Attacking in PHP

We're Intentionally

Slowing It Down

Page 43: Password Storage and Attacking in PHP

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

Page 44: Password Storage and Attacking in PHP

We Can Do Better

Page 45: Password Storage and Attacking in PHP

PBKDF2git checkout pbkdf2

Uses the standard PBKDF2 algo - With SHA512 primitive

Slower, and harder to use on GPU

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

Page 46: Password Storage and Attacking in PHP

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

Page 47: Password Storage and Attacking in PHP

We Can StillDo Better

Page 48: Password Storage and Attacking in PHP

BCryptgit checkout bcrypt

Uses the standard BCrypt algo - based on Blowfish cipher

Same execution time,Much harder to run on GPU

crypt $2a$

Page 49: Password Storage and Attacking in PHP

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

Page 50: Password Storage and Attacking in PHP

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.

Page 51: Password Storage and Attacking in PHP

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

Page 52: Password Storage and Attacking in PHP

We Can DoEven Better!

Page 53: Password Storage and Attacking in PHP

Let's Encrypt Instead!

Page 54: Password Storage and Attacking in PHP

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

Page 55: Password Storage and Attacking in PHP

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.

Page 56: Password Storage and Attacking in PHP

The Future

Page 57: Password Storage and Attacking in PHP

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)

Page 58: Password Storage and Attacking in PHP

The Future

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

Page 59: Password Storage and Attacking in PHP

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

Page 60: Password Storage and Attacking in PHP

Anthony Ferrarajoind.in/7792@ircmaxell

[email protected]/ircmaxell


Top Related