Freestyle第4期之网站前端安全分享XSS进阶篇

写在前面 2

知识回顾 2

XSS的定义 2

XSS的危害 2

XSS的产生 3

如何攻击 4

深入解读XSS 4

XSS分类 4

XSS出现场景 4

实战XSS 9

攻击篇 9

防御篇 10

其他 11

写在前面

本周五为大家带来的是安全分享之XSS的进阶篇,这部分的内容是基于前2次的安全分享的基础之上的,希望通过这次分享让大家在对XSS有了一个理论层面的认识之上做一个小小的加深,或者以前迷迷糊糊的孩纸们能够通过这次从开发者角度演示XSSXSS有一个系统的了解。

 

知识回顾

首先还是先回忆一下老生常谈的概念问题:

XSS的定义

看百科怎么说XSS

XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的。XSS属于被动式的攻击,因为其被动且不好利用,所以许多人常忽略其危害性。 

XSS的危害

说到危害,到底有哪些呢?且看:

1.钓鱼欺骗;

2.网站挂马;

3.身份盗用;

4.盗取网站用户信息;

5.垃圾信息发送;

6.劫持用户Web行为;

7.XSS蠕虫:XSS 蠕虫可以用来打广告、刷流量、挂马、恶作剧、破坏网上数据、实施DoS攻击等。

XSS的产生

说了一大堆理论,都是不怎么靠谱的东西,还是来看一下他是怎么产生的吧。

****************************************************************

[zhangyongqiao.pt@search041125 htdocs]$ cat test.php

<?PHP

        echo "欢迎你,".$_GET['name'];

?>

[zhangyongqiao.pt@search041125 htdocs]$

****************************************************************

首先在一个具有LAMP环境的机器上建立如上的一个PHP脚本,这个脚本大概的意思就是输出“欢迎你,”加上后面赋值给name属性的值。

那么我们访问一下这个页面,


 

【由于机器的编码问题,导致“欢迎你”这几个字是乱码,我们先无视他。】

看地址栏显示,当给name赋值时,会正常在html页面中展示。同时看到页面返回的源文件内容。

然后我们对name的值做一些改动。

 

出现了如图的信息,那么表示这段脚本就成功的被注入了。

我们看一下源文件的内容:

****************************************************************

欢迎你,zhangyongqiao<script>alert(1);</script>

****************************************************************

如何攻击

也许有人就要问,证明脚本注入了又会怎么样呢?

设想一下,如果黑客同学将这段脚本改成如下形式:

获取当前用户的cookies

返回给服务器,并生成相应的日志。

所作的事情不用太多,对于存在这类安全问题的网站,往往其他安全措施也不完善。那么,简单的,利用你的cookie登录网站,黑客同学得到了你的权限,你的信息也全部暴露在黑客同学的面前了。仅仅是一个普通的用户可能对网站产生的影响不会很大。试想一下,如果这个被攻击的人是管理员呢?

当然,这只是上面那么多危害的一种,别忘了我可是列出了7种危害。

 

深入解读XSS

XSS分类

