owasp zap openid connect kong oauth dast Cybersécurité

Tests dynamiques de sécurité (DAST) sous OWASP Zap avec…

L’ensemble du code source est disponible sur mon Github  😁

 

Un peu de théorie… 📚

On utilise de nos jours beaucoup de données, au seins de diverses applications, qui elles-mêmes peuvent s’échanger des données sur de multiples plateformes, accessible depuis une multitude d’appareils.

Quid de la sécurité pour éviter toute utilisation abusive ou frauduleuse ?

 

Protocole

OAuth

C’est un protocole permettant une autorisation à ‘consommer’ une API sécurisée. On peut alors interagir avec une application via une autorisation accordé par ce protocole sans avoir à partager son username ou mot de passe en clair.

 

OpenID Connect

C’est une surcouche à OAuth. Autant ce dernier et un protocole  d’autorisation de ressources, OIDC est un protocole d’identification, permettant de vérifier l’identité d’un utilisateur en se basant sur l’authentification fourni par un serveur d’autorisation.

 

Kong

Celui-ci est le serveur d’autorisation précédemment évoqué.

 

Logiciel

OWASP ZAP

Logiciel gratuit et open source, c’est l’outils de pentest le plus connue. Il n’as pas pour but de vous faire remonter la dernière faille zéro day du jour, mais plutôt de tester des mécanismes d’intrusions standard dont les plus connus.

Mais pourquoi un tuto? Car pour permettre de tester votre application dans sa globalité, et afin d’accéder à l’ensemble des pages et sous pages, vous allez devoir manipuler ZAP pour lui indiquer comment s’authentifier comme un vrai utilisateur. Vous ne parcourrez que partiellement votre appli web dans le cas contraire.

 

Authentification: form-based script

Vous allez avoir des scripts déjà fait au sein même de ZAP pour le cas d’application simple, tel que des sites wordpress. En effet, vous avez une URL statique, des credentials à envoyé dans une requête et ça fonctionne. Ce sont des form-based script.

 

Authentification: authentication-based script

Un autre type, appelé authentification-based script, peuvent ajouter des éléments pour des connexion à des sites plus complexe. Par exemple, si vous devez injecter en requête HTTP POST un token anti-CRSF. Il ajoute une sécurité en plus à votre site web, il est généré en général via des éléments renvoyé par le serveur (state, nonce, etc.). Cela permet d’éviter des attaques de type CRSF ( cross-site request forgery) qui consiste à transmettre à un user connecté une requête HTTP falsifié, résultant en une exécution d’une action sans être au courant ou l’initiateur, mais via ses propres droits. L’user est donc complice de l’attaque sans même sans rendre compte.

 

Authentification: HTTP-sender script

C’est celui-ci dont on va utiliser pour ce tuto. Ce script est appelé automatiquement lors de chaque requête que va envoyer ou recevoir ZAP vers votre application web. Mais pourquoi le script précédent ne peut-il pas correspondre ?

Voici un diagramme de séquence entre vos divers autorités :

diag de sequence zap open id connect kong oauth owasp2

 

Vous allez donc avoir une multitude d’échange (rendant impossible le login avec un script menant vers une page statique, au vu de nos multitude redirections on va manger un timeout), permettant de générer des variables aléatoires (state, nonce, crsf token, etc.). Avec celles-ci vous allez pouvoir vous loger dans votre application web, et enfin recevoir un cookie de session ou un JWT. C’est l’un des deux selon votre appli web, qui sera consommé par celle-ci afin de vérifier votre authenticité. Nous ne pouvons récupérer l’ensemble de ces champs avec l’un des type de script dont nous avons parlé précédent, et qui sont essentiel.

Le script HTTPSender interceptant chaque requête, on va pouvoir lui injecter en header HTTP GET ce cookie de session/JWT que l’on va stocker en variable globale, permettant de maintenir notre utilisateur connecté et permettant de parser l’appli web dans son intégralité.

 

Nous savons maintenant comment injecter ces tokens. Cependant, je n’ai parlé de comment le générer, avant de pouvoir l’envoyer des nos requêtes. Nous allons devoir utiliser une approche hybride selon la complexité de vos application web, avec d’une part du selenium/webdriver afin de remplir les champs comme bon nous semble, ne nous loger, et de récupérer les cookies et autre token que nous souhaitons. Vous pourrez toujours faire des appels supplémentaires GET ou POST si votre application nécessite d’avantage de complexité.

 

