SAÉ 204 - Projet Intégratif
Retour aux SAE
By / Troncati Théo & Auduberteau Emilien
Contexte :
L’objectif de cette SAE était de découvrir la bibliothèque Python Scapy à travers plusieurs challenges. Chaque challenge portait sur un protocole réseau et comprenait un fichier de capture Wireshark (.pcap) ainsi qu’une description.
L’ensemble des travaux s’inscrivait dans un cadre progressif, centré sur l’analyse de différents protocoles réseau.
La réalisation des challenges nécessitait de mobiliser l’ensemble des notions réseau étudiées tout au long de l’année.
Déroulement :
Dans un premier temps, le but était de s'entrainer à utiliser les chaines de caractères Python ainsi que la différence avec les chaines binaires.

Dans un second temps, le but était de comprendre comment la bibliothèque Scapy fonctionnait, la structure, les fonctions, etc... Pour cela, nous avions plusieurs exercices à effectuer comme "sniffer" des paquets IPv4 et IPv6 et de récupérer les informations contenues dans le protocole ARP et Neighbor Discovery puis de les afficher dans la console.

Dans un troisième temps, le but était de pouvoir récupérer des informations sensibles dans les trames qui ont été capturées dans le fichier Wireshark et de les afficher pour l'utilisateur.

Dans un quatrième temps, le but était de récupérer des informations sensibles en direct, c'est à dire en "sniffant" le réseau. Bien sur, pour pouvoir récupérer des informations sensibles, il fallait que le protocole soit non-chiffré, sinon impossible de déchiffrer le message... Comme challenges, nous avions à récupérer les informations sensibles contenues dans les protocoles suivants : FTP, TELNET, HTTP.
Conclusion :
Cette SAE m'a permis de mieux comprendre comment fonctionnait la pile protocolaire TCP/IP et donc les différents protocoles. En effet, pour pouvoir détecter des connexions, il a fallu comprendre comment le protocole TCP ou UDP fonctionnait ainsi que les différents champs des en-têtes. Il m'a aussi fallu prendre des informations dans les en-têtes des protocoles de plus bas au plus haut niveau comme par exemple l'adresse MAC en passant par les ports puis par les champs de protocoles applicatifs. Finalement il m'a fallu comprendre l'algorithme derrière les protocoles applicatifs pour pouvoir intercepter des messages sensibles.

Pour conclure, cette SAE m'a permis de m'améliorer grandement sur les bases du réseau Internet ainsi que la programmation en Python. En effet j'ai pu apprendre à créer des outils d'automatisation et de détection sur le réseau.
Documents :
Fichiers à télécharger :
Exemples de code Scapy
Sniffer Telnet
                        
                            
    #___________    .__    _________      .__  _____  _____ 
    #\__    ___/___ |  |  /   _____/ ____ |__|/ ____\/ ____\
    #  |    |_/ __ \|  |  \_____  \ /    \|  \   __\\   __\ 
    #  |    |\  ___/|  |__/        \   |  \  ||  |   |  |   
    #  |____| \___  >____/_______  /___|  /__||__|   |__|   
    #             \/             \/     \/                  

    from scapy.all import *

    port = 2323
    src_ip = "0.0.0.0"
    dst_ip = "0.0.0.0"
    syn = False
    syn_ack = False
    ack = False
    handshake = False
    stop_sniffing = False
    handshake_detected = False
    telnet = False
    stop = False
    mot = ""
    word_list = []
    fin_client = False
    fin_server = False

    def sniff_function(trame):
        global port, src_ip, dst_ip, syn, syn_ack, ack, handshake, stop_sniffing, handshake_detected, telnet

        if trame.haslayer('TCP') and trame.haslayer('IP'):
            if trame.haslayer('TCP'):
                if trame['TCP'].dport == port and trame['TCP'].flags & 0x02:
                    syn = True
                    src_ip = trame['IP'].src
                    dst_ip = trame['IP'].dst
                if trame['TCP'].sport == port and trame['TCP'].flags & 0x12:
                    syn_ack = True
                if trame['TCP'].dport == port and trame['TCP'].flags & 0x10:
                    ack = True

        if trame.haslayer('TCP') and trame.haslayer(Raw):
            data = trame[Raw].load
            if len(data) >= 2 and data[0] == 0xFF and data[1] in [0xFB, 0xFC, 0xFD, 0xFE]:
                telnet = True

        if syn and syn_ack and ack and telnet and not handshake_detected:
            print("[✓] Connexion Telnet detectée !\n")
            handshake_detected = True
        
    def sniff_infos(trame):
        global stop, mot, port, word_list, fin_client, fin_server

        if trame.haslayer('TCP') and trame.haslayer('Raw'):
            if trame['TCP'].dport == port:
                        
                if b"\n" not in trame['Raw'].load:
                    mot += trame['Raw'].load.decode(errors="ignore")
                
                if b"\n" in trame['Raw'].load:
                    print("[+]", mot)
                    word_list.append(mot)
                    mot = ""

        #Détecter fin de connexion sur le port
        if trame.haslayer('TCP'):
            if trame['TCP'].dport == port and 'F' in trame['TCP'].flags:
                fin_client = True
            if trame['TCP'].sport == port and 'F' in trame['TCP'].flags:
                fin_server = True
            
        if fin_client and fin_server:
            stop = True
            print("\n[-] Connexion fermée")

    if __name__ == "__main__":
        print("\n🔍 Analyse en cours, veuillez patienter...")
        sniff(filter="", prn=sniff_function, store=0, iface="Loopback Pseudo-Interface 1", stop_filter=lambda x: handshake_detected)
        sniff(filter="", prn=sniff_infos, store=0, iface="Loopback Pseudo-Interface 1", stop_filter=lambda x: stop)
                        
