Fortigate – Autenticação de Desvio Levando à Assunção Completa do Dispositivo

Escrito por  Carlos Vieira

 

Pesquisa de vulnerabilidade 1Day pela Equipe de Pesquisa da Hakai

Este post trata da jornada para criar uma Prova de Conceito sobre a CVE-2022-40684, esta vulnerabilidade foi atribuída pela Fortinet como uma falha de autenticação usando uma vulnerabilidade de caminho ou canal alternativo [CWE-288].

Linha do Tempo

07/10/2022 – Primeira notícia sobre a vulnerabilidade, em 10/07/2022 Gi7w0rm twittou que a Fortinet estava contatando alguns clientes VIP para avisar sobre uma vulnerabilidade crítica afetando seu firewall FortiGate.

#Fortinet is currently advising it’s customers on a high severity #vulnerability in
FortiOS: From 7.0.0 to 7.0.6 and from 7.2.0 to 7.2.1
FortiProxy: From 7.0.0 to 7.0.6 and 7.2.0#CVE: CVE-2022-40684#authbypass #RCE #prepareforimpact@campuscodi @uuallan @GossiTheDog pic.twitter.com/eiVrtsozC0

— Gitworm (@Gi7w0rm) October 7, 2022

07/10/2022 – Nossa equipe começou a monitorar a internet para explorar esse tipo de vulnerabilidade e também iniciou o processo de inteligência para identificar o nível de exposição de nossos clientes. Procuramos por possíveis exploits funcionais, mas não identificamos nenhum tipo de exploração em ambiente real e também não foi possível identificar nenhum exploit público.

08/10/2022 – Neste dia, nossa equipe de Pesquisa em Segurança (SRT) iniciou o processo de análise do patch fornecido pela Fortinet. A ideia era entender como o patch funciona, para que pudéssemos entender o comportamento do fluxo de autenticação e criar um exploit para a vulnerabilidade.

No mesmo dia, nossa equipe descobriu que se tratava de um problema relacionado à API.

Sabendo que o patch estava diretamente relacionado à API, começamos o processo de descoberta para entender como a API do FortiGate funciona. Essa análise foi feita de forma dinâmica (Acessando o firewall e interceptando solicitações por meio de um proxy como o Burp).

Processo de Análise

O primeiro passo foi: baixar duas versões do firmware do firewall, uma versão vulnerável e a outra com o patch aplicado pela Fortinet.

Portal do cliente da fortinet

No portal de clientes, baixamos as duas versões, 7.2.1 (vulnerável) e a versão 7.2.2 (com o patch da Fortinet).

Portal do cliente (Download firmwares)

No website, é importante prestar atenção ao baixar o firmware para o FortigateVM (FGT_VM64-v7.2.x.XXX-FORTINET.out.ovf.zip).

Agora que baixamos os dois firmwares, vamos separá-los em diferentes pastas, “patched” (com patch) e “old” (antigo).

Agora é mais fácil saber qual firmware representa cada versão.

Vamos analisar.

Inicialmente, podemos observar que o firmware está compactado no formato zip e dentro dele há um arquivo OVF (Open Virtualization Format).

Vamos descompactar!

Temos vários arquivos, mas os mais importantes são os arquivos de disco “VMDK”.

O maior disco é o fortios.vmdk, que provavelmente contém todo o sistema operacional do firewall, vamos montá-lo e verificar o conteúdo.

Vamos fazer o mesmo com o disco já com o patch da Fortinet, desta forma será mais fácil fazer um “diff” entre as versões.

Para montar o disco vmdk, precisaremos instalar o qemu-utils, vamos executar o seguinte comando:

sudo apt install qemu-utils

E depois de instalar, vamos habilitar o módulo do kernel ndb.

sudo modprobe nbd

Após habilitar o módulo, podemos usar o qemu-nbd para montar os discos em nosso sistema, tendo assim acesso ao disco do firewall em ambas as versões, antiga e patcheada.

Podemos começar com uma comparação simples, entre um arquivo que existe entre as duas versões, por exemplo, o arquivo “boot.msg”.

Na captura de tela, podemos ver que não houve alteração no arquivo “boot.msg” entre as duas versões.

Dessa forma, podemos analisar outros arquivos e verificar quais deles foram alterados.

Podemos identificar que o próximo arquivo na sequência, “datafs.tar.gz”, é diferente nas duas versões.

Outro arquivo que também é diferente na nova versão é o arquivo “rootfs.gz”, que aparentemente é toda a estrutura das aplicações internas do firewall (incluindo a API).

