第一个:单个循环,移除标签的属性。
下面代码是:首先截取#号后面的值,然后创建一个div,然后将#号后面的值都赋值给div,然后使用querySelectorAll选取div下所有的子元素;然后获取子元素的属性,并将属性全部删除,但是我们在运行的时候会发现一个问题。
我们明明输入的是:<img src=1 οnerrοr=alert(1)>,但是运行后得出的结果是它只删除了一个src,把onerror留了下来。
这里使用调试方法来查看它每一步运行的值。
我们现将断点放在 for (let el of root.querySelectorAll(‘*’)) {和for (let attr of el.attributes) {这两行上,然后逐步往下走,可以在右边的作用域中看到它的data是:
获取到了这个,
然后我们就接着往下走。然后可以看到el获取的值是img,也就说说它已经成功获得到了这个标签。
然后接着继续走;然后attr获取到了第一个元素:src,之后,它执行了下面的移除操作。
接下来按照预期应该是回到标签内继续匹配元素onerror然后进行删除,但是当继续下一步的时候,attr取到的值是空的,就直接跳出循环,直接结束。
按照我们的思维这中方式应该是正确的,但是,在进行循环的过程中,attr首先匹配到的是src元素,然后在循环过后直接删除,删除了之后,剩余的哪个onerror自动往前移动,就好像做核酸一样,拍你前面的那个人因为没有带口罩被撵走了,那你自然是要往前走一位来替代它的位置。这个也是,onerror替代了src排的第一个的位置,它就变成了第一个,但是我在刚刚循环的时候,已经把第一个给循环了,我要去循环下一个的时候它没有了,所以我就结束循环了。
所以要破解这关的话就是将元素的顺序打乱,根据他的漏洞来让他删除后所剩下的是我们所需要的就可以了。
就是将src元素写道第2为,在删除第一位的时候它变成第一位就会保留了,然后将onerror保存到第四位,那样在删除第一位后,原来的第三位变成了第二位,第四位就变成了第三位,,第二位运行完后被删除,最开使的第四位就变成了第2位,但是我们已经执行完第二位了,所以后面就没有了,他就跳出了循环。