darcosion / Echosounder

petit programme marrant
MIT License
14 stars 1 forks source link

Implémenter la fonctionnalité de scan traceroute pour la découverte de réseau multiples #45

Closed darcosion closed 2 years ago

darcosion commented 2 years ago

Cette issue devrait (de bon alloi) être résolue après #43 Actuellement, on scan uniquement le réseau local sur lequel on se situe.

Or on pourrais récupérer la liste des réseaux locaux pour avoir plus de visibilité. De plus du fuzzing d'IP local en traceroute permettrait la découverte de réseaux locaux cachés (dont les routes ne sont pas transmises par les routeurs locaux).

Voici une liste d'élément à implémenter :

darcosion commented 2 years ago

Ok, juste pour notation, depuis python 3.3, il y a un module ipaddress qui permet de distinguer les IP publiques de privé dans notre contexte, qui risque d'être très pratique.

voir particulièrement : https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Address.is_private

darcosion commented 2 years ago

Il est également possible de vérifier si une IP fait partie d'un subnet ! https://docs.python.org/3/library/ipaddress.html#ipaddress.IPv4Network.subnet_of

darcosion commented 2 years ago

Cette fonctionnalité est horrible car l'interprétation des noeuds dans un traceroute est une problématique absolument pas triviale.

La création d'un simple traceroute capable de faire ressortir les IP privées m'a pris 2h : ed4190721cdd8ecf030acd2aebfa071f56a4f277

Un traceroute, suivant sur quoi il pointe, ne sera en plus, pas traité de la même façon par l'opérateur (un traceroute sur les DNS google donne directement en premier noeud une IP publique alors que un traceroute vers une IP du load balancer google renvoie deux IP privées, puis les IP publiques...).

Il reste l'intégration dans les subnet appropriés des IP concernés. Actuellement, elles ne sont pas automatiquement intégrés dans les VLAN appropriés.

darcosion commented 2 years ago

L'intégration dans subnet a été effectué, énormément de chose à dire de ce coté : c4ae4343698db94b0c3ffcf1186d13de55b7dc3a

Une fonction de récupération d'ID de noeud par son IP a été ajouté pour faciliter certains traitements du graphe : https://github.com/darcosion/Echosounder/blob/c4ae4343698db94b0c3ffcf1186d13de55b7dc3a/static/main.js#L573-L575

Une fonction de récupération de VLAN associé à une IP a été ajouté pour permettre une meilleur intégration des VLAN possibles : https://github.com/darcosion/Echosounder/blob/c4ae4343698db94b0c3ffcf1186d13de55b7dc3a/static/main.js#L577-L592

La fonction de traceroute est très intéressante car elle permet de lier entre eux des IP privés et donc de deviner le routage.

darcosion commented 2 years ago

Ok, je vois peut-être comment faire pour détecter des réseaux à partir de routage !

On pourrais lancer en front un scan traceroute itératif avec un grand nombre d'IP publiques et un TTL très réduit.

Les IP publiques à tester mèneraient vers un grand nombre d'opérateurs différents avec des routes complexes dans le but d'observer les règles de routage du réseau concerné. En plus de ça, on pourrais rajouter du "traceroute fuzzing" pour permettre de trouver des routes et des CIDR de cette façon !

darcosion commented 2 years ago

Ok, j'ai testé un outil pour ça : https://github.com/CAIDA/pyipmeta (dépendance à installer en dur : https://github.com/CAIDA/libipmeta )

Si on DL ici les données de caida, on peut l'utiliser : https://publicdata.caida.org/datasets/routing/

Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyipmeta
>>> ipm = pyipmeta.IpMeta(providers=['pfx2as -f routeviews-rv2-20220315-1200.pfx2as.gz'])
[14:30:46:400] ipmeta_init: initializing libipmeta
[14:30:46:400] ipmeta_init: using datastore patricia
[14:30:46:400] ipmeta_enable_provider: enabling provider (pfx2as)
>>> ipm.lookup('192.172.226.0')
[{'source': 3, 'id': 60435, 'country_code': '', 'continent_code': '', 'region': '', 'city': '', 'post_code': '', 'lat_long': (0.0, 0.0), 'metro_code': 0, 'area_code': 0, 'region_code': 0, 'connection_speed': '', 'asns': [1909], 'asn_ip_count': 256, 'polygon_ids': [], 'matched_ip_count': 1}]
>>> ipm.lookup('192.172.226.0/24')
[{'source': 3, 'id': 60435, 'country_code': '', 'continent_code': '', 'region': '', 'city': '', 'post_code': '', 'lat_long': (0.0, 0.0), 'metro_code': 0, 'area_code': 0, 'region_code': 0, 'connection_speed': '', 'asns': [1909], 'asn_ip_count': 256, 'polygon_ids': [], 'matched_ip_count': 256}]

Petit soucis, cet outil est une dépendance en plus bien vener, qui plus est...

Il faudrait qu'on soit d'accord sur le fait de l'installer ou non, et surtout sur ce qu'implique cette dépendance.

darcosion commented 2 years ago

L'issue 340901351009d7b0123278205605ff8aefe73a16 résous cela en remplaçant la dépendance par un service spécifique.

La problématique IP -> AS est sortie de ce contexte pour être géré par l'issue #52

darcosion commented 2 years ago

L'identification d'AS a été implémenté en front : 7251236142ddfa8c190411bd75685fa9d8975333

Actuellement, nous obtenons des résultats pour un scan IP publique d'AS en traceroute. Cela reste intéressant bien que complexe.

darcosion commented 2 years ago

La représentation front a été réalisé et le back a été recodé énormément.

Il y a pleins de problématiques qui ont été codés, je les détaillerais une fois la douleur passé : b1f20430a76c13f0a1ca017edbd86bdf65a9dfc5 72363d5f4ceb43a579a091be223860ecfc5938d1

darcosion commented 2 years ago

Coté backend une route API traceroute CIDR a été implémenté : 5fb6e3f74363396f5a5f68122f01103a0ff72ed6

Elle utilise une astuce lié à ipadresse et aux slicer en python :

>>> a = ipaddress.IPv4Network('192.168.1.0/28')
>>> slicer = len(list(a.hosts())) // 4
>>> for i in list(a.hosts())[::slicer]:
...     print(i)
... 
192.168.1.1
192.168.1.4
192.168.1.7
192.168.1.10
192.168.1.13

de cette façon, quelque soit la taille du CIDR, seules 7 IP maximum seront scannés.

darcosion commented 2 years ago

Le scan CIDR a été codé en front a68d30bb1d6420f963f259b8e17704b308df3c51, j'ai du faire une petite fonction de dépaquetage ici mais sinon tout est bon et simple : https://github.com/darcosion/Echosounder/blob/a68d30bb1d6420f963f259b8e17704b308df3c51/static/main.js#L738-L742