Continuamos analisando vulnerabilidades de comutadores industriais: executamos código arbitrário sem senha



Na Pesquisa positiva 2019, revisamos o Moxa Industrial Switch Management Protocol. Desta vez, continuaremos este tópico e analisaremos em detalhes a vulnerabilidade CVE-2018-10731 nos comutadores Phoenix Contact da linha de modelos FL SWITCH 3xxx, FL SWITCH 4xxx e FL SWITCH 48xx identificados por nossos especialistas. Essa vulnerabilidade, detectada na interface da web do dispositivo, permite a execução de código arbitrário sem conhecer as credenciais do dispositivo e é classificada em 9 de 10 na escala CVSS versão 3.

Primeira vista


Os dispositivos mencionados acima estão executando o Linux e você pode usar a interface da web para configurá-los. Como em muitos outros dispositivos de IoT, domésticos e industriais, a interface da Web consiste em muitos aplicativos CGI que processam solicitações HTTP do usuário. No nosso caso, os aplicativos CGI usam ativamente a biblioteca cgic, o que facilita o trabalho com solicitações HTTP, e as funções dessa biblioteca são incorporadas à biblioteca compartilhada libipinfusionweb.solocalizada no sistema de arquivos do dispositivo.

Ao processar uma solicitação HTTP, o servidor da Web passa os dados da solicitação do usuário para o aplicativo CGI como um conjunto de variáveis ​​de ambiente. Seu processamento inicial é realizado pela função de mainbiblioteca libipinfusionweb. Em seguida, a função mainchama a função do cgiMainaplicativo CGI, na qual o processamento adicional da solicitação ocorre.



Figura 1. Processando uma solicitação HTTP

No decorrer de seu trabalho, a função principal da biblioteca libipinfusionwebchama uma função get_login_userque determina se o usuário passou a autenticação no sistema usando os valores de Cookie passados.



Figura 2. Fragmento de pseudocódigo da

função principal A função get_login_userrecebe o valor do parâmetro Cookie c_sessionusando a função cookies_get_valuee o armazena em uma variável local_e0. A variável em si local_e0é uma matriz de caracteres de byte único com um comprimento de 0x80 e está localizada a uma distância de 0xE0 do início da pilha.



Figura 3. Fragmento do pseudocódigo da função get_login_user

No entanto, no código da função cookies_get_value, pode ser visto que o cgiCookieStringvalor do parâmetro Cookie recebido pela função possui um comprimento máximo de 0x400 bytes.



Figura 4. Um fragmento do pseudocódigo da função cookies_get_value

Assim, ao passar um parâmetro Cookie com mais de 0xE0 (224) caracteres, a função get_login_usersalvará o valor desse parâmetro em sua pilha, resultando na local_e0substituição de todas as informações na pilha atrás da variável , incluindo o endereço função de retorno.

Nota: Quando uma função chama outra, o endereço de retorno é armazenado na pilha. O controle é transferido para esse endereço quando a função chamada termina seu trabalho. Portanto, se você reescrever esse endereço, poderá obter controle sobre o processo de execução do programa. Por exemplo, um invasor pode substituir esse endereço pelo endereço de um código de shell malicioso localizado no espaço de endereço do programa.

Observe que a reescrita do endereço de retorno ocorre antes da verificação da autenticação, o que torna possível explorar essa vulnerabilidade para um invasor que não conhece as credenciais do dispositivo.

Exploração


Examinamos várias opções para demonstrar a possibilidade de explorar essa vulnerabilidade. O mais simples é escrever o código da carga útil na pilha (0x400 - 0xE0 = 800 bytes permanece para ele, basta o código) e reescrever o endereço de retorno com o endereço do código. Teoricamente, essa opção era possível, pois o processador do comutador vulnerável não suporta a função NX-bit (ou seja, permite a execução de código localizado em qualquer lugar, inclusive na pilha), mas na prática tinha sérias limitações.

O processador de switch vulnerável possui uma arquitetura MIPS; muitas das instruções do processador nessa arquitetura são codificadas em sequências de bytes que contêm zero bytes. O conteúdo do buffer é gravado no primeiro byte zero (devido ao uso da funçãostrcpy), portanto, é necessário usar apenas operandos que não contenham um byte nulo, o que é impossível, pois qualquer carga útil usaria pelo menos vários desses bytes.