Si on doit résumer la procédure :

  1. Approche hybride selenium/webdriver pour bypass les xxx redirections vers la bonne page de login, avec l’ensemble des state/nonce généré aléatoirement qui sont nécéssaire
  2. Remplir la page de login avec nos credentials et valider
  3. Extraire le cookie de session ou JWT (bearer token) en variable globale
  4. Injecter ce cookie/JWT en header de requête pour tout HTTP GET via notre HTTPSender script afin d’être authentifié

 

Beaucoup de pratique 😁

Avant de vous lancer directement dans l’automatisation de vos tâches pour une CI/CD par exemple, dans un environnement sans UI, veillez à connaître dans les moindres détails l’ensemble des échanges qui s’effectue entre votre divers protocoles, car vous allez devoir scripter chaque requête à la main afin de reproduire une connexion à vos ressources comme si celle-ci était faîte depuis un navigateur. Cela va aller de la connexion sur le site avec vos credentials, avec la récupération de divers éléments (state, nonce, crsf token, etc.) afin de pouvoir en générer d’autres permettant de prouver votre identité ( divers cookie, token, etc.)

Afin de faciliter la tâche, je vous conseil de débuter de scripter la partie authentification à votre site web via l’application desktop dans un premier temps. Vous pourrez ainsi voir les divers échanges entre vos protocole, si vous ne connaissez pas la procédure dans sa globalité.

 

OWASP ZAP en mode desktop

Je vais détailler d’avantage le contenu des scripts dans la partie suivante, et me consacrer dans celle-ci principalement à vous présenter l’application desktop Zap.

 

Moteur de scripting

Zap est écrit en Java. Mais nous pouvons écrire nos scripts dans d’autres langages via des moteurs de scripts :

  • Javascript via Graal.js ou Oracle Nashorn
  • Zest via Mozilla
  • Python via Jython

J’aime bien le python, donc la suite du tuto sera utilisé avec Jython.

Python et javascript vous permettent d’écrire tout à la main vos scripts. Cependant, Zest vous permet d’enregistrer automatiquement toute action que vous faîtes sur votre appli web, lorsque vous la scanné en mode manuel. Vous pouvez ainsi vous décharger de la tâche pénible de scripter chaque action nécessaire pour être authentifier au sein de votre application, et juste naviguer en mode manuel via Zap sur votre application. Zest va s’occuper d’enregistrer chaque étape dans un format ressemblant à du JSON. Gain de temps assuré ! 😎

zest script
Enregistrement de la séquence d’authentification via le moteur de script Zest (Mozilla)
Scripting – Standalone script
create standalone script
Création d’un script autonome (standalone)
Scripting – HTTPSender script
create http sender script
Création d’un HTTPSender script
Test de l’authentification

Une fois que vos deux scripts sont crée on va pouvoir tester notre solution. Par exemple pour un scan actif.

Commencez par clique-droit sur votre script standalone, et exécutez le afin de reset le contenu de notre cookie. A faire entre chaque parcours manuel de votre application, sinon vous risquez de vous prendre un time out si votre cookie se refresh à chaque session.

Ensuite clique-droit sur votre script http-sender afin de l’activer.

Vous pouvez maintenant lancer votre scan actif et vérifier que le spider récupère bien des pages avec un code de retour OK (200). Choisissez votre point de départ et lancez le balayage :

 

On peut voir que le scan se passe comme souhaité. Vérifiez qu’il passe bien dans vos sous-domaines réservés aux utilisateurs authentifié.

OWASP ZAP en mode automatique/headless

Scripting – Standalone script

On commence par écrire notre premier script qui nous permet d’initialiser une seule et unique fois notre variable globale du cookie à null :

Scripting – HTTPSender script

La partie la plus importante du projet consiste à écrire notre script qui va à la fois nous permettre de nous connecter, de récupérer notre objet nous permettant de nous authentifier, pour enfin l’envoyer dans chaque requête qui passe par Zap.

On commence donc par divers imports de bibliothèque dont on va avoir besoin. Ne vous affolez pas à voir des imports de lib Java dans le script Python !

On y défini quelques variables globales, dont la page de connexion initiale à notre app web :

Lorsque vous créez un script HTTPSender avec le squelette de base, vous allez avoir ces deux fonctions de base :

  • sendingRequest : appelé à chaque envoie de requête à travers Zap vers notre app
  • ResponseReceived : appelé à chaque réponse de notre app vers Zap.

Nous n’utiliserons que la première, car nous souhaitons simplement modifier notre en-tête de requête afin d’ajouter un élément qui nous permette de prouver que l’on est un utilisateur authentifié.

