Visar inlägg med etikett PHP. Visa alla inlägg
Visar inlägg med etikett PHP. Visa alla inlägg

onsdag 5 januari 2011

DoS:a PHP med en siffra

Flyttalet 2.2250738585072011e-308 hänger PHP 5.3 och öppnar upp för enkla men effektiva DoS-attacker.

Varför? Läs vidare.

Normala flyttal
Ett 64-bitars flyttal representeras av en teckenbit, elva exponentbitar och 52 mantissabitar. Elva bitar till exponenten innebär att minsta tillåtna exponent är -1022 och den maximala är 1023.

Ett så kallat normalt flyttal karaktäriseras också av att första siffran i mantissan är skild från noll, t ex 6.008043e10. Om första siffran vore noll, t ex 0.540030002e13 så skulle ju talet kunna skrivas 5.40030002e12, dvs med femman först, tolv som exponent och man hade tjänat en siffras precision i mantissan. Därför har man också kunna tolka den första biten som implicit eller gömd. Alltså har man 53 bitars precision i mantissan.

Det betyder att det minsta normala, 64-bitars flyttalet är binärt 1e-1022, decimalt 2.2250738585072010e-308.

Subnormala tal
Vad händer om datorn får ett resultat som är mindre än 1e-1022? Tidigare så ledde det till "flush to zero", dvs resultatet blev noll. Men sen kom man på att till priset av förlorad precision (= mindre antal signifikanta siffror i mantissan) så kunde man fortfarande representera resultatet som ett flyttal. Tricket var att låta första biten i mantissan vara noll för dessa subnormala tal! Exponenten representeras av bara nollor.

Nu plötsligt kunde man representera tal som 0.0000000010111e-1022.

Subnormala tal och PHP
Låt oss nu titta på det där talet som hängde PHP 5.3.

2.2250738585072011e-308 = 0.1111111111111111111111111111111111111111111111111111 x 2^-1022

I minnet representeras det av:
Teckenbiten: 0
Exponenten: 00000000000
Mantissan: 1111111111111111111111111111111111111111111111111111

Om ni räknar ettorna så ser ni att de är 52 till antalet. Tillsammans med den inledande nollan (implicit för 0-exponent) så fyller de hela mantissan på 53 bitar. Vi har alltså att göra med det största möjliga, subnormala flyttalet i ett 64-bitarssystem.

Och det värdet hänger tydligen PHP 5.3!

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.