CSRF (Cross-site request forgery,跨站请求伪造)也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而**CSRF则通过伪装成受信任用户请求受信任的网站****。**简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。它的危害是修改用户信息,并且执行恶意操作
plain
CSRF和XSS区别:
最大的区别就是 CSRF没有盗取用户的Cookie,而是直接的利用了浏览器的Cookie让用户去执行某个动作,XSS可以执行恶意js代码盗取到cookie
CSRF是借用户的权限完成攻击,CSRF攻击者并没有拿到用户的权限,而XSS是直接盗取到了用户的权限 ,然后实施破坏。
攻击原理
1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
2.在用户信息用过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
3.用户未退出网站A之前,在同一浏览器中打开一个TAB页访问网站B;网站B是我们构造的CSRF利用页面
4.网站B接受到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;
5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
glsl
CSRF模型:
1.用户登录受信任网站A 并在本地生成cookie
2.在不登出A的情况下 访问危险网站B,危险网站的权限是用户自己去赋予的
漏洞验证
plain
1.检测CSRF漏洞是一项比较繁琐的工作, 最简单的方法就是burp抓取一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本上可以确定存在CSRF漏洞。
2.随着对CSRF漏洞研究的不断深入,不断涌现出一些专门针对CSRF漏洞检测的工具,若CSRFTester,CSRF Request Builder等。
添加信息
删除信息
修改信息
一切可执行的地方,并且没有进行二次验证码和token验证的地方,就有可能存在CSRF
防御CSRF
CSRF产生的根本原因是用户请求的所有参数和参数值都是可以被预测的,也就是说攻击者想要构造出一个伪造请求,必须要知道这个请求中所用到的所有参数和参数值, 我们防御的形式就是在在用户请求的数据中加入一个 "不可预测的因子" 从而使攻击者无法构造出一个完整的请求,保证其随机性( 通过当前时间戳生成随机数 )也就是Token
目前防御有三种策略
1.验证HTTP Referer字段;
2.在请求地址中添加token并验证;
3.在HTTP头中自定义属性并验证。
验证码
验证码是CSRF攻击最简单有效的方式,它要求用户在每次操作时都输入一个验证码,通过强烈用户进行交互的方式防止用户在不知情的情况下方式网络请求,也可以是清除Cookie但是这样的话用户体验感会很差,谁也不希望每进入一个东西就要重新验证登录一遍,因此这个只能作为CSRF辅助手段,在集中特殊操中进行,如注册 登录
参数加密
参数加密也是一个"不可预测" 因子的好方法,顾名思义就是对用户请求中的某些参数进行运算和加密处理,从而使攻击者无法构造出正确的参数值
cypher
未加密:
http://www.mybank.com/Transfer.php?toBankId=11&moeny=1000
加密:
toBankli参数值改为哈希值方式即可有效防御CSRF攻击
http://www.mybank.com/Transfer.php?toBankId=md5( salt+11 )&money=1000
加密后攻击者是不知道salt的情况下是无法构造出这个URl, 服务端获得的方式是在服务器的Session,Cookie中取得toBankid=11
的值然后进行对比,然后结合salt将用户请求的数据进行对比,如果相同则被认为是合法的
但是这种方法还是不太有效,因为会也用户体验的问题,加密后的URL变的难懂,加密后无法统计,如果每次加密参数都改变,那么用户无法收藏这类url
Token
与验证码的方法类似,Token的方法是在用户提交的参数之前再添加一个伪随机数Token,这个对用户来说是透明的,不会降低用户体验
cypher
http://www.mybank.com/Transfer.php?toBankId=11&money=1000 &Token=[randomseed]
注意:
Token必须要做到足够随机,即使用足够安全的随机数生成算法,才能保证攻击者无法预测
Token必须由用户和服务器共同管理不能被第三方获知 最常见是讲Token放在用户的Session或Cookie中,但是这种保存方法是简历在Session和Cookie
不会被攻击者获知下才有效,如果网站同时存在XSS,那么攻击者完全可以盗取Cookie,那么这种防御就失效,这种利用XSS漏洞来进行CSRF攻击的过程成为 XSRF
寻找CSRF
分析burp抓取数据包: 数据包的几个关键字段,是否根据cookie来判断数据包,请求可以伪造,判断CSRF重点在于请求是否可以伪造 ,csrf
就是让你执行当前的一条微信请求
java
检查:
Referer
Auth
CSRFthken
一个安全的请求是:一个随机的token,一个旧密码验证这些我们无法获取到的
只要我们使用burp进行抓包,去去除Referer:http:.//baidu.com 以及token=,还可以正常发送响应,那么就存在CSRF 否则不存在,因为只要去除了我们就可以自己构造,可以伪造我们想要的请求
蠕虫CSRF
通常XSS如果是存储型的蠕虫传播(自动修改个人简历)也是使用GET 和POST 进请求来完成的,如果这个请求不存在CSRF 那么也就无法进行传播
这也是漏洞组合拳的概念,通过一种漏洞引导使用到另一种漏洞,两个漏洞结合起来危害就很大了,
📌CSRF蠕虫构造起来也更加简单,但是XSS是完成静默传播(利用存储型)而CSRF蠕虫则需要用户点击,也就是主动式。就是要诱使用户点击CSRF代码的链接,这需要用到一些社工技巧
案例
百度空间的互关好友发送消息没有任何限制的,百度程序员在实现短消息功能时使用的是$_REQUEST类变量传参 给攻击者的CSRF漏洞提供了方便
cypher
内推请求百度用户中心发送站内的短消息功能是通过一个GET请求实现 如下
http://msg.baidu.com/?ct=22&cm=MailSend&th=bmSubmit&sn=用户账号&co=消息内容
该请求没有做任何的安全限制, 只需指定sn参数为发送消息的用户账户,co为消息内容,就可以实现给任意用户发送指定消息
百度空间获取好友数据的功能也是通过 GET 请求来完成 如下
http://frd.baidu.com/?ct=28& un =用户账号
&cm=FriList&th=bmABCFriList&callback=gotfriends
此请求通常也是没有任何的安全限制,只需将 un 参数设定为任意用户账号,就可以获得指定用户的百度好友数据
利用这两个漏洞可以实现一个完全由客户端脚本实现的CSRF蠕虫,这个蠕虫实际上就是一条链接,受害者单击后就会自动将这条链接发送给所有好友
详细代码见: web安全攻防71页
漏洞条件
plain
1.被害用户已经完成身份认证
2.新请求的提交不需要重新身份认证或确认机制
3.攻击者必须了解Web APP请求的参数构造
4.引诱用户触发攻击的指令(社工)
CSRF攻击利用
根据请求分为 : get类型CSRF post类型CSRF本质就是在不知情的情况下执行请求
DVWA密码修改
java
这是一个修改登录密码的get请求,密码为123123 我们将包抓取
我们将抓取的请求进行模拟,我们在网页上插入了链接,现在演示的是DVWA靶场,登录密码为password,在这个修改页面修改为123123
我们通过模拟网页拿到请求可以将我们登录密码设置为我们想要的密码
在这里修改为了00saber,使用img懒加载到网页中
<1img src="http://localhost///DVWA-master/vulnerabilities/csrf/?password_new=00saber&password_conf=00saber&Change=Chang">
java
这里我们也可以不使用img标签自己构造请求,结合burp自带功能抓取包后生成Poc字段进行攻击
我们模拟页面将重新设置密码的请求发送过去,在html中img是会自动加载,那么我们就会更改了用户的密码
将原先的登录密码password设置为了我们的ss123123包括密码(演示目前密码为00saber)
java
现在靶场原先的
username : admin password: saber
重发请求修改后
username : admin password: 00saber
修改完后之前的密码不能登录进去了,这 样就完成了我们的一个修改密码的请求,通过抓取到链接,将密码重置后再发送给浏览器完成,我们使用重置发送的密码进行登录
抓包修改信息
我们进入合天网安实验室登录后进入个人中心
我们进行学号修改,然后使用burp进行包的抓取
进入到重发器后我们修改发送,没有显示违规可以正常发送就存在CSRF,但是CSRF还是需要敏感信息,不是敏感信息的也就没用
总结:攻击步骤分为: 抓包知道请求----构造这个请求html----给用户打开
http://burpsuite/show/11/w13i4gezubi4bfb7nii3uekay0ftpxgw
注意
cypher
命令执行成功的前提是用户必须通过路由器的认证,拿到对应的Cookie 但如果Cookie失效,但通常用户不会登录到路由器上,甚至一年都不会
但是发现登录路由器 也是一个GET,可以伪造这种请求登录到路由器拿到正确的Cookie,伪造用户登录拿到真是Cookie 再执行攻击
<img src=http://admin:admin@192.168.1.1>
但是前提是路由器使用的是默认的密码以及默认的管理地址。如果用户修改了的话那么这样的攻击就无法奏效
GET型请求 CSRF
get类型的csrf利用非常简单,只需要一个http请求,一般会这样利用
java
<img
src:"http://bank.example/withdraw?amount=10000&for=hacker">
POST型请求CSRF
java
POST型利用起来只需要一个自动提交的表单
<from action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming"/> name为参数 value为参数的值
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
<script> document.tormsl0l.submlt(); </scrlpt> 自动提交表单
Poc生成
我们修改请求from比较麻烦,在burp上有小功能可以使用
java
通过右键进行相关工具使用CSRPoc生成就可以得到我们的html代码
java
我们可以选择复制html也可以使用浏览器测试,会自己生成一个链接我们使用浏览器访问即可
随便进入到个人信息修改页面,一个个填写完所有需要的信息后 打开bp抓取到修改的包
直接右键点开生成CSRF的POC
直接生成POC
即可,不用很多复杂操作,然后复制到本地HTML
文件,生成后打开,HTML文件我们的用户信息就会修改
另类CSRF
jsonp-读取类 CSRF
JSONP是通过script 标签加载数据的方式去获取数据当做JS代码来执行提前在页面上声明一-个函数,函数名通过接口传参的方式传给后台,后台解析到函数名
后在原始数据上 [**包裹」这个函数名,发送给前端。换句话说,JSONP需要对应接口的后端的配合才能实现。要注意 JSONP只支持GET方式的请求,不支持
**POST请求
java
script标签可以加载其它域下的js ,我们可以利用这个特性实现从其它域下获取数据。 通过<script src="http://127.0.0. 1:8080/getNews"> </script>
这时会向接口发送获取数据,获取数据后作为js来执行。但是这个数据是JSON格式的,直接作为js运行的话如何去得到这个数据去操作呢?这时候我们可以在
src后面加上一-个回调函数showData 。 <script src="http://127.0.0. 1:8080/qetNews ? callback= showData"> </script>
jsonp是修改 ca llback= showData">,数据会双向修改 只有敏感信息才会收取这种漏洞
cors-读取类CSRF
cors全称是跨源资源共享,是一种ajax跨域请求资源的方式,支持现代浏览器,IE支持到10以上,cors的实现方式很简单,当使用XMLHttpRequest发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头: Origin ,后台进行一系列处理,如果确定接受请求则在返回结果中加入一个响应头:Access-Contro-Allow-Origin; 浏览器判断请求头是否有Oringi的值,如果有那么处理响应,我们就拿到数据,没有就直接驳回我们无法拿到数据
注意
加入的响应头:Access-Contro-Allow-Origin 是在对方网站存在,对方网站如果不存在这个字段那么自然这个数据也就拿不到了,说明这个网站不允许其他网站来加载里面的数据寻找这类cors在于观察字段是否有Origin,响应后是否有其相对应的数据发生变化
漏洞成因
java
在配置了cors的前题下,当你登录网站A ,并跨域访问网站B的时候,浏览器判断你的操作是跨域,这时候会在数据包
里面手动加个origin字段,内容为: origin:b.com ,这样你就能跨域 了,当cors的配置错误时就会产生cors漏洞, 我们就自己读取里面的数据再发送给浏览器,这样就可以得到数据 ,
如果网站中存在了cors漏洞,那么就可以获取用户的任意的信息,只要我给你发一个html我就可以获取到你的个人信息
实例
准备了一个接口里面也含有数据,我们请求这个接口
token referer对比
横向对比,谁安全等级高?
📌token安全等级更高,因为并不是任何服务器都可以取得referer,如果从HTTPS跳到HTTP,也不会发送referer。token的话,要遵守不可预测性原则,保证其随机性( 通过当前时间戳生成随机数 )
referer验证,从什么角度去做?怎么杜绝问题
📌对header中的referer的验证,一个是空referer,一个是referer过滤或者检测不完善。 为了杜绝这种问题,在验证的白名单中,正则规则应当写完善。
token,对token测试会注意哪方面内容,会对token的哪方面进行测试?
plain
针对token的攻击, 一是对它本身的攻击,重放测试一次性、分析加密规则、校验方式是否正确等 ;
二是结合信息泄露漏洞对它的获取,结合着发起组合攻击;
信息泄露有可能是缓存、日志、get,也有可能是利用跨站;
很多跳转登录的都依赖token,有一个跳转漏洞加反射型跨站就可以组合成登录劫持了
注意:
cypher
命令执行成功的前提是用户必须通过路由器的认证,拿到对应的Cookie 但如果Cookie失效,但通常用户不会登录到路由器上,甚至一年都不会
但是发现登录路由器 也是一个GET,可以伪造这种请求登录到路由器拿到正确的Cookie
<img src=http://admin:admin@192.168.1.1>
但是前提是路由器使用的是默认的密码以及默认的管理地址。如果用户修改了的话那么这样的攻击就无法奏效