La fonction est simple. On vérifie que notre cookie existe. Si c’est le cas, on l’injecte simplement à notre requête via une fonction défini plus tard. Dans le cas contraire, on va récupérer ce cookie d’abords.

Cette fonction est très généraliste, vous devrez l’adapter en fonction de l’ensemble des étapes nécessaires concernant votre type d’authentification. Chaque site étant différent, je ne peux vous la faire dans sa globalité. Mais le schéma global est le suivant :

  • Créer une fenêtre Firefox. Vous pouvez lui spécifier des arguments, par exemple –headless qui doit être obligatoire si vous tournez sous une CI/CD par exemple. Si vous êtes sur un environnement windows, vous devrez rajouter le –disable-gpu ( qui est une issue connue sur le github de Zap), ou encore ajouter –disable-extensions pour gagner en performance. Si vous avez un proxy d’entreprise par exemple, vous pourrez aussi lui passer.
  • Ouvrir Firefox sur votre page de login. Selon votre provider d’autorisation, vous allez avoir plusieurs redirections. J’ai rajouté une condition afin d’être certains d’être sur la bonne page de login à l’arrivée.
  • Remplir les champs pour s’authentifier via Selenium. Je vous ait mis quelques exemple pour trouver vos champs, et les remplir.
  • Une fois connecté et arrivé sur notre page final pour un utilisateur authentifié, je récupère mon cookie pour l’injecter dans ma variable global. Dans mon cas je récupère un cookie dont le nom est « session », ainsi que sa valeur.

On peut enfin dans une dernière fonction injecter notre cookie de session dans l’entête de l’ensemble de nos requêtes qui transitent par Zap, nous permettant de maintenir notre authentification durant tout le processus de scan :

 

Dans le cas ou vous souhaitez envoyer un Json Web Token (JWT ou appelé Bearer Token) c’est quasiment la même chose :

Dans ce cas là, n’oubliez pas de sauvegarder en variable globale dans la fonction login(), votre token d’accès ainsi que votre token d’expiration. Dans le cas que votre token ne dure pas une session complète mais pour un temps limité, vous devrez ajouter dans la méthode login() une étape permettant de vérifier que votre jeton est encore valide. Dans le cas contraire, il faudra repasser par l’étape login() afin de demander de renouveler votre jeton.

C’est fait de tête rapidos, mais le principe est là si vous souhaitez implémenter une vérification de token concernant sa date de validité et d’expiration :

 

Lancement en CI/CD

On lance notre image depuis le répo officiel :

Afin d’utiliser nos scripts, on doit les déplacer au sein même de notre image dans les dossiers correspondant : /scripts pour les scripts, et /plugin pour y mettre n’extension du moteur de script Jython. En effet il n’est pas disponible de base, il faut soit le rajouter à la main comme ceci, soit l’ajouter (indiqué dans la commande suivante) au lancement de Zap :

Nous n’avons plus qu’a lancer le script zap-x.sh (très important le -x afin de tourner dans un mode headless). J’autorise tout les IP à accéder à Zap en désactivant la clée API et en whitelistant via le name et regex. Vous pouvez ajouter des extensions ici à la volée, ou même mettre à jour ceux déjà présent :

 

Script global

Je fais référence à un script main.py dans ma dernière commande docker. En effet pas besoin dans ZAPDesktop, mais en version full-script, vous allez devoir avoir besoin d’un script que l’on peu qualifier de global, qui va discuter avec notre image de Zap lancé en mode daemon. Ce mode daemon va permettre à ZAP d’être à l’écoute de tout appel. Nous pourrons communiquer entre celui-ci et notre script main.py via l’api REST offerte.

Faîte vous un environnement virtuel Python, que ça soit Venv sur MAC OS ou Anaconda pour windows. On aura besoin de descendre une dépendance :

pip install python-owasp-zap-v2.4

 

Voici la manœuvre à suivre pour communiquer avec ZAP, et surtout comment charger, activer et lancer vos scripts afin de gérer toute l’étape d’authentification dans un environnement headless avant de lancer les spider pour crawl et de lancer les attaques via scanner :

 

Requête générique

Si votre flux d’authentification est plus complexe, et que vous devez récupérer des champs comme le State, None, ou encore un CRSF Token, je vous met ci dessous de quoi réaliser des requêtes génériques GET et POST dans le scritpt HTTPSender :

 

android ios react native expo Cours web Mobile – React Native

Chap 2 : Builder & générer les .apk &…

Après quelques instants de build.. TADAAA !

Objectif

  • Signer son app
  • Builder offline et en local son app
  • Générer les fichiers d’installation Android (apk) & iOS (ipa)

 

