« Mitmproxy » : différence entre les versions

De Wiki doc

(Page créée avec « Category:Services_mandataire [https://mitmproxy.org/ Mitmproxy] est un mandataire (''proxy'') destiné au débogage, tests, notamment de pénétrations ainsi qu'aux évaluation des mesures de protections d'un système d'information. Il est extrêmement utile pour comprendre le fonctionnement d'un programme officiant au travers de sessions ''HTTPS'' puisqu'il permet de réunir les éléments nécessaires à l'inspection des trames chiffrées par ''TLS''. Il... »)
 
(Corrections de fautes de français + légère mise en forme + ajout de la section "Sources")
 
Ligne 1 : Ligne 1 :
[[Category:Services_mandataire]]
[[Category:Services_mandataire]]


[https://mitmproxy.org/ Mitmproxy] est un mandataire (''proxy'') destiné au débogage, tests, notamment de pénétrations ainsi qu'aux évaluation des mesures de protections d'un système d'information.
[https://mitmproxy.org/ Mitmproxy] est un mandataire (''proxy'') destiné au débogage, tests, notamment de pénétrations ainsi qu'aux évaluations des mesures de protections d'un système d'information.
Il est extrêmement utile pour comprendre le fonctionnement d'un programme officiant au travers de sessions ''HTTPS'' puisqu'il permet de réunir les éléments nécessaires à l'inspection des trames chiffrées par ''TLS''.
Il est extrêmement utile pour comprendre le fonctionnement d'un programme officiant au travers de sessions ''HTTPS'' puisqu'il permet de réunir les éléments nécessaires à l'inspection des trames chiffrées par ''TLS''.


Il peut, en outre, servir à espionner la navigation ''HTTPS'' des utilisateurs d'un réseau limité (obligeant l'accès au ''WAN'' par l'intermédiaire d'un mandataire). À l'issue de la lecture de ce document, vous devriez être sensibilisé à ne jamais réaliser d'opérations personnelles sur ce genre de réseau (connexion à un ''Webmail'' ou à tout portail nécessitant un identifiant personnel par exemple).
Il peut, en outre, servir à espionner la navigation ''HTTPS'' des utilisateurs d'un réseau à accès limité (obligeant l'accès au ''WAN'' par l'intermédiaire d'un mandataire). À l'issue de la lecture de ce document, vous devriez être sensibilisé à ne jamais réaliser d'opérations personnelles sur ce genre de réseau (connexion à un ''Webmail'' ou à tout portail nécessitant un identifiant personnel par exemple).


Cette documentation explique brièvement comment se servir de l'outil pour enregistrer les clés de sessions ''TLS'' et présente un cas pratique avec le déchiffrement d'un <code>docker pull</code>. Les trames capturées via [[Tcpdump]] pourront alors être examinées par un outil graphique comme [[Wireshark]].
Cette documentation explique brièvement comment se servir de l'outil pour enregistrer les clés de sessions ''TLS'' et présente un cas pratique avec le déchiffrement d'un <code>docker pull</code>. Les trames capturées via [[Tcpdump]] pourront alors être examinées par un outil graphique comme [[Wireshark]].
Ligne 13 : Ligne 13 :
  apt install --no-install-recommends mitmproxy
  apt install --no-install-recommends mitmproxy


Le fait de lancer <code>mitmproxy</code> créé automatiquement le répertoire <code>~/.mitmproxy</code> contenant les éléments secrets utilisés dans une transaction ''TLS''. Il est alors possible d'importer le certificat serveur dans la base local du client à espionner ou générer son propre certificat via [[openssl|OpenSSL]]. Afin d'agrémenter la démonstration, la seconde solution sera utilisée. Outre l'aspect didactique, générer votre propre certificat est indispensable lorsque l'interception de la communication d'une application exigeante en terme de vérification est utilisée (ce pourquoi [[Docker]] est utilisé en guise d'exemple). Il est en effet nécessaire dans ce cas d'ajouter des noms alternatifs dans la section <code>subjectAltName</code> du [https://fr.wikipedia.org/wiki/X.509 certificat X.509] afin de spécifier les adresses signées par celui-ci.
Le fait de lancer <code>mitmproxy</code> créé automatiquement le répertoire <code>~/.mitmproxy</code> contenant les éléments secrets utilisés dans une transaction ''TLS''. Il est alors possible d'importer le certificat serveur dans la base local du client à espionner ou générer son propre certificat via [[openssl|OpenSSL]].
 
Afin d'agrémenter la démonstration, la seconde solution sera utilisée. Outre l'aspect didactique, générer votre propre certificat est indispensable lorsque l'interception concerne la communication d'une application exigeante en terme de vérification (ce pourquoi [[Docker]] est utilisé en guise d'exemple). Il est en effet nécessaire dans ce cas d'ajouter des noms alternatifs dans la section <code>subjectAltName</code> du [https://fr.wikipedia.org/wiki/X.509 certificat X.509] afin de spécifier les adresses signées par celui-ci.


==Configuration des clés==
==Configuration des clés==
Ligne 34 : Ligne 36 :
</syntaxhighlight>
</syntaxhighlight>


Le point d'intérêt principal de ces opérations et qui devra être personnalisé en fonction du cas à traiter est la sous commande <code>printf "subjectAltName=DNS:*.ycharbi.fr,DNS:*.docker.io,DNS:*.cloudflare.docker.com,IP:127.0.0.1"</code> présente à la ligne numéro 8. Utilisez les domaines que vous voulez voir validé par ''TLS'' lors de la poignée de main entre une application cliente et votre mandataire.
Le point d'intérêt principal de ces opérations et qui devra être personnalisé en fonction du cas à traiter est la sous-commande <code>printf "subjectAltName=DNS:*.ycharbi.fr,DNS:*.docker.io,DNS:*.cloudflare.docker.com,IP:127.0.0.1"</code> présente à la ligne numéro 8. Utilisez les domaines que vous voulez voir validé par ''TLS'' lors de la poignée de main entre une application cliente et votre mandataire.


==Tests de fonctionnement==
==Tests de fonctionnement==
Ligne 42 : Ligne 44 :
où :
où :
* '''SSLKEYLOGFILE= ''' : emplacement du fichier contenant les clés négociées lors des différentes sessions ''TLS''
* '''SSLKEYLOGFILE= ''' : emplacement du fichier contenant les clés négociées lors des différentes sessions ''TLS''
* '''--certs *= ''' : emplacement du certificat chaîné serveur pour signer le domaine spécifié dans la commande (ici <code>*</code> pour tout les domaines). Il peut y avoir plusieurs fois ce paramètre pour mettre autant de certificat que de domaines au besoin
* '''--certs *= ''' : emplacement du certificat chaîné serveur pour signer le domaine spécifié dans la commande (ici <code>*</code> pour tout les domaines). Il peut y avoir plusieurs fois ce paramètre pour mettre autant de certificats que de domaines au besoin


Les clients ''HTTP'' communs peuvent êtres utilisés pour tester le fonctionnement de la solution
Les clients ''HTTP'' communs peuvent êtres utilisés pour tester le fonctionnement de la solution
Ligne 55 : Ligne 57 :
Pour que cela fonctionne, il faut :
Pour que cela fonctionne, il faut :
* un certificat avec les bons domaines renseignés dans le champ <code>subjectAltName</code> (fait dans l'étape préparatoire)
* un certificat avec les bons domaines renseignés dans le champ <code>subjectAltName</code> (fait dans l'étape préparatoire)
* ajouter ce certificat dans la configuration du registre d'image Docker dont l'adresse sera remplacée par celle de notre mandataire (la commande de tirage de l'image reste identique)
* ajouter ce certificat dans la configuration du registre d'image ''Docker'' dont l'adresse sera remplacée par celle de notre mandataire (la commande de tirage de l'image reste identique)
* configurer ''Docker'' pour utiliser notre mandataire
* configurer ''Docker'' pour utiliser notre mandataire
* ajouter ce même certificat dans la base interne du système client
* ajouter ce même certificat dans la base interne du système client
* mettre à jour la configuration de ''Systemd'' et relancer le démon ''Docker''
* rafraîchir la configuration de ''Systemd'' et relancer le démon ''Docker''


==Installation des paquets==
==Installation des paquets==
Ligne 64 : Ligne 66 :
  apt install --no-install-recommends docker.io tcpdump
  apt install --no-install-recommends docker.io tcpdump


Le premier servira d'application ''TLS'' cliente, le second, capturera le trafic chiffré. Celui-ci sera par la suite déchiffré par ''Wireshark'' à l'aide des clés enregistrées par ''Mitmproxy'' pendant la communication.
Le premier servira d'application ''TLS'' cliente et le second capturera le trafic chiffré. Celui-ci sera par la suite déchiffré par ''Wireshark'' à l'aide des clés enregistrées par ''Mitmproxy'' pendant la communication.


==Configuration de l'environnement==
==Configuration de l'environnement==
Ligne 99 : Ligne 101 :


===Deuxième console===
===Deuxième console===
Exécuté l'enregistreur de trames
Exécuter l'enregistreur de trames
  tcpdump -ni any -w /tmp/tls.pcap port not 22
  tcpdump -ni any -w /tmp/tls.pcap port not 22


Ligne 106 : Ligne 108 :
  docker pull alpine
  docker pull alpine


Si tout est bon, votre image a été récupérée par <code>docker</code>, <code>tcpdump</code> a enregistré l'échange chiffré et <code>mitmproxy</code> a journalisé les sessions en plus d'avoir enregistré les clés de sessions ''TLS''. Il ne reste plus qu'à quitter les programmes des deux premières consoles pour en envoyer les fichiers de capture et de clés à une machine graphique possédant <code>wireshark</code> pour déchiffrement et analyse.
Si tout est bon, votre image a été récupérée par <code>docker</code>, <code>tcpdump</code> a enregistré l'échange chiffré et <code>mitmproxy</code> a journalisé les sessions en plus d'avoir enregistré les clés ''TLS'' de celles-ci. Il ne reste plus qu'à quitter les programmes des deux premières consoles pour en envoyer les fichiers de capture et de clés à une machine graphique possédant <code>wireshark</code> pour déchiffrement et analyse.
  scp /tmp/tls.pcap /tmp/clés_tls_mitm.txt ycharbi@\[2001:db8::1\]:/tmp/
  scp /tmp/tls.pcap /tmp/clés_tls_mitm.txt ycharbi@\[2001:db8::1\]:/tmp/


Ligne 113 : Ligne 115 :


Les paquets ''TLS'' se déchiffrent instantanément, laissant apparaître les paquets ''HTTP'' qu'ils masquaient. Vous pouvez ainsi observer les ''URL'' que le client ''Docker'' requêtes pour récupérer ses images.
Les paquets ''TLS'' se déchiffrent instantanément, laissant apparaître les paquets ''HTTP'' qu'ils masquaient. Vous pouvez ainsi observer les ''URL'' que le client ''Docker'' requêtes pour récupérer ses images.
=Sources=
* https://docs.mitmproxy.org/stable/
** https://docs.mitmproxy.org/stable/howto-wireshark-tls/
** https://docs.mitmproxy.org/stable/concepts-options/
* https://medium.com/@ifeanyiigili/how-to-setup-a-private-docker-registry-with-a-self-sign-certificate-43a7407a1613
* https://betterprogramming.pub/deploy-a-docker-registry-using-tls-and-htpasswd-56dd57a1215a

Dernière version du 15 août 2024 à 16:42


Mitmproxy est un mandataire (proxy) destiné au débogage, tests, notamment de pénétrations ainsi qu'aux évaluations des mesures de protections d'un système d'information. Il est extrêmement utile pour comprendre le fonctionnement d'un programme officiant au travers de sessions HTTPS puisqu'il permet de réunir les éléments nécessaires à l'inspection des trames chiffrées par TLS.

Il peut, en outre, servir à espionner la navigation HTTPS des utilisateurs d'un réseau à accès limité (obligeant l'accès au WAN par l'intermédiaire d'un mandataire). À l'issue de la lecture de ce document, vous devriez être sensibilisé à ne jamais réaliser d'opérations personnelles sur ce genre de réseau (connexion à un Webmail ou à tout portail nécessitant un identifiant personnel par exemple).

Cette documentation explique brièvement comment se servir de l'outil pour enregistrer les clés de sessions TLS et présente un cas pratique avec le déchiffrement d'un docker pull. Les trames capturées via Tcpdump pourront alors être examinées par un outil graphique comme Wireshark.

Mise en œuvre

Installation

Installation de l'outil

apt install --no-install-recommends mitmproxy

Le fait de lancer mitmproxy créé automatiquement le répertoire ~/.mitmproxy contenant les éléments secrets utilisés dans une transaction TLS. Il est alors possible d'importer le certificat serveur dans la base local du client à espionner ou générer son propre certificat via OpenSSL.

Afin d'agrémenter la démonstration, la seconde solution sera utilisée. Outre l'aspect didactique, générer votre propre certificat est indispensable lorsque l'interception concerne la communication d'une application exigeante en terme de vérification (ce pourquoi Docker est utilisé en guise d'exemple). Il est en effet nécessaire dans ce cas d'ajouter des noms alternatifs dans la section subjectAltName du certificat X.509 afin de spécifier les adresses signées par celui-ci.

Configuration des clés

Création du répertoire d'accueil des éléments secrets

mkdir -p ~/.mitmproxy/certs

Génération desdits éléments

# Génération de la clé privée de l'autorité de certification (AC)
openssl genrsa -out ~/.mitmproxy/certs/ca.key 2048
# Génération du couple de clés du serveur mandataire
openssl req -new -x509 -days 365 -key ~/.mitmproxy/certs/ca.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=Acme Root CA" -out ~/.mitmproxy/certs/ca.crt
# Création d'un fichier de demande de certificat auprès de l'AC
openssl req -newkey rsa:2048 -nodes -keyout ~/.mitmproxy/certs/serveur.key -subj "/C=CN/ST=GD/L=SZ/O=Acme, Inc./CN=*" -out ~/.mitmproxy/certs/serveur.csr
# Génération d'un certificat signé par l'AC et intégrant la liste des domaines à certifier
openssl x509 -req -extfile <(printf "subjectAltName=DNS:*.ycharbi.fr,DNS:*.docker.io,DNS:*.cloudflare.docker.com,IP:127.0.0.1") -days 365 -in ~/.mitmproxy/certs/serveur.csr -CA ~/.mitmproxy/certs/ca.crt -CAkey ~/.mitmproxy/certs/ca.key -CAcreateserial -out ~/.mitmproxy/certs/serveur.crt

# Chaînage du certificat avec la clé associée pour mitmproxy
cat ~/.mitmproxy/certs/serveur.crt ~/.mitmproxy/certs/serveur.key > ~/.mitmproxy/certs/cert.pem

Le point d'intérêt principal de ces opérations et qui devra être personnalisé en fonction du cas à traiter est la sous-commande printf "subjectAltName=DNS:*.ycharbi.fr,DNS:*.docker.io,DNS:*.cloudflare.docker.com,IP:127.0.0.1" présente à la ligne numéro 8. Utilisez les domaines que vous voulez voir validé par TLS lors de la poignée de main entre une application cliente et votre mandataire.

Tests de fonctionnement

Afin de tester notre préparation, nous pouvons lancer mitmproxy de la façon suivante :

SSLKEYLOGFILE="/tmp/clés_tls_mitm.txt" mitmproxy --certs *=~/.mitmproxy/certs/cert.pem

où :

  • SSLKEYLOGFILE=  : emplacement du fichier contenant les clés négociées lors des différentes sessions TLS
  • --certs *=  : emplacement du certificat chaîné serveur pour signer le domaine spécifié dans la commande (ici * pour tout les domaines). Il peut y avoir plusieurs fois ce paramètre pour mettre autant de certificats que de domaines au besoin

Les clients HTTP communs peuvent êtres utilisés pour tester le fonctionnement de la solution

curl --proxy 127.0.0.1:8080 --cacert ~/.mitmproxy/certs/cert.pem https://doc.ycharbi.fr/index.php/Mitmproxy
wget -e https_proxy=127.0.0.1:8080 --ca-certificate ~/.mitmproxy/certs/cert.pem https://doc.ycharbi.fr/index.php/Mitmproxy

L'exploitation du fichier de clés est expliqué dans le cas pratique de la section suivante.

Cas pratique

Comme énoncé en introduction, nous allons utiliser notre outil pour analyser les requêtes effectuées par un docker pull. Cet outil étant particulièrement chiant avec HTTPS (comme la majorité des applications écrites en Golang), la mise en œuvre de notre capture représente un bon exercice.

Pour que cela fonctionne, il faut :

  • un certificat avec les bons domaines renseignés dans le champ subjectAltName (fait dans l'étape préparatoire)
  • ajouter ce certificat dans la configuration du registre d'image Docker dont l'adresse sera remplacée par celle de notre mandataire (la commande de tirage de l'image reste identique)
  • configurer Docker pour utiliser notre mandataire
  • ajouter ce même certificat dans la base interne du système client
  • rafraîchir la configuration de Systemd et relancer le démon Docker

Installation des paquets

Installation de Docker et de Tcpdump

apt install --no-install-recommends docker.io tcpdump

Le premier servira d'application TLS cliente et le second capturera le trafic chiffré. Celui-ci sera par la suite déchiffré par Wireshark à l'aide des clés enregistrées par Mitmproxy pendant la communication.

Configuration de l'environnement

Ajout du certificat du mandataire comme celui d'un registre d'images

mkdir -p /etc/docker/certs.d/127.0.0.1:8080
cp ~/.mitmproxy/certs/serveur.crt /etc/docker/certs.d/127.0.0.1:8080/ca.crt

Configuration du mandataire pour les requêtes au dépôt distant

mkdir -p /etc/systemd/system/docker.service.d
cat << '_EOF_' > /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTPS_PROXY=https://127.0.0.1:8080"
_EOF_

Ajout du certificat dans la base interne du système

cp ~/.mitmproxy/certs/serveur.crt /usr/local/share/ca-certificates/
update-ca-certificates

Rechargement de la configuration de Systemd et du démon Docker

systemctl daemon-reload
systemctl restart docker.service

ASTUCE

Il est possible d'afficher les variables d'environnements passées à l'exécutable de Docker par le service Systemd via la commande systemctl show --property=Environment docker afin de valider la bonne prise en compte de notre paramètre. Un docker search alpine vous indiquera rapidement si votre installation est correcte. En cas de fonctionnement, le mandataire affichera la session et la commande renverra son résultat habituel. En cas d'erreur, une indication sur l'origine du problème rencontré par le client sera renvoyée dans la console.

Tests de fonctionnement

Nous aurons besoin de trois consoles pour réaliser les opérations qui vont suivre. Un multiplexeur de terminal comme Tmux peut s'avérer bien utile dans de pareils circonstances. La commande tmux new -A -s toto peut être utilisée pour initier un tel environnement (totalement facultatif).

Première console

Exécuter le mandataire

SSLKEYLOGFILE="/tmp/clés_tls_mitm.txt" mitmproxy --certs *=~/.mitmproxy/certs/cert.pem

Deuxième console

Exécuter l'enregistreur de trames

tcpdump -ni any -w /tmp/tls.pcap port not 22

Troisième console

Tirer une image du registre distant

docker pull alpine

Si tout est bon, votre image a été récupérée par docker, tcpdump a enregistré l'échange chiffré et mitmproxy a journalisé les sessions en plus d'avoir enregistré les clés TLS de celles-ci. Il ne reste plus qu'à quitter les programmes des deux premières consoles pour en envoyer les fichiers de capture et de clés à une machine graphique possédant wireshark pour déchiffrement et analyse.

scp /tmp/tls.pcap /tmp/clés_tls_mitm.txt ycharbi@\[2001:db8::1\]:/tmp/

Sur la machine graphique

Ouvrir le fichier de capture /tmp/tls.pcap avec Wireshark et ajouter le fichier de clés /tmp/clés_tls_mitm.txt dans les paramètres du protocole TLS : <ctrl>+<maj>+<p> > Protocols > TLS > (Pre)-Master-Sercret log filename > Parcourir... > /tmp/clés_tls_mitm.txt > OK.

Les paquets TLS se déchiffrent instantanément, laissant apparaître les paquets HTTP qu'ils masquaient. Vous pouvez ainsi observer les URL que le client Docker requêtes pour récupérer ses images.

Sources