Upload
allyson-farmer
View
226
Download
0
Embed Size (px)
DESCRIPTION
Agenda 3 How PHP generate session number? What’s session value? How to create a session php_session_create_id() Preliminary analysis Secondary reduction Conclusion Q&A
Citation preview
How I Met Your GirlfriendAttacking sessions and pseudo-random numbers in PHP
Black Hat USA 2010Samy Kamkar
Agenda
2
How PHP generate session number?
Preliminary analysis
Secondary reduction
Conclusion
Q&A
Agenda
3
How PHP generate session number?• What’s session value?• How to create a session• php_session_create_id()
Preliminary analysis
Secondary reduction
Conclusion
Q&A
What’s session value?
4
Sessions are required to keep track of users after they have authenticated using various credentials.
Session value is the identity of an user generated by some random functions that should be unpredictable.
If one could predict the session value, he has all rights as the victim.
How to create a session
5
PHP provides several functions for producing pseudo-random numbers and a primary function for starting sessions.
php_session_start(){
php_session_initialize(){
php_session_create_id()}php_session_reset_id(){
php_session_send_cookie()}
}
How to create a session (cont.)
6
php_session_start(){ php_session_initialize() { php_session_create_id() } php_session_reset_id() { php_session_send_cookie() }}
How to create a session (cont.)
7
php_session_start(){ php_session_initialize() { php_session_create_id() } php_session_reset_id() { php_session_send_ () }}
cookie
php_session_create_id()
8
Session values are generated by following:• Client IP address(32 bits)• Current epoch(32 bits)• Current microseconds( [0,1000000), 20 bits)• A random value from php_combined_lcg() (64 bits)
Totally 32 + 32 + 20 + 64 = 148 bits
php_session_create_id(){
gettimeofday( &tv , NULL );spprintf( &buf , 0 , “%.15s%ld%ld%0.8F” , remote_addr ?
remote_addr : “” , tv.tv_sec , tv.tv_usec , php_combined_lcg() * 10 );
MD5( buf ) or SHA1(buf);return buf;
}
Agenda
9
How PHP generate session number?
Preliminary analysis• I love social networks• I love HTTP request
Secondary reduction
Conclusion
Q&A
I love social networks
10
Session values are generated by following:• • Current epoch(32 bits)• Current microseconds( [0,1000000), 20 bits)• A random value from php_combined_lcg() (64 bits)
However, in most social network sites, we can see someone logged in immediately. Additionally, we can contact the user via chat, message, comment, etc. and find his IP indirectly.
Client IP address(32 bits)
I love HTTP request
11
Session values are generated by following:• • • Current microseconds( [0,1000000), 20 bits)• A random value from php_combined_lcg() (64 bits)
In fact, we also get the epoch when user logged in.
Current epoch(32 bits)
But we don’t know the server’s time zone.
Make a request “HEAD / HTTP/1.0”
Agenda
12
How PHP generate session number?
Preliminary analysis
Secondary reduction• php_combined_lcg()• lcg_seed()• Review
Conclusion
Q&A
php_combined_lcg()
13
php_combined_lcg(){
php_int32 q , z;if ( ! LCG(seeded) ) lcg_seed();
MODMULT( 53668,40014,12211,2147483563L,LCG(s1) );MODMULT( 52774,40692,3791,2147483399L,LCG(s2) );z = LCG(s1) – LCG(s2);if ( z < 1 ) z += 2147483562 ;return z * 4.656613e-10;
}
#define MODMULT( a , b , c , m , s ) \q = s / a; \ s = b * ( s – a * q ) – c * q; \if ( s < 0 ) s += m
lcg_seed()
14
s1• Known epoch(tv.tv_sec), need to guess tv.tv_usec• tv.tv_usec is in range [0,1000000)
lcg_seed(){
if ( gettimeofday( &tv , NULL ) == 0 ) //SuccessLCG(s1) = tv.tv_sec ^ (~tv.tv_usec);
elseLCG(s1) = 1;
LCG(s2) = (long) getpid();LCG(seeded) = true;
}
s2: pid is in range (1024,32768) on Linux
0 = 00000000 00000000 00000000 00000000106 = 00000000 00001111 01000010 01000000⇨ The first 12 bits are always known
Review
15
Session values are generated by following:• Client IP address(32 bits)• Current epoch(32 bits)• Current microseconds( [0,1000000), 20 bits)• A random value from php_combined_lcg() (64 bits)▪ s1 = tv.tv_sec ^ (~tv_usec) ⇨ 20 bits▪ s2 = pid ⇨ 15 bits
148 bits session value is reduced to 20 bits!
or 0 bit if we can access the server⇨ 20 bits or 35 bits, where 20 bits are from the same variable before
Agenda
16
How PHP generate session number?
Preliminary analysis
Secondary reduction
Conclusion• Brute force?
Q&A
Brute force?
17
Of course! We need only 220 times to get s1 and s2, which can be computed in a second.
If you can run your php on server, use getmypid() to get s2 and use lcg_value() to compute s1.
Otherwise, visit a page using session_start() to get your session, and brute force with 220 * 217 possible permutation.
Agenda
18
How PHP generate session number?
Preliminary analysis
Secondary reduction
Conclusion
Q&A
Q&A
19
php_session_start(){ php_session_initialize() { php_session_create_id() { gettimeofday( &tv , NULL ); spprintf( &buf , 0 , “%.15s%ld%ld%0.8F” , remote_addr ? remote_addr : “” , tv.tv_sec , tv.tv_usec , php_combined_lcg() * 10 ); MD5( buf ) or SHA1(buf); return buf; } } php_session_reset_id() { php_session_send_cookie() }}
php_combined_lcg(){ php_int32 q , z; if ( ! LCG(seeded) ) lcg_seed(); MODMULT( 53668,40014,12211,2147483563L,LCG(s1) ); MODMULT( 52774,40692,3791,2147483399L,LCG(s2) ); z = LCG(s1) – LCG(s2); if ( z < 1 ) z += 2147483562 ; return z * 4.656613e-10;}
lcg_seed(){ if ( gettimeofday( &tv , NULL ) == 0 ) LCG(s1) = tv.tv_sec ^ (~tv.tv_usec); else LCG(s1) = 1; LCG(s2) = (long) getpid(); LCG(seeded) = true;}
Thanks for your attendance