Fortinet FortiSIEM has a hard-coded SSH public key for user "tunneluser" which is the same between all installs. An attacker with this key can successfully authenticate as this user to the FortiSIEM Supervisor. The unencrypted key is also stored inside the FortiSIEM image. While the user's shell is limited to running the /opt/phoenix/phscripts/bin/tunnelshell script, SSH authentication still succeeds. Versions 5.2.5 and 5.2.6 have been verified as vulnerable.
2c28af53eba7e337d89352df4d65040bfaf3d030410b0fb0308bd4147ae2c358
Vendor: Fortinet
Product: FortiSIEM
Tested version: 5.2.5, 5.2.6. I haven't confirmed older versions, but there
is a good chance they're also affected.
CVE: Fortinet hands out their own CVEs according to Mitre, and since no
human confirmation was received by Fortinet, no CVE was created yet.
== Summary:
FortiSIEM has a hardcoded SSH public key for user "tunneluser" which is the
same between all installs. An attacker with this key can successfully
authenticate as this user to the FortiSIEM Supervisor. The unencrypted key
is also stored inside the FortiSIEM image. While the user's shell is
limited to running the /opt/phoenix/phscripts/bin/tunnelshell script, SSH
authentication still succeeds.
== Timeline:
Dec 2, 2019: Email sent to Fortinet PSIRT with vulnerability details.
Dec 3, 2019: Automated reply from PSIRT that email was received.
Dec 23, 2019: Sent a reminder email to PSIRT about requesting a human
confirmation.
Jan 3, 2019: Public Release
No human response was received by Fortinet for over 30 days. I stated that
if a confirmation was received before January 2nd that they would be given
an additional 60 days (90 days from initial release) to resolve the
vulnerability before releasing it publicly. No such response was received,
so it's now being publicly released.
== Workaround:
Clear out (or delete) the /home/tunneluser/.ssh/authorized_keys file on the
Supervisor:
supervisor# echo "" > /home/tunneluser/.ssh/authorized_keys
OR
supervisor# rm /home/tunneluser/.ssh/authorized_keys
Also, ensure any of your nodes are behind firewalls with only trusted
access to ports.
== Details:
The FortiSIEM Supervisor has 2 different sshd daemons listening: one is on
the standard port 22/tcp, and the other on port 19999/tcp):
supervisor# netstat -lnp |grep sshd
tcp 0 0 0.0.0.0:22 0.0.0.0:*
LISTEN 38593/sshd
tcp 0 0 0.0.0.0:19999 0.0.0.0:*
LISTEN 38615/sshd
tcp 0 0 :::22 :::*
LISTEN 38593/sshd
tcp 0 0 :::19999 :::*
LISTEN 38615/sshd
The sshd daemon on 19999/tcp uses its own configuration file:
Supervisor# ps aux |grep 38615
root 38615 0.0 0.0 66288 512 ? Ss Sep25 0:00
/usr/sbin/sshd -p 19999 -f /etc/ssh/sshd_config.tunneluser
When looking for this user under ssh configuration files, the sshd
19999/tcp only allows tunneluser to authenticate:
supervisor# grep -R tunneluser /etc/ssh/
/etc/ssh/sshd_config.tunneluser:AllowUsers tunneluser@*
/etc/ssh/sshd_config.tunneluser:DenyUsers "!tunneluser@*,*"
Note that there's no DenyUsers tunneluser@* for the standard sshd
configuration. This means that tunneluser can also successfully
authenticate over sshd port 22/tcp.
The Supervisor has an entry for tunneluser in its passwd file:
supervisor# grep tunneluser /etc/passwd:
tunneluser:x:501:502::/home/tunneluser:/opt/phoenix/phscripts/bin/tunnelshell
The Supervisor allows tunneluser to connect with the following SSH key, and
forward port 2 to localhost. I've confirmed with other users of FortiSIEM
that this key is the same for other installs as well. It is not
auto-generated for each FortiSIEM instance:
supervisor# cat /home/tunneluser/.ssh/authorized_keys
permitopen="127.0.0.1:2" ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEArtFWNhmJqezB0NC5NAbWGZBDWHpGsB+d0+bI46mIJMVyfLhuIa5s5iZF30ehRxu0tTILp40EDe5S9VkdlOymJFvA3dUTlfuhwKvV1hUHXe/5ARTC8AX+1QeZDGnzUKBp/64in6STyaG/1KZj0U1rKUTH42SJWjTrvE/vHqilrcY9SmPx498mPzR8CvlJKYCm1WvweIUoqiVnIqIAQrZqTR+0ea1LksQ6YP4PqpTZpe495bIhk+f2pwPI6PU2q0X61Ae99kqo07whoktb3NdNSI9y/yWJleKdw/FaR0Cj7Ilqg3KyR8evHQoOTHpWiTRAPOpo82qfbx6W0ykrRjo/QQ==
builder@ao-build
The corresponding SSH Private Key is located on all nodes (Supervisor,
Collector, etc.) under the /opt/phoenix/id_rsa.tunneluser file. Running the
following command confirms that this key matches that of the public key:
# ssh-keygen -y -f /opt/phoenix/id_rsa.tunneluser
ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAQEArtFWNhmJqezB0NC5NAbWGZBDWHpGsB+d0+bI46mIJMVyfLhuIa5s5iZF30ehRxu0tTILp40EDe5S9VkdlOymJFvA3dUTlfuhwKvV1hUHXe/5ARTC8AX+1QeZDGnzUKBp/64in6STyaG/1KZj0U1rKUTH42SJWjTrvE/vHqilrcY9SmPx498mPzR8CvlJKYCm1WvweIUoqiVnIqIAQrZqTR+0ea1LksQ6YP4PqpTZpe495bIhk+f2pwPI6PU2q0X61Ae99kqo07whoktb3NdNSI9y/yWJleKdw/FaR0Cj7Ilqg3KyR8evHQoOTHpWiTRAPOpo82qfbx6W0ykrRjo/QQ==
This means that anyone with access to any FortiSIEM image (to copy the SSH
private key) can authenticate successfully via SSH to the FortiSIEM
Supervisor on port 19999/tcp as tunneluser. They will be limited to the
/opt/phoenix/phscripts/bin/tunnelshell script, but if this is bypassed then
full shell access can be obtained.
iptables and ip6tables are present on the Supervisor. However, they are
both permissive and accept all traffic destined to them:
supervisor# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere
...
supervisor bin]# ip6tables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
...