神奇的javascript-不用括号带参执行函数

背景

两周前,我遇到一个挺有意思的xss,过滤了很多符号,包括<>=()`[]等。

我将此问题抽象成ctf题目,题目源码公开在 github

前两天在 题目评论 中看到有师傅把答案贴出来了,我就说一下这个案例。

测试时遇到的问题

实际测试时遇到的问题,也是题目中有两个比较难的地方:

1
2
* javascript不用 <>=()`[] 等符号,怎么调用函数?
* javascript不用 <>=()`[] 等符号,怎么调用函数,并且带上参数?

第一个问题简单一点:在发生类型转换时,会执行valueOf或者toString属性值指向的函数。

1
1-{valueOf:function(){alert(1)}}

第二个问题难一点,需要对this的用法比较熟悉。

1
2
3
4
5
6
7
在函数外部,this指向window对象

在函数内部:

* 普通调用时
* strict模式下,this指向undeined
* 非strict模式下,this指向当前对象

还有一些方式改变this指向的对象,包括:

1
2
* 调用call函数、apply函数等指定对象
* new构造函数

this涉及的情况比较多,也比较反直觉,这里就不多说了。可以看 11 | this:从JavaScript执行上下文的视角讲清楚this 这篇文章。

题目解法

我的解法和 @rmb122 师傅一样:

1
https://04bdb3a0.o53.xyz/a1e60ae3-4bac-4012-a0f3-5b7018677979.php?a=xx%27-{valueOf:test.a,%27call%27:%22%27%22%2blocation.hash}-%27#';hello('a','b','c');//

我也把题目发给我做前端开发的朋友,他的解法如下:

1
https://04bdb3a0.o53.xyz/a1e60ae3-4bac-4012-a0f3-5b7018677979.php?a=%27%2B{toString:%20test.a,call:%20%27hello%27%2B[...hello%2B%27%27][29]%2B%22%27a%27,%22%2B%22%27b%27,%22%2B%22%27c%27%22%2B[...hello%2B%27%27][56]}%2B%27

中间有个小插曲:在朋友把他的解法发我后,我在代码中添加了对[]符号的过滤,因为我碰到的实际案例中也过滤了[]符号。

总结

虽然当时绕过了xss的过滤,也清楚触发流程,但是我不明白为什么会这么触发。

所以补了一下和此题相关的语法及概念,包括以下内容:

1
2
3
* 类型转换
* this是什么
* 函数是一等公民

由这个问题想到,是否其他语言有类似场景?比如某个对象可控时,对它做运算会导致函数调用。

1
2
3
obj = {"可控key":"可控value"}

操作 obj

这是一个木有答案的问题。