[PYTHON] Comment intercepter ou falsifier la communication SSL de l'appareil iOS réel par un proxy

introduction

Lorsque vous interagissez avec le serveur Web / API via l'API dans le développement d'applications pour smartphone, il n'y a rien de tel que "Si vous utilisez https, la communication ne sera pas remarquée par l'utilisateur", tout comme vous pouvez le faire avec les outils de l'application Web. Vous pouvez vérifier le contenu de la communication et le modifier.

Par conséquent, si vous ne concevez pas et n'implémentez pas l'API de l'application ou du serveur sur cette base, la falsification de la transmission du résultat du jeu par l'utilisateur de l'application, l'opération d'endommagement du boss de raid, etc. dans les jeux sociaux, l'opération d'achat avec l'application de site EC, etc. Sera également possible.

De plus, j'ai récemment publié une application intitulée "Tout ce que vous pouvez écouter de la musique gratuitement !! --Net Radio"](https://itunes.apple.com/jp/app/nettorajio-j-popmo-wu- liaode / id769979888? mt = 8), vérifiez si la bibliothèque de liens statiques installée dans cette application ne communique pas avec un serveur externe inconnu, ou si vous avez l'intention d'utiliser SSL mais ne communiquez pas autrement Pour ce faire, j'utilise un outil de serveur proxy appelé mitmproxy.

Le contenu suivant est comme ça

--À propos de mitmproxy et de son introduction --Confirmation du contenu de la communication --Falsification du contenu de la communication (réécriture de demande, réécriture de réponse)

Ce dont vous avez besoin est:

À propos de mitmproxy et de son introduction

mitmproxy est un outil de proxy en ligne de commande. Le nom mitm est une abréviation de man-in-the-middle et semble provenir de termes utilisés dans des termes de communication tels que l'attaque de l'homme du milieu.

Une attaque intermédiaire est radicale, mais c'est un outil utile lors de la vérification d'une application que vous avez vous-même développée.

L'image ressemble à ceci:

mitm_2.jpg