跨站脚本一般分为两类,非持久型XSS(反射XSS)与持久型XSS(存储XSS

非持久型的是指那些浏览器每次都要在参数中提交恶意数据才能触发的跨站脚本漏洞。前面演示的XSS漏洞属于这种类型。

与非持久型XSS相反,它是指通过提交恶意数据到存储器(比如数据库、文本文件等),Web应用程序输出的时候是从存储器中读出恶意数据输出到页面的一类跨站脚本漏洞。

 

XSS出现场景

接下来看一下XSS的出现场景,XSS一般的注入点会在以下四种情况。

1.输出在HTML页面

2.输出在HTML属性中

3.输出在JS代码中

4.基于DOM

下面我们对每种情况做一次实例,让大家有更直观的了解。

输出在HTML页面

首先第一种情况,输出在HTML页面中的注入,前面的唯一一个实例就是如此。

输出在HTML属性中

我们再来看第二种情况:输出在HTML属性中的:

源代码如下:

****************************************************************

[zhangyongqiao.pt@search041125 htdocs]$ cat test3.php

<?php

echo "<a href=\"".$_GET['name']."\">enter</a>";

?>

[zhangyongqiao.pt@search041125 htdocs]$

****************************************************************

这段代码大概的意思就是返回一个带有超链接的字段“enter”,超链接的内容需要自己赋值。我们访问一下页面,然后对这个页面做手工注入:

注入的脚本为:

http://10.232.41.125:8713/test3.php?name=test">hi</a><script>alert(1);</script><!--


 返回的页面源代码如下:

****************************************************************

<a href="test">hi</a><script>alert(1);</script><!--">enter</a>

****************************************************************

通过分析这段脚本看出,首先用下引号对属性name赋值的闭合,然后是对a标签做了一次闭合,最后再进行脚本注入就ok了。当然,这里会发现后面的脚本">enter</a>这段会遗留下来,其实是否对它做屏蔽是无关紧要的。有兴趣的孩纸可以试一下。因为关键代码已经被解释出来了,不影响注入,这里注释掉是从实战出发,为了不在页面注入的时候留下痕迹。

(别忘了,还有个enter会输出哦~

 

输出在JS代码中

下面是第三种情况,输出在js中的

****************************************************************

[zhangyongqiao.pt@search041125 htdocs]$ cat test4.php

<?php

echo "<script>";

echo "var yourname =".$_GET['name'].";";

echo "</script>";

?>

[zhangyongqiao.pt@search041125 htdocs]$

****************************************************************

这块内容的主要是UED的孩纸们在写JS的时候会遇到,当对name这个变量做赋值的时候,就会存在跨站,

注入脚本如下:

http://10.232.41.125:8713/test4.php?name="a";alert(1);</script><!--


同上面的2个例子一样,这里对"var yourname =".$_GET['name'].";";这段代码做了各种闭合,得到的html源文件如下:

<script>var yourname ="a";alert(1);</script><!--;</script>

首先是闭合了赋值语句,然后输出注入脚本,最后注释掉了分号。当然,最后一个闭合js的标签是不会被HTML解释出来的。

 

以上的三种注入虽然出现的场景不一样,但是仔细研究就会发现重现的方式与HTML的源码回显等等都是类似的,最后一种出现场景比较特殊,待我们细细来看:

基于DOM

引用一段师姐的话:

DOMDocument Object Model的缩写。据W3C DOM规范,DOM是一种与浏览器,平台,语言无关的接口,使得你可以访问页面其他的标准组件。 

DOM认为是JavaScript输出的页面,基于DOM的跨站脚本漏洞就是出现在JavaScript代码中的漏洞。请注意,之前的3种输出是属于Web应用程序(CGI程序)代码中的漏洞。 

然后我们再来看实例:

****************************************************************

[zhangyongqiao.pt@search041125 htdocs]$ cat test5.php

<script>

document.write(window.location.search);

</script>

[zhangyongqiao.pt@search041125 htdocs]$

****************************************************************

先解释一下这段代码,window.location.search,这个函数的意思就是返回url中非文件部分的内容,也就是url从问号开始之后的所有内容。

这里解释一下url中的第一个问号的作用:

Get请求有如下特性:它会将数据添加到URL中,通过这种方式传递到服务器,通常利用一个问号?代表URL地址的结尾与数据参数的开端,后面的参数每一个数据参数以名称=的形式出现,参数与参数之间利用一个连接符&来区分。 

 

那么我们就可以邪恶的利用这个函数对页面进行注入了。我们看到如下效果:

 

但是,神奇的是,我们查看页面的源代码

****************************************************************

<script>

document.write(window.location.search);

</script>

****************************************************************

页面里面并没有回显那些被注入的脚本,因此,这个地方我们在开发的时候需要重点关注,对于window.location.search的理解应该是页面中windowlocation对象中封装的一个search属性。只能深入到这里了。具体的还是要找一个专业写JS的孩纸来剖析。

 

POST请求的XSS

讲了这么多的xss的注入场景,这些场景有一个共同点,就是他们都属于GET方式的请求,那么试问POST的请求就不能进行注入吗?

当然可以。

在此之前,还是要重申一下getpost的区别。这里直接借用网上比较犀利的一段解释:

1. get是从服务器上获取数据,post是向服务器传送数据。

2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。

3. 对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。

4. get传送的数据量较小,不能大于2KBpost传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KBIIS5中为100KB

5. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。

建议:

1get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;

2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式;

 

这里基本上已经说的非常之全了。那么对于稍微安全一点的请求方式,我们怎么来进行手工注入呢?惯例是先看脚本:

****************************************************************

[zhangyongqiao.pt@search041125 htdocs]$ cat index.php

<?php

echo "sa, ".$_POST['name'];

?>

[zhangyongqiao.pt@search041125 htdocs]$

****************************************************************

对比一下最开始的那段脚本,只是简单的把get请求换成了post请求,怎么注入呢?别急,咱们有工具。这里推荐一个强有力的模拟post请求发送的firefox插件hackbar,效果如下:

 

我们所要做的就是在load url的位置写上访问的地址,然后在post data的位置写上我们要传送出去的数据,最后点击execute就可以了。最后得到的效果就和get的相同了。

得到页面源代码如下:

sa, <script>alert(1)</script>

有人要问,那我如何去获取这些post请求对应的参数呢?在chromfirefox中都带有请求截获的工具,firefoxhttpfoxfirebug都有这个功能,而chrom的控制台也有这方面的功能。

实战XSS

攻击篇

我们从开发者写代码的角度对XSS做了一个简单的剖析,那么如果真的遇到XSS漏洞了,我们怎么去寻找和注入呢?

接下来我们就来简单的演示一下如何去寻找一个漏洞和“攻击”一个网站。(这里只做测试,不做恶意破坏。)

先来一个准备工作,如此庞大的互联网,如果要对网站做手工检测,当然整个人直接就崩溃了,所以我们用一个轻量级可随身携带的安全扫描工具webcruiser,利用这个工具找到网站的漏洞比起手动探索性测试效率高多了。具体工具的使用方法大家还是看说明书吧,在这里不多做介绍,首先找到一个目标网站(出于道德,这里还是不把具体的网站给写出来了)

1.首先扫描出那些安全漏洞。

 

然后我们复制含有可注入点的url

当我们访问这个网页的时候,发现网页上有一个可以输出的编辑框

 

在编辑框中输出一些有区分度的字符串,提交搜查请求,

我们得到一个返回结果页,这时候我们查看源文件,在源文件中搜索aaaaaa字符串,

 这时候我们在页面中得到了如下返回情况

<td width="180" align="left"><input type="text" name="key" id="key" value="aaaaaa" size="26" οnfοcus="this.select();"></td>

这下大家应该都明白了吧。这种场景就是存在在html属性的xss漏洞。我们需要做的就是在字符串后面将input标签闭合,然后写入脚本即可。马上来动手试试吧。

修改请求串如下:aaaaaa"/><script>alert(1)</script>


 

 

防御篇

学习安全当然不是为了去攻击网站了,我们是好孩纸啊,那么我们来看一下如何预防这类攻击呢?太简单了,只要对脚本做转译就可以啦。

我们拿最后的那个post的例子来看,修改脚本如下:

****************************************************************

[zhangyongqiao.pt@search041125 htdocs]$ cat index.php

<?php

$n="sa, ".$_POST['name'];

echo htmlspecialchars($n);

?>

[zhangyongqiao.pt@search041125 htdocs]$

****************************************************************

我们利用htmlspecialchars对在html中输出的脚本做转译,当然当输出的是url的时候,php还提供了类似的函数。

然后我们再进行一次XSS注入:

 

如此脚本已经完全被转译,同时能够正常输出啦。也就是说页面没有翻译这些脚本,那么函数到底做了什么呢?我们看一下html源文件:

sa, <script>alert(1)</script>

好了,这下知道了吧,函数仅仅是将特殊符号做了转译。

其他

最后的最后,在写上面这些脚本做尝试的时候,需要对自己PHP的配置文件做一个小修改:

 magic_quotes_gpc:这是在PHP中一个特殊的函数魔术函数,它在引用的过程中只有在传递$_GET,$_POST,$_COOKIE时才会发生作用。 magic_quotes_gpc=on 将单引号转换为\’,所以大家在编码的时候记得配置一下。不然第三个脚本是不能重现的。 其他几个脚本不会有影响。

【有人说那么这不就是一个php安全过滤操作的一个函数吗?当然是,但是由于这个函数的很多局限性,如在对数据库写操作的时候,对字符串做一些转译,导致很多类似操作都变的很麻烦,所以一般的开发人员都会将这个值给off了,然后自己重写一个类似的函数】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值