fredag 30 juli 2010

PHP-sessioner sårbara

Samy Kamkar, killen bakom MySpace-masken och XSS håller precis en väldigt underhållande presentation. Han har bland annat slaktat PHP-sessioner ...

Målet för attacken är att ta över en inloggad persons session i en webbapplikation skriven i PHP.

session_start() initialiserar en PHP-session. Samy har analyserat entropin i sessions-idt:
  • 32 bitar från din IP-adress
  • 32 bitar från sekunder sen 1/1 1970
  • 32 bitar från nuvarande antal mikrosekunder
  • 64 bitar från pseudoslumpgeneratorn (PRNG, pseudo random number generator)
Totalt 160 bitar, dvs jobbigt att brute force:a

Men …
  • 0 bitar från din IP-adress eftersom den knappast kan anses hemlig.
  • 0 bitar från sekunder sen 1/1 1970 eftersom man kan polla tjänsten en gång i sekunden för att se exakt när du loggar på (typiskt sociala nätverk där din kompis loggar in)
  • 20 bitar från nuvarande antal mikrosekunder eftersom det bara finns en miljon mikrosekunder!
  • 64 bitar från PRNG
Totalt 84 bitar, inte lika jobbigt att brute force:a

Men …

Den enda slump som finns i en PRNG kommer från fröet. Resten är en predikterbar sekvens av siffror, lika varje gång fröet är lika. Just därför är det så allvarligt att PHP-utvecklarna har tabbat sig i fröberäkningen.

Fröberäkningen XOR:ar tidpunkten för serverstarten i antalet sekunder sen 1/1 1970 med antalet mikrosekunder. Felet är att man mixar det helt slumpmässiga antalet mikrosekunder med den del av antalet sekunder sen 1/1 1970 som är variabelt (dvs den del som är någorlunda slumpmässig). Och eftersom det bara finns en miljon mikrosekunder så är fröet nu nere i 20 bitar entropi.

Total entropi: 40 bitar

Vidare med time-space-tradeoff så behöver vi bara brute force:a hälften, dvs 20 bitar. Genomförbart inom sekunder med i snitt en halv miljon request till den sårbara tjänsten.

Sen är PHP-sessionen övertagen.

3 kommentarer:

Jonas sa...

Intressant!

Michael Boman sa...

64-bitar PRNG byggs bland annat av 32-bittars Process ID (PID), men Linux använder sig bara utav 15-bittar för PID, så man sparar ytterligare 17 bittar (fixat i PHP 5.3.2).

Så svaret (slutsumman) är rätt, men det saknades lite detaljer i uträkningen.

Simson1 sa...

De hemsidor som är lite mer noga med säkerheten låser sina sessioner till det IP-nr som användes vid inloggningen (ofta det tre första oktetterna i IP-adressen). Då går denna attack ej att genomföra (förutsatt att man inte sitter på samma WAN-IP).