0%

[GYCTF2020]Node Game

最近把JavaScript入了一下门,就顺便做了个js题目

源码

app.get('/', function(req, res) {
    const action = req.query.action ? req.query.action : "index";
    if( action.includes("/") || action.includes("\\") ){
        res.send("Errrrr, You have been Blocked");
    }
    let file = path.join(__dirname + '/template/' + action + '.pug');
    const html = pug.renderFile(file);
    res.send(html);
});

app.post('/file_upload', function(req, res){
    const ip = req.connection.remoteAddress;
    let obj = {
        msg: '',
    };
    if (!ip.includes('127.0.0.1')) {
        obj.msg="only admin's ip can use it"
        res.send(JSON.stringify(obj));
        return
    }
    fs.readFile(req.files[0].path, function(err, data){
        if(err){
            obj.msg = 'upload failed';
            res.send(JSON.stringify(obj));
        }else{
            const file_path = '/uploads/' + req.files[0].mimetype + "/";
            const file_name = req.files[0].originalname;
            const dir_file = __dirname + file_path + file_name;
            if(!fs.existsSync(__dirname + file_path)){
                try {
                    fs.mkdirSync(__dirname + file_path)
                } catch (error) {
                    obj.msg = "file type error";
                    res.send(JSON.stringify(obj));
                    return
                }
            }
            try {
                fs.writeFileSync(dir_file,data)
                obj = {
                    msg: 'upload success',
                    filename: file_path + file_name
                }
            } catch (error) {
                obj.msg = 'upload failed';
            }
            res.send(JSON.stringify(obj));
        }
    })
})

app.get('/source', function(req, res) {
    res.sendFile(path.join(__dirname + '/template/source.txt'));
});


app.get('/core', function(req, res) {
    const q = req.query.q;
    const resp = "";
    if (q) {
        const url = 'http://localhost:8081/source?' + q;
        console.log(url)
        const trigger = blacklist(url);
        if (trigger === true) {
            res.send("<p>error occurs!</p>");
        } else {
            try {
                http.get(url, function(resp) {
                    resp.setEncoding('utf8');
                    resp.on('error', function(err) {
                        if (err.code === "ECONNRESET") {
                            console.log("Timeout occurs");
                            return;
                        }
                    });

                    resp.on('data', function(chunk) {
                        try {
                            resps = chunk.toString();
                            res.send(resps);
                        }catch (e) {
                            res.send(e.message);
                        }

                    }).on('error', (e) => {
                        res.send(e.message);});
                });
            } catch (error) {
                console.log(error);
            }
        }
    } else {
        res.send("search param 'q' missing!");
    }
})

function blacklist(url) {
    const evilwords = ["global", "process", "mainModule", "require", "root", "child_process", "exec", "\"", "'", "!"];
    const arrayLen = evilwords.length;
    for (var i = 0; i < arrayLen; i++) {
        const trigger = url.includes(evilwords[i]);
        if (trigger === true) {
            return true
        }
    }
}

就简单贴几个路由和过滤函数
根目录是解析一个template目录下的pug文件并返回,查了一下pug就是一个渲染模板一类的东西,可以在里面写一些代码进行渲染,命令执行估计是靠这个
file_upload路由需要remote_address是localhost,必然需要找一个ssrf点,上传一个文件到对应的mimetype文件夹下,mimetype即为文件上传部分的content-type(注意不是请求头中的content-type)
source路由展示源码,写死了无法控制
core路由是一个ssrf点,但是路由写死了source,后面的参数q可控,但需要通过blacklist的检测

阅读全文 »

[WMCTF2020] wp

看了两天题目,做出来的都是一开始的非预期,马上就上了一个打了补丁的v2.0然后不会做了呜呜呜,base64这题还是个phppwn,好不容易找到了.so文件还需要pwn爷爷去做,webweb代码审计看到头痛也看不出名堂,太菜了

base64

算不上题解,只能说是找到.so文件的步骤,呜呜呜

题目给了一个base64解码功能,简单测试之后发现当输入字符长度不是4的倍数,或者出现不能解码的字符的时候,就会把能解码的部分阶段解码返回,顺便输出一个看不懂的字符画(师傅说那个画的是’base64decodefail’)
查看源码可以看到一个hint,输入参数filename=hint.php,得到

阅读全文 »

[RCTF 2019]Nextphp

全新的知识,PHP7.4中的全新玩法
上来直接给一个shell,直接执行phpinfo看一眼,open_basedir写上了,disable_function超级过滤,把平常用的mail和unsetenv都给禁了,常用的bypass_disable_function via RD_PRELOAD都不能用了,得寻找新的突破口

可以先var_dump(scandir(‘.’));看一眼有没有其他的可利用文件,发现一个preload.php,里面写了一个类

<?php
final class A implements Serializable {
    protected $data = [
        'ret' => null,
        'func' => 'print_r',
        'arg' => '1'
    ];

    private function run () {
        $this->data['ret'] = $this->data['func']($this->data['arg']);
    }

    public function __serialize(): array {
        return $this->data;
    }

    public function __unserialize(array $data) {
        array_merge($this->data, $data);
        $this->run();
    }

    public function serialize (): string {
        return serialize($this->data);
    }

    public function unserialize($payload) {
        $this->data = unserialize($payload);
        $this->run();
    }

    public function __get ($key) {
        return $this->data[$key];
    }

    public function __set ($key, $value) {
        throw new \Exception('No implemented');
    }

    public function __construct () {
        throw new \Exception('No implemented');
    }
}

说实话我是没看懂这个类能怎么利用的,虽然我印象中析构函数会将工作目录切换到根目录,但是这里显然也没有析构函数,而尝试了一下用这个类的反序列化去执行命令,显然还是PHP函数,无法绕过disable_function

阅读全文 »

[cybrics 2020] web wp

金砖五国CTF?感觉还是个大一点的比赛,看得到其他国家的队伍
全程看题陪跑,比赛还没结束已经开始写wp了呜呜呜呜

Hunt

用到了谷歌的验证码服务没翻墙做不了。。。。是不是该考虑一下充点钱了

Gif2png

阅读全文 »

[CISCN2019 华东南赛区]Double Secret

国赛国赛,考的一个没听说过的RC4加密算法,只要能把加密算法做出来就是很简单的题目了

题解

打开题啥也没有抓包啥也没有就一句Welcome To Find Secret,直接猜get提交一个secret或者路由secret好吧(我是不是也开始成为赛棍了)
路由secret有效,给一句Tell me your secret.I will encrypt it so others can’t see,在get提交一个secret,给出了加密的奇奇怪怪的字符串
测试测试,乱输的时候出现了报错,用的flask,直接展示了部分源码

if(secret==None):
        return 'Tell me your secret.I will encrypt it so others can\'t see'
    rc=rc4_Modified.RC4("HereIsTreasure")   #解密
    deS=rc.do_crypt(secret)
 
    a=render_template_string(safe(deS))
 
    if 'ciscn' in a.lower():
        return 'flag detected!'
    return a
阅读全文 »