CSRF基础 一、CSRF 漏洞的 CTF 常见题型CSRF的全名是Cross Site Request Forgery翻译成中文就是跨站点请求伪造。 它是一种常见的Web攻击但很多开发者对它很陌生。CSRF也是Web安全中最容易被忽略的一种攻击方式甚至很多安全工程师都不太理解它的利用条件与危害因此不予重视。但CSRF在某些时候却能够产生强大的破坏性。CSRF跨站请求伪造在 CTF 中通常不单独以“弹窗”形式出现而是要求你以受害者的身份完成一项敏感操作例如修改密码修改绑定邮箱/手机账号接管转账、购买商品添加管理员账号删除文章/资源发表特定内容如带有 Flag 的评论题目通常会提供一个机器人Bot或管理员模拟用户当提交链接后Bot 会在已登录状态下自动访问。目标是伪造请求让 Bot 执行预设的操作。二、CSRF 基础利用流程2.1 前提条件目标操作对应的接口已知URL、参数没有有效的反 CSRF Token或者 Token 存在缺陷用户Bot处于登录状态Cookie 不设置SameSiteStrict大多数情况下Lax或None可利用2.2 基本攻击 HTML最常见的 CSRF 攻击页面是一个自动提交的表单htmlbodyformactionhttp://target.com/change_passwordmethodPOSTidcsrfinputtypehiddennamenew_passwordvaluehacked123/formscriptdocument.getElementById(csrf).submit();/script/body/html!DOCTYPEhtmlhtmlheadtitle密码修改/title/headbodyscript// 页面加载后自动提交POST请求window.onloadfunction(){// 目标URLconsturl/change_password;// 创建并提交表单constformdocument.createElement(form);form.methodPOST;form.actionurl;form.style.displaynone;// 添加密码字段constinputdocument.createElement(input);input.typehidden;input.namenew_password;input.value123456;form.appendChild(input);document.body.appendChild(form);// 提交表单form.submit();};/scriptp正在提交密码修改请求请稍候.../p/body/html如果是 GET 请求可以简化为imgsrchttp://target.com/delete?id1styledisplay:none;或者使用window.open、iframe等方式触发。将上述 HTML 托管到服务器或题目提供的“提交页面”并让 Bot 访问即可完成攻击。三、CSRF 防御识别与绕过CTF 中的关键CTF 中 CSRF 题目往往设置了防御需要找到绕过方法。3.1 无防御最简单接口直接通过 Cookie 验证身份没有任何 Token 或 Referer 验证。直接构造表单提交即可。示例修改密码接口POST /user/change_pass参数passwordxxxBot 登录后访问你的页面即中招。3.2 仅校验 Referer/Origin服务器检查请求头中的 Referer 或 Origin 是否为同源。绕过技巧让请求不带 Referer使用meta标签设置referrer策略meta namereferrer contentno-referrer从 HTTPS 向 HTTP 发起请求时浏览器不会发送 Referer但现代浏览器可能有限制通过data:URL 或javascript:协议打开页面部分浏览器不发送 Referer构造同源 Referer如果目标站点存在 XSS 或其它页面可控可以在同源页面发起请求。利用开放重定向漏洞构造 Referer 以假乱真http://target.com/redirect?urlhttp://evil.com/csrf.html访问后 Referer 会包含target.com。Origin 头部绕过某些服务器只验证 Origin 是否存在不验证值或者存在多个白名单域时可利用子域。3.3 存在 CSRF Token 但验证不严格Token 防御是最常见的。绕过方向Token 未与用户绑定服务器只检查请求中是否有 Token而不校验其与用户会话的对应关系。你可以自己在目标站获取一个有效的 Token然后用在 CSRF 页面中。Token 可重复使用有些系统 Token 是固定的如每个用户一个固定 Token获取一次后可以一直用。Token 为空时跳过验证尝试将 Token 参数的值留空或直接删除参数看是否还能通过。使用 GET 方法传输 Token如果 Token 通过 URL 传递容易泄露如 Referer也可以尝试读取。双重提交 Cookie模式如果服务端只验证 Cookie 里的 token 和请求参数/头里的 token 是否一致而不同步校验服务端存储。此时你可以配合任何能设置目标域 Cookie 的漏洞如 CRLF、子域 Cookie 控制来设置一个假的 Cookie然后发起请求时同时发送相同的假 Token。3.4 SameSite Cookie 限制SameSiteStrict完全阻止跨站请求携带 CookieCSRF 无法直接利用除非结合 XSS。SameSiteLax顶级导航top-level navigation的 GET 请求会携带 Cookie。可以利用将敏感操作改成GET 请求前提是网站接受 GET 执行修改操作用a标签诱骗点击a hrefhttp://target.com/change?passwordhackedClick here/a并利用社会工程学让 Bot 或用户点击。使用window.open打开目标 URL。通过表单methodGET提交虽然不常用。SameSiteNone需要Secure此时完全无防御等同于无 SameSite。3.5 特殊 Content-Type 绕过某些后端框架只检查Content-Type是否为application/x-www-form-urlencoded如果不是则拒绝。但我们可以通过表单设置enctypetext/plain尝试绕过虽然参数可能不会被正确解析。还有使用fetch或XMLHttpRequest时可以设置复杂格式但跨域请求中非简单请求会触发预检需要服务器支持 CORS。常规 CSRF 页面通常只发起简单请求。四、CTF 实战场景与步骤场景 1无防御修改密码接口POST /reset_pass参数passwordnewpwd无 Token无 SameSiteBot 每隔一段时间访问提交的链接利用部署如下 HTML 到服务器或题目提供的托管页面formactionhttp://ctf.site/reset_passmethodPOSTinputtypehiddennamepasswordvaluehacked/formscriptdocument.forms[0].submit();/script提交你的链接给 Bot然后使用新密码登录管理员账户拿 Flag。场景 2Referer 绕过利用开放重定向接口POST /admin/delete参数id1检查 Referer 必须包含admin.site.com网站上存在开放重定向https://admin.site.com/redirect?url...构造 CSRF 页面htmlbodyonloaddocument.forms[0].submit()formactionhttps://admin.site.com/admin/deletemethodPOSTinputtypehiddennameidvalue1/form/body/html将上面的页面保存为csrf.html托管然后构造链接https://admin.site.com/redirect?urlhttp://your-server.com/csrf.html当 Bot 访问这个重定向链接时它最终会跳转到你的 CSRF 页面而 Referer 会是admin.site.com然后表单自动提交成功。场景 3Token 验证但未绑定用户修改密码页面存在 Tokeninput typehidden namecsrf_token valueabcd1234但同一个 Token 对所有用户都有效或者不验证 Token 归属。利用方法自己先以普通用户登录目标站打开修改密码页面查看源码拿到自己的 Token。构造 CSRF 页面填入你拿到的 Token 值。提交页面给 BotBot 访问时也会使用该 Token服务端校验通过完成密码修改。场景 4结合 XSS 绕过 Token组合漏洞修改密码接口有严格 Token每次随机无法预测。但是发现另一个页面存在 XSS 漏洞如留言板反射型 XSS。攻击链利用 XSS 编写脚本功能是读取当前页面的 CSRF Token通常在meta或隐藏域中然后立即用该 Token 发起修改密码的请求。将带有 XSS Payload 的链接发给 Bot。Bot 触发 XSS脚本自动执行从同源页面拿到 Token 并发起 CSRF 请求。这种实际上就是XSS 直接完成的请求已经超出了传统 CSRF 范畴但经常在 CTF 中出现。XSS Payload 示例假设 Token 存在namecsrf_token的 input 中scriptvartokendocument.getElementsByName(csrf_token)[0].value;varxhrnewXMLHttpRequest();xhr.open(POST,/change_pass,true);xhr.setRequestHeader(Content-Type,application/x-www-form-urlencoded);xhr.send(new_passwordhackedcsrf_tokentoken);/script五、CTF 中 CSRF 常用技巧总结防御方式绕过手法无防御直接表单提交检查 Referer去掉 Refererno-referrer、利用开放重定向伪造 RefererSameSiteLax将操作改为 GET、用a点击、window.openCSRF TokenToken 重用、获取自己 Token 公用、Token 为空绕过、双重提交 Cookie 设置自定义请求头 (X-API-Key)如果仅靠自定义头防御且不验证 CORS无法通过表单绕过此时需要 XSS 辅助六、搭建接收/利用环境由于 CSRF 不需要像 XSS 那样接收数据只需要一个能托管 HTML 页面的地方可以利用题目自带的“提交链接”功能有些直接放 HTML 代码。使用自己的 VPS 起一个 HTTP 服务python -m http.server 80把 HTML 文件放上去。使用在线服务如 GitHub Pages、JSBin、Pastebin需渲染原始 HTML等。结合ngrok将本地端口映射到公网。页面基本模板htmlbodyformaction目标操作URLmethodPOST!-- 参数隐藏域 --/formscriptdocument.forms[0].submit();/script/body/html七、总结CSRF 利用的核心是伪造请求让受害者的浏览器在不知情下执行操作。CTF 中 CSRF 的攻克路径确认操作接口 → 分析防御机制Token/Referer/SameSite→ 寻找绕过方法 → 构造攻击页面 → 诱骗 Bot 访问。纯粹的 CSRF 现在已不多见通常会与其它漏洞XSS、URL 跳转、CRLF一起组合考察。掌握 Token 验证逻辑缺陷、SameSite 特性、Referer 控制是绕过防御的关键。