首页 > 其他分享 >2023Hgame

2023Hgame

时间:2023-02-10 22:45:04浏览次数:38  
标签:2023Hgame admin res req session diary data

2023Hgame

Shared Diary

源代码先放一下

const express = require('express');
const bodyParser = require('body-parser');
const session = require('express-session');
const randomize = require('randomatic');
const ejs = require('ejs');
const path = require('path');
const app = express();

function merge(target, source) {
    for (let key in source) {
        // Prevent prototype pollution
        if (key === '__proto__') {
            throw new Error("Detected Prototype Pollution")
        }
        if (key in source && key in target) {
            merge(target[key], source[key])
        } else {
            target[key] = source[key]
        }
    }
}

app
    .use(bodyParser.urlencoded({extended: true}))
    .use(bodyParser.json());
app.set('views', path.join(__dirname, "./views"));
app.set('view engine', 'ejs');
app.use(session({
    name: 'session',
    secret: randomize('aA0', 16),
    resave: false,
    saveUninitialized: false
}))

app.all("/login", (req, res) => {
    if (req.method == 'POST') {
        // save userinfo to session
        let data = {};
        try {
            merge(data, req.body)
        } catch (e) {
            return res.render("login", {message: "Don't pollution my shared diary!"})
        }
        req.session.data = data

        // check password
        let user = {};
        user.password = req.body.password;
        if (user.password=== "testpassword") {
            user.role = 'admin'
        }
        if (user.role === 'admin') {
            req.session.role = 'admin'
            return res.redirect('/')
        }else {
            return res.render("login", {message: "Login as admin or don't touch my shared diary!"})
        }
    }
    res.render('login', {message: ""});
});

app.all('/', (req, res) => {
    if (!req.session.data || !req.session.data.username || req.session.role !== 'admin') {
        return res.redirect("/login")
    }
    if (req.method == 'POST') {
        let diary = ejs.render(`<div>${req.body.diary}</div>`)
        req.session.diary = diary
        return res.render('diary', {diary: req.session.diary, username: req.session.data.username});
    }
    return res.render('diary', {diary: req.session.diary, username: req.session.data.username});
})


app.listen(8888, '0.0.0.0');

第一种方法通过正常解 ssti完成

image-20230209161234948

漏洞点在这里 可以控制ssti

先看看怎么样才能进入这里,需要不满足这个条件

    if (!req.session.data || !req.session.data.username || req.session.role !== 'admin') {
        return res.redirect("/login")
    }

必须要有session.data data里面也要有username 然后 role必须要使admin

上面有个merge函数 先看这个login路由吧

image-20230209162555074

这里将data赋值给了session.data 所以我们可以通过merge函数来将我们的输入赋值给data

继续往下看 我们可以通过rq.body赋值给data

image-20230209211356118

这里如果我们的user.password等于testpassword的话就给user.role赋值为admin 然后如果user.role为admin的话就可以使req.session.role赋值为admin

image-20230209211658616

然后在看一下条件 if (!req.session.data || !req.session.data.username || req.session.role !== 'admin') {我们只差req.session.data.username没有满足了 所以我们只需要在执行merge函数的时候将data同样赋值上username属性就可以了

然后就执行到这里了<%- global.process.mainModule.require('child_process').execSync('cat /flag') %>

image-20230209211949297

image-20230209211929471

第二种方法 直接用ejs 通过原型链污染直接rce就可以了

image-20230209215407321

这样使直接可以的 但是平台题目这里污染就会报错 然后污染不成功 自己服务器上的还是可以的 通过排错 应该使docker的问题 直接命令行 node app.js 可直接污染上的 但是 用docker的话 在merege函数这里是会报错的

标签:2023Hgame,admin,res,req,session,diary,data
From: https://www.cnblogs.com/kkkkl/p/17110545.html

相关文章