前端Sandbox hook toString的一点思路
字数 1395 2025-08-26 22:11:51

前端Sandbox Hook toString的绕过思路详解

前言

本文总结了在Web安全领域中绕过前端Sandbox中toString方法被Hook的多种技术思路,主要基于Defcon China决赛中的secret_house题目和Google CTF决赛中的Blind XSS题目。

基本场景分析

1. 简单Hook toString的场景

Function.prototype.toString = function() {
  return '[No source code for you. Not on my watch, not in my world]';
}

这种简单的Hook会阻止通过Function.prototype.toString.call()获取函数源代码。

2. 复杂Sandbox场景(secret_house)

secret_house题目实现了更完整的Sandbox限制:

  1. 重写Function.prototype.toStringnoop
  2. 限制window.opendocument.createElement
  3. 通过事件监听器在页面加载时进一步加固
  4. 禁用DOM元素的innerHTML属性

绕过思路详解

方法一:获取原生toString方法

核心思想:通过iframe创建一个新的执行环境,获取未被Hook的原生toString方法。

1. 使用srcdoc属性

ifr = document.createElement('iframe');
ifr.srcdoc = '\x3script\x3eparent.result = Function.prototype.toString.call(parent.get_secret)\x3c/script\x3e';
document.head.append(ifr);

特点

  • srcdoc创建的iframe与父页面同源
  • 绕过同源策略限制

2. 使用javascript伪协议

ifr = document.createElement('iframe');
ifr.src = '\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74:parent.result = Function.prototype.toString.call(parent.get_secret)';
document.head.append(ifr);

限制

  • 题目中createElement被重写,无法直接创建iframe

方法二:利用Function.prototype.apply

核心思想:通过重写apply方法恢复原生createElement

Function.prototype.apply = function() {
  Document.prototype.createElement = this;
};
a = document.createElement('a');  // 触发apply调用
ifr = document.createElement('iframe');
ifr.srcdoc = '\x3cscript\x3eparent.result = Function.prototype.toString.call(parent.get_secret)\x3c/script\x3e';
document.head.append(ifr);

原理

  • 利用apply调用时的this指向原函数
  • createElement恢复为原始函数

限制

  • 题目中后续会将createElement再次设为noop

方法三:利用CSP解析特性

预期解法:利用DNS解析和CSP策略的差异。

http://secret-bctf.art./?xss=alert(get_secret)

关键点

  • 浏览器不认为secret-bctf.artsecret-bctf.art.是同一个域
  • 导致Sandbox脚本(sandbox.js)不会被加载
  • 直接绕过所有限制

方法四:利用DOM解析时序

非预期解法:利用页面加载时序和DOM结构特点。

onload = function(){
  document.body.innerHTML = `\x3ciframe srcdoc='\x3cscript\x3eparent.result = Function.prototype.toString.call(parent.get_secret)\x3c/script\x3e'\x3e\x3c/iframe\x3e`;
}

原理

  • Sandbox脚本执行时body元素尚未存在
  • document.all不包含body元素
  • body.innerHTML未被Hook

方法五:Firefox特有方法

1. 使用uneval函数

http://secret-bctf.art/?xss=alert(uneval(get_secret))

2. 使用toSource方法

http://secret-bctf.art/?xss=alert(get_secret.toSource())

特点

  • Firefox特有方法
  • 直接获取函数源代码,不依赖toString

防御措施分析

  1. 完整Sandbox实现

    • 不仅Hook toString,还需限制DOM操作
    • 注意页面加载时序的影响
  2. CSP策略

    • 注意域名解析的细微差别
    • 明确指定所有可能的域名变体
  3. 环境隔离

    • 彻底禁用iframe创建
    • 监控全局函数修改

总结

绕过前端Sandbox的关键思路包括:

  1. 寻找未被污染的执行环境(iframe)
  2. 利用语言特性恢复被Hook的函数
  3. 利用策略解析差异(CSP/DNS)
  4. 利用浏览器实现差异(Firefox特有方法)
  5. 利用页面加载时序和DOM结构特点

这些技术展示了前端安全防护与绕过的复杂博弈,开发者在实现安全机制时需要全面考虑各种可能的绕过途径。

前端Sandbox Hook toString的绕过思路详解 前言 本文总结了在Web安全领域中绕过前端Sandbox中 toString 方法被Hook的多种技术思路,主要基于Defcon China决赛中的 secret_house 题目和Google CTF决赛中的 Blind XSS 题目。 基本场景分析 1. 简单Hook toString的场景 这种简单的Hook会阻止通过 Function.prototype.toString.call() 获取函数源代码。 2. 复杂Sandbox场景(secret_ house) secret_ house题目实现了更完整的Sandbox限制: 重写 Function.prototype.toString 为 noop 限制 window.open 和 document.createElement 通过事件监听器在页面加载时进一步加固 禁用DOM元素的 innerHTML 属性 绕过思路详解 方法一:获取原生toString方法 核心思想 :通过iframe创建一个新的执行环境,获取未被Hook的原生 toString 方法。 1. 使用srcdoc属性 特点 : srcdoc 创建的iframe与父页面同源 绕过同源策略限制 2. 使用javascript伪协议 限制 : 题目中 createElement 被重写,无法直接创建iframe 方法二:利用Function.prototype.apply 核心思想 :通过重写 apply 方法恢复原生 createElement 。 原理 : 利用 apply 调用时的 this 指向原函数 将 createElement 恢复为原始函数 限制 : 题目中后续会将 createElement 再次设为 noop 方法三:利用CSP解析特性 预期解法 :利用DNS解析和CSP策略的差异。 关键点 : 浏览器不认为 secret-bctf.art 和 secret-bctf.art. 是同一个域 导致Sandbox脚本( sandbox.js )不会被加载 直接绕过所有限制 方法四:利用DOM解析时序 非预期解法 :利用页面加载时序和DOM结构特点。 原理 : Sandbox脚本执行时 body 元素尚未存在 document.all 不包含 body 元素 body.innerHTML 未被Hook 方法五:Firefox特有方法 1. 使用uneval函数 2. 使用toSource方法 特点 : Firefox特有方法 直接获取函数源代码,不依赖 toString 防御措施分析 完整Sandbox实现 : 不仅Hook toString ,还需限制DOM操作 注意页面加载时序的影响 CSP策略 : 注意域名解析的细微差别 明确指定所有可能的域名变体 环境隔离 : 彻底禁用iframe创建 监控全局函数修改 总结 绕过前端Sandbox的关键思路包括: 寻找未被污染的执行环境(iframe) 利用语言特性恢复被Hook的函数 利用策略解析差异(CSP/DNS) 利用浏览器实现差异(Firefox特有方法) 利用页面加载时序和DOM结构特点 这些技术展示了前端安全防护与绕过的复杂博弈,开发者在实现安全机制时需要全面考虑各种可能的绕过途径。