PfSense Command Injection Vulnerability Analysis

Source: Internet
Author: User

PfSense Command Injection Vulnerability Analysis

In this article, we will introduce you to CVE-2014-4688 vulnerabilities in PfSense 2.1.3 and earlier; for a later version, pfSense has fixed this vulnerability.

0x01 Diag_dns.php script Command Injection Vulnerability

The following shows the code snippets with the command injection vulnerability in the script diag_dns.php. We can see that this code first checks whether the POST parameter host exists. If so, the value of the variable $ GET is assigned to the variable $ POST. Then, the Code continues to check whether the value of the GET parameter createalias is equal to true. If yes, remove the blank space at the beginning and end of the value of the POST parameter host: trim () the function removes the blank characters at the beginning and end of the string, but the blank characters in the middle of the string remain unchanged. Afterwards, there are some other statements, but they are not the focus of our attention here. We are concerned about how to insert commands to run in backquotes.

/* Cheap hack to support both $_GET and $_POST */if ($_GET['host'])$_POST = $_GET;if($_GET['createalias'] == "true") {$host = trim($_POST['host']);if($_GET['override'])$override = true;$a_aliases = &$config['aliases']['alias'];$type = "hostname";$resolved = gethostbyname($host);if($resolved) {$host = trim($_POST['host']);$dig=`dig "$host" A | grep "$host" | grep -v ";" | awk '{ print 5 }'`;


Because we can directly manipulate the value of the variable $ host, We can insert the command we want to execute in the back quotes of the injection code. Next, we enter the following content to make it the input value of the POST variable host:
192.168.1.1 "; ifconfig>/usr/local/www/temp.txt; echo +"

The following shows the HTTP request containing the preceding input string.

Figure 1 malicious requests sent to the server

When the preceding request is executed, the Web browser displays the following content, which contains an error message because a valid host name is not provided.

Figure 2 error message: invalid hostname

We have placed a special character in The POST parameter host provided by the user. This character is used to separate multiple commands for sequential execution. Note that in this case, the second command is executed only when the first command returns ''(successful return). Therefore, only ensure that all the preceding commands are successful, the subsequent commands can be executed. The following are some commands that can be executed in the back quotes:
# Dig "192.168.1.1 ";
# Ifconfig>/usr/local/www/temp.txt;
# Echo + "" A | grep "192.168.1.1 ";
# Ifconfig>/usr/local/www/temp.txt;
# Echo + "" | grep-v ";" | awk '{print $5 }'

We can see that each command is correctly executed, and the most important command is ifconfig, which has been injected into the script to obtain the output content. Because we cannot directly obtain the output results of these commands through the response packet, We must output the results to a file under DocumentRoot through the pipeline command before normal access through the Web browser. Some request content in https: // pfsense/temp.txt is shown below.

Figure 3 generated temp.txt File

Previously, we have successfully injected the ifconfig command and obtained the output result. In fact, this means that we can input any command to the diag_dns.php script and get the output result.

Therefore, attackers can inject specially crafted commands and execute them on the server.

0x02 Command Injection in Diag_smart.php script

The diag_smart.php script contains a function named update_email. The Code is as follows. This function is used to edit the smartd. conf file to add or delete an email address that notifies you of disk errors. The following code shows that this function has a POST parameter named smartmonemail. Note that this function will call the sed command and pass the unescaped parameter directly to the shell_exec function.

 function update_email($email)  {  // Did they pass an email?  if(!empty($email))  {  // Put it in the smartd.conf file  shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN -H -m " $email . "/' /usr/local/etc/smartd.conf");  }  // Nope  Else  {  // Remove email flags in smartd.conf  shell_exec("/usr/bin/sed -i old 's/^DEVICESCAN.*/DEVICESCAN/'usr/local/etc/smartd.conf");  }  }  if($_POST['email'])  {  // Write the changes to the smartd.conf file  update_email($_POST['smartmonemail']);  }


In fact, the above Code has a vulnerability that allows us to inject arbitrary commands into the shell_exec function and execute it. The following request shows a Command Injection example, which reflects "Command Injection" to the/var/local/www/cmd.txt file.

When the shell_exec function is executed, the following commands will actually be executed.
#/Usr/bin/sed-I old's/^ DEVICESCAN. */DEVICESCAN-H-m ejan/'+/usr/local/etc/lynx. cfg;
# Echo + "Command + Injection">/usr/local/www/cmd.txt;
# Echo + '/usr/local/etc/smartd. conf;

In the preceding commands, the first and third commands are only supporting roles, and the intermediate commands are the main character we want to inject. In fact, we can use the shell_exec function to inject arbitrary commands. If you use a browser to access https: // pfsense/cmd.txt, you will find that this string has actually been saved to the corresponding file under DocumentRoot.


Figure 4 generated TXT file

In other words, attackers can inject arbitrary commands and execute them on the server.

0x03 command injection vulnerability in Status_rrd_graph_img.php script

The status_rrd_graph_img.php script also has the command injection vulnerability, which is mainly caused by the method of calling the exec () function. The following is some code related to this vulnerability.
if ($_GET['database']) {  $curdatabase = basename($_GET['database']);  } else {  $curdatabase = "wan-traffic.rrd";  } if(strstr($curdatabase, "queues")) {  log_error(sprintf(gettext("failed to create graph from %s%s,emoving database"),$rrddbpath,$curdatabase));  exec("/bin/rm -f $rrddbpath$curif$queues");  Flush();  Usleep(500);  enable_rrd_graphing();  }  if(strstr($curdatabase, "queuesdrop")) {  log_error(sprintf(gettext("failed to create graph from %s%s,emoving database"),$rrddbpath,$curdatabase));  exec("/bin/rm -f $rrddbpath$curdatabase");  Flush();  Usleep(500);  enable_rrd_graphing();  }

At the beginning of the above Code, the basename function is called based on the database setting of the GET parameter: If this parameter is set, it is used to call the basename function; otherwise, it is set as a static string wan-traffic.rrd. Because we want to inject code into this script, we must set this parameter to a value because we must do so to bypass the basename function. In addition, the basename function requires a file path as its parameter, and the returned value is the file name section in the path (excluding the extension). It must be noted that in Linux/BSD (pfSense) use forward slash (/) as the path separator. Therefore, the content returned by this function is basically the string following the last forward slash (/), which must be taken into account when injecting the parameter value, because the content before the last forward slash will be deleted. Therefore, we can inject arbitrary characters into the GET parameter database, except the forward slash. It should be noted that we can inject a command to any exec () Statement in the code above, which depends mainly on the string passed by the GET parameter databage -- in this example, we use the second exec () function call because it is simpler. When the code at the bottom is executed, the following commands will also be executed.

#/Bin/rm-f/var/db/rrd/$ curdatabase;

We can add characters at the end of the command to insert other commands to be executed after the rm command is run. Note that if the command separator is used, the inserted command will be executed only after the rm command is successfully executed. If we do not care about the execution result of the rm command, we can use & to separate the commands. Note that we cannot echo text to any directory because forward slashes are not allowed here. To overcome this problem, we can first use the cd command to enter the pre-defined directory, and then use the command pipeline to achieve text transmission. First, we must figure out the current directory of the code to be executed. Here it is/var/db/rrd/directory. The following request shows how to execute the queues; echo + "CMD + INJECT"> cmd.txt command.

Figure 5 request for executing the echo command

Because the current directory is/var/db/rrd/, for this reason, the content of the created cmd.txt file is cmd inject, which can be verified by displaying the content of the file.
# Cat/var/db/rrd/cmd.txt CMD INJECT

To generate the same file in DocumentRoot under the PfSense installation path, we can use three cd .. command to return to the upper-level directory, switch to the/usr/local/www/directory, and execute the echo command from here. In this way, the file "cmd.txt" can be generated in/usr/local/www/cmd.txt.pdf.

Figure 6 Request for executing the echo command

Because we are currently in the documentrootdirectory of the PfSense webapplication, we only need to request cmd.txt in the browser to know whether the output cmd inject has been received.

Figure 7 generated TXT file

This vulnerability allows us to execute arbitrary code on the PfSense server, so this firewall will eventually become useless. In other words, attackers can inject arbitrary commands and execute them on the server.

0x04 Summary

This article analyzes in detail some of the command injection vulnerabilities we found in PfSense, hoping to help readers.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.