Code source du chapitre disponible sur Github.
 

 

Introduction

Vous pouvez utiliser directement Expo pour lancer très facilement votre build sur leurs serveurs distants, avec la simple commande :

expo build:android

Pourquoi je ne l’utilise pas ?

Car lorsque que j’ai voulu lancer un build, leurs serveurs étaient down, laissant mon build en attente. Flemme de perdre plus de temps, je me suis lancé dans les recherches afin de savoir si l’on pouvait nous même générer notre build. C’est un peu plus tricky, mais ça marche.

 

A SAVOIR AVANT DE SE LANCER DANS LE DEV MOBILE

Je souhaite vous parler de compte développeur. ça vous évitera toute surprise comme j’ai pu avoir en développant ma première application sur les stores.

Si vous souhaitez distribuer votre application sur les stores :

  • iOS : Compte développeur nécessaire ( 100€ par an )
  • Android : Compte développeur nécessaire (25€ à vie )

Avec une licence, vous pouvez ensuite lancez autant d’application que vous le souhaitez, vous n’êtes pas limité en nombre.

 

Si vous souhaitez seulement builder votre application en local :

  • iOS : Compte développeur toujours nécessaires, sur un macOS exclusivement. Vous ne pouvez générer votre certificat, teamID et votre fichier de provision en local par vous même.
  • Android : Pas besoin de compte spécifique. Juste un macOS ou Linux d’obligatoire. Car votre fichier de clée nécessaire au build est générable en local, par vous même.

 

Prérequis

  • Bash
  • NodeJS

Build pour Android

  • macOS ou Linux ( pensez à avoir une VM )
  • JDK/JRE (Java Development kit) en version 8 exclusivement

Build pour iOS

  • macOS
  • Xcode (minimum v11.4)
  • Fastlane ( préférez l’installation par Homebrew, le plus simple et rapide moyen )

 

Si comme moi vous êtes pauvres et n’avez pas de macbook pour build votre .IPA, je vous ait fait un article qui vous sauvera un ou deux jours de recherche et de test pour avoir un macOS Catalina sur votre linux qui est proche d’avoir les performances d’une install native ! Oubliez windows, oubliez virtual box ou vmware. Même mon pc à 4000€ ne fait pas tourner macOS, car aucun de ces softs ne peut attribuer des ressources graphiques, entrainant de gros ralentissement lors de vos déplacement de souris et ouverture de logiciel. Bref, c’est inutilisable, à moins de passer par mon tuto qui utilise le combo QEMU/KVM, et qui fait tourner lui Catalina facilement sur mon portable à 2 coeurs de 2015 😁

 

On utilisera la TurtleCLI pour générer le build. Installez le via npm :

npm install -g turtle-cli

 

Signature de l’application

Android

La première étape consiste à signer l’application. Cela permet de créer des certificats concernant la sécurité, pour la distribution. On va utiliser l’outil keytool de java pour générer notre keystore :

Vous pouvez apercevoir aussi des clés avec l’extension « .keystore ». C’est une clée comme les « .jks » avec un format différent.

Cette commande va vous demander plusieurs questions vous concernant :

Génération du keystore

Un fichier va être crée. Veillez à bien mettre de côté de fichier. Il vous sera demander à chaque build de votre application

 

iOS

Il vous faudra un certificat, un apple Team ID, et un fichier de provision

 

 Génération du certificat

Allez sur votre compte développeur Apple. Dans l’onglet certificat, cliquez sur le bouton + :

apple ios generation application ipa certificat p12 provision

 

Choisissiez l’option iOS Distribution (app store and ad hoc ) :

 

Faîte continuer, et on arrive sur une nouvelle fenêtre nous invitant à envoyer un fichier CRC :

apple ios generation application ipa certificat p12 provision

 

On va devoir générer un certificat. Pour cela, lancez l’application Trousseaux d’accès qui est dans le dossier Applications/Utilitaires de votre macbook. Dans le menu en haut à gauche, cliquez sur Trousseaux d’accès, puis sur Assistant de certification, puis sur Demander un certificat à une autorité de certificat :

apple ios generation application ipa certificat p12 provision

 

Remplir les champs demandé, et faîte enregistrer en local :

apple ios generation application ipa certificat p12 provision

 

Vous aurez un nouveau fichier sur votre bureau :

apple ios generation application ipa certificat p12 provision

 

On retourne sur le compte développeur Apple ouvert précédemment, nous étions rester sur la fenêtre ou on nous demander notre fichier CSR. C’est le fichier que nous venons de générer sur le bureau que nous allons upload :

apple ios generation application ipa certificat p12 provision

 