Sniffer HTTP
                        
                            
    #  ___ ___________________________________  _________      .__  _____  _____ 
    # /   |   \__    ___/\__    ___/\______   \/   _____/ ____ |__|/ ____\/ ____\
    #/    ~    \|    |     |    |    |     ___/\_____  \ /    \|  \   __\\   __\ 
    #\    Y    /|    |     |    |    |    |    /        \   |  \  ||  |   |  |   
    # \___|_  / |____|     |____|    |____|   /_______  /___|  /__||__|   |__|   
    #       \/                                        \/     \/               
    #by Emilien

    from scapy.all import *
    import base64

    port = 80
    handshake_detected = False
    syn = False
    ack = False
    syn_ack = False
    http = False
    fin_client = False
    fin_server = False
    stop = False

    def sniff_function(trame):
        global port, syn, syn_ack, ack, handshake_detected, http, fin_client, fin_server, stop
        if trame.haslayer('TCP') and trame.haslayer('IP'):
                
                #Detecter ouverture de connexion
                if trame['TCP'].dport == port and trame['TCP'].flags & 0x02:
                    syn = True
                if trame['TCP'].sport == port and trame['TCP'].flags & 0x12:
                    syn_ack = True
                if trame['TCP'].dport == port and trame['TCP'].flags & 0x10:
                    ack = True
                
                #Detecter fin de connexion
                if trame['TCP'].dport == port and 'F' in trame['TCP'].flags:
                    fin_client = True
                if trame['TCP'].sport == port and 'F' in trame['TCP'].flags:
                    fin_server = True
                
        #Detected méthode HTTP
        if trame.haslayer('TCP') and trame.haslayer('Raw'):
            data = trame['Raw'].load
            if len(data) > 2 and data[0] == 0x47 and data[1] == 0x45 and data[2] == 0x54:
                http = True
                print("[✓] GET HTTP detecté !\n")
        
        if syn and syn_ack and ack and http:
            http = False
            find_info(trame)
        
        if fin_server and fin_client:
            stop = True
            print("\n[-] Connexion fermée")

    def find_info(trame):
        data = trame.load.decode(errors="ignore")
        data_table = data.split("\n")
        for i in range(len(data_table)):
            if "Authorization: Basic" in data_table[i]:
                login = data_table[i].split(" ")[2]
                decoded_bytes = base64.b64decode(login)
                decoded_str = decoded_bytes.decode("utf-8", errors="ignore")
                login_table = decoded_str.split(":")
                print(f"Nom utilisateur: {login_table[0]}\n")
                print(f"Le mot de passe: {login_table[1]}\n")

    if __name__ == "__main__":
        print("\n🔍 Analyse en cours, veuillez patienter...")
        sniff(filter="", prn=sniff_function, store=0, iface="Realtek 8822CE Wireless LAN 802.11ac PCI-E NIC", stop_filter=lambda x: stop)