low等级:
反射型(reflected)
在输入框随便输入一串字符,跟踪字符发现其出现在<pre>标签中,于是可以通过自建标签方式进行弹框,
这里输入<script>alert(1)</script>来实现弹框。
当然还能输入<img src="xx" οnerrοr="javascript:alert(1)"/>
也可以通过输入<svg οnlοad="javascript:alert(1)"></svg>
DOM型:
在下拉框中选择不同的选项会在url中显示不同的参数,可知url中default中该点可能存在注入点
同上面反射型注入类似,在url中的defaule这个注入点中自建标签即可弹框
这里输入<script>alert(1)</script>来实现弹框。
当然还能输入<img src="xx" οnerrοr="javascript:alert(1)"/>
也可以通过输入<svg οnlοad="javascript:alert(1)"></svg>
存储型(stored)
可见输入的内容会显示到div标签中,所以在这里也是用自建标签方式来弹框,方法跟上面一样,这里不重复累述,这里需要注意的是name这个输入框有长度限制,需要在message这个输入框中进行注入。
middle等级:
反射型:
尝试输入<script>alert(1)</script>进行弹框,发现回显alert(1),猜测可能对script字符串进行了过滤,
这里有多种方法绕过过滤script字符串
1、使用大小写混写script来进行弹框,成功弹框
<Script>alert(1)</Script>
2、双写script进行弹框,原理是先过滤中间的script字符,过滤完会合成一个新的script字符串,成功弹框
<scrip<script>t>alert(1)</scrip<script>t>
3、也可以用img标签:<img src="xx" οnerrοr="javascript:alert(1)"/>
4、也可以使用svg标签:<svg οnlοad="javascript:alert(1)"></svg>
DOM型:
查看源码发现该代码会过滤<script字符串,输入的内容会显示在select标签中的option标签中的value属性中,先闭合option标签,再自建标签,发现无法弹框,接着再闭合select标签,发现成功弹框。
下面两种方式弹框
1、利用img标签
</option></select><img src="1" οnerrοr="alert(1)">
2、利用svg标签
</option></select><svg οnlοad="javascript:alert(1)"></svg>
存储型:
查看源码可知,$message框用了htmlspecialchars函数,该函数会将字符串html实体化,防止以html形式运行代码,这里没法进行注入
再来看$name框,这里只是过滤了<script>标签,所以可以从这里进行注入,但这里有一个注意点,name框的在前端被设置了字符输入的长度,在前端改掉即可
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
注入的payload:
1、<sscript>alert(1)</sscript>
2、当然还有script大小写绕过、img标签、svg标签等方法,上面有写,这里不重复累述
high等级:
反射型:
查看源码,可知这里使用了黑名单的方式使用正则表达式完全过滤了script字符,大小写绕过和双写script标签在这都无法适用了,那么换种标签注入即可,用img 标签、svg标签都可以
payload:
<img src="xx" οnerrοr="alert(1)"/>
<svg οnlοad="alert(1)"></svg>
DOM型:
查看源码,可知这里采用了白名单的方式来防止注入
这里可以采用#方法来绕过服务器端的业务操作
下面是解释说明:
(注意#这个方法仅适用于DOM型xss注入)
#是一个浏览器指导字符,该字符后面的的数据不会被传到服务器后端,所以可以通过该符号来绕过后端代码的过滤
payload:
#?default=<script>alert(1)</script>
存储型:
跟反射型的high级别同理,$message字段被html实体化了,无法注入,也是只能在$name字段进行注入。该注入点也是采用了黑名单,用正则表达式完全过滤<script>字符,这里采用img标签和svg标签即可
payload
<img src="s" οnerrοr="alert(documee)"/>
<svg οnlοad="alert(1)"></svg>
总结
防范xss攻击需要做到以下几点:
1、在前端js对输入的字符使用htmlspecialchars
函数将输入内容html实体化
2、尽量采用白名单策略,只允许特定字符输入,并在前端过滤掉#字符
3、采用黑名单过滤特殊字符,如script、<>、<、alert等
4、将重要的cookie设置为http only,防止黑客通过JavaScript的document.cookie盗取cookie值
5、过滤javascript的on事件,如onclick、onload、onerror等