Upload
ivan-novikov
View
2.605
Download
5
Embed Size (px)
DESCRIPTION
Cryptography problems in modern web applications. Defcon-Russia #11 meeting slides from @d0znpp, ONsec company.
Citation preview
Cryptography in web applica2ons: vulnerabili2es and
a8acks 21/08/2012 DCG #7812
Saint-‐Petersburg by @d0znpp
[d0znpp@localhost ~]# whoami
ONsec company: founder and expert Fun: security researcher, interna2onal speaker, bug hunter, Neuron-‐hackspace member (neuronspace.ru) Science: sta2s2cal algorithms and machine learning areas
Defcon Russia (DCG #7812)
Introduc2on
Where you can see crypto in webapps? • passwords storage mechanism • one-‐2me passwords • unique codes • remember tokens • CSRF tokens • CAPTCHA • etc
Defcon Russia (DCG #7812)
Introduc2on
• Everything unique based on randoms • In general randoms are pseudo random • Every random values ini2ated by seed value • Seed is your target. If you know seed, you know all "random" values.
• Each process has their seed • Keep-‐alive connec2on share seed in many scripts
Why you can know a seed value? Defcon Russia (DCG #7812)
Task #1
How do you hack it?
mt_srand(micro2me()*10000); mt_srand(getmypid());
$secret = md5(mt_rand().mt_rand().mt_rand());
Defcon Russia (DCG #7812)
Problem #1. Weak seed
• Ini2ate rand from short-‐length seed mt_srand(micro2me()*10000); mt_srand(getmypid());
• Brute-‐force a8ack restores seed
Defcon Russia (DCG #7812)
Task #2
How do you hack it?
mt_srand((double)micro2me()*1000000); mt_srand(uniqid("",true));
$secret = md5(mt_rand().mt_rand().mt_rand());
Defcon Russia (DCG #7812)
Problem #2. Predicated seed
• Ini2ate rand from predicated seed mt_srand((double)micro2me()*1000000); • Official PHP doc example (h8p://www.php.net/manual/en/func2on.mt-‐srand.php):
func2on make_seed() { list($usec, $sec) = explode(' ', micro2me()); return (float) $sec + ((float) $usec * 100000);}
Defcon Russia (DCG #7812)
Task #3
How do you hack it?
func2on resetUserPassword($userid){ $newpass = sha1(mt_rand(). mt_rand().
mt_rand());} func2on generateCaptcha(){
mt_srand((double)micro2me()*10000); return $captcha[mt_rand(0,30)].
$captcha[mt_rand(0,30)]…} Defcon Russia (DCG #7812)
Problem #3. Keep-‐Alive glue
Stefan Esser, 2008 h8p://www.suspekt.org/2008/08/17/mt_srand-‐and-‐not-‐so-‐random-‐numbers/ Keep-‐Alive is your friend When some informa2on is known about the internal state of the random number generator Keep-‐Alive HTTP request can make exploits very easy. Because follow request during a Keep-‐Alive HTTP connec2on are handled by the same process (same random number generator) the state of the random number generator stays the same and random numbers can be precalculated from the outside. While this is always true for mod_php, it is not true for CGI and only some2mes true for fastcgi setup
Defcon Russia (DCG #7812)
Problem #3. Keep-‐Alive glue
• Ini2ate random with predicated value: GET /newcaptha HTTP/1.1 Connec2on: Keep-‐Alive • Generate predicated next random value GET /recoverpass HTTP/1.1 Connec2on: Keep-‐Alive
Defcon Russia (DCG #7812)
Task #4
How do you hack it?
func2on resetPassword($email){ if(userExists($email)){ mt_srand((double)micro2me()*1000000); $new_pass = md5(mt_rand()); if (sendPassByEmail($email,$new_pass)){ updateUserPass($email,$new_pass); }else return false; }else return false;}
Defcon Russia (DCG #7812)
Problem #4. Race condi2on
Defcon Russia (DCG #7812)
mt_srand( (double)
microtime()* 1000000)
Q1: change my password
Q2: change admin
Q3: change my password
Date:Tue, 21 Aug 2012 09:34:37
Date:Tue, 21 Aug 2012 09:34:37
Date:Tue, 21 Aug 2012 09:34:37
• Locally brute microseconds Q1, Q3 • Determine interval where Q2 are exists • Remotely brute Q1 value
Problem #4. Race condi2on
• Request to reset self password • Request to reset admin password • Request to reset self password again • Parse "Date" header in HTTP response • Compare "Date" seconds in 3 responses (D1, D2, D3), D1>D2>D3 or D1>D2 (D3 in next second)
• If D1,D2,D3 seconds are different, try again
Defcon Russia (DCG #7812)
Problem #4. Race condi2on
• Locally brute rand values R1, R3 from D1 and D3 responses (10^6 value for D1 and 10^6-‐R3 for D3)
• Now you know a short interval (R1;R3) where R2 are exists
• Remotely brute R2 via ~10^3 HTTP responses (not 10^6 anymore)
• Sucks where balancer/frontend are present Defcon Russia (DCG #7812)
Problem #4. Race condi2on
• What we can do with balancers/frontends? • Find appserver’s 2me in others HTTP responses parts except of “Date” header
• i.e. phpinfo output + mod_unique_id (default) h8p://h8pd.apache.org/docs/2.2/mod/mod_unique_id.html: The UNIQUE_ID environment variable is constructed by encoding the 112-‐bit (32-‐bit IP address, 32 bit pid, 32 bit <me stamp, 16 bit counter) quadruple using the alphabet [A-‐Za-‐z0-‐9@-‐] in a manner similar to MIME base64 encoding, producing 19 characters Defcon Russia (DCG #7812)
Bonus for phpinfo hunters ;)
• Use UNIQUE_ID Apache environment variable ($_SERVER[‘UNIQUE_ID’]) for determine real PID and micro2me at appserver
• Usefully for session predic2on • Read original work h8p://media.blackhat.com/bh-‐us-‐10/whitepapers/Kamkar/BlackHat-‐USA-‐2010-‐Kamkar-‐How-‐I-‐Met-‐Your-‐Girlfriend-‐wp.pdf for details
Defcon Russia (DCG #7812)
Task #5
func2on generateMySafetyToken(){ mt_srand($really_random_value); $salt = generateRandomString(8); $newpass = generateRandomString(32); updateUser($salt.md5($newpass.
$reallyLongAndSecretSalt)); } func2on generateRandomString($l){
$chars = “abcdeghijklmnopqrtuvwxz…”; for($i=0;$i<$l;$i++) @$r.=
$chars[mt_rand(0,strlen($chars)-‐1)]; return $r; } Defcon Russia (DCG #7812)
Problem #5. Shared randoms
• Genera2ng randoms and share it values in HTTP responses (various unique IDs)
• Seed value may be recovered by randoms • By seed value you get all the values of randoms a�er shared
Defcon Russia (DCG #7812)
Rands sequence length (bytes) Seeds count
1 ~ 3,5*10^7 (~= mt_getrandmax()/62)
2 ~ 5,5*10^5
3 ~ 9*10^3
4 ~ 150
5 ~ 4
Problem #5. Shared randoms
• How many random values you need to recover seed?
• mt_getrandmax() = 2^32/2 • For 62 preset (a-‐z A-‐Z 0-‐9):
Defcon Russia (DCG #7812)
Problem #5. Shared randoms
• Recovering seed by brute 2^32 values take 1,2 hour on my laptop CPUs (i7 1.8GHz)
• One PHP process for brute per each /proc/cpuinfo item
• Let me know if you want to get demo scripts ;)
Defcon Russia (DCG #7812)
Problem #5. Shared randoms
• How to recover seed by various mt_rand(N,M) calls?
• Easy and usefully for universal rainbow-‐tables • First rand value for seeds require only (4+4)*2^32 bytes = 32Gb in row storage
mt_srand(1337); $base_rand = mt_rand(); mt_srand(1337); echo mt_rand(0,10)." -‐ ".($base_rand/mt_getrandmax()*10).”\n";
Problem #5. Shared randoms
• Pay your a8en2on for strange rounding:
mt_rand(0,10) mt_rand()/mt_getrandmax()*10
2 2.6646899723749 1 1.3880474685636 3 3.532942404753 7 7.1748687313753 6 5.4621864228799 2 2.6917412330824 0 0.60019337134445
What about hashes?
• MD5 brute speed is about 11*10^9 hashes/sec on AMD Radeon HD6990 (~$800)
Tools: • oclHashcat(pro/lite) • ighashgpu • johntheripper • egbruteforcer (insidepro)
Defcon Russia (DCG #7812)
Typically problems
• md5($salt.$pass) really hard to brute at present moment
• Why? Read h8p://hashcat.net/forum/thread-‐1437.html for details
• Wait for new oclHashcat version (late 2012) • Other tools has no md5($salt.$pass) template
• Dic2onary a8acks really slow (~ 10^3 h/s)
Defcon Russia (DCG #7812)
How much 2me to brute?
Row MD5 brute speed (modern hardware) • CPU: ~10^7 hash/sec 150W $180 • GPU: ~10^10 hash/sec 500W $800 • FPGU: ~10^11 hash/sec 250W $1200
Defcon Russia (DCG #7812)
Thx & ques2ons ???
• Stefan Esser 2008 for great research • Mykola Ilin (Defcon UA, Kiev) for answers
and prac2ce, theore2cal base and others • Neuronspace (haskspace Moscow) for all ;) • Solar Designer for phpass
h8p://www.openwall.com/phpass/ which protect us by /dev/urandom based rands ;)
Follow me: @d0znpp d0znpp[special char]ONsec.ru
Defcon Russia (DCG #7812)