sessionStorage Fingerprinting

Background

With the advent of the performance function in HTML it's now possible to zero in on the device's clock speed. Once you have this data you can tell if a device is running the browser on a peice of hardware or if it is a virtual machine. Virtual machines use either use a synthetic HPET based counter (typically showing as 10,000Mhz) or an ACPI based counter (typically showing as 35795 MHz).


How It Works

The window.performance.now() yields a time measurement in milliseconds which is an integral number of the Windows performance counter ticks (1/f where f is the Windows performance counter frequency).By sampling window.performance.now() it is possible to determine the underlying time unit with some math. The more samples performed the better the results, with the downside of some latency. NOTE: Firefox claimed to have closed this detection but it seems that it does occasionally work in newer versions.


Entropy Estimate: TBD


Code

The JavaScript function below fingerprints the sessionstorage settings for the device.
Note: Depending on your output method you may need to URL encode the returned results.

Source Code

function clock() {

    "use strict";

    var strOnError, lngInitClk, lngDiffClk, lngTmp, strOut, i;

 

    strOnError = "<clkhz>error</clkhz>";

    lngInitClk = 0;

    lngDiffClk = 0;

    lngTmp = 0;

    strOut = "";

    i = 0;

 

    try {

        lngInitClk = performance.now() / 1000;

        lngDiffClk = performance.now() / 1000 - lngInitClk;

        for (i = 0; i < 20; i++) {

            lngDiffClk = clockcalc(lngDiffClk, performance.now() / 1000 - lngInitClk);

        }

        lngTmp = (Math.round(1 / lngDiffClk));

        strOut = "<clkMHz>" + lngTmp + "</clkMHz>";

        return strOut;

    } catch (err) {

        return strOnError;

    }

}

 

function clockcalc(lngDiff, lngElapse) {

    var lngrOnError;

    lngOnError = 0;

    try {

        if (lngDiff < 0.00000001) {

            return lngElapse;

        }

        if (lngDiff < lngElapse) {

            return clockcalc(lngElapse - Math.floor(lngElapse / lngDiff) * lngDiff, lngDiff);

        } else if (lngDiff == lngElapse) {

            return lngDiff;

        } else {

            return clockcalc(lngElapse, lngDiff);

        }

    } catch (err) {

        return lngOnError;

    }

}

Validation

Unlike other code on the Internet we do everything possible to verify our code for you. In order to minimize problems and maximize compatibility this code has been verified with JSLint and has been extensively tested with over 1100 OS/Browser combinations using BrowserStack.


Reference

TBD