Translated ['mobile-pentesting/android-app-pentesting/README.md', 'netwo

This commit is contained in:
Translator 2023-07-17 13:23:21 +00:00
parent a29be56125
commit 8c75ea0599
2 changed files with 373 additions and 234 deletions

View file

@ -5,7 +5,7 @@
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
@ -17,7 +17,7 @@
**HackenProof est la plateforme des primes de bugs cryptographiques.**
**Obtenez des récompenses sans délai**\
Les primes HackenProof ne sont lancées que lorsque leurs clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
Les primes HackenProof ne sont lancées que lorsque les clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
**Acquérez de l'expérience en pentesting web3**\
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 dès ses débuts.
@ -25,7 +25,7 @@ Les protocoles blockchain et les contrats intelligents sont le nouvel Internet !
**Devenez la légende du hacker web3**\
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) commencez à gagner grâce à vos hacks !
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) commencez à gagner grâce à vos piratages !
{% embed url="https://hackenproof.com/register" %}
@ -73,7 +73,7 @@ Les primes HackenProof ne sont lancées que lorsque leurs clients déposent le b
**Acquérez de l'expérience en pentesting web3**\
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 à ses débuts.
**Devenez une légende du hacking web3**\
**Devenez la légende du hacker web3**\
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) et commencez à gagner grâce à vos hacks !
@ -136,11 +136,11 @@ android:filterTouchesWhenObscured="true">
Vous pouvez utiliser [**qark**](https://github.com/linkedin/qark) avec le paramètre `--exploit-apk` pour créer une application malveillante afin de tester les vulnérabilités potentielles de **Tapjacking**.\
Un projet d'exemple implémentant ce type de fonctionnalité peut être trouvé dans [**FloatingWindowApp**](https://github.com/aminography/FloatingWindowApp).
La mitigation est relativement simple car le développeur peut choisir de ne pas recevoir les événements tactiles lorsqu'une vue est recouverte par une autre. Utilisez la [Référence du développeur Android](https://developer.android.com/reference/android/view/View#security):
La mitigation est relativement simple car le développeur peut choisir de ne pas recevoir les événements tactiles lorsqu'une vue est recouverte par une autre. Utilisez la [Référence du développeur Android](https://developer.android.com/reference/android/view/View#security) :
> Parfois, il est essentiel qu'une application puisse vérifier qu'une action est effectuée avec la pleine connaissance et le consentement de l'utilisateur, comme accorder une demande d'autorisation, effectuer un achat ou cliquer sur une publicité. Malheureusement, une application malveillante pourrait essayer de tromper l'utilisateur en lui faisant effectuer ces actions, sans le savoir, en dissimulant l'objectif réel de la vue. Pour remédier à cela, le framework propose un mécanisme de filtrage tactile qui peut être utilisé pour améliorer la sécurité des vues qui fournissent un accès à des fonctionnalités sensibles.
>
> Pour activer le filtrage tactile, appelez [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29) ou définissez l'attribut de mise en page android:filterTouchesWhenObscured sur true. Lorsqu'il est activé, le framework ignorera les touches reçues chaque fois que la fenêtre de la vue est masquée par une autre fenêtre visible. Par conséquent, la vue ne recevra pas de touches chaque fois qu'un toast, une boîte de dialogue ou une autre fenêtre apparaîtra au-dessus de la fenêtre de la vue.
> Pour activer le filtrage tactile, appelez [`setFilterTouchesWhenObscured(boolean)`](https://developer.android.com/reference/android/view/View#setFilterTouchesWhenObscured%28boolean%29) ou définissez l'attribut de mise en page android:filterTouchesWhenObscured sur true. Lorsqu'il est activé, le framework ignorera les touches reçues chaque fois que la fenêtre de la vue est masquée par une autre fenêtre visible. Par conséquent, la vue ne recevra pas de touches chaque fois qu'un toast, une boîte de dialogue ou une autre fenêtre apparaît au-dessus de la fenêtre de la vue.
### Détournement de tâche
@ -152,17 +152,17 @@ La mitigation est relativement simple car le développeur peut choisir de ne pas
**Stockage interne**
Les fichiers **créés** sur le **stockage interne** sont **accessibles** uniquement par l'**application**. Cette protection est implémentée par Android et est suffisante pour la plupart des applications. Cependant, les développeurs utilisent souvent `MODE_WORLD_READBALE` et `MODE_WORLD_WRITABLE` pour donner accès à ces fichiers à une autre application, mais cela ne limite pas les autres applications (malveillantes) à y accéder.\
Lors de l'**analyse statique**, vérifiez l'utilisation de ces **modes**, lors de l'**analyse dynamique**, vérifiez les **permissions** des fichiers créés (certains d'entre eux peuvent être lisibles/inscriptibles dans le monde entier).\
Les fichiers **créés** sur le **stockage interne** sont **accessibles** uniquement par l'**application**. Cette protection est mise en œuvre par Android et est suffisante pour la plupart des applications. Cependant, les développeurs utilisent souvent `MODE_WORLD_READBALE` et `MODE_WORLD_WRITABLE` pour donner accès à ces fichiers à une autre application, mais cela ne limite pas les autres applications (malveillantes) à y accéder.\
Lors de l'**analyse statique**, vérifiez l'utilisation de ces **modes**, lors de l'**analyse dynamique**, vérifiez les **autorisations** des fichiers créés (certains d'entre eux peuvent être lisibles/inscriptibles dans le monde entier).\
[Plus d'informations sur cette vulnérabilité et comment la corriger ici.](https://manifestsecurity.com/android-application-security-part-8/)
**Stockage externe**
Les fichiers créés sur le **stockage externe**, tels que les cartes SD, sont **lisibles et inscriptibles globalement**. Étant donné que le stockage externe peut être retiré par l'utilisateur et également modifié par n'importe quelle application, vous ne devez **pas stocker d'informations sensibles à l'aide du stockage externe**.\
Les fichiers créés sur le **stockage externe**, tels que les cartes SD, sont **lisibles et inscriptibles à l'échelle mondiale**. Étant donné que le stockage externe peut être supprimé par l'utilisateur et également modifié par n'importe quelle application, vous ne devez **pas stocker d'informations sensibles à l'aide du stockage externe**.\
Comme pour les données provenant de toute source non fiable, vous devez **effectuer une validation des entrées** lors de la manipulation de **données provenant du stockage externe**. Nous vous recommandons vivement de ne pas stocker d'exécutables ou de fichiers de classe sur le stockage externe avant le chargement dynamique. Si votre application récupère des fichiers exécutables à partir du stockage externe, les fichiers doivent être signés et vérifiés cryptographiquement avant le chargement dynamique.\
Informations tirées [d'ici](https://manifestsecurity.com/android-application-security-part-8/).
Le stockage externe peut être **accédé** via `/storage/emulated/0`, `/sdcard`, `/mnt/sdcard`
Le stockage externe peut être **accédé** dans `/storage/emulated/0`, `/sdcard`, `/mnt/sdcard`
{% hint style="info" %}
À partir d'Android 4.4 (**API 17**), la carte SD dispose d'une structure de répertoire qui **limite l'accès d'une application au répertoire spécifique à cette application**. Cela empêche une application malveillante d'accéder en lecture ou en écriture aux fichiers d'une autre application.
@ -222,9 +222,13 @@ python3 xamarin-decompress.py -o /path/to/decompressed/apk
```
et enfin, vous pouvez utiliser [**ces outils recommandés**](../../reversing/reversing-tools-basic-methods/#net-decompiler) pour **lire le code C#** des DLL.
### Analyse statique automatisée du code
### Applications superpackées
L'outil [**mariana-trench**](https://github.com/facebook/mariana-trench) est capable de trouver des **vulnérabilités** en **scannant** le **code** de l'application. Cet outil contient une série de **sources connues** (qui indiquent à l'outil les **endroits** où l'**entrée** est **contrôlée par l'utilisateur**), des **sinks** (qui indiquent à l'outil les **endroits dangereux** où une entrée utilisateur malveillante pourrait causer des dommages) et des **règles**. Ces règles indiquent la **combinaison** de **sources-sinks** qui indique une vulnérabilité.
Selon ce [**billet de blog**](https://clearbluejar.github.io/posts/desuperpacking-meta-superpacked-apks-with-github-actions/), superpacké est un algorithme méta qui compresse le contenu d'une application dans un seul fichier. Le blog parle de la possibilité de créer une application qui décompresse ce type d'applications... et une façon plus rapide qui consiste à **exécuter l'application et à récupérer les fichiers décompressés du système de fichiers**.
### Analyse de code statique automatisée
L'outil [**mariana-trench**](https://github.com/facebook/mariana-trench) est capable de trouver des **vulnérabilités** en **analysant** le **code** de l'application. Cet outil contient une série de **sources connues** (qui indiquent à l'outil les **endroits** où l'**entrée** est **contrôlée par l'utilisateur**), des **sinks** (qui indiquent à l'outil les **endroits dangereux** où une entrée utilisateur malveillante pourrait causer des dommages) et des **règles**. Ces règles indiquent la **combinaison** de **sources-sinks** qui indique une vulnérabilité.
Avec cette connaissance, **mariana-trench examinera le code et trouvera les vulnérabilités possibles**.
@ -264,7 +268,7 @@ Les protocoles blockchain et les contrats intelligents sont le nouvel Internet !
**Devenez la légende du pirate web3**\
Gagnez des points de réputation avec chaque bogue vérifié et conquérez le sommet du classement hebdomadaire.
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) commencez à gagner grâce à vos piratages !
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) et commencez à gagner grâce à vos piratages !
{% embed url="https://hackenproof.com/register" %}
@ -286,7 +290,7 @@ Grâce à la connexion ADB, vous pouvez utiliser **Drozer** et **Frida** à l'in
Vous pouvez utiliser un **émulateur** tel que :
* [**Android Studio**](https://developer.android.com/studio) (Vous pouvez créer des appareils **x86** et **arm**, et selon [**ceci** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**les dernières versions x86** **supportent les bibliothèques ARM** sans avoir besoin d'un émulateur ARM lent).
* [**Android Studio**](https://developer.android.com/studio) (Vous pouvez créer des appareils **x86** et **arm**, et selon [**ceci** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html), les **dernières versions x86** **supportent les bibliothèques ARM** sans avoir besoin d'un émulateur ARM lent).
* Si vous voulez essayer d'**installer** une **image** puis vous voulez la **supprimer**, vous pouvez le faire sur Windows : `C:\Users\<User>\AppData\Local\Android\sdk\system-images\` ou Mac : `/Users/myeongsic/Library/Android/sdk/system-image`
* C'est l'**émulateur principal que je recommande d'utiliser et vous pouvez**[ **apprendre à le configurer sur cette page**](avd-android-virtual-device.md).
* [**Genymotion**](https://www.genymotion.com/fun-zone/) **(Version gratuite :** Personal Edition, vous devez créer un compte. _Il est recommandé de **télécharger** la version **AVEC**_ _**VirtualBox** pour éviter les erreurs potentielles._)
@ -300,7 +304,7 @@ Comme la plupart des gens utiliseront **Genymotion**, notez cette astuce. Pour *
![](<../../.gitbook/assets/image (200) (1).png>)
Remarquez également que dans la **configuration de la machine virtuelle Android dans Genymotion**, vous pouvez sélectionner le mode **Bridge Network** (ce sera utile si vous vous connectez à la machine virtuelle Android à partir d'une autre machine virtuelle avec les outils).
Remarquez également que dans la **configuration de la machine virtuelle Android dans Genymotion**, vous pouvez sélectionner le mode **Bridge Network** (ce sera utile si vous devez vous connecter à la machine virtuelle Android à partir d'une autre machine virtuelle avec les outils).
Ou vous pouvez utiliser un **appareil physique** (vous devez activer les options de débogage et ce serait bien si vous pouvez le rooter) :
@ -311,42 +315,42 @@ Ou vous pouvez utiliser un **appareil physique** (vous devez activer les options
5. Revenez en arrière et vous trouverez les **Options pour les développeurs**.
> Une fois que vous avez installé l'application, la première chose à faire est de l'essayer et d'enquêter sur ce qu'elle fait, comment elle fonctionne et de vous familiariser avec celle-ci.\
> Je vous suggère de **réaliser cette analyse dynamique initiale en utilisant l'analyse dynamique MobSF + pidcat**, afin de pouvoir **apprendre comment l'application fonctionne** pendant que MobSF **capture** de nombreuses **données intéressantes** que vous pourrez examiner ultérieurement.
### Fuite de données involontaire
> Je vous suggère de **réaliser cette analyse dynamique initiale en utilisant l'analyse dynamique MobSF + pidcat**, afin de pouvoir **apprendre comment l'application fonctionne** tout en capturant MobSF beaucoup de **données intéressantes** que vous pourrez examiner ultérieurement.
### Fuite de données non intentionnelle
**Journalisation**
Souvent, les développeurs laissent des informations de débogage accessibles au public. Ainsi, toute application avec l'autorisation `READ_LOGS` peut **accéder à ces journaux** et peut obtenir des informations sensibles à travers cela.\
Lors de la navigation dans l'application, utilisez [**pidcat**](https://github.com/JakeWharton/pidcat)_(Recommandé, il est plus facile à utiliser et à lire)_ ou [adb logcat](adb-commands.md#logcat) pour lire les journaux créés et **rechercher des informations sensibles**.
Souvent, les développeurs laissent des informations de débogage accessibles au public. Ainsi, toute application disposant de l'autorisation `READ_LOGS` peut **accéder à ces journaux** et obtenir des informations sensibles.\
Lors de la navigation dans l'application, utilisez [**pidcat**](https://github.com/JakeWharton/pidcat)_(Recommandé, il est plus facile à utiliser et à lire_) ou [adb logcat](adb-commands.md#logcat) pour lire les journaux créés et **rechercher des informations sensibles**.
{% hint style="warning" %}
Notez que **à partir des versions ultérieures d'Android 4.0**, **les applications ne peuvent accéder qu'à leurs propres journaux**. Les applications ne peuvent donc pas accéder aux journaux d'autres applications.\
Notez que **à partir des versions ultérieures à Android 4.0**, **les applications ne peuvent accéder qu'à leurs propres journaux**. Les applications ne peuvent donc pas accéder aux journaux d'autres applications.\
Quoi qu'il en soit, il est toujours recommandé de **ne pas enregistrer d'informations sensibles**.
{% endhint %}
**Mise en cache du presse-papiers**
Android fournit un framework basé sur le presse-papiers pour fournir la fonction de copier-coller dans les applications Android. Mais cela crée un problème sérieux lorsque certaines **autres applications** peuvent **accéder** au **presse-papiers** qui contient des données sensibles. La fonction de copier-coller devrait être **désactivée** pour les parties sensibles de l'application. Par exemple, désactivez la copie des détails de la carte de crédit.
Android fournit un framework basé sur le presse-papiers pour permettre la fonction de copier-coller dans les applications Android. Mais cela crée un problème sérieux lorsque **une autre application** peut **accéder** au **presse-papiers** qui contient des données sensibles. La fonction de **copier-coller** devrait être **désactivée** pour les parties **sensibles** de l'application. Par exemple, désactivez la copie des détails de la carte de crédit.
**Journaux de plantage**
Si une application **plante** pendant son exécution et qu'elle **enregistre des journaux** quelque part, ces journaux peuvent être utiles à un attaquant, surtout dans les cas où l'application Android ne peut pas être inversée. Ensuite, évitez de créer des journaux lorsque les applications plantent et si les journaux sont envoyés via le réseau, assurez-vous qu'ils sont envoyés via un canal SSL.\
En tant que pentester, **essayez de jeter un coup d'œil à ces journaux**.
Si une application **plante** pendant son exécution et qu'elle **enregistre des journaux** quelque part, ces journaux peuvent être utiles à un attaquant, surtout dans les cas où l'application Android ne peut pas être rétro-ingénierée. Dans ce cas, évitez de créer des journaux lorsque l'application plante et si les journaux sont envoyés via le réseau, assurez-vous qu'ils sont envoyés via un canal SSL.\
En tant que pentester, **essayez de consulter ces journaux**.
**Données d'analyse envoyées à des tiers**
La plupart des applications utilisent d'autres services dans leur application, comme Google Adsense, mais parfois elles **laissent échapper des données sensibles** ou des données qui ne sont pas nécessaires à envoyer à ce service. Cela peut se produire parce que le développeur n'a pas correctement implémenté la fonctionnalité. Vous pouvez **vérifier en interceptant le trafic** de l'application et voir si des données sensibles sont envoyées à des tiers ou non.
**Données analytiques envoyées à des tiers**
La plupart des applications utilisent d'autres services dans leur application, comme Google Adsense, mais parfois elles **laissent fuir** des données sensibles ou des données qui ne sont pas nécessaires à l'envoi à ce service. Cela peut se produire parce que le développeur n'a pas implémenté correctement la fonctionnalité. Vous pouvez **vérifier en interceptant le trafic** de l'application et voir si des données sensibles sont envoyées à des tiers ou non.
### Bases de données SQLite
La plupart des applications utiliseront des **bases de données SQLite internes** pour enregistrer des informations. Lors du test de pénétration, **vérifiez** les **bases de données** créées, les noms des **tables** et des **colonnes** et toutes les **données** enregistrées, car vous pourriez trouver des **informations sensibles** (ce qui constituerait une vulnérabilité).\
La plupart des applications utilisent des **bases de données SQLite internes** pour enregistrer des informations. Lors du pentest, **consultez** les **bases de données** créées, les noms des **tables** et des **colonnes** et toutes les **données** enregistrées, car vous pourriez trouver des **informations sensibles** (ce qui constituerait une vulnérabilité).\
Les bases de données doivent être situées dans `/data/data/nom.du.package/databases` comme `/data/data/com.mwr.example.sieve/databases`
Si la base de données enregistre des informations confidentielles et est **chiffrée**, mais que vous pouvez **trouver** le **mot de passe** dans l'application, c'est toujours une **vulnérabilité**.
Si la base de données enregistre des informations confidentielles et est **chiffrée**, mais que vous pouvez **trouver** le **mot de passe** à l'intérieur de l'application, c'est toujours une **vulnérabilité**.
Énumérez les tables en utilisant `.tables` et énumérez les colonnes des tables en utilisant `.schema <nom_de_la_table>`
### Drozer (Exploiter les activités, les fournisseurs de contenu et les services)
### Drozer (Exploiter les activités, les fournisseurs de contenu et les services exportés)
**Drozer** vous permet de **prendre le rôle d'une application Android** et d'interagir avec d'autres applications. Il peut faire **tout ce qu'une application installée peut faire**, comme utiliser le mécanisme de communication inter-processus (IPC) d'Android et interagir avec le système d'exploitation sous-jacent. À partir du [Guide Drozer](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf).\
Drozer est un outil utile pour **exploiter les activités exportées, les services exportés et les fournisseurs de contenu**, comme vous le verrez dans les sections suivantes.
@ -363,7 +367,7 @@ Lorsqu'une activité est exportée, vous pouvez invoquer son écran à partir d'
Vous pouvez également démarrer une activité exportée depuis adb :
* PackageName est com.example.demo
* Le nom du package est com.example.demo
* Le nom de l'activité exportée est com.example.test.MainActivity
```
adb shell am start -n com.example.demo/com.example.test.MainActivity
@ -427,17 +431,17 @@ Chaque fois que vous trouvez un lien profond, vérifiez qu'il ne reçoit pas de
**Paramètres dans le chemin**
Vous devez également vérifier si un lien profond utilise un paramètre dans le chemin de l'URL, par exemple : `https://api.example.com/v1/users/{username}`, dans ce cas, vous pouvez forcer une traversée de chemin en accédant à quelque chose comme : `example://app/users?username=../../unwanted-endpoint%3fparam=value`.\
Notez que si vous trouvez les points d'extrémité corrects dans l'application, vous pourrez peut-être provoquer une **redirection ouverte** (si une partie du chemin est utilisée comme nom de domaine), une **prise de contrôle de compte** (si vous pouvez modifier les détails des utilisateurs sans jeton CSRF et que le point d'extrémité vulnérable utilise la méthode correcte) et toute autre vulnérabilité. Plus d'informations à ce sujet [ici](http://dphoeniixx.com/2020/12/13-2/).
Notez que si vous trouvez les points d'extrémité corrects dans l'application, vous pourriez être en mesure de provoquer une **redirection ouverte** (si une partie du chemin est utilisée comme nom de domaine), une **prise de contrôle de compte** (si vous pouvez modifier les détails des utilisateurs sans jeton CSRF et que le point d'extrémité vulnérable utilise la méthode correcte) et toute autre vulnérabilité. Plus d'informations à ce sujet [ici](http://dphoeniixx.com/2020/12/13-2/).
**Plus d'exemples**
Un [rapport intéressant sur les primes de bug](https://hackerone.com/reports/855618) concernant les liens (_/.well-known/assetlinks.json_).
Un [rapport intéressant de prime de bug](https://hackerone.com/reports/855618) sur les liens (_/.well-known/assetlinks.json_).
### Protection insuffisante de la couche de transport
* **Absence d'inspection de certificat :** L'application Android ne parvient pas à vérifier l'identité du certificat qui lui est présenté. La plupart des applications ignorent les avertissements et acceptent n'importe quel certificat auto-signé présenté. Certaines applications passent plutôt le trafic par une connexion HTTP.
* **Négociation de poignée de main faible :** L'application et le serveur effectuent une poignée de main SSL/TLS, mais utilisent une suite de chiffrement non sécurisée qui est vulnérable aux attaques de l'homme du milieu (MITM). Ainsi, tout attaquant peut facilement décrypter cette connexion.
* **Fuite d'informations de confidentialité :** La plupart du temps, il arrive que les applications effectuent une authentification via un canal sécurisé, mais que toutes les autres connexions se fassent via un canal non sécurisé. Cela n'ajoute rien à la sécurité de l'application, car les données sensibles restantes, telles que les cookies de session ou les données utilisateur, peuvent être interceptées par un utilisateur malveillant.
* **Fuite d'informations de confidentialité :** La plupart du temps, il arrive que les applications effectuent une authentification via un canal sécurisé, mais toutes les autres connexions se font via un canal non sécurisé. Cela n'ajoute rien à la sécurité de l'application car les données sensibles restantes, telles que les cookies de session ou les données utilisateur, peuvent être interceptées par un utilisateur malveillant.
Parmi les 3 scénarios présentés, nous allons discuter de **comment vérifier l'identité du certificat**. Les 2 autres scénarios dépendent de la **configuration TLS** du serveur et de l'envoi ou non de données non chiffrées par l'application. Le testeur de pénétration doit vérifier par lui-même la configuration TLS du serveur ([ici](../../network-services-pentesting/pentesting-web/#ssl-tls-vulnerabilites)) et détecter si des **informations confidentielles sont envoyées par un canal non chiffré/vulnérable**.\
Plus d'informations sur la découverte et la correction de ce type de vulnérabilités [**ici**](https://manifestsecurity.com/android-application-security-part-10/).
@ -446,7 +450,7 @@ Plus d'informations sur la découverte et la correction de ce type de vulnérabi
Par défaut, lors de l'établissement d'une connexion SSL, le client (application Android) vérifie que le certificat du serveur a une chaîne de confiance vérifiable remontant à un certificat de confiance (racine) et correspond au nom d'hôte demandé. Cela pose un problème d'**attaques de l'homme du milieu (MITM)**.\
Dans l'épinglage de certificat, une application Android contient elle-même le certificat du serveur et ne transmet les données que si le même certificat est présenté.\
Il est recommandé d'**appliquer l'épinglage SSL** pour les sites où des informations sensibles doivent être envoyées.
Il est recommandé d'**appliquer l'épinglage SSL** pour les sites où des informations sensibles vont être envoyées.
### Inspection du trafic HTTP
@ -495,7 +499,7 @@ C'est dangereux car **un attaquant peut forcer l'application à lancer un compos
Vous connaissez probablement ce type de vulnérabilités sur le Web. Vous devez être particulièrement prudent avec ces vulnérabilités dans une application Android :
* **Injection SQL :** Lorsque vous travaillez avec des requêtes dynamiques ou des fournisseurs de contenu, assurez-vous d'utiliser des requêtes paramétrées.
* **Injection JavaScript (XSS) :** Vérifiez que la prise en charge de JavaScript et des plugins est désactivée pour tous les WebViews (désactivée par défaut). [Plus d'informations ici](webview-attacks.md#javascript-enabled).
* **Injection JavaScript (XSS) :** Vérifiez que JavaScript et la prise en charge des plugins sont désactivés pour tous les WebViews (désactivés par défaut). [Plus d'informations ici](webview-attacks.md#javascript-enabled).
* **Inclusion de fichiers locaux :** Vérifiez que l'accès au système de fichiers est désactivé pour tous les WebViews (activé par défaut) `(webview.getSettings().setAllowFileAccess(false);)`. [Plus d'informations ici](webview-attacks.md#javascript-enabled).
* **Cookies persistants** : Dans plusieurs cas, lorsque l'application Android termine la session, le cookie n'est pas révoqué ou il peut même être enregistré sur le disque.
* [**Drapeau de sécurité** dans les cookies](../../pentesting-web/hacking-with-cookies/#cookies-flags)
@ -505,15 +509,15 @@ Vous connaissez probablement ce type de vulnérabilités sur le Web. Vous devez
**HackenProof est la plateforme des primes pour les bugs de cryptographie.**
**Obtenez une récompense sans délai**\
Les primes HackenProof sont lancées uniquement lorsque les clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bogue.
Les primes HackenProof ne sont lancées que lorsque leurs clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
**Acquérez de l'expérience en pentesting web3**\
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 à ses débuts.
**Devenez la légende du hacker web3**\
Gagnez des points de réputation avec chaque bogue vérifié et conquérez le sommet du classement hebdomadaire.
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) commencez à gagner grâce à vos hacks !
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) et commencez à gagner grâce à vos hacks !
{% embed url="https://hackenproof.com/register" %}
@ -530,40 +534,40 @@ Gagnez des points de réputation avec chaque bogue vérifié et conquérez le so
docker pull opensecurity/mobile-security-framework-mobsf
docker run -it -p 8000:8000 opensecurity/mobile-security-framework-mobsf:latest
```
Notez que MobSF peut analyser les applications **Android** (apk), **IOS** (ipa) et **Windows** (apx) (les applications Windows doivent être analysées à partir d'un MobSF installé sur un hôte Windows).\
De plus, si vous créez un fichier **ZIP** avec le code source d'une application **Android** ou **IOS** (allez dans le dossier racine de l'application, sélectionnez tout et créez un fichier ZIP), MobSF pourra également l'analyser.
Notez que MobSF peut analyser les applications **Android** (apk), **IOS** (ipa) et **Windows** (apx) (_les applications Windows doivent être analysées à partir d'un MobSF installé sur un hôte Windows_).\
De plus, si vous créez un fichier **ZIP** avec le code source d'une application **Android** ou **IOS** (allez dans le dossier racine de l'application, sélectionnez tout et créez un fichier ZIP), il pourra également l'analyser.
MobSF vous permet également de **comparer/différencier** les analyses et d'intégrer **VirusTotal** (vous devrez définir votre clé API dans _MobSF/settings.py_ et l'activer : `VT_ENABLED = TRUE` `VT_API_KEY = <Votre clé API>` `VT_UPLOAD = TRUE`). Vous pouvez également définir `VT_UPLOAD` sur `False`, alors le **hash** sera **uploadé** à la place du fichier.
MobSF vous permet également de **comparer/différer** les analyses et d'intégrer **VirusTotal** (vous devrez définir votre clé API dans _MobSF/settings.py_ et l'activer : `VT_ENABLED = TRUE` `VT_API_KEY = <Votre clé API>` `VT_UPLOAD = TRUE`). Vous pouvez également définir `VT_UPLOAD` sur `False`, alors le **hash** sera **téléchargé** au lieu du fichier.
### Analyse dynamique assistée avec MobSF
MobSF peut également être très utile pour l'analyse dynamique sur Android, mais dans ce cas, vous devrez installer MobSF et **genymotion** sur votre hôte (une machine virtuelle ou Docker ne fonctionnera pas). Remarque : Vous devez **d'abord démarrer une machine virtuelle dans genymotion** et **ensuite MobSF**.\
MobSF peut également être très utile pour l'**analyse dynamique** sur Android, mais dans ce cas, vous devrez installer MobSF et **genymotion** sur votre hôte (une machine virtuelle ou Docker ne fonctionnera pas). _Remarque : Vous devez **d'abord démarrer une machine virtuelle dans genymotion** et **ensuite MobSF**._\
L'analyseur dynamique de MobSF peut :
* **Extraire les données de l'application** (URL, journaux, presse-papiers, captures d'écran réalisées par vous, captures d'écran réalisées par "**Exported Activity Tester**", e-mails, bases de données SQLite, fichiers XML et autres fichiers créés). Tout cela est fait automatiquement, sauf pour les captures d'écran, vous devez appuyer lorsque vous souhaitez une capture d'écran ou vous devez appuyer sur "**Exported Activity Tester**" pour obtenir des captures d'écran de toutes les activités exportées.
* Capturer le **trafic HTTPS**
* Utiliser **Frida** pour obtenir des **informations en temps réel**
À partir des versions Android > 5, il démarrera automatiquement Frida et définira les paramètres de **proxy** globaux pour capturer le trafic. Il ne capturera que le trafic de l'application testée.
À partir des versions d'Android supérieures à 5, il démarrera automatiquement Frida et définira les paramètres **proxy** globaux pour capturer le trafic. Il ne capturera le trafic que de l'application testée.
**Frida**
Par défaut, il utilisera également certains scripts Frida pour contourner la vérification de l'authenticité SSL, la détection de root et la détection de débogueur, ainsi que pour surveiller les API intéressantes.\
Par défaut, il utilisera également certains scripts Frida pour **contourner la vérification de l'authenticité SSL**, la **détection de root** et la **détection de débogueur**, ainsi que pour **surveiller les API intéressantes**.\
MobSF peut également **appeler des activités exportées**, capturer des **captures d'écran** et les **enregistrer** pour le rapport.
Pour **démarrer** les tests dynamiques, appuyez sur le bouton vert "**Start Instrumentation**". Appuyez sur "**Frida Live Logs**" pour voir les journaux générés par les scripts Frida et sur "**Live API Monitor**" pour voir toutes les invocations des méthodes accrochées, les arguments passés et les valeurs retournées (cela apparaîtra après avoir appuyé sur "Start Instrumentation").\
MobSF vous permet également de charger vos propres scripts Frida (pour envoyer les résultats de vos scripts Frida à MobSF, utilisez la fonction `send()`). Il dispose également de **plusieurs scripts pré-écrits** que vous pouvez charger (vous pouvez en ajouter d'autres dans `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), il vous suffit de les **sélectionner**, d'appuyer sur "**Load**" et d'appuyer sur "**Start Instrumentation**" (vous pourrez voir les journaux de ces scripts dans "**Frida Live Logs**").
Pour **démarrer** les tests dynamiques, appuyez sur le bouton vert : "**Start Instrumentation**". Appuyez sur "**Frida Live Logs**" pour voir les journaux générés par les scripts Frida et sur "**Live API Monitor**" pour voir toutes les invocations des méthodes accrochées, les arguments passés et les valeurs retournées (cela apparaîtra après avoir appuyé sur "Start Instrumentation").\
MobSF vous permet également de charger vos propres **scripts Frida** (pour envoyer les résultats de vos scripts Frida à MobSF, utilisez la fonction `send()`). Il dispose également de **plusieurs scripts pré-écrits** que vous pouvez charger (vous pouvez en ajouter d'autres dans `MobSF/DynamicAnalyzer/tools/frida_scripts/others/`), il vous suffit de les **sélectionner**, d'appuyer sur "**Load**" et d'appuyer sur "**Start Instrumentation**" (vous pourrez voir les journaux de ces scripts dans "**Frida Live Logs**").
![](<../../.gitbook/assets/image (215).png>)
De plus, vous disposez de certaines fonctionnalités auxiliaires de Frida :
* **Énumérer les classes chargées** : Il affichera toutes les classes chargées.
* **Capturer les chaînes de caractères** : Il affichera toutes les chaînes de caractères capturées lors de l'utilisation de l'application (très bruyant).
* **Capturer les comparaisons de chaînes de caractères** : Cela peut être très utile. Il affichera les 2 chaînes de caractères comparées et si le résultat était Vrai ou Faux.
* **Énumérer les méthodes de classe** : Indiquez le nom de la classe (comme "java.io.File") et il affichera toutes les méthodes de la classe.
* **Rechercher un modèle de classe** : Recherche de classes par motif.
* **Tracer les méthodes de classe** : Tracez une classe entière (voir les entrées et sorties de toutes les méthodes de la classe). N'oubliez pas que par défaut, MobSF trace plusieurs méthodes intéressantes de l'API Android.
* **Énumérer les classes chargées** : cela affichera toutes les classes chargées
* **Capturer les chaînes de caractères** : cela affichera toutes les chaînes de caractères capturées lors de l'utilisation de l'application (très bruyant)
* **Capturer les comparaisons de chaînes de caractères** : cela pourrait être très utile. Cela affichera les 2 chaînes de caractères comparées et si le résultat était vrai ou faux.
* **Énumérer les méthodes de classe** : indiquez le nom de la classe (comme "java.io.File") et cela affichera toutes les méthodes de la classe.
* **Rechercher un modèle de classe** : recherche de classes par motif
* **Tracer les méthodes de classe** : **tracer** une **classe entière** (voir les entrées et sorties de toutes les méthodes de la classe). N'oubliez pas que par défaut, MobSF trace plusieurs méthodes intéressantes de l'API Android.
Une fois que vous avez sélectionné le module auxiliaire que vous souhaitez utiliser, vous devez appuyer sur "**Start Intrumentation**" et vous verrez toutes les sorties dans "**Frida Live Logs**".
@ -609,7 +613,7 @@ C'est un **excellent outil pour effectuer une analyse statique avec une interfac
### [Qark](https://github.com/linkedin/qark)
Cet outil est conçu pour rechercher plusieurs **vulnérabilités de sécurité liées aux applications Android**, que ce soit dans le **code source** ou dans les **APK empaquetés**. L'outil est également **capable de créer un APK déployable "Proof-of-Concept"** et des **commandes ADB** pour exploiter certaines des vulnérabilités trouvées (activités exposées, intents, tapjacking...). Comme avec Drozer, il n'est pas nécessaire de rooter l'appareil de test.
Cet outil est conçu pour rechercher plusieurs **vulnérabilités liées à la sécurité des applications Android**, que ce soit dans le **code source** ou dans les **APK empaquetés**. L'outil est également **capable de créer un APK déployable "Proof-of-Concept"** et des **commandes ADB** pour exploiter certaines des vulnérabilités trouvées (activités exposées, intents, tapjacking...). Comme avec Drozer, il n'est pas nécessaire de rooter l'appareil de test.
```bash
pip3 install --user qark # --user is only needed if not using a virtualenv
qark --apk path/to/my.apk
@ -706,10 +710,10 @@ Utile pour détecter les logiciels malveillants : [https://koodous.com/](https:/
**Obtenez une récompense sans délai**\
Les primes HackenProof ne sont lancées que lorsque les clients déposent le budget de récompense. Vous recevrez la récompense après la vérification du bug.
**Acquérez de l'expérience en pentest web3**\
**Acquérez de l'expérience en pentesting web3**\
Les protocoles blockchain et les contrats intelligents sont le nouvel Internet ! Maîtrisez la sécurité web3 dès ses débuts.
**Devenez une légende du hacking web3**\
**Devenez la légende du hacker web3**\
Gagnez des points de réputation avec chaque bug vérifié et conquérez le sommet du classement hebdomadaire.
[**Inscrivez-vous sur HackenProof**](https://hackenproof.com/register) et commencez à gagner grâce à vos hacks !
@ -734,11 +738,11 @@ Trouvez un guide étape par étape pour déobfusquer l'APK sur [https://blog.lex
(D'après ce guide) La dernière fois que nous avons vérifié, le mode de fonctionnement de Dexguard était :
* charger une ressource en tant qu'InputStream ;
* charger une ressource en tant que InputStream ;
* alimenter le résultat à une classe héritant de FilterInputStream pour le décrypter ;
* effectuer une obfuscation inutile pour perdre quelques minutes de temps d'un réverseur ;
* alimenter le résultat décrypté à un ZipInputStream pour obtenir un fichier DEX ;
* enfin, charger le DEX résultant en tant que ressource en utilisant la méthode `loadDex`.
* enfin charger le DEX résultant en tant que ressource en utilisant la méthode `loadDex`.
### [DeGuard](http://apk-deguard.com)
@ -762,7 +766,7 @@ APKiD vous donne des informations sur **comment un APK a été créé**. Il iden
### [Androl4b](https://github.com/sh4hin/Androl4b)
AndroL4b est une machine virtuelle de sécurité Android basée sur ubuntu-mate qui comprend la collection des derniers frameworks, tutoriels et laboratoires de différents geeks de la sécurité et chercheurs pour la rétro-ingénierie et l'analyse de logiciels malveillants.
AndroL4b est une machine virtuelle de sécurité Android basée sur Ubuntu-Mate, qui comprend une collection des derniers frameworks, tutoriels et laboratoires de différents experts en sécurité et chercheurs pour la rétro-ingénierie et l'analyse de logiciels malveillants.
### OWASP

View file

@ -4,86 +4,181 @@
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
## Introduction
GraphQL agit comme une alternative à l'API REST. Les API REST nécessitent que le client envoie plusieurs requêtes à différents points de terminaison sur l'API pour interroger les données de la base de données backend. Avec GraphQL, vous n'avez besoin d'envoyer qu'une seule requête pour interroger le backend. C'est beaucoup plus simple car vous n'avez pas à envoyer plusieurs requêtes à l'API, une seule requête peut être utilisée pour collecter toutes les informations nécessaires.
GraphQL agit comme une alternative aux API REST. Les API REST nécessitent que le client envoie plusieurs requêtes à différents points de terminaison de l'API pour interroger les données de la base de données backend. Avec GraphQL, vous n'avez besoin d'envoyer qu'une seule requête pour interroger le backend. C'est beaucoup plus simple car vous n'avez pas à envoyer plusieurs requêtes à l'API, une seule requête peut être utilisée pour collecter toutes les informations nécessaires.
## GraphQL
À mesure que de nouvelles technologies émergent, de nouvelles vulnérabilités apparaîtront également. Par **défaut**, GraphQL ne met pas en œuvre **l'authentification**, c'est au développeur de l'implémenter. Cela signifie que par défaut, GraphQL permet à n'importe qui de l'interroger, toute information sensible sera disponible pour les attaquants non authentifiés.
À mesure que de nouvelles technologies émergent, de nouvelles vulnérabilités apparaîtront également. Par **défaut**, GraphQL n'implémente **pas** l'**authentification**, il incombe au développeur de l'implémenter. Cela signifie que par défaut, GraphQL permet à n'importe qui de le consulter, toutes les informations sensibles seront disponibles pour les attaquants non authentifiés.
Lorsque vous effectuez vos attaques de force brute de répertoire, assurez-vous d'ajouter les chemins suivants pour vérifier les instances GraphQL.
Lorsque vous effectuez vos attaques de force brute de répertoire, assurez-vous d'ajouter les chemins suivants pour vérifier les instances de GraphQL.
* _/graphql_
* _/graphiql_
* _/graphql.php_
* _/graphql/console_
* `/graphql`
* `/graphiql`
* `/graphql.php`
* `/graphql/console`
* `/api`
* `/api/graphql`
* `/graphql/api`
* `/graphql/graphql`
<figure><img src="../../.gitbook/assets/image (6) (1) (3).png" alt=""><figcaption></figcaption></figure>
Une fois que vous trouvez une instance GraphQL ouverte, vous devez savoir **quelles requêtes elle prend en charge**. Cela peut être fait en utilisant le système d'introspection, plus de détails peuvent être trouvés ici : [**GraphQL : un langage de requête pour les API.**\
Une fois que vous avez trouvé une instance GraphQL ouverte, vous devez savoir **quelles requêtes elle prend en charge**. Cela peut être fait en utilisant le système d'introspection, plus de détails peuvent être trouvés ici : [**GraphQL : un langage de requête pour les API.**\
Il est souvent utile de demander à un schéma GraphQL des informations sur les requêtes qu'il prend en charge. GraphQL nous permet de le faire...](https://graphql.org/learn/introspection/)
### Empreinte
L'outil [**graphw00f**](https://github.com/dolevf/graphw00f) est capable de détecter quelle moteur GraphQL est utilisé sur un serveur, puis imprime des informations utiles pour l'auditeur de sécurité.
L'outil [**graphw00f**](https://github.com/dolevf/graphw00f) est capable de détecter quel moteur GraphQL est utilisé sur un serveur, puis imprime des informations utiles pour l'auditeur de sécurité.
#### Requêtes universelles <a href="#universal-queries" id="universal-queries"></a>
Si vous envoyez `query{__typename}` à n'importe quel point de terminaison GraphQL, il inclura la chaîne `{"data": {"__typename": "query"}}` quelque part dans sa réponse. C'est ce qu'on appelle une requête universelle, et c'est un outil utile pour sonder si une URL correspond à un service GraphQL.
La requête fonctionne parce que chaque point de terminaison GraphQL a un champ réservé appelé `__typename` qui renvoie le type de l'objet interrogé sous forme de chaîne.
### Énumération de base
Graphql prend généralement en charge GET, POST (x-www-form-urlencoded) et POST(json).
GraphQL prend généralement en charge les méthodes **GET**, **POST** (x-www-form-urlencoded) et **POST**(json). Bien que pour des raisons de sécurité, il soit recommandé de n'autoriser que le format json pour éviter les attaques CSRF.
**query={\_\_schema{types{name,fields{name\}}\}}**
#### Introspection
Pour utiliser l'introspection afin de découvrir des informations sur le schéma, interrogez le champ `__schema`. Ce champ est disponible sur le type racine de toutes les requêtes.
```bash
query={__schema{types{name,fields{name}}}}
```
Avec cette requête, vous trouverez le nom de tous les types utilisés :
![](<../../.gitbook/assets/image (202).png>)
**query={\_\_schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind\}}\}}\}}}**
{% code overflow="wrap" %}
```bash
query={__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}
```
{% endcode %}
Avec cette requête, vous pouvez extraire tous les types, leurs champs et leurs arguments (et le type des arguments). Cela sera très utile pour savoir comment interroger la base de données.
Avec cette requête, vous pouvez extraire tous les types, leurs champs et leurs arguments (ainsi que le type des arguments). Cela sera très utile pour savoir comment interroger la base de données.
![](<../../.gitbook/assets/image (207) (3).png>)
**Erreurs**
Il est intéressant de savoir si les **erreurs** vont être **affichées** car elles contribueront avec des informations utiles.
Il est intéressant de savoir si les **erreurs** vont être **affichées**, car elles fourniront des **informations** utiles.
```
?query={__schema}
?query={}
?query={thisdefinitelydoesnotexist}
```
![](<../../.gitbook/assets/image (205) (1).png>)
**Énumérer le schéma de la base de données via l'introspection**
GraphQL permet l'introspection de son schéma, ce qui signifie que vous pouvez récupérer des informations sur les types, les champs et les relations disponibles dans l'API. Cela peut être utile pour comprendre comment l'API est structurée et pour identifier les points d'entrée potentiels pour les attaques.
{% hint style="info" %}
Si l'introspection est activée mais que la requête ci-dessus ne fonctionne pas, essayez de supprimer les directives `onOperation`, `onFragment` et `onField` de la structure de la requête.
{% endhint %}
```bash
#Full introspection query
Pour récupérer le schéma de l'API, vous pouvez envoyer une requête GraphQL avec la requête suivante :
query IntrospectionQuery {
__schema {
queryType {
name
}
mutationType {
name
}
subscriptionType {
name
}
types {
...FullType
}
directives {
name
description
args {
...InputValue
}
onOperation #Often needs to be deleted to run query
onFragment #Often needs to be deleted to run query
onField #Often needs to be deleted to run query
}
}
}
```
query {
__schema {
types {
name
fields {
name
}
}
}
fragment FullType on __Type {
kind
name
description
fields(includeDeprecated: true) {
name
description
args {
...InputValue
}
type {
...TypeRef
}
isDeprecated
deprecationReason
}
inputFields {
...InputValue
}
interfaces {
...TypeRef
}
enumValues(includeDeprecated: true) {
name
description
isDeprecated
deprecationReason
}
possibleTypes {
...TypeRef
}
}
fragment InputValue on __InputValue {
name
description
type {
...TypeRef
}
defaultValue
}
fragment TypeRef on __Type {
kind
name
ofType {
kind
name
ofType {
kind
name
ofType {
kind
name
}
}
}
}
```
Cela renverra une liste de tous les types disponibles dans l'API, ainsi que les champs disponibles pour chaque type. Vous pouvez utiliser ces informations pour identifier les types de données sensibles et les relations entre les différents types.
Requête d'inspection en ligne :
```
/?query=fragment%20FullType%20on%20Type%20{+%20%20kind+%20%20name+%20%20description+%20%20fields%20{+%20%20%20%20name+%20%20%20%20description+%20%20%20%20args%20{+%20%20%20%20%20%20...InputValue+%20%20%20%20}+%20%20%20%20type%20{+%20%20%20%20%20%20...TypeRef+%20%20%20%20}+%20%20}+%20%20inputFields%20{+%20%20%20%20...InputValue+%20%20}+%20%20interfaces%20{+%20%20%20%20...TypeRef+%20%20}+%20%20enumValues%20{+%20%20%20%20name+%20%20%20%20description+%20%20}+%20%20possibleTypes%20{+%20%20%20%20...TypeRef+%20%20}+}++fragment%20InputValue%20on%20InputValue%20{+%20%20name+%20%20description+%20%20type%20{+%20%20%20%20...TypeRef+%20%20}+%20%20defaultValue+}++fragment%20TypeRef%20on%20Type%20{+%20%20kind+%20%20name+%20%20ofType%20{+%20%20%20%20kind+%20%20%20%20name+%20%20%20%20ofType%20{+%20%20%20%20%20%20kind+%20%20%20%20%20%20name+%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20ofType%20{+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20kind+%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20name+%20%20%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20%20%20}+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}++query%20IntrospectionQuery%20{+%20%20schema%20{+%20%20%20%20queryType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20mutationType%20{+%20%20%20%20%20%20name+%20%20%20%20}+%20%20%20%20types%20{+%20%20%20%20%20%20...FullType+%20%20%20%20}+%20%20%20%20directives%20{+%20%20%20%20%20%20name+%20%20%20%20%20%20description+%20%20%20%20%20%20locations+%20%20%20%20%20%20args%20{+%20%20%20%20%20%20%20%20...InputValue+%20%20%20%20%20%20}+%20%20%20%20}+%20%20}+}
```
La dernière ligne de code est une requête graphql qui va extraire toutes les méta-informations du graphql (noms d'objets, paramètres, types...).
La dernière ligne de code est une requête GraphQL qui va extraire toutes les méta-informations du GraphQL (noms des objets, paramètres, types...)
![](<../../.gitbook/assets/image (206).png>)
@ -93,7 +188,7 @@ Si l'introspection est activée, vous pouvez utiliser [**GraphQL Voyager**](http
Maintenant que nous savons quel type d'informations est stocké dans la base de données, essayons d'**extraire certaines valeurs**.
Dans l'introspection, vous pouvez trouver **quel objet vous pouvez interroger directement** (car vous ne pouvez pas interroger un objet juste parce qu'il existe). Dans l'image suivante, vous pouvez voir que le "_queryType_" s'appelle "_Query_" et qu'un des champs de l'objet "_Query_" est "_flags_", qui est également un type d'objet. Par conséquent, vous pouvez interroger l'objet flag.
Dans l'introspection, vous pouvez trouver **quels objets vous pouvez interroger directement** (car vous ne pouvez pas interroger un objet simplement parce qu'il existe). Dans l'image suivante, vous pouvez voir que le "_queryType_" s'appelle "_Query_" et qu'un des champs de l'objet "_Query_" est "_flags_", qui est également un type d'objet. Vous pouvez donc interroger l'objet flag.
![](../../.gitbook/assets/screenshot-from-2021-03-13-18-17-48.png)
@ -101,11 +196,11 @@ Notez que le type de la requête "_flags_" est "_Flags_", et que cet objet est d
![](../../.gitbook/assets/screenshot-from-2021-03-13-18-22-57.png)
Vous pouvez voir que les objets "_Flags_" sont composés de **name** et de **value**. Ensuite, vous pouvez obtenir tous les noms et valeurs des flags avec la requête :
Vous pouvez voir que les objets "_Flags_" sont composés d'un **nom** et d'une **valeur**. Vous pouvez ensuite obtenir tous les noms et valeurs des flags avec la requête :
```javascript
query={flags{name, value}}
```
Notez que dans le cas où l'**objet à interroger** est un **type primitif** comme une **chaîne de caractères** comme dans l'exemple suivant
Notez que si l'**objet à interroger** est un **type primitif** comme une **chaîne de caractères** comme dans l'exemple suivant
![](<../../.gitbook/assets/image (441).png>)
@ -113,8 +208,7 @@ Vous pouvez simplement l'interroger avec:
```javascript
query={hiddenFlags}
```
Dans un autre exemple où il y avait 2 objets à l'intérieur de l'objet "_Query_" : "_user_" et "_users_".\
Si ces objets n'ont pas besoin d'argument pour être recherchés, vous pouvez **récupérer toutes les informations** en demandant simplement les données que vous voulez. Dans cet exemple d'Internet, vous pourriez extraire les noms d'utilisateur et les mots de passe enregistrés :
Dans un autre exemple où il y avait 2 objets à l'intérieur de l'objet "_Query_" : "_user_" et "_users_". Si ces objets n'ont pas besoin d'arguments pour être recherchés, vous pouvez **récupérer toutes les informations** en demandant simplement les données que vous souhaitez. Dans cet exemple provenant d'Internet, vous pourriez extraire les noms d'utilisateur et les mots de passe enregistrés :
![](<../../.gitbook/assets/image (208).png>)
@ -122,224 +216,264 @@ Cependant, dans cet exemple, si vous essayez de le faire, vous obtenez cette **e
![](<../../.gitbook/assets/image (210).png>)
On dirait qu'il va chercher en utilisant l'argument "_**uid**_" de type _**Int**_.\
Quoi qu'il en soit, nous savions déjà cela, dans la section [Énumération de base](graphql.md#basic-enumeration), une requête a été proposée qui nous montrait toutes les informations nécessaires : `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Il semble que la recherche se fasse en utilisant l'argument "_**uid**_" de type _**Int**_. Quoi qu'il en soit, nous savions déjà cela, dans la section [Énumération de base](graphql.md#basic-enumeration), une requête a été proposée qui nous montrait toutes les informations nécessaires : `query={__schema{types{name,fields{name, args{name,description,type{name, kind, ofType{name, kind}}}}}}}`
Si vous lisez l'image fournie lorsque j'exécute cette requête, vous verrez que "_**user**_" avait l'**arg** "_**uid**_" de type _Int_.
Ainsi, en effectuant une légère bruteforce de _**uid**_, j'ai découvert qu'avec _**uid**=**1**_, un nom d'utilisateur et un mot de passe ont été récupérés :\
Ainsi, en effectuant une légère force brute sur l'**uid**, j'ai découvert qu'avec _**uid**=**1**_, un nom d'utilisateur et un mot de passe ont été récupérés :\
`query={user(uid:1){user,password}}`
![](<../../.gitbook/assets/image (211).png>)
Notez que j'ai **découvert** que je pouvais demander les **paramètres** "_**user**_" et "_**password**_" parce que si j'essaie de chercher quelque chose qui n'existe pas (`query={user(uid:1){noExists}}`), j'obtiens cette erreur :
Notez que j'ai **découvert** que je pouvais demander les **paramètres** "_**user**_" et "_**password**_" car si j'essaie de chercher quelque chose qui n'existe pas (`query={user(uid:1){noExists}}`), j'obtiens cette erreur :
![](<../../.gitbook/assets/image (213).png>)
Et pendant la phase d'**énumération**, j'ai découvert que l'objet "_**dbuser**_" avait comme champs "_**user**_" et "_**password**_".
Et pendant la phase d'**énumération**, j'ai découvert que l'objet "_**dbuser**_" avait comme champs "_**user**_" et "_**password**_.
**Astuce de vidage de chaîne de requête (merci à @BinaryShadow\_)**
Si vous pouvez rechercher par un type de chaîne, comme : `query={theusers(description: ""){username,password}}` et que vous **recherchez une chaîne vide**, cela **déversera toutes les données**. (_Notez que cet exemple n'est pas lié à l'exemple des tutoriels, pour cet exemple, supposez que vous pouvez rechercher en utilisant "**theusers**" par un champ String appelé "**description**"_).
Si vous pouvez rechercher par un type de chaîne, comme : `query={theusers(description: ""){username,password}}` et que vous **recherchez une chaîne vide**, cela **videra toutes les données**. (_Notez que cet exemple n'est pas lié à l'exemple des tutoriels, pour cet exemple, supposez que vous pouvez rechercher en utilisant "**theusers**" avec un champ de type chaîne appelé "**description**"_).
GraphQL est une technologie relativement nouvelle qui commence à gagner du terrain parmi les startups et les grandes entreprises. Outre l'absence d'authentification par défaut, les points d'extrémité graphQL peuvent être vulnérables à d'autres bugs tels que l'IDOR.
GraphQL est une technologie relativement nouvelle qui commence à gagner en popularité parmi les start-ups et les grandes entreprises. Mis à part l'absence d'authentification par défaut, les points d'extrémité GraphQL peuvent être vulnérables à d'autres bugs tels que l'IDOR.
### Recherche
Pour cet exemple, imaginez une base de données avec des **personnes** identifiées par l'e-mail et le nom et des **films** identifiés par le nom et la note. Une **personne** peut être **amie** avec d'autres **personnes** et une personne peut **avoir des films**.
Pour cet exemple, imaginez une base de données avec des **personnes** identifiées par leur adresse e-mail et leur nom, et des **films** identifiés par leur nom et leur note. Une **personne** peut être **amie** avec d'autres **personnes** et une personne peut **avoir des films**.
Vous pouvez **rechercher** des personnes **par** le **nom** et obtenir leurs e-mails :
Vous pouvez **rechercher** des personnes **par** leur **nom** et obtenir leurs adresses e-mail :
```javascript
{
searchPerson(name: "John Doe") {
email
}
searchPerson(name: "John Doe") {
email
}
}
```
Vous pouvez **rechercher** des personnes **par** leur **nom** et obtenir les **films** auxquels elles sont **abonnées** :
```javascript
{
searchPerson(name: "John Doe") {
email
subscribedMovies {
edges {
node {
name
}
}
}
}
searchPerson(name: "John Doe") {
email
subscribedMovies {
edges {
node {
name
}
}
}
}
}
```
Notez comment il est indiqué de récupérer le `nom` des `subscribedMovies` de la personne.
Notez comment il est indiqué de récupérer le `name` des `subscribedMovies` de la personne.
Vous pouvez également **rechercher plusieurs objets en même temps**. Dans ce cas, une recherche de 2 films est effectuée:
Vous pouvez également **rechercher plusieurs objets en même temps**. Dans ce cas, une recherche de 2 films est effectuée :
```javascript
{
searchPerson(subscribedMovies: [{name: "Inception"}, {name: "Rocky"}]) {
name
}
searchPerson(subscribedMovies: [{name: "Inception"}, {name: "Rocky"}]) {
name
}
}r
```
Ou même **les relations de plusieurs objets différents en utilisant des alias**:
Ou même **relations de plusieurs objets différents en utilisant des alias** :
```javascript
{
johnsMovieList: searchPerson(name: "John Doe") {
subscribedMovies {
edges {
node {
name
}
}
}
}
davidsMovieList: searchPerson(name: "David Smith") {
subscribedMovies {
edges {
node {
name
}
}
}
}
johnsMovieList: searchPerson(name: "John Doe") {
subscribedMovies {
edges {
node {
name
}
}
}
}
davidsMovieList: searchPerson(name: "David Smith") {
subscribedMovies {
edges {
node {
name
}
}
}
}
}
```
### Mutations
**Les mutations sont utilisées pour effectuer des modifications côté serveur.**
Dans l'**introspection**, vous pouvez trouver les **mutations déclarées**. Dans l'image suivante, le "_MutationType_" est appelé "_Mutation_" et l'objet "_Mutation_" contient les noms des mutations (comme "_addPerson_" dans ce cas) :
Dans l'**introspection**, vous pouvez trouver les **mutations déclarées**. Dans l'image suivante, l'objet "_MutationType_" est appelé "_Mutation_" et l'objet "_Mutation_" contient les noms des mutations (comme "_addPerson_" dans ce cas) :
![](../../.gitbook/assets/screenshot-from-2021-03-13-18-26-27.png)
Pour cet exemple, imaginez une base de données avec des **personnes** identifiées par leur adresse e-mail et leur nom et des **films** identifiés par leur nom et leur note. Une **personne** peut être **amie** avec d'autres **personnes** et une personne peut **avoir des films**.
Pour cet exemple, imaginez une base de données avec des **personnes** identifiées par leur adresse e-mail et leur nom, et des **films** identifiés par leur nom et leur note. Une **personne** peut être **amie** avec d'autres **personnes** et une personne peut **avoir des films**.
Une mutation pour **créer de nouveaux** films dans la base de données peut ressembler à celle-ci (dans cet exemple, la mutation est appelée `addMovie`) :
Une mutation pour **créer de nouveaux** films dans la base de données peut ressembler à celle-ci (dans cet exemple, la mutation s'appelle `addMovie`) :
```javascript
mutation {
addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) {
movies {
name
rating
}
}
addMovie(name: "Jumanji: The Next Level", rating: "6.8/10", releaseYear: 2019) {
movies {
name
rating
}
}
}
```
**Notez comment les valeurs et le type de données sont indiqués dans la requête.**
**Notez comment à la fois les valeurs et le type de données sont indiqués dans la requête.**
Il peut également y avoir une **mutation** pour **créer** des **personnes** (appelée `addPerson` dans cet exemple) avec des amis et des fichiers (notez que les amis et les films doivent exister avant de créer une personne liée à eux):
Il peut également y avoir une **mutation** pour **créer** des **personnes** (appelée `addPerson` dans cet exemple) avec des amis et des fichiers (notez que les amis et les films doivent exister avant de créer une personne liée à eux) :
```javascript
mutation {
addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) {
person {
name
email
friends {
edges {
node {
name
email
}
}
}
subscribedMovies {
edges {
node {
name
rating
releaseYear
}
}
}
}
}
addPerson(name: "James Yoe", email: "jy@example.com", friends: [{name: "John Doe"}, {email: "jd@example.com"}], subscribedMovies: [{name: "Rocky"}, {name: "Interstellar"}, {name: "Harry Potter and the Sorcerer's Stone"}]) {
person {
name
email
friends {
edges {
node {
name
email
}
}
}
subscribedMovies {
edges {
node {
name
rating
releaseYear
}
}
}
}
}
}
```
### Brute-force en lot dans une seule requête API
### Regroupement de force brute dans une seule requête API
Cette information a été prise sur [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\
L'authentification via l'API GraphQL avec **l'envoi simultané de nombreuses requêtes avec des identifiants différents** pour les vérifier. C'est une attaque de force brute classique, mais maintenant il est possible d'envoyer plus d'une paire de login/mot de passe par requête HTTP en raison de la fonctionnalité de regroupement de GraphQL. Cette approche tromperait les applications de surveillance de taux externes en leur faisant croire que tout va bien et qu'il n'y a pas de bot de force brute essayant de deviner les mots de passe.
Ces informations ont été extraites de [https://lab.wallarm.com/graphql-batching-attack/](https://lab.wallarm.com/graphql-batching-attack/).\
L'authentification via l'API GraphQL consiste à **envoyer simultanément de nombreuses requêtes avec des identifiants différents** pour les vérifier. Il s'agit d'une attaque de force brute classique, mais il est maintenant possible d'envoyer plus d'une paire de nom d'utilisateur/mot de passe par requête HTTP grâce à la fonctionnalité de regroupement de GraphQL. Cette approche tromperait les applications de surveillance de taux externes en leur faisant croire que tout va bien et qu'il n'y a pas de bot de force brute qui essaie de deviner les mots de passe.
Ci-dessous, vous pouvez trouver la démonstration la plus simple d'une demande d'authentification d'application, avec **3 paires d'adresses e-mail/mot de passe différentes à la fois**. Évidemment, il est possible d'envoyer des milliers de demandes en une seule fois de la même manière :
Ci-dessous, vous trouverez la démonstration la plus simple d'une demande d'authentification d'application, avec **3 paires d'adresse e-mail/mot de passe différentes à la fois**. Il est évidemment possible d'en envoyer des milliers dans une seule requête de la même manière :
![](<../../.gitbook/assets/image (182) (1).png>)
Comme nous pouvons le voir sur la capture d'écran de la réponse, les premières et troisièmes requêtes ont renvoyé _null_ et ont reflété les informations correspondantes dans la section _error_. La **deuxième mutation avait les données d'authentification correctes** et la réponse avait le jeton de session d'authentification correct.
Comme nous pouvons le voir sur la capture d'écran de la réponse, les première et troisième requêtes ont renvoyé _null_ et ont reflété les informations correspondantes dans la section _error_. La **deuxième mutation avait les données d'authentification correctes** et la réponse contenait le jeton de session d'authentification correct.
![](<../../.gitbook/assets/image (119) (1).png>)
## GraphQL sans introspection
De plus en plus de **points de terminaison graphql désactivent l'introspection**. Cependant, les erreurs que graphql lance lorsqu'une demande inattendue est reçue sont suffisantes pour que des outils comme [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) puissent recréer la plupart du schéma.
De plus en plus de **points de terminaison GraphQL désactivent l'introspection**. Cependant, les erreurs que GraphQL génère lorsqu'une requête inattendue est reçue sont suffisantes pour que des outils comme [**clairvoyance**](https://github.com/nikitastupin/clairvoyance) puissent recréer la majeure partie du schéma.
De plus, l'extension de Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observe les requêtes d'API GraphQL passant par Burp** et **construit** un schéma GraphQL interne avec chaque nouvelle requête qu'elle voit. Il peut également exposer le schéma pour GraphiQL et Voyager. L'extension renvoie une fausse réponse lorsqu'elle reçoit une requête d'introspection. En conséquence, GraphQuail montre toutes les requêtes, arguments et champs disponibles pour une utilisation dans l'API. Pour plus d'informations, [**consultez ceci**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
De plus, l'extension Burp Suite [**GraphQuail**](https://github.com/forcesunseen/graphquail) **observe les requêtes d'API GraphQL passant par Burp** et **construit** un **schéma** GraphQL interne à chaque nouvelle requête qu'elle voit. Elle peut également exposer le schéma pour GraphiQL et Voyager. L'extension renvoie une fausse réponse lorsqu'elle reçoit une requête d'introspection. En conséquence, GraphQuail affiche toutes les requêtes, arguments et champs disponibles pour une utilisation dans l'API. Pour plus d'informations, [**consultez ceci**](https://blog.forcesunseen.com/graphql-security-testing-without-a-schema).
## CSRF dans GraphQL
### Contourner les défenses d'introspection GraphQL <a href="#bypassing-graphql-introspection-defences" id="bypassing-graphql-introspection-defences"></a>
Si vous ne savez pas ce qu'est CSRF, lisez la page suivante :
Si vous ne parvenez pas à exécuter des requêtes d'introspection pour l'API que vous testez, essayez d'insérer un **caractère spécial après le mot-clé `__schema`**.
{% content-ref url="../../pentesting-web/csrf-cross-site-request-forgery.md" %}
[csrf-cross-site-request-forgery.md](../../pentesting-web/csrf-cross-site-request-forgery.md)
{% endcontent-ref %}
Lorsque les développeurs désactivent l'introspection, ils peuvent utiliser une expression régulière pour exclure le mot-clé `__schema` dans les requêtes. Vous devriez essayer des caractères tels que les **espaces**, les **retours à la ligne** et les **virgules**, car ils sont **ignorés** par GraphQL mais pas par une expression régulière défectueuse.
Vous pouvez trouver plusieurs points de terminaison GraphQL **configurés sans jetons CSRF.**
Notez que les demandes GraphQL sont généralement envoyées via des demandes POST en utilisant le type de contenu **`application/json`**.
```javascript
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
```
Cependant, la plupart des points d'extrémité GraphQL prennent également en charge les requêtes POST **`form-urlencoded` :**
```javascript
query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
```
Par conséquent, comme les demandes CSRF comme les précédentes sont envoyées **sans demandes de pré-vol**, il est possible de **réaliser** des **changements** dans le GraphQL en abusant d'un CSRF.
Cependant, notez que la nouvelle valeur par défaut du cookie `samesite` de Chrome est `Lax`. Cela signifie que le cookie ne sera envoyé que depuis un site tiers dans les demandes GET.
Notez également qu'il est généralement possible d'envoyer la **requête de** **requête** également en tant que **requête GET et que le jeton CSRF pourrait ne pas être validé dans une requête GET.**
De plus, en abusant d'une **attaque XS-Search**, il pourrait être possible d'exfiltrer du contenu de l'extrémité GraphQL en abusant des informations d'identification de l'utilisateur.
Pour plus d'informations, **consultez le** [**post original ici**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html).
## Autorisation dans GraphQL
De nombreuses fonctions GraphQL définies sur l'extrémité peuvent ne vérifier que l'authentification du demandeur mais pas l'autorisation.
La modification des variables d'entrée de la requête pourrait entraîner la **fuite** de détails de compte sensibles [leaked](https://hackerone.com/reports/792927).
La mutation pourrait même entraîner la prise de contrôle du compte en essayant de modifier les données d'autres comptes.
```javascript
Ainsi, si le développeur a seulement exclu `__schema{`, la requête d'introspection ci-dessous ne serait pas exclue.
```bash
#Introspection query with newline
{
"operationName":"updateProfile",
"variables":{"username":INJECT,"data":INJECT},
"query":"mutation updateProfile($username: String!,...){updateProfile(username: $username,...){...}}"
"query": "query{__schema
{queryType{name}}}"
}
```
### Contourner l'autorisation dans GraphQL
Si cela ne fonctionne pas, essayez d'exécuter la sonde avec une méthode de requête alternative, car l'introspection peut être désactivée uniquement pour les requêtes POST. Essayez une requête GET ou une requête POST avec un type de contenu `x-www-form-urlencoded`.
En enchaînant des requêtes, il est possible de contourner un système d'authentification faible.
### Structures GraphQL divulguées
Dans l'exemple ci-dessous, on peut voir que l'opération est "forgotPassword" et qu'elle ne devrait exécuter que la requête forgotPassword associée. Cependant, il est possible de la contourner en ajoutant une requête à la fin, dans ce cas, nous ajoutons "register" et une variable utilisateur pour que le système s'enregistre en tant que nouvel utilisateur.
<figure><img src="../../.gitbook/assets/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
## Structures GraphQL divulguées
Si l'introspection est désactivée, essayez de regarder le code source du site web. Les requêtes sont souvent préchargées dans le navigateur sous forme de bibliothèques JavaScript. Ces requêtes pré-écrites peuvent révéler des informations puissantes sur le schéma et l'utilisation de chaque objet et fonction. L'onglet `Sources` des outils de développement peut rechercher tous les fichiers pour énumérer où les requêtes sont enregistrées. Parfois, même les requêtes protégées par l'administrateur sont déjà exposées.
Si l'introspection est désactivée, essayez de consulter le code source du site web. Les requêtes sont souvent préchargées dans le navigateur sous forme de bibliothèques JavaScript. Ces requêtes pré-écrites peuvent révéler des informations puissantes sur le schéma et l'utilisation de chaque objet et fonction. L'onglet `Sources` des outils de développement peut rechercher tous les fichiers pour énumérer les emplacements où les requêtes sont enregistrées. Parfois, même les requêtes protégées par l'administrateur sont déjà exposées.
```javascript
Inspect/Sources/"Search all files"
file:* mutation
file:* query
```
## CSRF dans GraphQL
Si vous ne savez pas ce qu'est le CSRF, lisez la page suivante :
{% content-ref url="../../pentesting-web/csrf-cross-site-request-forgery.md" %}
[csrf-cross-site-request-forgery.md](../../pentesting-web/csrf-cross-site-request-forgery.md)
{% endcontent-ref %}
Là-bas, vous allez pouvoir trouver plusieurs points d'extrémité GraphQL **configurés sans jetons CSRF**.
Notez que les requêtes GraphQL sont généralement envoyées via des requêtes POST en utilisant le Content-Type **`application/json`**.
```javascript
{"operationName":null,"variables":{},"query":"{\n user {\n firstName\n __typename\n }\n}\n"}
```
Cependant, la plupart des points d'extrémité GraphQL prennent également en charge les requêtes POST **`form-urlencoded`**:
```javascript
query=%7B%0A++user+%7B%0A++++firstName%0A++++__typename%0A++%7D%0A%7D%0A
```
Par conséquent, comme les requêtes CSRF précédentes sont envoyées **sans requêtes de pré-vérification**, il est possible d'**effectuer** des **modifications** dans le GraphQL en abusant d'une CSRF.
Cependant, notez que la nouvelle valeur par défaut du drapeau `samesite` de Chrome est `Lax`. Cela signifie que le cookie ne sera envoyé que depuis un site tiers lors de requêtes GET.
Notez également qu'il est généralement possible d'envoyer la **requête de** **query** également en tant que requête **GET** et que le jeton CSRF pourrait ne pas être validé dans une requête GET.
De plus, en abusant d'une [**attaque XS-Search**](../../pentesting-web/xs-search.md), il pourrait être possible d'exfiltrer du contenu depuis le point de terminaison GraphQL en abusant des informations d'identification de l'utilisateur.
Pour plus d'informations, **consultez l'** [**article original ici**](https://blog.doyensec.com/2021/05/20/graphql-csrf.html).
## Autorisation dans GraphQL
De nombreuses fonctions GraphQL définies sur le point de terminaison peuvent uniquement vérifier l'authentification du demandeur mais pas l'autorisation.
La modification des variables d'entrée de la requête pourrait entraîner la **fuite** de détails sensibles du compte ([lien](https://hackerone.com/reports/792927)).
Une mutation pourrait même entraîner une prise de contrôle du compte en essayant de modifier les données d'autres comptes.
```javascript
{
"operationName":"updateProfile",
"variables":{"username":INJECT,"data":INJECT},
"query":"mutation updateProfile($username: String!,...){updateProfile(username: $username,...){...}}"
}
```
### Contourner l'autorisation dans GraphQL
[Enchaîner des requêtes](https://s1n1st3r.gitbook.io/theb10g/graphql-query-authentication-bypass-vuln) peut contourner un système d'authentification faible.
Dans l'exemple ci-dessous, vous pouvez voir que l'opération est "forgotPassword" et qu'elle ne devrait exécuter que la requête forgotPassword qui lui est associée. Cela peut être contourné en ajoutant une requête à la fin, dans ce cas nous ajoutons "register" et une variable utilisateur pour que le système s'enregistre en tant que nouvel utilisateur.
<figure><img src="../../.gitbook/assets/GraphQLAuthBypassMethod.PNG" alt=""><figcaption></figcaption></figure>
## Contourner la limitation de débit en utilisant des alias
Normalement, les objets GraphQL ne peuvent pas contenir plusieurs propriétés avec le même nom. Les alias vous permettent de contourner cette restriction en **nommant explicitement les propriétés que vous souhaitez** que l'API renvoie. Vous pouvez utiliser des alias pour renvoyer **plusieurs instances du même** type d'objet dans une seule requête.
Pour plus d'informations sur les alias GraphQL, consultez [Aliases](https://portswigger.net/web-security/graphql/what-is-graphql#aliases).
Bien que les alias soient destinés à limiter le nombre d'appels API que vous devez effectuer, ils peuvent également être utilisés pour effectuer une attaque de force brute sur un point de terminaison GraphQL.
De nombreux points de terminaison auront une sorte de **limiteur de débit en place pour empêcher les attaques de force brute**. Certains limiteurs de débit fonctionnent en fonction du **nombre de requêtes HTTP** reçues plutôt que du nombre d'opérations effectuées sur le point de terminaison. Étant donné que les alias vous permettent effectivement d'envoyer plusieurs requêtes dans un seul message HTTP, ils peuvent contourner cette restriction.
L'exemple simplifié ci-dessous montre une série de **requêtes avec alias vérifiant si les codes de réduction du magasin sont valides**. Cette opération pourrait potentiellement contourner la limitation de débit car il s'agit d'une seule requête HTTP, même si elle pourrait potentiellement être utilisée pour vérifier un grand nombre de codes de réduction en une seule fois.
```bash
#Request with aliased queries
query isValidDiscount($code: Int) {
isvalidDiscount(code:$code){
valid
}
isValidDiscount2:isValidDiscount(code:$code){
valid
}
isValidDiscount3:isValidDiscount(code:$code){
valid
}
}
```
## Outils
### Scanners de vulnérabilités
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) : Boîte à outils qui peut être utilisée pour récupérer des schémas et rechercher des données sensibles, tester l'autorisation, forcer les schémas et trouver des chemins vers un type donné.
* [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html) : Peut être utilisé en tant que standalone ou [extension Burp](https://github.com/doyensec/inql).
* [https://github.com/gsmith257-cyber/GraphCrawler](https://github.com/gsmith257-cyber/GraphCrawler) : Ensemble d'outils pouvant être utilisé pour récupérer des schémas et rechercher des données sensibles, tester l'autorisation, forcer les schémas et trouver des chemins vers un type donné.
* [https://blog.doyensec.com/2020/03/26/graphql-scanner.html](https://blog.doyensec.com/2020/03/26/graphql-scanner.html) : Peut être utilisé en tant qu'extension autonome ou [extension Burp](https://github.com/doyensec/inql).
* [https://github.com/swisskyrepo/GraphQLmap](https://github.com/swisskyrepo/GraphQLmap) : Peut être utilisé en tant que client CLI pour automatiser les attaques.
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) : Outil qui répertorie les différentes façons d'atteindre un type donné dans un schéma GraphQL.
* [https://gitlab.com/dee-see/graphql-path-enum](https://gitlab.com/dee-see/graphql-path-enum) : Outil répertoriant les différentes façons d'atteindre un type donné dans un schéma GraphQL.
### Clients
@ -358,17 +492,18 @@ file:* query
* [**https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696**](https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696)
* [**https://medium.com/@apkash8/graphql-vs-rest-api-model-common-security-test-cases-for-graphql-endpoints-5b723b1468b4**](https://medium.com/@apkash8/graphql-vs-rest-api-model-common-security-test-cases-for-graphql-endpoints-5b723b1468b4)
* [**http://ghostlulz.com/api-hacking-graphql/**](http://ghostlulz.com/api-hacking-graphql/)
* [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.m**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md)
* [**https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md**](https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/GraphQL%20Injection/README.md)
* [**https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696**](https://medium.com/@the.bilal.rizwan/graphql-common-vulnerabilities-how-to-exploit-them-464f9fdce696)
* [**https://portswigger.net/web-security/graphql**](https://portswigger.net/web-security/graphql)
<details>
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFTs**](https://opensea.io/collection/the-peass-family)
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? Ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe Telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>