Le mécanisme approximatif consiste à utiliser le partage Internet (la fonction qu'OSX lui-même devient un routeur WiFi) dans le réglage standard de Mac OSX, à relayer la communication avec le proxy et à utiliser le WiFi sur le périphérique iOS réel.

Installation de Python

Pour exécuter mitmproxy, vous avez d'abord besoin de Python, alors installez Python avec homebrew.

 $ brew update
 $ brew upgrade
 $ brew install python

Ensuite, installez pip. easy_insall doit être installé en même temps que brew installe python.

$ easy_install pip

Installation de mitmproxy

Installer mitmproxy à partir de pip

$ pip install mitmproxy

Si vous l'avez déjà installé et souhaitez le mettre à jour, ajoutez l'option -U comme suit et mettez-le à jour.

$ pip install mitmproxy -U

En installant avec pip, les bibliothèques associées seront également installées.

Démarrez mitmproxy

Pour exécuter, spécifiez le port avec l'option -p comme suit.

$ mitmproxy -p 8080

J'ai spécifié le port 8080, mais cela nécessite également que 8080 soit spécifié dans les paramètres WiFi du côté de l'iPhone.

Vous pouvez spécifier l'adresse du serveur et le numéro de port en sélectionnant Manuel avec proxy HTTP dans les paramètres WiFi d'iOS.

IMG_0669.jpg

(Sunny dans la figure est le nom de la machine de Mac OSX, qui est le nom du WiFi, alors ne vous inquiétez pas)

Installation du certificat racine sur l'iPhone réel

De plus, lorsque vous exécutez mitmproxy, un certificat appelé mitmroxy-ca.pem est créé dans ~ / .mitmproxy /. Il est possible de l'installer en envoyant ce certificat par mail depuis OS X vers iPhone et en ouvrant le certificat depuis le client de messagerie côté iPhone. Vous pouvez vérifier ce certificat dans [Paramètres] [Général] [Provision], qui est familier aux développeurs d'applications iOS.

Utilisez mitmproxy

Une utilisation simple de mitmproxy consiste à afficher les demandes et les réponses, à les falsifier ou à arrêter la communication.

En ce qui concerne la falsification de la demande, par exemple, vous pouvez modifier les paramètres de la demande déjà envoyée et vous pouvez renvoyer la demande modifiée.

名称未設定.jpg

Réécrire de manière interactive les données de demande / réponse

À partir de la liste des demandes sur l'écran montré dans la figure où mitmproxy est démarré, appuyez sur la touche [Entrée] pour passer à l'écran des détails de demande / réponse GET. Modifier la requête (requête, chemin, URL, en-tête, formulaire, corps, méthode) avec [clé e] Vous pouvez revenir à la liste et RE-OBTENIR la demande modifiée avec la [touche r].

Vous pouvez également annuler les modifications avec la [touche V], ce qui est difficile à remarquer. Vous pouvez vérifier ces raccourcis en appuyant sur la touche [?].

Cette capacité à modifier les demandes de manière interactive facilite les essais d'appels d'API côté serveur, ce qui le rend idéal pour la validation et les tests lorsque les spécifications côté API du serveur sont inconnues. Vous serez également en mesure de tester des systèmes anormaux lorsque les paramètres sont perturbés, par exemple lors de la demande d'éléments de facturation et de l'envoi de reçus au serveur lors d'un achat intégré.

Au contraire, dans cette réécriture interactive, même si vous éditez la requête et GET / POST à nouveau, la communication côté application est terminée, donc si vous pouvez tester en recevant la demande / réponse falsifiée côté application, etc. Je pense qu'il y en a peu.

Falsification des données en temps réel par script

Avec mitmproxy, vous pouvez appliquer un script pour chaque communication en spécifiant un fichier de script Python qui décrit le contenu à falsifier à l'avance, au lieu de falsifier la demande / réponse par une opération interactive.

Par exemple, supposons que vous ayez un système appelé Raid Boss dans un jeu social où un grand nombre d'utilisateurs combattent un boss commun.

Dans la plupart des cas, le flux sera:

Compte tenu de la modification des dégâts avec mitmproxy et du nombre d'objets de récompense qui ont causé des dégâts, cela devient comme suit.

En falsifiant la réponse à la requête avec un script, il devient possible de faire des choses qui n'ont pas pu être expirées par la réécriture interactive.

Spécifier un script

$ mitmproxy -s examples/add_header.py

Le fichier add_header.py de l'exemple a le contenu simple suivant, il doit donc être amené à l'introduction.

add_header.py


def response(context, flow):
    flow.response.headers["newheader"] = ["foo"]

La méthode de réponse est une méthode qui réécrit la réponse de communication avant de la livrer au client HTTP (S). Remplacez cette méthode, ajoutez "newheader" à l'en-tête de réponse et définissez la valeur sur la chaîne "foo" de la liste.

La classe Flow et la classe Response sont définies dans flow.py, vous devrez donc vous y référer pour comprendre les spécifications.

https://github.com/mitmproxy/mitmproxy/blob/master/libmproxy/flow.py

Il existe également un exemple de code qui utilise un script pour déterminer si la demande concerne un hôte spécifique, ce qui est le plus utile.

https://github.com/mitmproxy/mitmproxy/blob/master/examples/redirect_requests.py

redirect_requests.py crée et retourne une réponse originale pour toutes les requêtes à l'hôte sur "example.com" et redirige vers "mitmproxy.org" s'il s'agit de "example.org".

Sur la base de cet exemple de code, il sera rapide de falsifier et de vérifier la demande adressée à l'hôte que vous préparez.

À propos de mitmdump

Lorsque vous installez mitmproxy, un outil appelé mitmdump est également installé. Contrairement au mitmproxy expliqué jusqu'à présent, mitmdump renvoie le résultat sur la sortie standard au lieu de l'affichage de la liste interactive comme l'écran de la console mentionné ci-dessus, il semble donc que vous puissiez affiner le résultat en l'utilisant avec grep. En utilisant cela, vous avez l'intention d'utiliser https pour un hôte spécifique, mais vous serez en mesure de vérifier efficacement s'il s'agit de http.

Résumé du fonctionnement et de l'application

Ce que je n'ai pas écrit ici

La méthode décrite ici modifie les paramètres wifi pour accéder au port 8080. Cependant, si vous utilisez un proxy transparent, vous pouvez faire communiquer la machine réelle comme d'habitude en utilisant le port 80 par défaut du wifi.

Pour savoir comment utiliser le proxy transparent, veuillez consulter le site suivant.

Mitmproxy transparent avec partage Wifi sur Mac http://bagpack.hatenablog.jp/entry/2014/02/04/225553

en conclusion

Si les concepteurs / opérateurs d'API Web du monde entier et les développeurs d'applications ne connaissent pas correctement ce qui précède, cela prendra un temps différent de la gestion de contenu d'origine, comme la récupération en cas de panne et le suivi des contrevenants, et des dommages se produiront. Cela provoque même un sentiment de stagnation dans le plan. Je pense que le début est que le design est passif en raison d'une pensée optimiste telle que la tranquillité d'esprit si vous communiquez avec https avec une application pour smartphone, alors j'ai pensé que c'était la première chose à savoir comment intercepter / falsifier la communication.

En fait, le Game Center d'Apple semble envoyer des scores via plist, et il semble que vous puissiez changer le score de l'utilisateur de l'application simplement en falsifiant la demande interactive par mitmproxy (bien que cela puisse être corrigé maintenant). ..

Setting highscores on Apple's GameCenter http://mitmproxy.org/doc/tutorials/gamecenter.html

Les mesures de sécurité spécifiques varieront en fonction des exigences et des priorités de chaque contenu, alors pensez par vous-même. Ou Si vous nous consultez, nous réfléchirons ensemble.

URL de référence

mitmproxy http://mitmproxy.org/

exemple de script mitmproxy https://github.com/mitmproxy/mitmproxy/tree/master/examples

Vérifiez le contenu de la communication SSL à l'aide de mitmproxy http://ido.nu/kuma/2012/01/29/how-to-use-mitmproxy/

Avez-vous commencé à utiliser pip en raison de la dépendance de pyasn1 et PyOpenSSL? https://github.com/mitmproxy/mitmproxy/issues/37

Recommended Posts

Comment intercepter ou falsifier la communication SSL de l'appareil iOS réel par un proxy
Comment tracer beaucoup de légendes en changeant la couleur du graphique en continu avec matplotlib
[Python] Comment utiliser l'instruction for. Une méthode d'extraction en spécifiant une plage ou des conditions.
[Introduction à Python] Comment trier efficacement le contenu d'une liste avec le tri par liste
Comment calculer la volatilité d'une marque
[python] Comment trier par le Nth Mth élément d'un tableau multidimensionnel
Comment obtenir une liste de fichiers dans le même répertoire avec python
[Introduction à Python] Comment obtenir l'index des données avec l'instruction for
[Python] Comment gérer l'erreur d'instance is "is instance () arg 2 doit être un type ou un tuple de types"
Comment créer un sous-menu avec le plug-in [Blender]
Comment identifier l'élément avec le plus petit nombre de caractères dans une liste Python?
[Ruby] Comment remplacer uniquement une partie de la chaîne de caractères correspondant à l'expression régulière?
Un mémo sur la façon de surmonter le problème difficile de la capture d'effets avec l'IA
Créez un tableau à deux dimensions en ajoutant une ligne à la fin d'un tableau vide avec numpy
Comment insérer un processus spécifique au début et à la fin de l'araignée avec la tremblante
[Ubuntu] Comment supprimer tout le contenu du répertoire
[Python] Comment créer une liste de chaînes de caractères caractère par caractère
Comment tester les attributs ajoutés par add_request_method de pyramid
Comment afficher une liste des versions installables avec pyenv
Une histoire sur la façon de traiter le problème CORS
Comment connecter le contenu de la liste dans une chaîne de caractères
Comment envoyer des fichiers d'un seul coup en se connectant à un hôte de l'autre côté de la plate-forme avec SCP en plusieurs étapes
Comment déterminer l'existence d'un élément sélénium en Python
[Introduction à Python] Comment fractionner une chaîne de caractères avec la fonction split
Comment vérifier la taille de la mémoire d'une variable en Python
[Introduction à StyleGAN] J'ai joué avec "The Life of a Man" ♬
Comment faire une commande pour lire le fichier de paramètres avec pyramide
J'ai essayé de résumer brièvement la procédure de démarrage du développement de Django
Comment vérifier la taille de la mémoire d'un dictionnaire en Python
Comment trouver l'adresse mémoire de la valeur de la trame de données Pandas
Comment afficher le résultat de sortie de la commande man Linux dans un fichier
Comment surveiller l'état d'exécution de sqlldr avec la commande pv
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Comment envoyer une requête à l'API DMM (FANZA) avec python
[NNabla] Comment supprimer le niveau intermédiaire d'un réseau prédéfini
Comment exécuter le code pratique du livre "Making Profitable AI with Python" sur Google Colaboratory
[EC2] Comment faire une capture d'écran de votre smartphone avec du sélénium
J'ai essayé de communiquer avec un serveur distant par communication Socket avec Python.
Réfléchissez à la façon d'écrire un filtre avec les versions Shotgun API-Contact
Comment couper la partie inférieure droite de l'image avec Python OpenCV
[Python] Explique comment utiliser la fonction range avec un exemple concret
[Reconnaissance d'image] Comment lire le résultat de l'annotation automatique avec VoTT
Comment gérer l'erreur SSL lors de la connexion à S3 avec Python boto
[NNabla] Comment ajouter une couche de quantification à la couche intermédiaire d'un modèle entraîné
Comment mettre un numéro de ligne au début d'un fichier CSV
Paramètre pour entrer le contenu de la bibliothèque avec pytest et effectuer un test de débogage
Comment réparer la population initiale avec un algorithme génétique utilisant DEAP
Comment créer un wrapper qui préserve la signature de la fonction à envelopper
[Introduction à Python] Comment écrire une chaîne de caractères avec la fonction format
Comment bien formater une liste de dictionnaires (ou d'instances) en Python
Comment lire une vidéo tout en regardant le nombre d'images (Mac)
J'ai essayé de vérifier le résultat du test A / B avec le test du chi carré
Résumé de la création d'un environnement LAMP + Wordpress avec Sakura VPS
Comment trier en spécifiant une colonne dans le tableau Python Numpy.
Comment obtenir le "nom" d'un champ dont la valeur est limitée par l'attribut choice dans le modèle Django
Comment ajouter un package avec PyCharm
Comment vérifier la version de Django
Comment passer le résultat de l'exécution d'une commande shell dans une liste en Python
N'hésitez pas à rédiger un test avec nez (dans le cas de + gevent)