Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions src/pentesting-web/file-inclusion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,22 @@ Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/
http://example.com/index.php?page=PhP://filter
```

### Single-pass traversal stripping bypass

A very common anti-pattern is a **single replacement pass** such as:

```php
$path = str_replace('../', '', $_GET['f']);
```

This is bypassable with **overlapping traversal** payloads like `....//`. The inner `../` is removed first, and the remaining bytes collapse into a fresh `../`. Repeat it until the request escapes the intended directory:

```
http://example.com/download.php?f=....//....//....//etc/passwd
```

If a client, proxy, or framework normalizes traversal before it reaches the vulnerable code, preserve the raw path (for example with `curl --path-as-is`).

## Remote File Inclusion

In php this is disable by default because **`allow_url_include`** is **Off.** It must be **On** for it to work, and in that case you could include a PHP file from your server and get RCE:
Expand Down Expand Up @@ -223,6 +239,16 @@ cd out
git checkout .
```

Don't stop at the current tree. **Deleted credentials and endpoints often survive in Git history**:

```bash
git log --oneline --decorate --all
git show <commit>
git diff <old_commit> <new_commit>
```

This is especially useful when the exposed repository currently looks harmless (for example an empty auth array), but an earlier commit still contains hardcoded users, passwords, API tokens, or internal routes.

> [!TIP]
> In the previous code, the final `+.txt` was added because the attacker needed a string that ended in `.txt`, so the string ends with it and after the b64 decode that part will return just junk and the real PHP code will be included (and therefore, executed).

Expand Down Expand Up @@ -830,6 +856,15 @@ curl --path-as-is -b "session=$SESSION" \

Tune the number of `../` segments until you escape the intended directory, then dump `/etc/passwd`, `/proc/self/cwd/app.py`, or other source/config files.

### Post-read triage order

Once you confirm an arbitrary file-read/download primitive, a fast triage order is:

1. Read `/etc/passwd` to discover local users and login shells.
2. Read web-server vhost configs such as `/etc/nginx/sites-enabled/<vhost>` or `/etc/apache2/sites-enabled/*.conf` to recover the **document root**, log paths, and PHP-FPM / proxy wiring.
3. Read application entrypoints from that document root to decide whether the bug is only **file read** or can become **file include / code exec** through another sink.
4. Pull source/config files (`.env`, framework settings, DB creds, job definitions) and look for secondary write, upload, deserialization, or command-execution primitives.

## References

- [PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
Expand All @@ -844,6 +879,7 @@ Tune the number of `../` segments until you escape the intended directory, then
- [Positive Technologies – Blind Trust: What Is Hidden Behind the Process of Creating Your PDF File?](https://swarm.ptsecurity.com/blind-trust-what-is-hidden-behind-the-process-of-creating-your-pdf-file/)
- [HTB: Imagery (admin log download traversal + `/proc/self/environ` read)](https://0xdf.gitlab.io/2026/01/24/htb-imagery.html)
- [HTB: Gavel](https://0xdf.gitlab.io/2026/03/14/htb-gavel.html)
- [0xdf – HTB: VariaType](https://0xdf.gitlab.io/2026/06/13/htb-variatype.html)

{{#file}}
EN-Local-File-Inclusion-1.pdf
Expand Down