Ao construir a cadeia ROP, novamente, teríamos que enfrentar as restrições do byte nulo: o endereço dos dispositivos ROP não deve conter zeros, o que complica bastante sua pesquisa. Em geral, só poderíamos usar um zero, copiado pela função strcpy. Isso impõe uma limitação à criação de uma cadeia de ROP completa e, além disso, os gadgets de que precisávamos eram extremamente poucos. No entanto, durante as pesquisas na biblioteca libipinfusionweb, foi encontrado o seguinte fragmento de código:



Figura 5. Um fragmento do código executável da biblioteca libipinfusionweb

Desde que o conteúdo do registro $ s0 seja controlado, esse fragmento de código permite executar um comando do SO usando uma função mysystem(inicialmente essa função não tinha um nome, mas a renomeamos, pois é muito semelhante à função do sistema no Linux).

Como estamos reescrevendo o endereço de retorno da função get_login_user, essa função será executada até o final. No epílogo da função get_login_user, você pode ver que o valor do registro $ s0 é restaurado do valor salvo anteriormente na pilha (no deslocamento 0xD8 da parte superior da pilha). No entanto, neste momento, esta área da pilha já está sob nosso controle, isto é, de fato, podemos alcançar o controle sobre o conteúdo do registrador $ s0 e, assim, executar comandos arbitrários OS usando a função mysystem.



Figura 6. Um trecho do código executável da função get_login_user

. Para demonstrar com êxito a exploração dessa vulnerabilidade, precisamos enviar como parâmetro uma Cookie c_sessionlinha longa que contém:

  • Comando de cadeia do SO, que será posteriormente passado para a função mysystem;
  • o endereço desse comando na pilha;
  • novo endereço de retorno (endereço do fragmento de código mostrado na Fig. 5).

A carga útil final deve se parecer com a seguinte:



Figura 7. Carga útil

Neste ponto, já tínhamos um shell no dispositivo obtido usando uma vulnerabilidade que precisava de direitos de administrador para operar. Portanto, conseguimos obter informações adicionais que nos ajudaram a operar:

  • O ASLR no dispositivo em estudo foi desativado - portanto, os endereços do gadget usado e os comandos do SO sempre serão os mesmos.



Figura 8. Status do ASLR no dispositivo sob investigação

  • O intervalo de endereços de memória em que a pilha pode estar. Para calcular o endereço exato, examinamos todos os endereços desse intervalo.

Como carga útil, implementamos o carregamento de um web shell, um aplicativo CGI com o seguinte conteúdo:

#!/bin/sh
eval $HTTP_CMD 2>&1

Como, de acordo com o protocolo CGI, o conteúdo dos cabeçalhos HTTP é transmitido ao aplicativo CGI na forma de variáveis ​​de ambiente com os nomes HTTP_ <Header Name>, este shell utilizará o comando evalpara executar o conteúdo do cabeçalho HTTP CMD. A figura abaixo mostra o resultado da operação e execução bem-sucedidas do comando ls usando o shell carregado.



Figura 9. O resultado da operação e execução bem-sucedidas do comando ls

Conclusão


Demonstramos a capacidade de explorar essa vulnerabilidade. Como já mencionamos, sua operação não requer conhecimento da senha e, portanto, pode ser executada mesmo por um invasor não autenticado.

Hackear um switch de rede industrial pode comprometer toda a produção. A violação da interação da rede pode afetar adversamente o processo até que ele pare completamente.

As informações sobre a vulnerabilidade e o PoC foram transmitidas ao fornecedor, que lançou a versão atualizada do firmware 1.34, e o identificador CVE-2018-10731 foi atribuído à própria vulnerabilidade.

À procura de uma pessoa


Se você deseja fazer essas coisas, estamos apenas procurando um especialista em nossa equipe. Estamos envolvidos na análise de segurança de sistemas de controle de processos (grandes instalações industriais / de energia / transporte, etc.). Em cada projeto, procuramos maneiras de parar ou interromper a operação desses objetos. Cada vez que encontramos muitas maneiras de influenciar o processo de fabricação, explorando hardware e software industrial, analisando protocolos de rede proprietários. Encontramos e relatamos muito zirodey, escrevemos relatórios (não de acordo com o GOST) e fazemos muito mais. Quando há tempo, falamos no IB e não apenas em conferências. Link para a vaga: hh.ru/vacancy/36371389

Publicado por Vyacheslav Moskvin, Positive Technologies

All Articles