As pastas atuais /mnt/fortigate-old e /mnt/fortigate-patched estão no formato somente leitura, então criarei duas novas pastas e copiarei os dois arquivos para as respectivas pastas.

Vamos começar descompactando os arquivos:

Após descompactar os arquivos, perdi muito tempo tentando entender o formato cpio.

Cpio vem de “Copy in and Copy out”, este é também um formato de compressão de arquivo, podemos usar o comando cpio para extrair este arquivo.

Após extrair os arquivos, teremos algo assim:

Agora temos várias pastas e arquivos para analisar 🙂

Farei o mesmo com a versão “patched”.

Agora vamos executar o comando diff para verificar a diferença entre as duas pastas:

Podemos ver que a parte responsável pela API de nó foi alterada.

Os arquivos comprimidos com .tar.xz estavam corrompidos (foi isso que nossos descompactados indicaram).

Neste ponto, pensamos no que poderia causar isso, e quando não conseguimos resolver o problema, estávamos certos de que o problema estava relacionado a uma API. Discutimos isso a partir do teste dinâmico (interagindo diretamente com o firewall e observando as solicitações).

09/10/2022 – No dia 9, a equipe da Horizon3 compartilhou uma captura de tela no Twitter com um possível exploit da vulnerabilidade, onde era possível alterar a chave SSH do usuário administrador do firewall, mas eles não forneceram o código-fonte do exploit.

10/10/2022 – Neste dia, nossa equipe conseguiu reproduzir com sucesso o exploit da vulnerabilidade, obtendo assim acesso total.

A vulnerabilidade é uma falha de configuração na autenticação da API FortiOS. No mesmo dia, nossa equipe postou sobre essa vulnerabilidade no Twitter, afirmando que não se tratava apenas de uma simples vulnerabilidade de “bypass de autenticação”, mas sim de uma vulnerabilidade que poderia levar à tomada completa do firewall.

Posso confirmar que a CVE-2022-40684 é realmente simples de explorar e fácil de utilizar como arma.

Não se trata apenas de um “bypass de autenticação para algumas funções”, essa vulnerabilidade causa uma tomada completa do dispositivo!

— Carlos Vieira (lynx) (@carlos_crowsec) October 10, 2022

Processo de análise dinâmica

Nós instalamos o firewall em nossa VMware e começamos a análise de duas maneiras: a primeira é entender como o frontend faz as solicitações e a segunda é entender como essas solicitações são processadas pelo firewall.

A primeira análise foi feita usando o Burp, e a segunda usando o modo de depuração do firewall e também sniffando a interface de loopback do firewall.

