环境:php环境即可,也可使用phpstudy。
参考文章:
深入理解浏览器解析机制和XSS向量编码-CSDN博客(很重要)
HTML 字符编码(自我复习)-CSDN博客
例题1:
<?php
header("X-XSS-Protection: 0");
$xss = isset($_GET['xss'])? $_GET['xss'] : '';
$xss = str_replace(array("(",")","&","\\","<",">","`"), '', $xss);
echo "<img src=\"{$xss}\">";
?>
若我们先把过滤条件筛除,只需要在url栏中输入:
?xss=1" onerror=location="javascript:alert(1)
得到结果的原因是,我们可以利用<img>标签中的src属性,若无图片,输入onerror他会执行js代码,而location是js中的一个元素,可以当做变量。
接下来,我们加入过滤条件:
可以发现,并没有绕过,此时我们想到编码问题,将(1)编译成%281%29,但结果我们发现并没有绕过WAF,这是为什么呢?因为在url地址栏中,浏览器会自动解析urlcode编码,相当于即使我们传参,url中仍然是(),自然会被WAF拦截,所以我们需要再次编码,将%281%29写成%25281%2529,这样%25会在地址栏中被解析成%,继而绕过WAF
绕过成功,值得注意的是,编码是工具,初次之外应该多学习js的知识,了解特性,才能多绕过WAF。例如下方的题,我们使用οnerrοr=javascript:alert(1)可能绕不过,但是可以使用prompt方法就可以绕过。因此任重而道远啊
<?php
header("X-XSS-Protection: 0");
$xss = isset($_GET['xss'])? $_GET['xss'] : '';
if(preg_match('/(script|alert|eval)/',$xss)){exit("no,no,no");
}
$xss = str_replace(array("(",")","&","\\","<",">","`"), '', $xss);
echo "<img src=\"{$xss}\">";
?>
例题2:
借鉴文章:
深入理解浏览器解析机制和XSS向量编码-CSDN博客
<textarea><script>alert(5)</script></textarea>
上述的脚本能执行吗?
答案是不能。原因是在HTML解析器的规则,其中有一种可以容纳字符引用的情况是“RCDATA状态中的字符引用”。这意味着在<textarea>和<title>标签中的字符引用会被HTML解析器解码,原因是对RCDATA有个特殊的情况。在浏览器解析RCDATA元素的过程中,解析器会进入"RCDATA状态"。在这个状态中,如果遇到"<"字符,它会转换到"RCDATA小于号状态"。如果"<"字符后没有紧跟着"/"和对应的标签名,解析器会转换回“RCDATA状态”。这意味着在RCDATA元素标签的内容中(例如<textarea>或<title>的内容中),唯一能够被解析器认做是标签的就是“</textarea>”或者"</title>"。因此,在"<textarea>"和“<title>”的内容中不会创建标签,就不会有脚本能够执行。
通俗来讲就是,在RCDATA中的所有标签,HTML都不认识,它只认识自身的闭合标签(</textarea>和</title>),因此就无法执行脚本。
例题3:
<a href="%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%31%29">aaa</a>
解码后代码:
javascript:alert(1)
这个链接是否可以生效,我们测试:
为什么不能生效呢,如果只是js代码的话,那我们解码完成后,应该会弹出一个js的效果。
不能对协议类型进行任何的编码操作,不然URL解析器会认为无类型。就如上述的情况一样。因为URL中被编码的"javascript"没有被解码,因此不会被URL解析器识别。该原则对协议后面的" : "(冒号)同样适用
例题4:
<a href="javascript:%61%6c%65%72%74%28%32%29">aaa</a>
这段例子用了两种编码方式,我们尝试完整的解码后:
javascript:alert(2)
结果:
我们推测,实体编码解析应在urlcode编码前,由于是get传参方式,若实体编码顺序在urlcode编码后,会导致urlcode编码已经解析完,已经传参时,实体编码还未解析,则结果不会弹框。