全面解读CSRF

发布时间 2023-08-27 19:34:11作者: zstui

一、简介:

​ CSRF:跨站请求伪造,也称为One Click Attack 缩写为CSRF。

1.1、CSRF与XSS区别:

	XSS   跨站脚本攻击      利用站点内的信任用户盗取cookie

	CSRF 跨站请求伪造攻击   通过伪装成信任用户请求信任的网站
  • XSS需要获取用户的凭证如cookie,然后修改浏览器的cookie等凭证登录网站从而盗取正常用户的账号。
  • CSRF不需要获取用户的凭证,CSRF利用用户在同一浏览器里同时打开多个网页,正常访问的网页的cookie等凭证存储在浏览器里,攻击者伪造一个正常请求的链接,修改关键参数,正常用户点击该链接后通过自己浏览器里存储的正常网站的凭证向网站发出恶意链接的请求。

1.2、具体流程:

  1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

  2. 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

  3. 用户未退出网站A之前,在同一浏览器中,打开一个标签页访问恶意网站B;

  4. 恶意网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求访问第三方站点A;

  5. 浏览器在接收到这些攻击性代码后,根据恶意网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自恶意网站B的恶意代码被执行。

    image-20230826090909659

二、常见利用方式:

2.1、GET型CSRF:

​ 正常访问给test账户转账10元:

http://www.nanhack.com/payload/xss/csrf1.php?name=test&money=10

​ 构建恶意链接给张三转账:

http://www.nanhack.com/payload/xss/csrf1.php?name=张三&money=10

image-20230826092633243

​ referer头有限制,添加referer绕过限制:

image-20230826092934916

2.1.1、4种GET型CSRF构造方式:

1.链接利用
<a href="http://127.0.0.1/csrf.php?name=张三&money=10">csrf</a>

2.iframe利用
iframe标签内容将在页面加载过程中自动进行加载,src指向的位置就是页面请求的位置
<iframe src="http://127.0.0.1/csrf.php?name=张三&money=10" style="display:none"/>
 可以通过设置iframe的 style="display:none"来禁用iframe加载的内容的显示
 
3.img标签利用
<img src="http://127.0.0.1/csrf.php?name=张三&money=10" />

4.CSS-backgroud利用
可以利用CSS中 backgroud样式中的url来加载远程机器上的内容,从而对url中的内容发送http请求列如:
body{
backgroud:#00f00 url("http://127.0.0.1/csrf.php?name=张三&money=10") no-repeat fixed top;
}

2.2、POST型CSRF:

​ 设置一个自动提交的表单,用户点击了该表单的网页后自动提交表单的内容。

<form name="csrf" action="www.nanhack.com/payload/xss/csrf2.php" method="post">
    <input type="hidden" name="name" value="张三">
    <input type="hidden" name="money" value="1000">
</form>

​ 用户点击该网页后自动提交表单,让浏览器认为由用户提交的表单。

2.3、CSRF+XSS:

2.3.1、使用CSRF执行XSS:
1.在恶意网站B中写入CSRF payload,使用这个CSRF来修改用户在A网站的昵称为XSS payload

2.诱惑用户访问恶意网站B,CSRF payload触发,用户在A网站的昵称被修改为XSS payload

3.用户重新访问A网站时,由于右上角显示了昵称,所以会触发对应的XSS payload,就会获取到cookie
2.3.2、使用XSS获取Token进行CSRF:
1.在A网站的URL中构造XSS payload,实现以下功能:
    a.获取本页面的Token值
    b.将Token值赋值给window.name

2.在B网站中插入实现以下功能的JS:
    a.创建一个iframe,并将iframe.src设为上面构造好的带有XSS payload的A网站的URL
    b.写一个function,首先将iframe.contentWindow.location设为任意一个与B网站同源的页面,然后使window.name = iframe.contentWindow.name
        修改iframe.contentWindow.location的原因是:当iframe中的页面为A网站的页面时,与B网站为不同源的,不能将iframe的window.name赋值给当前B网站窗口的window.name。但是我们把iframe中的页面换为与B网站同源的页面时,是可以进行window.name的赋值的。由于window.name的特性,其值本身与网站无关,是窗口的一个值。因此修改页面后window.name并未改变,我们就可以顺利取出了。
    c.将这个iframe销毁 

3.在B网站中插入真正的CSRF payload,带上已成功获取的window.name中的Token值,进行攻击。

三、修复建议:

​ CSRF产生的本质原因:重要操作的所有参数都是被恶意攻击者猜测到的。

3.1、验证码防御

​ 验证码防御被认为是对抗CSRF最简单的而且有效的防御方法

​ CSRF在用户不知情的情况下完成对应操作,而验证码强制用户与应用程序交互,才能最终完成操作。通常情况下,验证码能很好的遏制CSRF

​ 出于用户体验考虑,不可能每一操作都加入验证码。所以验证码只作为辅助手段,不能作为防御CSRF的主要解决方案。

​ 验证码防御也可以被认为是二次验证

3.2、token防御

​ CSRF本质原因:重要操作的所有参数都是被恶意攻击者猜测到的。

​ 生成一个随机且不被轻易猜测的参数。目前大多数防御都采取token。

3.3、referer cherk 防御

​ Referer check主要用于防止盗链。同理也可用于检查请求是否来自合法的"源"。

​ 比如用户修改密码,一定是在登陆系统之后进行操作。所以在修改提交表单的时候,一定会从系统后台提交。携带referer头。如果referer不是当前系统的域,那么极有可能遭受CSRF

​ 缺陷:referer头并不安全,攻击者可以随时构建referer头。

3.4、自定义请求头并验证

​ 不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。