跨站脚本攻击(Cross Site Scripting),缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。理论上,所有可输入的地方没有对输入数据进行处理的话,都会存在XSS漏洞,漏洞的危害取决于攻击代码的威力。
1️⃣xss的危害:
攻击者可以使用户在浏览器中执行其预定义的恶意脚本,其导致的危害可想而知,如劫持用户会话,插入恶意内容、重定向用户、使用恶意软件劫持用户浏览器、繁殖XSS蠕虫,甚至破坏网站、修改路由器配置信息等。XSS漏洞可以追溯到上世纪90年代。大量的网站曾遭受XSS漏洞攻击或被发现此类漏洞,如Twitter、Facebook、MySpace、Orkut、新浪微博和百度贴吧。研究表明,最近几年XSS已经超过缓冲区溢出成为最流行的攻击方式,有68%的网站可能遭受此类攻击。根据开放网页应用安全计划OWASP TOP10公布的2010年统计数据,XSS排名第2名仅次于代码注入,2017年的OWASP TOP10排行中位列第七名。
XSS 存在的根本原因是,对URL中的参数,对用户输入提交给 webserve r的内容,没有进行充分的过滤。如果我们能够在 web 程序中,对用户提交的URL中的参数,和提交的所有内容,进行充分的过滤,将所有的不合法的参数和输入内容过滤掉,那么就不会导致“在用户的浏览器中执行攻击者自己定制的脚本”。
但是,其实充分而完全的过滤,实际上是无法实现的。因为攻击者有各种各样的神奇的,你完全想象不到的方式来绕过服务器端的过滤,最典型的就是对URL和参数进行各种的编码,比如escape,encodeURI, encodeURIComponent, 16进制,10进制,8进制,来绕过XSS过滤。
2️⃣xss的原理:
HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,<title>与</title>之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。总结后为三点。
①攻击者对含有漏洞的服务器发起XSS攻击(注入JS代码)。
②诱使受害者打开受到攻击的服务器URL。
③受害者在Web浏览器中打开URL,恶意脚本执行。
3️⃣xss的分类:
从攻击代码的工作方式可以分为三个类型:
①持久型跨站:最直接的危害类型,跨站代码存储在服务器(数据库)。②非持久型跨站:反射型跨站脚本漏洞,最普遍的类型。用户访问服务器-跨站链接-返回跨站代码。③DOM跨站:DOM(document object model文档对象模型),客户端脚本处理逻辑导致的安全问题。
基于DOM的XSS漏洞是指受害者端的网页脚本在修改本地页面DOM环境时未进行合理的处置,而使得攻击脚本被执行。在整个攻击过程中,服务器响应的页面并没有发生变化,引起客户端脚本执行结果差异的原因是对本地DOM的恶意篡改利用。
4️⃣xss的攻击方式:
常用的XSS攻击手段和目的有:
①盗用cookie,获取敏感信息。
②利用植入 Flash,通过 crossdomain 权限设置进一步获取更高权限;或者利用 Java 等得到类似的操作。
③利用 iframe、frame、XMLHttpRequest 或 Flash 等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的如发微博、加好友、发私信等操作。
④利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。
⑤在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDoS攻击的效果。
⑥xss钓鱼网站,利用JavaScript脚本直接放用户跳转到钓鱼网站
⑦xss获取键盘记录,xss可以实现键盘操作,但是有局限性,不能跨域。
㈠、xss之存储型xss:(又被称为持久性XSS)
存储型 XSS 的攻击步骤:
①攻击者将恶意代码提交到目标网站的数据库中。②用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器。③用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。 存储型 XSS攻击常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
储存型XSS会把用户输入的数据“储存”在服务器端。这种XSS具有很强的稳定性。持久的XSS危害性大,容易造成蠕虫,因为每当用户打开页面,查看内容时脚本将自动执行。持久型XSS最大的危害在于可能在一个系统中的用户间互相感染,以致整个系统的用户沦陷。能够造成这种危害的脚本我们称之为XSS蠕虫。
㈡、xss之反射型xss :(也被称为非持久性XSS)
反射型 XSS 的攻击步骤:
①攻击者构造出特殊的 URL,其中包含恶意代码。
②用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
③用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。 反射型 XSS漏洞常见于通过 URL 传递参数的功能,如网站搜索、跳转等。
反射型XSS只是简单的把用户输入的数据“反射”给浏览器,也就是说需要诱使用户“点击”一个恶意链接,才能攻击成功。漏洞产生的原因是攻击者注入的数据反映在响应中。非持久型XSS攻击要求用户访问一个被攻击者篡改后的链接,用户访问该链接时,被植入的攻击脚本被用户游览器执行,从而达到攻击目的。
㈢、xss之DOM 型 XSS:
DOM 型 XSS 的攻击步骤:
①攻击者构造出特殊的 URL,其中包含恶意代码。
②用户打开带有恶意代码的 URL。
③用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行。 DOM 型 XSS 跟前两种 XSS 的区别:DOM 型 XSS 攻击中,取出和执行恶意代码由浏览器端完成,属于前端 JavaScript 自身的安全漏洞,而其他两种 XSS 都属于服务端的安全漏洞。
⛔DOM通常代表在html、xhtml和xml中的对象,使用DOM可以允许程序和脚本动态的访问和更新文档的内容、结构和样式。它不需要服务器解析响应的直接参与,触发XSS靠的是浏览器端的DOM解析,所以防范DOM型XSS完全就是前端的责任,必须注意!!!。
5️⃣xss之绕过:
大多数网站为了避免xss的攻击,对于攻击者的输入都采取了过滤的措施,导致攻击者通常不能正常插入恶意代码来达到攻击目的。但是仍存在一些漏洞可以利用,来绕过过滤措施。
xss绕过的方法有许多,主要取决于攻击者的思路和对前端技术的掌握,以下介绍几个简单的绕过方法。
1)对前端的输入字符数量限制可以尝试进行抓包重发或者修改前端的HTML。
2)防止后台对输入的内容进行正则匹配来过滤输入,对于这样的过滤可以考虑大小写混合输入的方法。
payload:<sCRipT>alert('你打篮球像oldboy')</sCrIPt>
3)防止后台对输入的内容进行替换,采用拼拼凑的输入方法。
payload:<sc<script>ript>alert('你打篮球像oldboy')</scr<script>ipt>
4)使用注释来干扰后台对输入内容的识别。
payload:<sc<!--test-->ript>alert('你打篮球像oldboy')</scr<!--tshauie-->ipt>
5)编码思路:后台有可能会对代码中的关键字进行过滤,但我们可以尝试将关键字进行编码后在插入。(注意:编码在输出时是否会被正常识别和翻译才是关键,不是所有的编码都是可以的)
例:使用事件属性onerror(): <img src=# οnerrοr="alert('oldboy')"/>
使用HTML进行编码: <img src=x οnerrοr="alert('yangshuang')"/> 6)htmlspecialchars()函数绕过:
该函数的语法:htmlspecialchars(string,flags,character-set,double_encode) 过滤原理:htmlspecialchars() 函数把预定义的字符转换为 HTML 实体,从而使XSS攻击失效。但是这个函数默认配置不会将单引号和双引号过滤,只有设置了quotestyle规定如何编码单引号和双引号才能会过滤掉单引号
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
’ (单引号)成为'
< (小于)成为 <
>(大于)成为 >
可用的quotestyle类型:
ENT_COMPAT - 默认。仅编码双引号
ENT_QUOTES - 编码双引号和单引号
ENT_NOQUOTES - 不编码任何引号
可使用以下语句绕过: q' onclick**='alert(111)' 点击执行 7) href 绕过:当输入的值在 a 标签 herf 里
payload: javascript:alert(1111) 直接代入 a 标签 herf 里面一样可以绕过 htmlspecialchars() 8)xss之js输出绕过:当目标是用JavaScript脚本输出的,只需闭合原有的表情即可插入代码
payload:<script> $ms=' 11111111'</script><script>alert(1111)</script> ;
6️⃣XSS的测试技巧:
①工具扫描:APPscan、awvs、burpsuite、XSSER XSSF②手动测试:Burpsuite、firefox(hackbar)
1)在目标站点上找到输入点,比如查询接口,留言板等;
2)输入一组"特殊字符+唯一识别字符",点击提交后,查看返回的源码,是否有做对应的处理;
3)通过搜索定位到唯一字符,结合唯一字符前后语法确认是否可以构造执行js的条件(构造闭合);提交构造的脚本代码,看是否可以成功执行,如果成功执行则说明存在XSS漏洞;第一种情况:可得知输出位置
输入一些敏感字符,例如<、>、"、'、()等等,在提交请求后去查看HTML源代码,看这些输入的字符是否被转义。在输出这些敏感字符的时候,很有可能程序已经做过了过滤,那么你在寻找这些字符的时候就不是那么容易了,这时候你可以直接输入“XXSER<>"'&”折床字符串,然后在查找源代码的时候直接进行查找XXSER或许比较方便一些。第二种情况:无法得知输出位置
非常多的Web应用程序源代码是不对外开放的,这时在进行测试XSS时就有可能无法得知输入数据到底在何处显示,比如测试某留言本是否存在XSS,那么在留言之后,你必须要经过管理员的审核才能进行显示,这时你是无法得知,你输入的数据在后台管理页面处于何种状态。
万能测试XSS漏洞payload:"/></textarea><script>alert(1)</script>
7️⃣XSS的防御策略:
只要有输入数据的地方,就可能存在 XSS 危险。永远不相信用户的输入。需要对用户的输入进行处理,只允许输入合法的值,其它值一概过滤掉。
XSS防御的总体思路是:对输入进行过滤,对输出进行编码
httpOnly: 在 cookie 中设置 HttpOnly 属性后,js脚本将无法读取到 cookie 信息。
输入过滤:一般是用于对于输入格式的检查,例如:邮箱,电话号码,用户名,密码…等,按照规定的格式输入。不仅仅是前端负责,后端也要做相同的过滤检查。因为攻击者完全可以绕过正常的输入流程,直接利用相关接口向服务器发送设置。
转义 HTML: 如果拼接 HTML 是必要的,就需要对于url中的引号,尖括号,斜杠进行转义,但这还不是很完善.想对 HTML 模板各处插入点进行充分的转义,就需要采用合适的转义库。 例如:htmlspecialchars()函数把一些预定义的字符转换为 HTML 实体
预定义的字符是: & (和号)成为 & " (双引号)成为 " ’ (单引号)成为' < (小于)成为 < >(大于)成为 >**
白名单:对于显示富文本来说,不能通过上面的办法来转义所有字符,因为这样会把需要的格式也过滤掉。这种情况通常采用白名单过滤的办法,当然也可以通过黑名单过滤,但是考虑到需要过滤的标签和标签属性实在太多,更加推荐使用白名单的方式。