LFI to RCE
Converting local file inclusion to remote command can be tricky or even impossible in many cases. Depending on system configurations, you may be able to pass arbitrary text, have a server-side language process it, then view it…if you’re lucky.
Grasping this concept may make sense, but I always find practical examples to be much more beneficial. I’ve created a vulnerable OSCP / CTF style machine with an example of the LFI to RCE log poisoning process. If you’re a William Gibson fan, you’ll enjoy this VM as it’s themed after Neuromancer. Feel free to download - it’s located in my projects directory. Stop reading if you’d prefer no spoilers.
Practical example: Straylight
This machine eventually brings us to a webpage that gives us a list of names to choose from. We pick one in order to see their activity log.
Once we select Case as an option we see the uri contains bolo.php?bolo=case. We now know the webpage is utilizing php – a server side language. We also see a possible LFI vector of “?bolo=case”. Seeing “something=x” is a possible indicator of a LFI.
There’s also a fairly obvious hint the php is just appending .log to the parameter. So where do we go from here? How do we know a LFI vulnerability exists, yet even a RFI? This is where having an LFI path list for manual poking is useful.
FuzzDB has some great lists if you’d like to manually poke around first. Otherwise there are some automated LFI tools available, including one I’ve built FI Cyberspace Scan
Quick write-up: https://liberty-shell.com/sec/2018/09/02/cyberscan/
Start looking around for world readable files such as /etc/passwd. In older versions of php an attacker can use a null byte %00 to stop php from processing further code. Maybe add a ? or + parameter on the end depending on the language being used. Also we aware of php filters. In our example nothing works besides keeping this .log appended to each parameter – which isn’t such a bad file extension to have.
Since we know each parameter will append .log - a search for log files will be priority. By default most system and application logs have permissions locked down. Servers with multiple system admins or service accounts that pull logs may have custom logs created for hassle-free access - this is what you’re banking on. Keep in mind some Linux distros will have common default logs named differently, so do your enumeration thoroughly – ex: access_log vs access.log
In this example we’re able to see the mail.log. The others had permissions locked down.
Log Poisoning via Mail
As the logs tell us, the server is running Postfix and also has port 25 SMTP open, which was found from a basic nmap scan. Now our goal is to inject php into the logs causing the php to render onto your web browser, once you refresh the page with the LFI vulnerability. Sending the phpinfo syntax is a great initial test, but our end goal will be to send this:
<?php echo system($_GET["cmd"]); ?>
So how can we get this php string into the postfix mail.log? By default Postfix includes dates, email addresses and some other basic data. Fire up mailx, mutt or telnet to send the victim server mail. Also, using smtp-user-enum on Kali may be a wise option to check for valid users – as long as VRFY isn’t disabled in postfix configs.
If you were thorough, you’ll notice the mail log includes the text of the mail subject. This is just perfect – now we can have php process any arbitrary code we mail it.
SMTP command flow via telnet may look something like this..
root@kali:~# telnet 192.168.105.6 25 Trying 192.168.105.6... Connected to 192.168.105.6. Escape character is '^]'. 220 straylight ESMTP Postfix (Debian/GNU) helo ok 250 straylight mail from: email@example.com 250 2.1.0 Ok rcpt to: root 250 2.1.5 Ok data 354 End data with <CR><LF>.<CR><LF> subject: <?php echo system($_GET["cmd"]); ?> blahblah .
Once this is logged, a parameter is placed in the URI to cat /etc/passwd.
We now have remote command execution. From here you can get creative and pass a webshell as a one-liner in the cmd parameter. Keep in mind mail is a useful vector to upload/download files. If you have an unstable initial shell, emailing a custom meterpreter shell as an attachment to apache2, www-data, etc may be possible.