Introduction
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.
LFI vulnerability in system_firmware_restorefullbackup.php
A LFI vulnerability exists in the system_firmware_restorefullbackup.php script. If a user has only the "Diagnostics: Restore Full Backup" privileges, as shown below, he won't be able to access the LFI vulnerability.
Figure 4: The 'restore full backup' privileges
Instead it must have "Allow access to all pages" privileges, which is a lot of privileges to begin with.
Figure 5: The 'access to all pages' privileges
Nevertheless, the web application is vulnerable to LFI injection, where we can pass arbitrary value in the downloadbackup GET parameter as shown on the picture below.
Figure 6: A request requesting the /etc/passwd file
The response to the picture can be shown below, where it's evident that the /etc/passwd has returned to the user.
Figure 7: The contents of /etc/passwd file
An attacker with previously described privileges could use this vulnerability to gain access to the whole Pfsense.
An attacker can use this vulnerability to download arbitrary file from the system. The fix the vulnerability the value passed in GET parameter downloadbackup needs to be properly secure to not allow reading arbitrary files from the server.
Conclusion
If you find this post interesting, you can follow our blog: RSS.
Comments