In this article we'll present the CVE-2014-4690 vulnerability existing in pfSense version <= 2.1.3. In later versions of pfSense, the vulnerabilities have been successfully remediated and are no longer present. You should also read the previous articles about PfSense vulnerabilities at the following locations:

LFI vulnerability in traversal in pkg_mgr_install.php

Let's take a look a the code contained in /usr/local/www/pkg_mgr_install.php file. It's has been copied below for completeness and clarity.

if ($_GET) { $pkgname = str_replace(array("<", ">", ";", "&", "'", '"'), "", htmlspecialchars_decode($_GET['pkg'], ENT_QUOTES | NT_HTML401)); switch($_GET['mode']) { case 'showlog': if (strpos($pkgname, ".")) { update_output_window(gettext("Something is wrong on the equest.")); } else if (file_exists("/tmp/pkg_mgr_{$pkgname}.log")) pdate_output_window(@file_get_contents("/tmp/pkg_mgr_{$pkgname}.log")); else update_output_window(gettext("Log was not retrievable.")); break; case 'installedinfo': if (file_exists("/tmp/{$pkgname}.info")) { $status = @file_get_contents("/tmp/{$pkgname}.info"); update_status("{$pkgname} " . gettext("installation completed.")); update_output_window($status); } else update_output_window(sprintf(gettext("Could not find %s."), pkgname)); break; default: break; } }

Notice that the code accepts two GET parameters mode, which is passed to the switch statement and supports values showlog or installedinfo. The second parameter is pkg, which is read into the pkgname variable by deleting the following characters from the inputted string: <, >, ;, &, ', ". Since the replace statement doesn't check for special characters . and /, we can traverse the directories on the server. In the code we can also see that the value of pkg parameter is unsafely concatenated with "/tmp/{$pkgname}.info". Therefore if we pass the value of ../usr/local/info/gettext in pkg parameter, the whole path to read will be: /tmp/../usr/local/info/gettex.info, which is an existing file on the disk. Take a look at such request below.

Figure 1: A request showing directory traversal in GET parameter pkg

Notice that the file beginning with "This is a gettext.info" is included in the output of a web page as seen below.

Figure 2: A response presenting the requested file

# head /usr/local/info/gettext.info This is gettext.info, produced by makeinfo version 4.13 from gettext.texi. To verify that this is the same file, we can connect to the Pfsense ia SSH and issue the head command to display the first part of the ile; the output below verifies the file is the same. INFO-DIR-SECTION GNU Gettext Utilities START-INFO-DIR-ENTRY gettext: (gettext). GNU gettext utilities. autopoint: (gettext)autopoint Invocation. Copy gettext nfrastructure. envsubst: (gettext)envsubst Invocation. Expand environment variables. gettextize: (gettext)gettextize Invocation. Prepare a package for ettext. msgattrib: (gettext)msgattrib Invocation. Select part of a PO file. <script type="text/javascript" src="javascript/domTT/domLib.js"></script> <script type="text/javascript" src="javascript/domTT/domTT.js"></script> <script type="text/javascript" src="javascript/domTT/behaviour.js"></script> <script type="text/javascript" src="javascript/domTT/fadomatic.js"></script> <script type="text/javascript" src="/javascript/row_helper_dynamic.js"></script>

Let's also display that in a web browser to present it in a clear way.

Figure 3: The file displayed in a web browser

Since the string concatenation appends the .info at the end of the string, we can only display files ending with .info extension. We can quickly search for all those files by issuing a find command as presented below.

# find / -name "*.info" /usr/local/info/gettext.info /usr/local/info/autosprintf.info /usr/pbi/snort-amd64/info/autosprintf.info /usr/pbi/snort-amd64/info/gettext.info /usr/pbi/snort-amd64/info/m4.info /usr/pbi/snort-amd64/info/autoconf.info /usr/pbi/open-vm-tools-nox11-amd64/info/autosprintf.info /usr/pbi/open-vm-tools-nox11-amd64/info/gettext.info /usr/pbi/open-vm-tools-nox11-amd64/info/m4.info /usr/pbi/open-vm-tools-nox11-amd64/info/autoconf.info /usr/pbi/havp-amd64/info/autosprintf.info /usr/pbi/havp-amd64/info/gettext.info

Note that the script does not accept NULL byte %00, which would allow us to download arbitrary file from the server.

An attacker can use this vulnerability to get the contents of arbitrary .info files from Pfsense. To fix the vulnerability the /usr/local/www/pkg_mgr_install.php script needs to implement proper security measures to prevent directory traversal attacks on the server.