LFI to Remote Code Execution
Confirmed LFI gives you file read. Getting to code execution requires a file you can both write to and include. The most reliable paths are log poisoning when the web server log is readable, session file injection when sessions are stored on disk, and PHP stream wrappers when the PHP configuration allows them. Confirm LFI file read works before attempting any of these.
Log Poisoning — Apache Access Log
The Apache access log records the User-Agent header verbatim. If the log file is readable via LFI, poison it with a PHP payload in the User-Agent and then include the log to execute it.
First confirm the log is readable:
10.10.14.5 - - [26/Mar/2026:12:00:01] "GET / HTTP/1.1" 200 4823 "-" "curl/7.88"
If you see log entries, poison the User-Agent with a PHP web shell:
Now trigger execution by including the log with a command parameter:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Other log paths to try if Apache is not the server:
Nginx:
/var/log/nginx/access.logSSH auth log:
/var/log/auth.log— poison by attempting SSH with a PHP payload as usernamePHP error log:
/var/log/php_errors.log
PHP Session File Injection
PHP session data is stored in files like /var/lib/php/sessions/sess_SESSIONID. If user-supplied input is stored in the session without sanitization, inject a PHP payload through a login or profile field, then include the session file.
Create a session and inject via a parameter that reflects into session data:
Extract the session ID from the cookie file and include the session file:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
PHP Stream Wrappers
PHP stream wrappers provide alternative code execution paths that don't require writing to disk. Which ones work depends on PHP configuration.
Sends the POST body as the file to include. Requires allow_url_include=On:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Inline execution using a data URI. Requires allow_url_include=On:
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Requires file upload capability. Upload a zip containing a PHP shell and include it via zip://::
/proc/self/environ
The environment of the web server process is exposed via /proc/self/environ. If it's readable, inject into the User-Agent header and include the file:
SCRIPT_NAME=/index.php SERVER_NAME=10.10.10.50 HTTP_USER_AGENT=curl/7.88
Reverse Shell Delivery
Once you have command execution through any of the above methods, get a reverse shell. Set up the listener first:
References
-
PHP — Stream Wrapperswww.php.net/manual/en/wrappers.php (opens in new tab)
php://input, data://, zip:// and phar:// wrapper documentation
-
PayloadsAllTheThings — File Inclusiongithub.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion (opens in new tab)
LFI to RCE payload collection including log paths and session injection
Was this helpful?
Your feedback helps improve this page.