朴素的CSRF漏洞

基本概念

什么是CSRF(xsrf)

CSRF,跨站请求伪造,是一种对网站的恶意利用。尽管听起来像跨站脚本,但它与XSS非常不同。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

CSRF的危害:

以受害者名义发送邮件,发消息,盗取账号,甚至于购买商品,转账等
造成的问题包括:个人隐私泄露以及财产安全。

CSRF攻击原理和过程:

1. 攻击原理:

攻击者利用目标用户的身份,以目标用户的名义进行某些非法操作。
CSRF攻击源于WEB的隐式身份验证机制,web的身份验证机制虽然可以保证一个请求是来自某个用户的浏览器,但是无法保证该请求是否是用户批准发送的。

2. 攻击过程:

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
  2. 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
    3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
  3. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
  4. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
    在这里插入图片描述

CSRF漏洞的利用条件

• 目标网站纯在CSRF漏洞
• 目标用户已经登录了目标网站,且能够执行网站的功能,在本地生成了cookie。
• 目标用户访问了攻击者构造的URL。

CSRF漏洞现状

主流的大型网站已经进行了相应的修复,各种中小型网站和后台管理员界面还是普遍纯在这一漏洞。

常见攻击方法:

1. 针对get请求的攻击

如果某银行网站以get请求来完成转账操作如:http://www.mybank.com/Transfer.php?toBankId=attacker&money=1000
攻击者构造网站B,里面写有一段HTML代码:

http://www.mybank.com/Transfer.php?toBankId=attacker&money=1000

如果受害者登录了网站A,然后用相同浏览器访问了网站B,这时你的银行账户就会少1000块。
原因在于:
网站A使用GET请求更新资源。在访问网站B之前,用户已经登录了银行网站A,而网站B中的< img >以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=attacker&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立即执行了转账操作。

2. 针对post请求的攻击

为杜绝基于get请求的攻击,银行决定用post请求完成转账操作。
银行网站A的WEB表单如下:

<form action="Transfer.php" method="POST">
<p>ToBankId: <input type="text" name="toBankId" /></p>
<p>Money: <input type="text" name="money" /></p>
<p><input type="submit" value="Transfer" /></p>
</form>

后台处理页面Transfer.php如下:

<?php
session_start();
if (isset($_REQUEST['toBankId'] &&isset($_REQUEST['money']))
{
    buy_stocks($_REQUEST['toBankId'],$_REQUEST['money']);
}
?>

网站B,仍然只是包含那句HTML代码:
<img src=http://www.mybank.com/Transfer.php?toBankId=attacker&money=1000>
首先登录银行网站A,然后用相同浏览器访问网站B,结果再次丢失1000块,这次事故的原因是:银行后台使用了S_REQUEST去获取请求的数据,而S_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用S_GET和S_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。(dollar符号使用了S代替)

3. 针对$_POST请求方式的攻击

经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:

<?php
session_start();
if (isset($_POST['toBankId'] &&isset($_POST['money']))
{
    buy_stocks($_POST['toBankId'],$_POST['money']);
}
?>

然而,网站B与时俱进,它改了一下代码:

<html>
<head>
<script type="text/javascript">
function steal()
{
      iframe = document.frames["steal"];
           iframe.document.Submit("transfer");
}
</script>
</head>
 
<body onload="steal()">
<iframe name="steal" display="none">
<form method="POST" name="transfer"action="http://www.myBank.com/Transfer.php">
<input type="hidden" name="toBankId" value="attacker">
<input type="hidden" name="money" value="1000">
</form>
</iframe>
</body>
</html>

如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块,因为这里危险网站B暗地里发送了POST请求到银行。
总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个< img >就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。
理解上面的3种攻击模式,其实可以看出,CSRF攻击是源于WEB的隐式身份验证机制,WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的.

修改自:https://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html.

漏洞利用

以DVWA为例,使用BP自动构造CSRF PoC功能实现CSRF漏洞的利用:
在这里插入图片描述

修改密码后,会提示密码修改成功,并返回Password changed。
那么我们刷新网站后重新填入数据,打开代理,使用BP抓取数据包。
将BP抓取到的数据包转至Repeater,然后在Repeater界面 “右键—>Engagement tools—>Generate CSRF POC”,即可生成POC
在这里插入图片描述

再在弹出的CSRF Poc generater页面,点击"Test in browser—>Copy",复制生成的URL

在这里插入图片描述

只要诱骗用户打开这个生成的URL,就可以在用户不知情的情况下将其密码修改为123456。

http://x.x.x.x/DVWA-master/vulnerabilities/csrf/?password_new=123456&password_conf=123456&Change=Change

模拟受害者:
打开刚访问目标网站A的浏览器(注意不能关闭原来登录网站A的TAB页面,此时也不能关闭代理),新建一个TAB页面,粘贴刚才在BP中复制的URL,访问得到如下页面
在这里插入图片描述

点击"Submit request"后,数据会提交到原来的网站A。如果可信任服务器正常响应这个请求,说明漏洞利用成功。
不过,这样的链接就差把“我要盗你号”写在脸上了。为了提高中奖率,我们可以搭一个简单的网站,设置默认打开,这样网站打开后就会默认访问index文件,把index里头的文件换成BP生成的代码,然后给受害者此网站的IP让其访问。如果用户访问了这个链接,那他此页的DVWA密码就被改了。

防御方法

针对CSRF的修复:
服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面添加伪随机数。
• 验证请求的Referer值,如果Referer是以自己网站开头的域名,则说明该请求来自网站自己,是合法的。如果Referer是来自其它网站或空白,就有可能来自CSRF攻击,那么应该使服务器拒绝该请求,但是也存在被绕过的可能。

• CSRF能成功的关键在于攻击者伪造了用户请求。所以,抵御CSRF攻击的关键在于:在请求中放入攻击者无法伪造的信息。比如在HTTP请求中以参数的形式加入一个随机变量token,并在服务器验证token,如果请求中没有token或者token的内容不正确,则认为该请求可能来自CSRF攻击并拒绝该请求。

• 在每次用户提交的时候都让用户填写一张图片上的随机数,也就是验证码。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>