Virtual patching on the local-in management interface
Virtual patching is a method of mitigating vulnerability exploits by using the FortiGate’s IPS engine to block known vulnerabilities. Virtual patching can be applied to traffic destined to the FortiGate by applying the FMWP (Firmware Virtual Patch) database to the local-in interface using local-in policies. Attacks geared towards GUI and SSH management access, for example, can be mitigated using the FMWP database pushed from FortiGuard, thereby virtually patching these vulnerabilities.
When the virtual-patch
option is enabled in a local-in policy, the IPS engine queries the FortiGuard API server using the WAD process to obtain a list of vulnerabilities targeting the FortiGate on the current FortiOS version. IPS enables vulnerability rules to scan local-in traffic on the specified interface. All matched local-in traffic is dropped accordingly.
To configure virtual patching:
config firewall local-in-policy edit <id> set action accept set virtual-patch {enable | disable} next end
The FortiGate must have a valid FMWR (Firmware) license to install the FMWP database. The FMWP database can be viewed by running the diagnose autoupdate versions
command.
# diagnose autoupdate versions FMWP Definitions --------- Version: 23.00084 signed Contract Expiry Date: Wed Jan 1 2031 Last Updated using manual update on Wed Sep 6 15:19:11 2023 Last Update Attempt: Wed Sep 6 15:40:08 2023 Result: No Updates
Once virtual-patch
is enabled, the WAD process will periodically query vulnerability items from the FortiGuard API server at "productapi.corp.fortinet.com" and forward it to IPS.
Sample vulnerability item found on the FortiGuard API server
{"ID":918630,"product":"fortios","vendor":"fortinet","max_version":"7.2.5","min_version":"7.2.0","severity":"high","vuln_type":"Format String","refs":["https://www.fortiguard.com/psirt/FG-IR-23-137"],"description":"This indicates detection of a Zero-Day vulnerability protected by a signature from Fortinet's FortiGuard Labs. This signature should help mitigate the threat proactively both prior to, and after an official statement is available from the vendor. Once an official advisory or statement is available from the vendor, the signature name and its description will be updated to provide more details regarding this vulnerability. Further details may also be made available in an advisory on FortiGuard Center (http://www.fortiguard.com).","patch_sig_id":10004065,"patch_sig_ids":[],"detection_sig_ids":null,"date_added":"2023-08-22T13:09:11","date_updated":"2023-08-22T13:09:11"}
FortiGuard can be queried from the FortiOS CLI for a list of vulnerability rules while specifying parameters for the vendor, version, product, and model by running the diagnose wad dev-vuln query
command. For example, to query Fortinet Inc.'s FortiOS 7.2.5:
# diagnose wad dev-vuln query vendor=fortinet&version=7.2.5&product=fortios Dev-Vuln Lookup result: success, cache: found, fgd: unknown, item: 0x7fb474e0b4a0 Vulnerability details: info entry (1): 'vendor' = fortinet 'product' = fortios 'model' = N/A 'version.min' = 7.2.0 'version.max' = 7.2.5 'firmware' = N/A 'build' = N/A 'date_added' = 2023-08-22T13:09:11 'date_updated' = 2023-08-22T13:09:11 'sig_id' = 10004065 'vuln_id' = 918630 'severity' = 3 ...
After receiving the vulnerability rules from the WAD process, the IPS engine marks them as virtual patch rules mapped to each CVE vulnerability signature. For example:
FortiOS.NodeJS.Proxy.Authentication.Bypass(CVE-2022-40684)
FortiOS.SSL.VPN.Web.Portal.Password.Improper.Authentication(CVE-2018-13382)
FortiOS.SSL.VPN.Web.Protoal.Pathname.Information.Disclosure(CVE-2018-13379)
To show the list of available FMWP signatures from the FMWP database:
# get rule fmwp status rule-name: "FortiOS.Fclicense.Daemon.Format.String." rule-id: 10004067 rev: 23.082 date: 1697644800 action: block status: enable log: disable log-packet: disable severity: 3.high service: TCP, HTTP location: server os: Linux application: Other rate-count: 0 rate-duration: 0 rate-track: none rate-mode: continuous vuln_type: Format String cve: 202329181 fos_comp: Web-GUI ....
The following are the diagnose commands:
# diagnose ips vpatch {fmwp-status | fmwp-enable-all | fmwp-reset}
fmwp-status |
Shows the current status of enabled FMWP signatures. |
fmwp-enable-all |
Enable all FMWP signatures in FMWP database. |
fmwp-reset |
Revert the results of |
Example
In this example, the FortiGate’s port2 is configured with virtual patching enabled. In the test scenario, the FortiGate is set to debug mode in order to block a harmless attack. IPS will scan local-in traffic and all matched local-in traffic will be dropped accordingly. Intrusion prevention logs will be recorded.
To configure virtual patching on the local-in management interface:
-
Configure the local-in policy:
config firewall local-in-policy edit 1 set intf "port2" set srcaddr "all" set dstaddr "all" set action accept set service "ALL" set schedule "always" set virtual-patch enable next end
-
From the Linux client, start a cURL download:
# curl -ik -H 'Host: 127.0.0.1:9980' -H 'User-Agent: Node.js' -H 'Forwarded: by=\"[::ffff:127.0.0.1]:443\";for=\"[::ffff:127.0.0.1]:5325\";proto=https;host=localhost' -H $'X-Forwarded-Vdom: root' 'https://10.1.100.175/api/v2/cmdb/system/admin'
The attack is blocked, and a security event log (intrusion prevention) is recorded.
1: date=2023-09-06 time=16:03:13 eventtime=1694041393775430036 tz="-0700" logid="0419016384" type="utm" subtype="ips" eventtype="signature" level="alert" vd="vd1" severity="critical" srcip=10.1.100.22 srccountry="Reserved" dstip=10.1.100.175 dstcountry="Reserved" srcintf="port38" srcintfrole="undefined" dstintf="vd1" dstintfrole="undefined" sessionid=8636 action="dropped" proto=6 service="HTTP" policyid=1 attack="FortiOS.NodeJS.Proxy.Authentication.Bypass." srcport=48940 dstport=80 hostname="127.0.0.1" url="/api/v2/cmdb/system/admin" agent="Node.js" httpmethod="GET" direction="outgoing" attackid=10002156 ref="http://www.fortinet.com/ids/VID10002156" incidentserialno=212860935 msg="vPatch: FortiOS.NodeJS.Proxy.Authentication.Bypass." crscore=50 craction=4096 crlevel="critical"