求解析可绕过Imperva WAF的XSS攻击JS代码逻辑及使用问题
该XSS payload 逐行运行逻辑与绕过原理解析
第一步:先把解码后的完整结构拆出来
原始payload经过URL解码、HTML解析之后的等价结构为:
<a href="j<CRLF>avascript:{ // 块内的解构声明 var {3:s, 2:h, 5:a, 0:v, 4:n, 1:e} = 'earltv' }[self][0][v+a+e+s](e+s+v+h+n)(/infected/.source)"> click </a>
核心JS逻辑拆解(所有看不懂的变量都是从字符串索引取的单字符)
JS里的字符串是类数组结构,每个字符都可以通过数字索引访问,payload里的解构写法本质就是把无意义字符串里的单字符取出来,拼成需要的关键字:
- 参考字符串为
'earltv',各索引对应的字符为:- 索引0 对应字符'e'
- 索引1 对应字符'a'
- 索引2 对应字符'r'
- 索引3 对应字符'l'
- 索引4 对应字符't'
- 索引5 对应字符'v'
- 按解构规则赋值后的变量值:
s = 'earltv'[3] = 'l'h = 'earltv'[2] = 'r'a = 'earltv'[5] = 'v'v = 'earltv'[0] = 'e'n = 'earltv'[4] = 't'e = 'earltv'[1] = 'a'
- 拼接后的关键代码完全等价于原生逻辑:
v+a+e+s→'e'+'v'+'a'+'l'→ 拼成eval(JS全局执行函数)e+s+v+h+n→'a'+'l'+'e'+'r'+'t'→ 拼成alert(弹窗函数)- 链式取全局对象的逻辑:
self本身就是等价于window的全局引用,多层[self][0]的写法是故意嵌套全局对象的引用链路,避免直接写window被WAF规则匹配,最终通过字符串拼出来的eval作为属性名,从全局对象上拿到eval函数,再把拼出来的alert(/infected/.source)作为参数传给eval执行。
整个代码运行完的最终效果,和原生写eval(alert(/infected/.source))没有任何区别,但是源码里完全没有出现连续的eval、alert关键字,这也是它能绕WAF静态扫描的核心原因。
各层绕过设计的原理
- 标签解析绕过:用
<a/href=...>里的斜杠代替标签名和属性之间的空格,HTML解析器会自动忽略标签名后面的孤立斜杠,等价于正常的<a href=...>结构,绕开WAF对<a加空格的规则匹配。 - 协议头绕过:在
javascript:协议头中间插入%0A%0D(也就是CRLF换行/回车符),解码后会变成j<换行>avascript:,JS引擎解析href里的javascript协议时,会自动忽略开头的所有空白字符(包括换行、制表符、回车),但是WAF因为检测到协议头中间被插入了换行,不会匹配到连续的javascript:字符串规则。 - 关键字绕过:完全不用连续的
eval、alert关键字,所有执行逻辑都通过从无意义字符串里取单字符、拼接成函数名的方式实现,WAF的静态关键字扫描规则完全扫不到匹配特征。
为什么不同场景下payload效果差异极大
- 部分场景被WAF拦截:要么是WAF已经更新了规则,能识别这种类数组字符串解构拼关键字的特征;要么是注入上下文里的%、引号、斜杠被转义,导致解码后的结构不合法。
- 大量场景无法生成可点击链接:
- 注入位置错误:比如注入点本身在script标签内部、或者已经在其他标签的属性值里,插入的a标签无法被浏览器渲染成正常的HTML元素,导致结构失效。
- 浏览器安全策略拦截:比如页面设置了严格的CSP策略,禁止执行inline的javascript协议链接;或者注入位置在sandbox沙箱iframe里,被禁止执行脚本,点击后无响应。
- 上下文编码问题:比如%0A%0D被转义成实体字符,无法解码成JS可识别的空白字符,导致javascript协议头失效,链接变成普通文本。
- 特殊字符被过滤:比如a标签结构里的斜杠、引号被WAF过滤,导致HTML标签结构断裂,无法生成可点击的元素。
内容的提问来源于stack exchange,提问作者Sebast1aan
相关产品推荐
相关产品推荐

