1.概念
全称是CSRF 跨站请求伪造攻击,攻击者利用用户已登陆的账号,诱导用户访问已构造好的恶意链接或页面,在用户不之情的情况下,做一些违反用户本意的一些违法操作。
同源策略:协议相同,域名相同,端口相同。(三者缺一不可)
判断一下两个ip是否同源?
http://www/baidu.com
https://www.baidu.com
不同源,因为协议不同
http 协议明文传输,端口80
https 协议密文传输,端口443
判断以下两个ip是否同源?
http://www.langyangyang.cn
http://www.langyangyangwoaini.cn
不同源,域名不同
什么是跨站?
两个不同源的网站互相访问,就是跨站
使用javascript 通过一个技术jsonp实现,只能发送跨站发送get请求。
通过跨站请求资源共享来实现。
2.CSRF攻击流程
跨站请求伪造攻击的案例
1.懒羊羊点击访问http://bank.com向服务器发起请求
2.服务器返回登陆的页面
3.懒羊羊输入账号密码,点击登陆,提交到服务器
4.服务器端进行数据库的查询,进制账号密码的验证,通过验证后将用户的的信息保存到SessionID中,并返回给浏览器操作页面和,SessionID(只要用户登陆成功都会返回一个SessionID)
5.此时浏览器就会把操作页面返回给懒羊羊了,有查询,转账等一些功能。(此时的SessionID就保存到了 浏览器的Cookie当中)
6.假设现在懒羊羊要进行查询余额的操作 ,那么点击余额的这个按钮时,就相等于在给银行发起查询余额的请求,此时这个请求就会携带的在Cookie中的SessionID
7.服务器接受到这个请求查看是否有SessionID,如果存在SessionID的话,不用再次进行验证 ,
直接执行相关的操作,没有的话重新登陆
8.此时突然页面弹出来 了一个小窗口,非常的有吸引力。
9.此时的懒羊羊接受不了诱惑点击了进去,进去到了一个
http://yule.com的视频网站
10.此时懒羊羊看了一会之后,突然又弹出来了一个窗口,让懒羊羊对这个网站进行评价,或者其他操作,并且要点击提交 按钮,否认不让懒羊羊在进行观看!
11.懒羊羊觉得这个视频太上头了 !!还想继续看,就点击了提交的按钮,并且没有在银行的网站中点击用户退出的操作,此时这个发送的按钮就带着Cookie的数据,其中就包含了SessionID一起发送给了银行服务器
12.此时服务器收到了请求,由于又SessionID,就无需在进行验证 登陆,直接执行了转账的操作
13.此时懒羊羊回到了页面,又查看了直接的余额,突然发现余额清零了?
1.为什么懒羊羊的账号余额清零了?
因为SessionID,SessionID表示了个人的身份,所以不会在进行检查
2.何为跨站?
因为这个请求是http://www.yule.con这个网站,将请求发给服务器的,属于跨站了,
因为他不属于本地内部的网站发送的,所以他一般是由攻击者构造好的,向银行发送的
3.何为伪造?
这并不是懒羊羊的本意,懒羊羊并没有要进行转账的操作。但是为什么能够成功。
因为他点击了攻击者的链接或者页面,但是这个恶意的请求是向银行服务器发起的,因为懒羊羊没有在访问这个恶意链接前,没有退出自己的账号,所以还存在的Sessionid,所以当懒羊羊,点击了提交按钮的时候,这个请求就带着SessionID一起发送了,此时的银行服务器,也不知道是不是懒羊羊本人,银行卡的服务器只认SessionID,只要检查出你有这个SessionID那么银行的服务器就会执行这个操作,伪造在于使用的是懒羊羊账号的SessionID,以懒羊羊的身份进行了转账的操作
如何解决:
退出用户账号,如果点击了用户退出,就会删除Cookie当中的SessionID
补充:
SessionID在用户没有退出之前不会发生变化
在用户退出登陆后,再次重新登陆SessionID会发生变化
3.基于pikachu靶场的CSRF实验
3.1CSRF(GET)
使用BP进行抓包
修改数据,开始BP进行拦截抓包
1.BP拦截到的GET请求数据包
GET请求数据包
GET /pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=girl&phonenum=111111111111&add=nba%2Blakesk&email=K%40KK&submit=submit HTTP/1.1
2.根据GET请求的数据包,构造恶意链接(掐头去尾)
不包含前面的GET请求和后面的协议
http://127.0.0.1/pikachu/vul/csrf/csrfget/csrf_get_edit.php?
sex=boyl&phonenum=88888888&add=nba%2Blakesk&email=K%40KK&submit=submit
为啥叫恶意链接?
因为我把里面的数据给修改了,可以看到我把sex的属性改成了boy,phonenum改成了8888888
假设一下
如果这个数据包是银行的数据包,如果在这个抓取到的数据包1代表的是查询,2代表的是转账
,我们把1修改成了2,本来用户要执行的是查询的操作,我们就修改称为了转账
3.将这个恶意链接发送给kobe诱导他点击该链接(修改成功的前提是用户没有退出,只要没有退出,那么这个执行的操作就会成功)
4.在同一个浏览器中执行这个操作。(不能在别的浏览器,因为没有SessionID)此时可以看到sex的性别就修改成boy了,意味着修改成功了
小扩展
GET请求和POST请求的区别是什么
GET请求的参数以查询字符串的格式通过URL传递。传递的数据量一般较小,而且不安全。
POST请求的参数可以放到请求包的包体中传递的。如果不使用抓包软件,一般看不到,相对安全。传输的量相对大一些
1.如果发送GET请求?
1.1浏览器输入网址,回车(这一定是GET请求)
1.2使用超链接a标签,href ="url"。发送的请求也是GET请求
1.3使用form表单,method属性设置的是GET
1.4编程使用request。GET函数发送的请求
2.如何发POST请求 HTML表单(自己写给html表单发送请求)
2.1使用form表单,method属性设置的POST
2.2编程使用request。POST函数发送的请求
3.2CSRF(POST)
1.使用BP进行抓包
修改数据,开始BP进行拦截抓包
可以看出改用户信息是通过POST发送的,信息在请求体中呈现
拿信息
/pikachu/vul/csrf/csrfpost/csrf_post_edit.php
……
sex=boy&phonenum=88888888888&add=nba%2Blakesk&email=K%40KK&submit=submit
2.根据抓取信息,构造恶意链接。如何构造?
如何构造POST请求?
通过表单提交数据时,提交的方法,可以选择GET或POST。所以在页面要使用form 表单
提交给谁?action:http://127.0.0.1/pikachu/vul/csrf/csrfpost/csrf_post_edit.php
数 据 : sex=ryao&phonenum=0000000000&add=nba%2Blakesk&email=K%40KK&submit=submit
<body>//改页面被加载,按钮自动执行单击事件//向http://127.0.0.1/pikachu/vul/csrf/csrfpost/csrf_post_edit.php//发送sex phonenum add email等信息<form action="http://127.0.0.1/pikachu/vul/csrf/csrfpost/csrf_post_edit.php" method="post"><input type="text" name="sex" value="ryao"><input type="text" name="phonenum" value="6666666666"><input type="text" name="add" value="nba+lakes"><input type="text" name="email" value="kobe@@@@@"><input type="submit" name="submit" value="submit" id="postsubmit"></form><script>//页面窗口加载解析完成后,马上调用这个匿名函数window.onload=function(){// 根据id元素的方式,获取控件的id,获取提交按钮,调用他的click方法.相当于自动点击该按钮document.getElementById("postsubmit") .click();}</script>
3.诱使客户点击刚刚所完成的html文件,该文件被加载,自动向链接,http://127.0.0.1/pikachu/vul/csrf/csrfpost/csrf_post_edit.php,,
以post的请求发送
修改成功
4.如果客户此时点击了退出登陆,那么则无法借助客户身份修改信息
如何在用户没有退出登录的情况下,依然可以防范CSRF问题
3.3CSRF防御-csrf_token(令牌)
基于pikachu靶场的csrf_token的演示
1.查看页面源代码
2.可以看出与之前的GET和POST不同的是在源代码中添加了token
3.查看Token的值,这个值是服务器返回给修改用户页面时,由服务器提交给浏览器的
如果你在正准备进行一个操作,比如你要进行修改资料,那么当你点击修改资料的按钮 时,会向服务器发起请求,服务器此时会返回一个token,在你提交修改资料后的按钮时,这个token会和你携带的请求一起发送给服务器,服务器先 验证Token。然后在处理请求。
注意:token是一次性的,每次都不一样。可以 刷新这个编辑页面查看这个token的值
可以看出和之前的token发生了变化
4.使用BP抓包 ,拦截数据。比csrf-get多了一个Token
5.将起始行的信息复制到一个文本中存储下来
GET /pikachu/vul/csrf/csrftoken/token_get_edit.php?sex=ryao&phonenum=66666666667&add=nba%2Blakes&email=kobe%40%40%40%40%40&token=3786763925f300bb0e594689612&submit=submit HTTP/1.1
6.根据GET请求构造恶意链接,完整的带参数的URL(掐头去尾)
http://127.0.0.1/pikachu/vul/csrf/csrftoken/token_get_edit.php?sex=bianxingren&phonenum=644444444444&add=nba%2Blakes&email=kobe%40%40%40%40%40&token=3786763925f300bb0e594689612&submit=submit
7.将恶意链接发给用户,诱使他 点击链接(即使用户没有退出,依旧会修改失败)
8.在同一个浏览器中执行这个操作,此时如果sex性别和phonenum没有被修改,说明Token起作用了
页面:没有改变修改失败
小扩展:
Token是怎么来的?谁给浏览器的?
Token是服务器给的(开发人员编写的,在服务器端生成,并返回给浏览器的),所以当用户修改数据后,提交给服务器,服务器可以验证Token是否正确
为什么我有了Token依旧提交失败?
因为 Token值是一次性的,生成了新的Token旧的Token就不能用了
如果把Token值给改了,还会执行吗?
不会。如果改了话,服务端就不认这个Token了,哪怕你只修改一个数据都不认了,
如果把Token值给改了就不会让你修改了,即使你是内部的页面(自己)也不能进行修改了,相当于你自己把令牌给改了,变成假的了,就连你正常的功能也屏蔽了
有解决Token提交失败的方法吗?
有的。在Token还没有提交前,就截取他的Token去使用,那么就可以成功。
举个例子:比如说我们要进行一个操作,但是我们在还在进行操作的时候,没有确定提交操作,
此时的Token就是还没有使用的,只要攻击者在用户完成操作前,截取掉用户的Token去操作使用,那么就可以提交成功