Bypass Authentication

Ce chapitre sera axé sur le bypass de l'authentification utilisant LDAP comme SSO:

La requĂŞte LDAP suivante :

(&(uid=admin)(userPassword=password123))

Le filtre (&(uid=admin)(userPassword=password123)) est une requête de recherche LDAP qui utilise l'opérateur AND (&) pour combiner deux critères. Cela signifie que la recherche va chercher des entrées qui répondent aux deux conditions suivantes en même temps :

  1. (uid=admin) : Rechercher une entrée ayant l'attribut uid (identifiant utilisateur) égal à "admin".

  2. (userPassword=password123) : Rechercher une entrée ayant l'attribut userPassword (mot de passe utilisateur) égal à "password123".

En résumé

Ce filtre LDAP va donc chercher une entrée qui :

  • a un identifiant (uid) Ă©gal Ă  "admin",

  • et a un mot de passe (userPassword) Ă©gal Ă  "password123".

Si une entrée correspond aux deux conditions, elle sera retournée par la requête.

Exploitation : Bypassing Authentication with Wildcards

Imaginons une application web qui implémente un processus de connexion intégrant OpenLDAP server:

Donc on aurai une requĂŞte de connexion de ce type :

(&(uid=admin)(userPassword=unknown))

Si on veut se connecter en tant qu'admin, il nous faudrait son mot de passe qui est inconnu. Cependant il existe une méthode pour la contourner en utilisant une wildcard * ce qui donnerait :

(&(uid=admin)(userPassword=*))

Le filtre (&(uid=admin)(userPassword=*)) utilise une wildcard (ou "caractère générique") * dans la condition userPassword=*. Cette wildcard signifie "n'importe quelle valeur" et permet d'ignorer la valeur exacte du mot de passe.

Explication du filtre avec la wildcard

Dans ce filtre LDAP :

  1. (uid=admin) : On cherche une entrée dont l'attribut uid est égal à "admin".

  2. (userPassword=*) : On cherche une entrée où l'attribut userPassword existe et peut avoir n’importe quelle valeur, sans vérifier si cette valeur est correcte.

Le caractère * permet donc de rechercher toutes les entrées où userPassword est défini, sans vérifier la valeur exacte.

Pourquoi utiliser cette technique pour un bypass d'authentification ?

En pratique, ce type de filtre peut être exploité dans un système d'authentification mal configuré. En effet, si une application utilise directement ce filtre pour valider l’accès d’un utilisateur, voici ce qui pourrait se passer :

  1. L’utilisateur malveillant envoie une requête LDAP avec (&(uid=admin)(userPassword=*)).

  2. Ce filtre ne vérifie pas le mot de passe exact, mais uniquement que l’attribut userPassword existe.

  3. Si le serveur LDAP accepte cette requête sans vérifier la valeur du mot de passe, l’utilisateur pourrait être authentifié comme "admin" sans fournir le mot de passe réel.

Pourquoi cette faille est-elle possible ?

Cette faille est due à une mauvaise configuration de l’authentification LDAP, où la validation de la valeur du mot de passe est mal implémentée. Le serveur LDAP accepte alors userPassword=* comme un critère valide pour l’authentification, ce qui contourne le besoin de vérifier le mot de passe exact.

Il est possible de réintérer la même chose, si on connait aucun user et ça sera le premier du répertoire qui sera utilisé

(&(uid=*)(userPassword=*))

De mĂŞme si on connait une partie du username

(&(uid=admin*)(userPassword=*))
(&(uid=*admin*)(userPassword=*))

Exploitation : Bypassing Authentication without Wildcards

Par moment, la wildcard est blacklist donc faut trouver un autre moyen tels que l'injection suivante :

<username>)(|(&

Ce qui donne :

(&(uid=admin)(|(&)(userPassword=abc)))

Le filtre (&(uid=admin)(|(&)(userPassword=abc))) est une injection LDAP qui tente de contourner l'authentification en utilisant une syntaxe de filtre complexe pour forcer le système à accepter l'entrée.

Décomposition du filtre

Ce filtre comporte plusieurs éléments importants :

  1. (uid=admin) : Cette partie recherche une entrée dont l'attribut uid est égal à "admin".

  2. (|(&)(userPassword=abc)) :

    • (|...) : Ce bloc utilise l'opĂ©rateur OR pour combiner les conditions Ă  l'intĂ©rieur.

    • (&) : Ce morceau Ă  l'intĂ©rieur du OR reprĂ©sente une expression "toujours vraie" (True) en LDAP. C'est une astuce pour dire au serveur LDAP que cette condition est automatiquement remplie.

    • (userPassword=abc) : Cette condition serait normalement utilisĂ©e pour vĂ©rifier si userPassword vaut "abc".

But de cette injection

Le filtre (|(&)(userPassword=abc)) dans son ensemble est conçu pour retourner True dès lors que (uid=admin) est trouvé. Étant donné que (&) renvoie toujours vrai, le OU (|(...)) fait en sorte que le filtre soit satisfait même si userPassword n'est pas "abc".

Résumé

Ce type de filtre injecté :

  1. Contourne la vérification exacte du mot de passe en utilisant des expressions "toujours vraies" ((&)).

  2. Permet de passer l’authentification en retournant vrai pour (uid=admin) sans vérifier le mot de passe.

Conclusion

Cette injection est une méthode de contournement dans un contexte où le caractère générique * est interdit. Elle utilise les opérateurs logiques pour forcer l’accès sans valider réellement les identifiants, ce qui exploite une faiblesse de validation dans le filtre LDAP.

Last updated