Greboca  

Just Another GNU/Linux User’s Blog  -  MITM as a Service 3G Edition by Bouygues, ou quand ton FAI bousille DNSSEC

 -  Février 2017 - 

Introduction

Pour avoir le support de DANE/TLSA sous Firefox, j’utilise depuis certain temps un addon nommé DNSSEC/TLSA Validator, qui permet en plus de vérifier la validité des signatures DNSSEC (sur les sites qui le supportent) en un coup d’œil. Si la signature est valide, les icônes clé (DNSSEC) et cadenas (HTTPS) apparaissent en vert, si elle erronée, l’icône de la clé apparaît en rouge et cadenas rouge ou gris (HTTP :// à la place du cadenas, en gris. HTTPS, cadenas rouge), comme dans les exemples suivants. Et si le serveur web visité ne supporte pas du tout DNSSEC, les 2 icônes sont en gris.
Un test avec le site dnssec-failed.org, dont la signature DNS est volontairement erronée, pour permettre aux sysadmin de faire des tests en rapport avec DNSSEC, nous donne le résultat attendu.
TLSA Validator: DNSSEC fail
Jusqu’à là, tout va bien, sauf qu’un jour, en utilisant une connexion 3G de Bouygues Telecom, je me suis rendu compte que j’avais un comportement bizarre au niveau de DNSSEC, pour à peu près tous les noms de domaines, j’ai les deux icônes en rouge (signature erronée) un peu partout, aussi bien sur les sites avec une bonne signature de DNSSEC (debian.org, freebsd.org… ) que des sites ne supportant pas du tout DNSSEC. J’ai décidé de faire les tests plus détaillés.

Voici l’exemple avec debian.org sur une connexion 3G Bouygues :
DNSSEC MITM: Bogus signature
Voici l’exemple avec debian.org sur une connexion fixe, en utilisant le résolveur DNS de Lorraine Data Network (LDN) pour être de ne pas tomber sur un autre DNS foireux :
debian_ldn.png

J’ai découvert ça il y a plusieurs mois, mais c’est toujours valable, je viens de refaire des tests… De toute évidence, c’est pas normal, du coup, j’ai essayé d’en savoir plus.

Sortez le popcorn et mettez vous bien à l’aise…

Tout d’abord, on fait un dig pour demander l’enregistrement RRSIG, pour debian.org, puis pour dnssec-failed.org, d’abord avec la connexion 3G Bouygues, ensuite avec une connexion propre, dans les 2 cas en interrogeant le serveur DNS de LDN (parce que je sais qu’il supporte DNSSEC). Le résultat est intéressant…

– Connexion Bouygues 3G

Pour debian.org :

me@laptop:~$ dig @80.67.188.188 +dnssec +cdflag debian.org

; <<>> DiG <VERSION> <<>> @80.67.188.188 +dnssec +cdflag debian.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49096
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;debian.org. IN A

;; ANSWER SECTION:
debian.org. 26 IN A 5.153.231.4
debian.org. 26 IN A 128.31.0.62
debian.org. 26 IN A 130.89.148.14
debian.org. 26 IN A 140.211.15.34
debian.org. 26 IN A 149.20.20.22

;; Query time: 704 msec
;; SERVER: 80.67.188.188#53(80.67.188.188)
;; WHEN: Thu Sep 22 20:14:32 CEST 2016
;; MSG SIZE rcvd: 119

On utilise le +cdflag (Checking Disabled) pour dire au serveur DNS de donner le champs RRSIG sans vérifier la signature. Sans quoi, si la signature est erronée, on aura comme réponse status: SERVFAIL, et aucun champs DNS, même pas les IP. Or là, on pas du tout de champs RRSIG pour un nom de domaine qui a pourtant une signature valide…

Puis pour dnssec-failed.org :

me@laptop:~$ dig @80.67.188.188 +dnssec +cdflag www.dnssec-failed.org

; <<>> DiG <VERSION> <<>> @80.67.188.188 +dnssec +cdflag www.dnssec-failed.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6583
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.dnssec-failed.org. IN A

;; ANSWER SECTION:
www.dnssec-failed.org. 6747 IN A 68.87.109.242
www.dnssec-failed.org. 6747 IN A 69.252.193.191

;; Query time: 224 msec
;; SERVER: 80.67.188.188#53(80.67.188.188)
;; WHEN: Thu Sep 22 20:16:46 CEST 2016
;; MSG SIZE rcvd: 8

Exactement le même résultat… or on sait que ce nom de domaine a une signature DNSSEC (volontairement erronée, mais existante), on devrait avoir un champs RRSIG car on a mis l’option +cdflag.

D’ailleurs, si vous avez l’habitude d’utiliser dig, vous avez remarqué que vers la fin de la réponse, il y a l’IP du serveur qui répond, et que ici, on a bien l’IP du serveur interrogé… Et pourtant j’insiste, le résolveur DNS interrogé supporte DNSSEC.

On refait les mêmes tests, sans l’option +cdflag, sur une connexion fixe, car on veut justement vérifier la validité de la signature.

– Connexion fixe

Pour debian.org :

me@laptop:~$ dig @80.67.188.188 +dnssec debian.org

; <<>> DiG <VERSION> <<>> @80.67.188.188 +dnssec debian.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 22069
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;debian.org. IN A

;; ANSWER SECTION:
debian.org. 109 IN A 140.211.15.34
debian.org. 109 IN A 149.20.20.22
debian.org. 109 IN A 5.153.231.4
debian.org. 109 IN A 128.31.0.62
debian.org. 109 IN A 130.89.148.14
debian.org. 109 IN RRSIG A 8 2 300 20161031065252 20160921055252 7866 debian.org. ZERtXROfGeAS+NYTa3BaDk/Q41QkuiimerRJ9+6WMSIeKNUnfPOJR01+ Y1KzxZ9bxhVJMaeLKeYs7eQmmOFiv1tIVb5fgQRjMdMn+1QyZZEz84Ru 9K5Udohml9wboEsQNEv+ejTSVjyDoZHwdBbZjZ9ToOt4v9bGLgCAXMu/ FjkFXJDyk5wJs3g9VgnrAYx3oHoIQFVALtu8u+bktVvDsHv+8rXbjkBv e6GkB1vAvh5HQ0X/cQbQ0lekFI8FtXFT

;; Query time: 51 msec
;; SERVER: 80.67.188.188#53(80.67.188.188)
;; WHEN: Thu Sep 22 19:54:48 CEST 2016
;; MSG SIZE rcvd: 353

Et là, on a une signature DNSSEC…

Puis pour dnssec-failed.org :

me@laptop:~$ dig @80.67.188.188 +dnssec www.dnssec-failed.org

; <<>> DiG <VERSION> <<>> @80.67.188.188 +dnssec www.dnssec-failed.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 5061
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;www.dnssec-failed.org. IN A

;; Query time: 147 msec
;; SERVER: 80.67.188.188#53(80.67.188.188)
;; WHEN: Thu Sep 22 19:56:34 CEST 2016
;; MSG SIZE rcvd: 50

On a exactement le comportement attendu, à savoir le refus de résolution d’adresse avec le message d’erreur status: SERVFAIL. En refaisant ce dernier test avec l’option +cdflag, on aura les IP et le champs RRSIG (certes signature invalide mais visible quand même).

A ce stade, ça pue déjà pas mal le Man In The Middle, je soupçonne très fortement Bouygues d’utiliser des proxies, qui en plus de faire du MITM, modifient les adresses sources pour mentir, en mettant l’IP du serveur interrogé pour chaque requête, voire champs SERVER: 80.67.188.188#53 (80.67.188.188).

Mais non, tu vois la mal partout, il y a une autre explication !

J’en doute très fort, mais supposons qu’il y a une autre explication, et que je soit parano… Alors on refait des tests suivants sur la connexion Bouygues 3G, avec des IP prises au hasard.
Le test est simple, prendre une IP au hasard, supposer que c’est un résolveur DNS, et l’utiliser dans la commande dig, pour interroger le serveur correspondant… et ensuite faire un nmap sur cette IP pour voir ce que c’est comme serveur, et on peut même faire un whois, pour bien voir que ça n’appartient pas aux ranges Bouygues Telecom.

Tomber du premier coup sur un vrai résolveur DNS public, j’y crois pas trop mais j’ai quand même fait le test avec 5 ou 6 différentes en tout (les 3 tests, dig, nmap et whois pour chaque IP), avec toujours le même résultat que l’exemple suivant, Je met qu’un seul pour ne pas écrire un pavé. L’exemple en question concerne l’IP 138.2.4.6, prise vraiment au hasard, qui appartient au range d’Oracle. Les autres IP que j’ai testé appartiennent entre autre à Cogent, IANA et j’en passe… avec d’interroger le serveur avec dig sur la connexion Bouygues 3G, commençons par dissiper le doute, on le fait d’abord sur une connexion fixe, certes pas la plus neutre du monde, mais un peu plus propre que la 3G chez Bouygues.

dig @138.2.4.6 +dnssec debian.org

; <<>> DiG <VERSION> <<>> @138.2.4.6 +dnssec debian.org
 ; (1 server found)
 ;; global options: +cmd
 ;; connection timed out; no servers could be reached

Voilà, ça répond pas, car ce n’est pas un résolveur DNS public, voir pas un résolveur DNS du tout. Pourtant, le même test chez Bouygues donne… une réponse, très similaire au test réalisée plus haut, avec le résolveur de LDN.

me@linuxbox:~$ dig @138.2.4.6 +dnssec debian.org

; <<>> DiG <VERSION> <<>> @138.2.4.6 +dnssec debian.org
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 14422
;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;debian.org. IN A

;; ANSWER SECTION:
debian.org. 300 IN A 140.211.15.34
debian.org. 300 IN A 149.20.20.22
debian.org. 300 IN A 5.153.231.4
debian.org. 300 IN A 128.31.0.62
debian.org. 300 IN A 130.89.148.14

;; Query time: 229 msec
;; SERVER: 138.2.4.6#53(138.2.4.6)
;; WHEN: <DATE>
;; MSG SIZE rcvd: 119

Une réponse à une requête DNS en interrogeant un serveur qui ne fait pas de DNS, voir pas un serveur du tout (IP prise au hasard pour rappel), il y a qu’une explication, un proxy qui fait du Man-In-The-Middle, intercepte et traite tous les requêtes DNS, en mentant sur l’origine des paquets réponses (voire le champs ;; SERVER:)

J’y crois pas, pourquoi ils se seraient donner tout ce mal ?

Je vous épargne la sortie du whois, pour vérifier que ce range d’IP appartient bien à Oracle et non pas à Bouygues Telecom… c’est vérifiable depuis n’importe quelle connexion Internet. Par contre, la sortie de nmap, effectué sur le réseau 3G de Bouygues, est beaucoup plus intéressante… Avant d’aller plus loin, une précision, si vous essayer nmap -Pn 138.2.4.6 sur une connexion à peu près propre, sans proxy qui fait du MITM, vous aurez comme réponse All 1000 scanned ports on 138.2.4.6 are filtered, un serveur DNS (port 53) qui répond sur Internet, mais dont tous les 1000 1ers ports (1-1000) sont filtrés, c’est quand même curieux…

Sur une conenxion 3G Bouygues, ça donne ça…

me@linuxbox:~$ sudo nmap -A 138.2.4.6

Starting Nmap <VERSION> ( http://nmap.org ) at <DATE>
Nmap scan report for 138.2.4.6
Host is up (0.13s latency).
Not shown: 993 filtered ports
PORT STATE SERVICE VERSION
21/tcp open ftp?
|_ftp-bounce: no banner
25/tcp open smtp Postfix smtpd
|_smtp-commands: Couldn't establish connection on port 25
53/tcp open domain ISC BIND hostmaster
80/tcp open http?
554/tcp open rtsp?
1723/tcp open pptp?
|_pptp-version: ERROR: Script execution failed (use -d to debug)
8080/tcp open http-proxy?
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Network Distance: 4 hops
Service Info: Host: smtp-proxy-1b.bouyguesbox.fr

TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
1 2.36 ms 10.42.0.1
2 75.44 ms 10.125.12.239
3 81.89 ms 10.125.14.234
4 94.37 ms 138.2.4.6

OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 358.62 seconds

Tour d’un coup, il y a plein de services qui tournent… Mais surtout, il y a un bon gros champs Service Info qui ne laisse aucun pas de doute sur le fait qu’on a bien à faire à proxy (pas si) transparent (que ça), appartenant à Bouygues Telecom

Service Info: Host: smtp-proxy-1b.bouyguesbox.fr

Et sur lequel il y a bien un serveur DNS prêt à intercepter vos requêtes, et à mentir sur les réponses, en cassant DNSSEC au passage…

53/tcp open domain ISC BIND hostmaster

Mais encore ?

On sait qu’il y a un DNS menteur, qui ne semble pas supporter DNSSEC (Le champs RRSIG dans les requêtes dig qui finit toujours chez Dave Null), mais on sait toujours pas pourquoi on reçoit des signatures erronés d’après DNSSEC/TLSA Validator… là pour le coup, j’ai pas une explication aussi complète, mais un début d’explication quand même…
Lors des requêtes DNS, soit avec dig +dnssec soit DNSSEC/TLSA Validator (j’ai pas determiné le moment exact), je reçois des paquets DNSKEY, contenant une clé publique, et issus avec comme IP source, plusieurs IP délirantes, appartenant à des ranges/entités différentes…
Wireshark: DNSKEY
Ici (agrandir la capture d’écran en cliquant dessus), c’est l’adresse IP l’université du Maryland, dont je n’ai jamais configuré un éventuel résolveur DNS public sur ma machine… Il y a également une IP du range de la Keio University. Je sais pas exactement ce que Bouygues Telecom fout, ni pourquoi j’ai clés DNSSEC qui semblent fausses, issue de serveurs que mon système n’a jamais interrogé, Mais encore une fois, ça sent l’injection de paquets avec l’adresse source forgée. En tout cas si quelqu’un à plus d’infos à ce sujet, ça m’intéresse…

Conclusion

Ça pue très fort, parce qu’on peut pas utilser le DNS qu’on veut. Quelque soit celui configuré sur el système, le proxy de Bouygues intercepte les requêtes DNS et y répond à la place du résolveur qu’on voulait interroger. Et je pense pas que Bouygues soit le seul à faire ce genre de magouilles. Si vous avez l’occasion de faire des tests sur des connexions agrumes télécom, SFR, ou encore Free, les retours m’intéressent. La seule solution que je vois, c’est de passer par un tunnel OpenVPN [1], dont le point de sortie doit se situer sur le même LAN, voire sur la même machine (de confiance) que le résolveur DNS qu’on utilise… il reste le problème de la requête première requête DNS pour établir la connexion VPN. Soit il faudra se connecter au VPN en spécifiant directement l’IP publique du serveur VPN, soit il faudra utiliser /etc/hosts (accès root évidemment nécessaire).

[1] Si c’est pas filtré, j’ai pas encore eu l’occasion de tester. Mais si jamais c’est filtré, on peut tenter de passer le flux VPN dans le port TCP 443, mais c’est sans garantie, et ça risque de créer de l’overhead au niveau de la bande passante/quantité de data utilisée (Il reste à vérifier si ce surplus reste dans la limite du raisonnable).

par /dev/null

Just Another GNU/Linux User’s Blog

« Computers are like ACs, they stop working properly when you open windows »

Gestion de paquets avec APT : Récupérer une clé manquante sur un réseau filtré

 -  Septembre 2016 - 

Introduction Par défaut, APT (Advanced Packaging Tool) essaye de vérifier la signature des paquets en utilisant des clés GPG, la plupart du temps (...)


[Coup de gueule] Réponse au bullshit sur l’interdiction du chiffrement

 -  Août 2016 - 

Contexte Comme vous le savez sûrement, notre grand démocrate ministre de la police de la pensée, B. Cazeneuve, n’aime pas trop le chiffrement, il (...)


[Coup de gueule] De la connardise industrielle, ou l’art de vomir sur les bonnes pratiques

 -  Janvier 2016 - 

Introduction Depuis quelques années, on assiste massivement à des soit-disant innovations technologiques, présentées majoritairement à coup de (...)


[Test] Prototype du nouveau clavier français du Ministère de l’inculture

 -  Janvier 2016 - 

Introduction ***************************WARNING*************************** * Too much sarcasm inside * ***************************WARNING************