简介

CSRF(Cross-Site Request Forgery,跨站请求伪造),特通过伪装成网站内收信任的用户请求受信任的网站,他和xss漏洞不一样,xss漏洞是通过攻击站点内的信任用户,因为csrf相对于xss没有那么流行,所以防范资源也相对稀少,所以被认为csrf相比xss的危险性更大。

原理

攻击者预测出了url的重要参数值,以此来伪造一个url请求

1
2
3
4
5
6
7
8
9
10
11
##受攻击流程

user1使用账号密码访问网站A
网站A接受账号密码后在user1浏览器中存储了sessionID
网站在没有退出网站A时新建一个页面访问了网站B
网站B自动触发访问网站A(有指向链接指向网站A)
此时user1是带着sessionID访问网站A的
此时网站A只需检验sessionIlD是否合法,合法则执行相应的操作。(因此具体啥工具就得看链接,以及网站B要求访问时携带的数据)

##示例
当你想再A网站给某个用户转账100元,那么单击"转账"按钮后,发出的http请求大概是"pay.php?user=xx&money=100"类似,此时攻击者在B网站构造链接"pay.php?user=hack&money=100",当用户没有退出A网站访问B网站并点击该链接就会导致你向攻击者账户转账100元,但这只涉及用户的操作,攻击者并没有获取用户Cookie或其他信息
1
2
3
4
##受害者被危害的前提

受害者登录受信任网站A,在本地生成cookie
受害者在不登出网站A的前提下,访问攻击网站B(或访问了攻击者构造的URL)

攻击流程

csrf攻击一般需要两个网站,这里用pikachu靶场演示攻击流程,我们用提示的账号密码来充当账户A,我们是攻击者B,pikachu靶场的post关比较符合攻击流程。

首先账户A在http://192.168.236.129:8084/vul/csrf/csrfpost/csrf_post.php登录。

可以看到报文是明文显示的,可以预测,正常的攻击流程需要一个可以被访问的攻击网站,这里我们就用一个有相关html页面的机器替代,之后将链接发给账户A点击http://127.0.0.1:81/csrf.html,实现修改信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<html>
<script> <!-- 这个script是用来自动提交表单的 -->
window.onload = function() {
document.getElementById("submit").click();
}
</script>
<body>
<form action="http://192.168.101.16/pikachu/vul/csrf/csrfpost/csrf_post_edit.php" method="POST">
<input type="hidden" name="sex" value="girl" />
<input type="hidden" name="phonenum" value="12345678922" />
<input type="hidden" name="add" value="usa" />
<input type="hidden" name="email" value="[email protected]" />
<input type="hidden" name="submit" value="submit" />
<input id="submit" type="submit" value="Submit request" style="display:none"/> <!-- style设置为display:none起到隐藏submit按钮的作用 -->
</form>
</body>

##代码来源:http://t.csdnimg.cn/a4DZu

burp测试csrf

在抓到包后,右键使用csrfpoc生成工具,攻击者可以将生成的html页面放在自己的服务器页面,或者直接用下图的测试链接,在浏览器打开,点击页面上的提交按钮,放包,之后发生页面跳转,之后会发现跳转的页面为更改完信息的页面,csrf利用成功。

修复手段

1.使用CSRF令牌

1
2
3
4
5
生成令牌:为每个用户会话生成一个唯一的CSRF令牌。这个令牌应该是随机生成的,并且与用户会话相关联。

嵌入令牌:在表单中嵌入这个令牌(通常在隐藏字段中),或者通过HTTP头传递。例如,使用`<input type="hidden" name="csrf_token" value="令牌值">`。

验证令牌:在服务器端验证每个请求中的令牌。如果令牌无效或者缺失,则拒绝请求。

2.使用SameSite Cookie属性

设置SameSite

:在设置Cookie时,使用SameSite属性来限制Cookie的跨站点请求。可以设置为Strict(仅在同一站点上发送)或Lax(在某些情况下允许发送)。

1
CodeSet-Cookie: sessionId=abc123; SameSite=Strict

3.验证HTTP Referer或Origin头

1
2
3
检查Referer头:验证`Referer`头或`Origin`头是否来自合法的来源。注意,这种方法并不是绝对可靠,因为`Referer`头可以被伪造或省略。

实施策略:检查请求的来源是否与期望的来源匹配。如果不匹配,则拒绝请求。

4.采用安全的HTTP方法

1
限制方法:只允许特定的HTTP方法(如`GET`、`POST`、`PUT`、`DELETE`)对特定资源进行访问。尤其是对可能修改数据的操作使用`POST`,并确保这些操作有有效的CSRF保护。

5.确保表单和AJAX请求都使用CSRF令牌

1
2
3
4
5
6
7
8
9
10
表单保护:对所有提交数据的表单添加CSRF令牌。

AJAX请求保护:
对所有AJAX请求也添加CSRF令牌。这通常通过设置自定义HTTP头来实现:

javascriptCopy Code$.ajaxSetup({
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});

6.保持系统和库的更新

1
应用补丁:确保你使用的框架和库都保持最新状态,因为更新通常包含了安全修复。

7.使用安全框架和库

1
框架支持:利用现代Web框架提供的内置CSRF保护功能。这些框架通常提供了处理CSRF令牌和验证的工具,减少了实现复杂度。

8.教育和审计

1
2
开发人员培训:确保开发人员了解CSRF的风险和防护措施。
代码审计:定期进行代码审计,以确保CSRF保护措施得以正确实施。