简单介绍下xss的原理与分类,此篇博文作为讲稿使用。学术不精望批评指正。

XSS全名Cross-Site Scripting,即跨站脚本。这么听名字可能有点懵逼,什么是跨站、用什么脚本。先不做解释,我们直接来看个例子。

代码如下,存在输入表单,将输入表单的内容提交给当前页面路径处理(action为空),也就是下头的php代码。

php把你输入的内容原封不动地写在一个input标签中返回回去。

 

 看一下实际运行情况:

输入aaaaa,提交前:

 

 提交后:

 

 没有问题。

如果我们输入一些其他的内容呢:

比如输入一个js脚本:

<script>alert(1)</script>

页面原封不动地把这段js返回给我们,并且没有执行alert(1):

 

 看一看源码是啥样的:

 

 我们看到js被作为value的值传了进去,而值是不会被解析为脚本的;

可是我们想让这段js执行起来啊,该怎么办呢。

其实很简单,只要想办法把js从<input>标签中取出来,让<script>标签成为真正的标签而不是value的值就好了

方法如下:

我们输入

"><script>alert(1)</script>

 

 点击提交以后:

 

 我们成功执行了这段js脚本!

来看看网页源码现在是什么样的:

 

 还记得我们的输入么?

"><script>alert(1)</script>

再结合php中对输入值的处理一起来看:

 

 php把输入的值取出来放到<input>标签中的value值中输出给页面

一个字符一个字符地分析我们的输入,第一个双引号闭合了value的双引号

 

 接下来的>闭合了input标签的标签符:

 

 至此,<input>标签已经结束了,剩下的<script>alert(1)</script>就自己构成了一对有效的标签,这不再是value的值了,而是一段可以执行的js代码:

 

 然后把<input>标签和js代码交给页面处理,得到一个value为空的框框和一个弹窗。

这其实就是一个反射型XSS,也叫做非持久型XSS。

对于反射形XSS:

来看看这个过程中发生了什么事:用户发出请求,服务器进行处理后把带有XSS代码的数据发送给用户浏览器,浏览器解析时触发XSS漏洞。

在现实的攻击中,攻击者常常把包含XSS代码的恶意链接发送给目标用户(如通过邮件等方式),促使目标用户访问该链接。

 

XSS除了反射型,还有存储型和DOM型。

 

存储型XSS:

存储型XSS会把用户输入的数据“存储在”服务端。这种XSS具有很强的稳定性。比较常见的一个场景就是,黑客写下一篇包含有恶意js代码的博客文章,文章发表后,所有访问该博客文章的用户,都会在他们的浏览器中执行这段恶意的js代码。黑客把恶意的脚本保存到服务器端,所以这种XSS攻击就叫做“存储型XSS”。

存储型XSS通常也叫做“持久型XSS”,因为从效果上来说,它存在的时间是比较长的。

 

DOM Based XSS:

实际上,这种类型的XSS并非按照“数据是否保存在服务端”来划分,DOM Based XSS从效果上来说也是反射型XSS。单独划分出来,是因为DOM Baesd XSS的形成原因比较特殊,发现它的安全专家专门提出了这种类型的XSS。出于历史原因,也就把它单独作为一个分类了。

通过修改页面的DOM节点形成的XSS,称之为DOM Based XSS。一般DOM型XSS是不需要与服务器端进行交互的,它只发生在客户端处理数据阶段。

我们看如下例子:

 

 存在一个input框和一个button,按下button后会执行test()函数,也就是构造一个超链接,这个超链接指向你输入字符串的url

按下button前:

 

 输入aaaaa后按button:

 

发现出现了一个名为testLink的超链接。点击这个超链接跳转后,并没有找到对应的文件:

 打开网页源码看看,这个超链接的确指向了aaaaa:

 

 只不过再当前路径下我们没有存储aaaaa文件,自然就访问不到。

 

那如果我们不输入常规的字符串,输入这个:

' onclick=alert(1); //

点击button后仍然出现超链接,再点击这个超链接看看:

 

 会发现浏览器弹出了alert框。

其实当我们输入上段数据后,页面代码就变成了:

<a herf='' onclick=alert(1); //'>testLink</a>

单引号先是闭合了href属性的单引号,然后构造onclick事件,只要点击这个超链接就会执行alert(1),最后的注释符//把原先href右侧的的单引号给注释掉了。

当然,我们还可以使用另外一种方式,不构造新事件,而是选择闭合掉<a>标签,并插入一个新的html标签。

比如输入:

'><img src=nothing onerror=alert(1) /><'               (/>表示转义>,具体用途之后会介绍)

会发现不需要点击button就会弹出警示框:

 

 来看看网页源码是啥样子的:

 

 我们的输入先是闭合了<a>标签,然后构造了一个<img>标签,图片来源路径为nothing,并找不到这个文件,所以会执行onerror后的操作,也就是alert(1)

最后再把原来的<a>标签的右半段闭合掉。

这边稍微解释一下为什么html标签中属性值会用双引号括起来,这是w3c标准组织规定的做法,如果不加双引号,就无法区分一些特殊字符。

 

至此,三种XSS的简单介绍已经讲解完毕。