Podemos ver que um dos endpoints mais acessados pelo frontend é /api/v2/*.

Agora podemos usar a CLI do FortiOS para entender sobre o que são essas solicitações.

FW-EXT # diagnose debug application httpsd 1Debug messages will be on for 30 minutes.FW-EXT # diagnose debug enable

Com o comando “diagnose debug application httpsd 1”, estamos indicando um filtro de depuração para o firewall, informando que queremos ler os logs em tempo real desse processo, permitindo assim entender o que acontece com cada solicitação.

Atenção: Não recomendamos fazer isso em um ambiente de produção, esse tipo de atividade consome muita CPU e memória do dispositivo!

O comando “diagnose debug enable” na verdade ativa o modo de depuração.

Agora podemos rastrear cada solicitação!

Para fins de teste, vamos fazer uma solicitação simples à API “usando o repeater” e verificar o comportamento internamente.

Agora vamos ver como fica na CLI.

Aparentemente, a Fortinet está adotando um modelo baseado em serviço em seu backend. Podemos ver várias chamadas para diferentes serviços como “api_cmdb_v2-handler”, “api_store_parameter”, “handle_cli_req_v2”.

Outro aspecto importante durante esse processo foi sniffar a interface de loopback do firewall.

Para sniffar as solicitações, podemos ir para:

  1. Guia de Rede
  2. selecionar “Diagnósticos”
  3. então “Captura de Pacotes”
  4. escolher a interface como “any”
  5. ativar o filtro
  6. adicionar 127.0.0.1 na entrada do host

Então, basta clicar em “Iniciar captura”.

Durante o processo, deixamos o processo de sniffing por 5 minutos enquanto usávamos a aplicação.

Isso ajudou muito a entender como funciona.

Depois de terminar o sniffing, basta clicar em parar e depois em “Salvar como pcap”.

Podemos usar o filtro “http.request” para capturar apenas as solicitações HTTP interceptadas.

Agora podemos ver que há várias solicitações HTTP que vão de 127.0.0.1 para 127.0.0.1.

Inicialmente, entendemos que isso se refere a um proxy reverso.

Um exemplo de solicitação interceptada pelo sniffing:

Você percebe algo estranho?

Nunca vi esse cabeçalho na minha vida. E você?
“forwarded” ????

forwarded: by="[::ffff:172.16.51.132]:80";for="[::ffff:172.16.51.1]:38284";proto=http;host=172.16.51.132

Temos 4 campos dentro deste cabeçalho separados por “;”.

by=”[::ffff:172.16.51.132]:80″
for=”[::ffff:172.16.51.1]:38284″
proto=http
host=172.16.51.132

Isso se parece um pouco com “X-Forwarded-For”, normalmente adicionado por proxies, mas com campos adicionais.

Isso foi a primeira coisa que notamos de estranho sobre essa solicitação.

Após muito tempo analisando os pcaps, identificamos uma solicitação feita com o User Agent “Node.js”.

É interessante notar que no modo de depuração obtivemos um caminho diferente dos outros.

Nesta solicitação, é feita uma chamada a um serviço “api_access_check_for_trusted_access”, também podemos notar que a solicitação foi feita pelo próprio loopback.

Depois de algum tempo tentando entender o que tudo isso significava, nossa equipe finalmente conseguiu reproduzir essa falha de autenticação no firewall!

GET /api/v2/monitor/system/firmware?vdom=root HTTP/1.1Host: 127.0.0.1User-Agent: Node.jsforwarded: by="[127.0.0.1]:1337";for="[127.0.0.1]:1337";proto=http;host=127.0.0.1Connection: close

Podemos ver que a solicitação foi feita com sucesso, sem nenhum tipo de restrição!

Em conclusão, podemos ver que a Fortinet se baseava apenas no seu cabeçalho personalizado para aceitar ou não uma determinada solicitação.

Confiando apenas no User-Agent e no cabeçalho “forwarded”.

Poc and nuclei template for this one. pic.twitter.com/18jtyJnu2E

— Carlos Vieira (lynx) (@carlos_crowsec) October 11, 2022

10/10/2022 – Naquele mesmo dia, a equipe de CTI da Fortinet entrou em contato para saber como foi o nosso processo de revisão do patch e se poderíamos ajudar com possíveis formas de identificar o caminho de exploração da vulnerabilidade.

10/10/2022 – Somente neste dia, após várias solicitações externas, a Fortinet postou em seu site oficial de resposta a incidentes um aviso informando qual era a solução alternativa e como proteger o uso da “solução alternativa”.

A Fortinet atribuiu o CVSS 9.6 a essa vulnerabilidade, sendo a vulnerabilidade mais crítica já identificada no firewall este ano.

11/10/2022 – Nossa equipe criou um script em Python e um modelo de núcleo para automatizar o processo de identificação dessa vulnerabilidade, para ajudar nossos clientes, identificando assim antecipadamente se estavam ou não vulneráveis à nova vulnerabilidade.

13/10/2022 – No dia 13, nossa equipe decidiu publicar o código no GitHub, ajudando assim a comunidade de segurança a identificar dispositivos vulneráveis e contribuindo para manter as empresas seguras.

Importante: Nossa equipe disponibilizou os scripts que não causavam nenhum dano ao firewall, realizando apenas ações de “somente leitura”, assim ajudando a identificar e não causar nenhum tipo de dano aos clientes.

Agora que a prova de conceito está pública, estou compartilhando meu próprio script para extrair algumas informações internas, como configurações LDAP e usuários.

Você também pode usar o script para extrair toda a configuração do dispositivo.

Por enquanto, vou compartilhar apenas o script automatizado para extrair informações. https://t.co/cYdSbZMwAK

— Carlos Vieira (lynx) (@carlos_crowsec) October 13, 2022

13/10/2022 – No mesmo dia, o GreyNoise identificou que a vulnerabilidade está sendo explorada em ambiente real, então aplique o patch ASAP.

O GreyNoise observou o primeiro IP explorando CVE-2022-40684, Tentativa de Bypass de Autenticação do FortiOS. O IP aproveitou o bypass de autenticação e tentou exportar um backup da configuração do FortiOS. https://t.co/AknYbOfLYn pic.twitter.com/zdpKHYB1Kk

— GreyNoise (@GreyNoiseIO) October 13, 2022

O código de exploração e o modelo do núcleo estão disponíveis aqui:

Logo da Hakai.