Give Me Your FortiGate Configuration Backup and I Rule Your Network

In a recent incident response case we were as always searching for the initial access. We have seen suspicious behavior from IP addresses that were assigned by the VPN. The respective public IP address was suspicious too, because it was owned by a VPS provider and was also listed in abuse databases. The most interesting part is how the attackers were able to authenticate to the VPN. Usually this happens by weak credentials of users, but these connections have been authorized by the guest account. How was that possible? Because a third party managed the VPN, it could be possible that they made a mistake by allowing the default guest account to log in and assigning a weak password to it. This was the beginning of our deep dive into the FortiNet FortiGate 100F VPN appliance, a “Next Generation Firewall” with VPN functionalities.

Fig. 1: FortiGate WebUI, Backup System Configuration

The configuration of these appliances can be read by creating a so-called configuration backup by using the WebUI as shown in Figure 1. It produces by default a text file which is basically plain text except for the passwords. The part of that file with our unknown guest password looked like this:

edit "guest"
set type password
set passwd ENC uCn8uiVJqzzEm8iba4onCc98AJDiYggVSDlYIph+gjN3cjSSEvX8kSNfm+TjIzSlGnH5dm8rCd6aLgPipLPP2okahye7oZZxXfse
BytbJ+7arJPz1e1mmnawL8/jFcl8g/SNNuSMo6q/f2Ilo7dnngJDZUfUeE2JiYpivmd5snDVadDoqOVRa8ji26I25r0IApELXg==
next

Fortunately these SSL-VPN credentials can be decrypted with the key “Mary had a littl”. This is apparently the first 16 characters of the famous American nursery rhyme “Mary had a little Lamb”. This has not been set by the administrators but was statically set by the manufacturer FortiNet in the firmware of the appliance. This vulnerability was found in 2019 by Bart Dopheide and has been assigned the CVE number CVE-2019-6693. The patch by FortiNet is no more than the recommendation to change the key (https://www.fortiguard.com/psirt/FG-IR-19-007). For this, commands have to be entered into the commandline interface. This is not obvious since you need to be aware of it. And so the inevitable happened: In our case, the default settings were retained and “Mary” worked.

Fig. 2: Elmo takes it easy

Long story short: Guest password recovered. It read … wait for it, the story has just begun. FortiNet customers could have the honorable idea of setting the “encryption” switch in the WebUI (see Figure 1) when generating the configuration backup file before saving it to disk. This will encrypt the whole file additionally on top of “Mary”. If the switch is enabled, the form is extended with the well-known textfields “enter password” and “repeat password”. We became suspicious when we noticed that the maximum length of the fields is set to 15 characters. That would have meant that there is no so-called key derivation function.

Rabbithole

Fortunately FortiGate is also available as virtual machine. This makes accessing the files way easier. The relevant code for the encryption resides in the file “init” which is around 70 MB in size. This file piqued our interest because it imported a bunch of crypto functions according to IDA. The relevant code within this file was found by searching for the static magic bytes of the encrypted configuration backups by which they always begin. These read #FGBK|4|FGVM64|7|04|2360|\x0A.

The encryption part looked like this:

Fig. 3: IDA

What happens (or happend you have to say today) in the firmware: First, the unencrypted file was archived using regular GZ. The output is then encrypted using AES-GCM. This output is prepended with a header beginning with the already mentioned magic bytes following a 12 byte initialization vector and a 16 byte GCM Authcode. The most interesting part was the key derivation. As shown in Figure 3 there was just a single round of SHA256. The result was the key for the AES-GCM encryption.

Fig. 4: Unexpected vulnerability

Mary got a crackable password

The problem with this implementation is the single hashing round. It’s been a long time since that was state of the art. It allows fast cracking of the password resulting in the decryption of the file. How fast depends on several factors. For one, the cracking tool used and the hardware it runs on. We developed tooling for hashcat and achieved (without further optimization) 580 million passwords per second utilizing a single RTX 3080 graphics card.
The factor the user can influence is the length of the password, but unfortunately the form field for setting the password is set to a limit of 15 characters. Together with the still existing vulnerability around “Mary got a littl” there is a serious chance an attacker could decrypt SSL-VPN passwords if the file falls into their hands even when the file is “additionally” encrypted. And we know of some network administrators out there sending these configuration backups via email around the world because they trust in the confidentiality of these files.

Responsible Disclosure

On October 12, 2023 we started the responsible disclosure process with FortiNet. On January 2, 2024 they assigned the CVE 2024-21754 and fixed the issue in FortiOS version 7.4.4, which was released around June 10, 2024. They published an advisory on June 11, 2024.
FortiNet doesn’t mention a time period in their responsible disclosure policy, but 243 days is a long time compared to the usually offered 90 days, even if it is only a low severity vulnerability.

PS: The password of the guest account in our incident response case was simply “guest”.

FortiNet Advisory: https://www.fortiguard.com/psirt/FG-IR-23-423

Tooling: https://github.com/GDATAAdvancedAnalytics/fortigategate

Article Link: Give Me Your FortiGate Configuration Backup and I Rule Your Network – cyber.wtf