Deeplink hijacking
Les activités utilisant les deeplinks étant exportées, n'importe quel application y a accès, Si celui-ci n'est pas correctement configuré et validé via un Asset Link correct, il est alors possible de créer une application utilisant exactement le même deeplink afin de potentiellement pouvoir intercepter des données sensibles.
Ressources utiles:
Deeplink Hijacking to ATO
Un cas très courant auparavant, beaucoup moins aujourd'hui est l'interception un jeton d'accès valide via deeplink hijacking.
En effet, lorsqu'une application mobile utilise le framework OAuth 2.0 pour l'authentification des utilisateurs, elle doit respecter deux réglementations de sécurité importantes.
La RFC 6749
La RFC 6749 définit le framework OAuth 2.0 : comment une application obtient un accès sécurisé à une API au nom d’un utilisateur.
L'objectif étant d'éviter qu'une application ne manipule directement le mot de passe de l'utilisateur.
Pour cela, OAuth 2.0 permet de:
S’authentifie auprès d'un fournisseur d’identité
Recevoir un token d’accès
Appeler les APIs avec ce même token
Il existe plusieurs flows d'authentifications plus ou moins sécurisés avec des potentielles vulnérabilités à différents niveaux
Ressource:
👋OAuthCependant, La RFC 6749 a été conçue avant l’explosion des apps mobiles modernes.
Elle ne précise pas clairement :
comment gérer les redirections mobiles
les navigateurs système à privilégier ou à éviter
les risques des WebViews
les les risques des URI custom schemes
Comment éviter les attaques d’interception de code.
C’est précisément ce que complète RFC 8252.
La RFC 8252
La RFC 8252 est un guide de sécurité spécialisé pour :
Android
iOS
Applications de bureau
Elle modernise l’usage d’OAuth sur mobile.
Elle met en avant les bonnes pratiques et des moyens de défense contre certains risques spécifiques aux applications faisant usage de deeplinks principalement.
Les principaux points d'attentions étant:
L'utilisation de Custom Tabs plutôt que de WebViews
L'utilisation du flow OAuth Code Flow + PKCE
La gestion des Custom URIs, Asset Links etc
Une application qui ne respecte pas ces recommandations s'expose donc à plusieurs risques dont des risques de deeplink hijacking pouvant mener à des ATO.
Exploitation
Dans un premier temps, il est donc nécessaire de savoir déceler des mauvaises pratiques et des non conformités avec ces RFC.
Deeplinks
Evidemment, la première chose à vérifier est si l'application cible utilise des deeplinks et si un ou plusieurs de ces deeplinks sont utilisés dans un processus d'authentification OAuth.
Voir la page précèdente pour la méthodologie:
🔗Deeplinks vulnsUne fois les deeplinks extraits, on peut vérifier s'ils sont utilisés lors d'authentifications OAuth de différentes manières:
On peut essayer de les trigger directement via un intent ou un hyperlien pour voir le comportement de l'app.
On peut essayer de se connecter à l'application tout en observant les logs logcat (Les liens de redirection OAuth sont souvent loggés).
On peut utiliser un outil d'instrumentalisation comme frida-trace.
On peut vérifier dans le code décompilé comment fonctionne le traitement des deeplinks
Asset Link
Une fois qu'un deeplink a été identifié comme utilisé dans un flow OAuth, il faut alors vérifier si un Deeplink Hijacking est exploitable.
Il est possible d'hijack un deeplink si:
Le deeplink utilise une URI custom: Si une URI custom est utilisée, alors il ne peut pas y avoir de vérification d'App Link et des applications tierces peuvent donc enregistrer le même deeplink.
Exemple:
L'application utilise une URL comme deeplink mais que celle-ci ne dispose pas d'un Asset Link valide
Se référer à la page:
Invalid Digital assets linksFlow OAuth
Si le deeplink peut être intercepté, alors cela représente déjà une vulnérabilité en tant que tel car cela peut permettre de rediriger un utilisateur vers une application tierce à la fin d'un processus d'authentification dans un scénario de phishing ciblé.
Cependant, l'intérêt final pour un attaquant serait de pouvoir exfiltrer les paramètres du callback qui contient les données qui lui permettraient de générer un jeton d'accès au nom de sa victime et atteindre un ATO.
Pour cela, il reste donc à vérifier si le Flow OAuth de utilisé est vulnérable (si flow OAuth Code Flow + PKCE n'est pas respecté)
Absence ou mauvaise implémentation de Proof Key for Code Exchange (PKCE)
PKCE permet de s'assurer que seule l'application qui a initié la demande peut demander et obtenir le jeton d'accès. Ce mécanisme résout ce problème en introduisant un concept de "preuve de clé".
Lors de la demande d'un code d'autorisation, l'application génère d'abord un "code_verifier" aléatoire et le stocke localement. Elle convertit ensuite ce "code_verifier" en un "code_challenge" en utilisant des algorithmes spécifiques. L'application envoie à la fois le "code_challenge" et la méthode du "code_challenge" au serveur d'authentification lors de la demande de code d'autorisation.
Le "code_verifier" est une chaîne générée aléatoirement, et le "code_challenge" est dérivé du "code_verifier" par conversion. Deux méthodes de conversion sont prises en charge :
plain: utilise directement le "code_verifier" comme "code_challenge" (pas idéal en terme de sécurité)
S256: applique un hachage SHA-256 au "code_verifier", suivi par un encodage Base64URL. Comme le résultat du hachage ne peut pas être inversé pour obtenir le "code_verifier", et parce que la méthodeplainpourrait être vulnérable aux attaques de type MitM pendant la transmission, l'utilisation deS256est fortement recommandée pour des raisons de sécurité.
Après l'authentification de l'utilisateur, le serveur d'authentification retourne le code d'autorisation à l'application. Lors de la demande d'un jeton d'accès, l'application envoie à la fois le code d'autorisation et le "code_verifier" au serveur d'authentification. Le serveur transforme le "code_verifier" en utilisant la méthode de "code_challenge" précédemment reçue et compare le résultat avec le "code_challenge" précédemment reçu pour vérifier la possession par le client du "code_verifier".
Ainsi, si l'application utilise uniquement le Code Flow OAuth, l'attaquant peut intercepter le deeplink et récupérer le code d'autorisation ("authorization_code").
Exemple:
En l'absence d'une validation supplémentaire via "code_verifier", l'attaquant peut ensuite envoyer une requête de pour récupérer un "access_token" valide.
Exemple:
Tips: Lors de la création d'un exploit de deeplink hijacking, il est intéressant d'utiliser android:priority="999" dans la balise <intent-filter> contenant le deeplink pour dire à Android que l'application malveillante a la priorité sur l'application légitime pour ce deeplink et la faire apparaître en première dans la pop-up de choix d'appli.
Contournements et dérivés possibles
code_verifier prédictible: Si le code_verifier n'est pas suffisemment aléatoire et robuste (valeur fixe, faible entropie, réutilisable)
code_verifier stocké de manière non sécurisé: récupérable par l'application tierce malveillante
OAuth misconfig:
serveur accepte PKCE optionnel
accepte
plainaccepte downgrade
accepte redirect_uri partielle
plusieurs flows autorisés
wildcard redirect_uri
Sur-exposition de données dans le callback: si le JWT se retrouve directement dans le callback par exemple
Outils
DeepLinkHijackingPoC
script python permettant de compiler (+ installer) simplement et rapidement une application PoC avec un deeplink spécifique en entrée utilisateur.
Exemple d'utilisation:
Ressource: https://github.com/mathis2001/DeepLinkHijackingPoC
Mis à jour