Nous pouvons désormais télécharger notre certificat ! Téléchargez le, et ouvrez le :

apple ios generation application ipa certificat p12 provision

 

Il sera automatiquement ajouté à notre trousseau d’accès, attaché à notre session :

apple ios generation application ipa certificat p12 provision

 

Sélectionnez votre certificat fraichement installé avec sa clé privée, et exportez les deux éléments :

apple ios generation application ipa certificat p12 provision

apple ios generation application ipa certificat p12 provision

 

Exportez au format .p12, et donnez lui un nom et mettez le de côté, ce fichier vous sera obligatoire pour builder :

apple ios generation application ipa certificat p12 provision

 

Un mot de passe sera demandé, notez le bien de côté, il vous le sera demandé lors du build :

apple ios generation application ipa certificat p12 provision

 

Vous avez maintenant un certificat au format .p12 sur votre bureau. Gardez le bien de côté.

 

Création du teamID

On revient sur le compte développeur Apple, et on va allez cette fois ci dans l’onglet Identifiers, cliquez sur + :

apple team build id

 

On coche App IDs, et on continue :

apple team build id

 

 

On sélectionne App, et on continue :

apple team build id

 

 

On remplis le champ Description qui est le nom de l’application, ainsi que son bundleID sous la forme recommandé. Dans Capabilities, vous cocherez les accès et autorisations que votre application à besoin. Par exemple si c’est une application photo, elle devra avoir accès à l’APN du smartphone. Vous cliquez ensuite sur Continue, puis Register :

apple team build id

 

Notez bien votre App ID Prefix, qui est votre Team ID. Vous en aurez besoin pour build par la suite.

 

 

Fichier de provision

Troisième et dernière étape. On va maintenant s’occuper de générer du fichier de provision, lui aussi nécessaire pour buid l’application.

Toujours sur notre compte développeur Apple, on va sélectionner cette fois ci l’onglet Profiles, et cliquer sur + :

apple build ios appstore provision file

 

On sélectionne ensuite App store, dans l’onglet Distribution. A savoir, les builds Ad Hoc ne sont pas pris en charge par Expo. On clique sur Continue :

apple build ios appstore provision file

 

Sélectionnez l’app ID précédemment crée, et faîte Continue :

apple build ios appstore provision file

 

Sélectionnez le certificat précédemment crée, et faîte Continue :

apple build ios appstore provision file

 

Donnez un nom à votre fichier de provision, et faîte Generate :

apple build ios appstore provision file

 

Téléchargez le, et gardez le de côté, vous en aurez besoin pour générer votre build :

apple build ios appstore provision file

 

Export de l’application

Android & iOS

La seconde étape consiste à exporter notre application. Cela permet de créer les bundles (iOS & Android) à partir des fichiers javascript. Vous devriez apercevoir la création d’un dossier « dist » dans votre répertoire courant via la commande suivante :


Attention à utiliser la bonne, selon si votre application contient du HTTP ou HTTPS.

 

Servir l’application

Android & iOS

On va maintenant lancer notre application à partir du bundle crée précédemment, en local. Pour cela on va utiliser python. Déplacez vous dans le dossier « dist » précédemment crée, et lancer la commande suivante :

 

Vérifiez bien que le serveur tourne, via curl, ou en lançant une connexion à votre localhost via votre navigateur :

 

Build l’application

Dernière étape, on va pouvoir lancer le build de nos fichiers. Revenez à la racine de votre projet et ouvrer une autre console.

Android

Lancez la commande suivante pour lancer le build via turtle-cli :

Voilà votre fichier APK, situé dans le répertoire annoncé dans la console.

 

iOS

Lancez la commande suivante pour lancer le build via turtle-cli :

 

Soucis fréquemment rencontré

EACESS permissions denied

Vous pouvez vous confronter à des erreurs d’accès aux fichiers pour installer des packets npm globaux ( pour turtle-cli ou encore expo ). Oubliez les sudo su et sudo en tout genre, qui m’ont fait juste galérer encore plus. Vous pouvez fix cela en deux étapes :

  • Utilisez l’option ‘–unsafe-perm‘ de NPM
  • Pour le dossier ‘lib/node_modules’ qui résisterait aux erreurs, passez un coup de chown -R votreNomUser pour donner accès à votre utilisateur courant de la session au dossier en lecture et écriture.

 

Conclusion

Nous venons de générer nos fichiers d’installation APK pour Android et IPA pour iOS, afin de distribuer notre application.
On s’attaque à la navigation entre plusieurs écrans sur notre prochain chapitre.