IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau/Web Python Discussion :

Sniffer un packet et la décortiquer (ethernet, IP, protocol, etc)


Sujet :

Réseau/Web Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut Sniffer un packet et la décortiquer (ethernet, IP, protocol, etc)
    Je travail sur ce projet depuis plusieurs semaine, j'ai fais énormément de recherche sur Google, dans les forums, mais chaque solution que je trouve fonctionne sur Linus ou si c'est pour Windows, on trouve scapy ou autre du même genre que ne fonctionne pas sur Python 3.2. j'ai trouvé aussi beaucoup de code qui me pemet de lire le header IP mais pas celui ethernet.

    Finalement il y a une semaine, j'ai trouvé un code qui fait ce qu'il faut, mais il est en C et je ne pragramme pas en C. J'ai donc passé des heures à faire l'apprentissage du language C pour pouvoir faire la conversion en Python 3.2. J'ai réussi à faire presque tout, mais je vois que j'ai une erreur en quelque part sans savoir où exactement car le résultat de mes donnée est erroné ou illogique.

    J'ai beau regardé dans winpcapy.py et aussi la librairie sur laquel elle est basé, soit le DLL "wpcap.dll" mais je n'arrive pas à comprendre où est mon erreur.

    Est-ce que quelqu'un est capable de m'aider ?

    Je vous donne le lien du code en C que j'ai trouvé et sur lequel je me suis basé pour faire mon code en Python, et je vous colle mon code en Python que j'ai fais jusqu'à maintenent.

    Merci de votre aide.

    Le lien du code en C sur lequel je me suis basé est : http://www.binarytides.com/code-pack...fer-c-winpcap/

    et voici mon code en python


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    #!/usr/bin/env python 3.2
    #-------------------------------------------------------------------------------
     
     
    from ctypes import *
    from winpcapy import *
    import sys
    import string
    import platform
    import socket
    import time
     
     
    if platform.python_version()[0] == "3":
    	raw_input=input
    LINE_LEN=16
    alldevs=POINTER(pcap_if_t)()
    d=POINTER(pcap_if_t)
    fp=pcap_t
    errbuf= create_string_buffer(PCAP_ERRBUF_SIZE)
    header=POINTER(pcap_pkthdr)()
    pkt_data=POINTER(c_ubyte)()
     
    ## struct ethernet_header
    class ETHER_HDR(Structure):
        _fields_ = [('dest',6 * c_ubyte),
                    ('source',6 * c_ubyte),
                    ('type',c_ushort)]
     
    ## struct Ip header (v4)
    class IPV4_HDR(Structure):
        _fields_ = [('ip_header_len',4 * c_ubyte),
                    ('ip_version',4 * c_ubyte),
                    ('ip_tos',c_ubyte),
                    ('ip_total_length',c_ushort),
                    ('ip_id',c_ushort),
                    ('ip_frag_offset',5 * c_ubyte),
                    ('ip_more_fragment',1 * c_ubyte),
                    ('ip_dont_fragment',1 * c_ubyte),
                    ('ip_reserved_zero',1 * c_ubyte),
                    ('ip_frag_offset1',c_ubyte),
                    ('ip_ttl',c_ubyte),
                    ('ip_protocol',c_ubyte),
                    ('ip_checksum',c_ushort),
                    ('ip_srcaddr',c_int),
                    ('ip_destaddr',c_int)]
     
    def processPacket(pkt_data, headerCaplen):
        print("\nprocessPacket")
        ## Ethernet header
        ethhdr = POINTER(ETHER_HDR)(pkt_data) ## cette ligne ne fonctionne peut-être
        print(ethhdr.contents.dest[0:6])
        print(ethhdr.contents.source[0:6])
        print(ethhdr.contents.type)
        print("mac dest : %.2x-%.2x-%.2x-%.2x-%.2x-%.2x" % (ethhdr.contents.dest[0],ethhdr.contents.dest[1],ethhdr.contents.dest[2],ethhdr.contents.dest[3],ethhdr.contents.dest[4],ethhdr.contents.dest[5]))
        print("mac source : %.2x-%.2x-%.2x-%.2x-%.2x-%.2x" % (ethhdr.contents.source[0],ethhdr.contents.source[1],ethhdr.contents.source[2],ethhdr.contents.source[3],ethhdr.contents.source[4],ethhdr.contents.source[5]))
     
        ## Ip packets
        if (socket.ntohs(ethhdr.contents.type) == 0):
            ## ip header
            iphdr = POINTER(IPV4_HDR)(pkt_data)
            print(iphdr.contents.ip_protocol)
            print(iphdr.contents.ip_srcaddr)
     
     
    def showNetCard():
            if (pcap_findalldevs(byref(alldevs), errbuf) == -1):
                    print ("Error in pcap_findalldevs: %s\n", errbuf.value)
                    sys.exit(1)
            ## Print the list
            i=0
            d=alldevs.contents
            while d:
                    i=i+1
                    print ("%d. %s" % (i, d.name))
                    if (d.description):
                        print (" (%s)\n" % (d.description))
                    else:
                        print (" (No description available)\n")
                    if d.next:
                         d=d.next.contents
                    else:
                         d=False
            if (i==0):
                    print ("\nNo interfaces found! Make sure WinPcap is installed.\n")
                    sys.exit(-1)
            print ("Enter the interface number (1-%d):" % (i))
            inum= raw_input('--> ')
            if inum in string.digits:
                    inum=int(inum)
            else:
                    inum=0
            if ((inum < 1) | (inum > i)):
                    print ("\nInterface number out of range.\n")
                    ## Free the device list
                    pcap_freealldevs(alldevs)
                    sys.exit(-1)
            return alldevs,inum
     
     
    def openDevice(alldevs,inum):
            d=alldevs
            for i in range(0,inum-1):
                    d=d.contents.next
            fp = pcap_open_live(d.contents.name,65536,1,1000,errbuf) ## ici on a une différence avec le sniffer.h, on a live de plus
            if (fp == None):
                    print ("\nError opening adapter\n")
                    ## Free the device list
                    pcap_freealldevs(alldevs)
                    sys.exit(-1)
            return fp
     
    def readPackets(fp):
            res = pcap_next_ex( fp, byref(header), byref(pkt_data))  ## ic on a une différence avec les byref de plus
     
     
            #print("valeur du res est: ",res)
     
     
            while(res >= 0):
                if(res == 0):
                    ## Timeout elapsed
                    break
                ## print pkt timestamp and pkt len
                seconds = header.contents.ts.tv_sec
                localtime_s = time.localtime(seconds)
                print("\nNext Packet : %d-%d-%d at %d:%d:%d (Packet Lenght : %d bytes)" % (localtime_s.tm_mday, localtime_s.tm_mon, localtime_s.tm_year, localtime_s.tm_hour, localtime_s.tm_min, localtime_s.tm_sec, header.contents.len))
                ##  Print the packet
            #    print(header.contents.caplen)
            #    print(type(pkt_data))
            #    print(sizeof(pkt_data))
            #    print(pkt_data[0:1024])
                processPacket(pkt_data, header.contents.caplen) ## j'ajoute ceci pour faire comme dans sniffer.h
     
            #    for i in range(1,header.contents.len + 1):
            #        print ("%.2x " % pkt_data[i-1])
            #        if (i % LINE_LEN) == 0:
            #            print ("\n")
                print ("\n\n")
                break
    #            res = pcap_next_ex( fp, byref(header), byref(pkt_data))
     
            if(res == -1):
                print ("Error reading the packets: %s\n" % pcap_geterr(fp))
                sys.exit(-1)
     
            pcap_close(fp)
     
    def main():
            ## show network card
            alldevs,inum = showNetCard()
     
            ## open the device
            fp = openDevice(alldevs,inum)
     
            ## Read the packets
            readPackets(fp)
     
     
            sys.exit(0)
     
     
    if __name__ == '__main__':
        main()

  2. #2
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mars 2013
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2013
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    J'ai finalement réussi à faire fonctionner mon code pour sniffer le packet ethernet et aussi le packet IP. Donc je trouve les MAC et aussi les IP, protocole et je pourrais continuer avec les header du protocole. Je n'avais pas besoin de ça et mon code est assez descriptif pour qu'une personne l'ajoute au besoin.

    Je partage donc la solution, mais je pose en même temps quelque questions.

    Une partie du code qui n'est pas de mon cru est incompréhensible pour moi.

    La ligne : PHAND=CFUNCTYPE(None,POINTER(c_ubyte),POINTER(pcap_pkthdr),POINTER(c_ubyte))
    combiner a la ligne : packet_handler=PHAND(_packet_handler)

    j'ai de la difficulté à bien les comprendre. même si une partie du code n'est pas de mon cru, je veux toujours comprendre pour pouvoir modifier et améliorer ou créer par la suite mes propre code moi-même.

    De plus, au final, ce petit projet est un début pour faire un logiciel Hotspot. J'ai déjà ouvert un autre billet à ce sujet. Je vais donc faire le lien entre les deux.
    Voici donc le lien sur le projet global: http://www.developpez.net/forums/d14...iciel-hotspot/

    Finalement, je suis coincé sur un nouveau problème, une fois que j'ai accès à la MAC adresse et que je peux donc la comparer à une liste de MAC permise. Si elle est permise, je veux pouvoir laisser passé le packet (mon logiciel hotspot sera installer sur un Gateway, ICS de Windows) donc par défaut tout les packets même sniffer vont poursuivre leur chemin. Mais si la MAC détecté n'est pas dans ma liste authorisé, je veux block l'accès à Internet pour ce PC. C'est là que j'ai un problème. Je veux le blocker et par la suite rediriger le PC client vers une page WEB d'authentification.

    Quelqu'un peut m'aider pour me donner un fil conducteur vers cette problématique. Toujours avoir en tête que je travail avec Python 3.2 sous Windows.

    Voici finalement mon code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    from ctypes import *
    from winpcapy import *
    import time
    import sys
    import string
    import platform
    import socket
    import struct
    import re
     
    if platform.python_version()[0] == "3":
            raw_input=input
     
     
    #/* prototype of the packet handler */
    #void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
    PHAND=CFUNCTYPE(None,POINTER(c_ubyte),POINTER(pcap_pkthdr),POINTER(c_ubyte))
     
    # Obtenir le TOS
    def getTOS(data):
        precedence = {0: "Routine", 1: "Priority", 2: "Immediate", 3: "Flash", 4: "Flash override", 5: "CRITIC/ECP",
                      6: "Internetwork control", 7: "Network control"}
        delay = {0: "Normal delay", 1: "Low delay"}
        throughput = {0: "Normal throughput", 1: "High throughput"}
        reliability = {0: "Normal reliability", 1: "High reliability"}
        cost = {0: "Normal monetary cost", 1: "Minimize monetary cost"}
     
    #   prend le 3ieme bit et va vers la droite
        D = data & 0x10
        D >>= 4
    #   prend le 4ieme bit et va vers la droite
        T = data & 0x8
        T >>= 3
    #   prend le 5ieme bit et va vers la droite
        R = data & 0x4
        R >>= 2
    #   prend le 6ieme bit et va vers la droite
        M = data & 0x2
        M >>= 1
    #   le 7ieme bit est vide et n'a pas besoin d'être analysé
     
        tabs = '\n\t\t\t'
        TOS = precedence[data >> 5] + tabs + delay[D] + tabs + throughput[T] + tabs + \
                reliability[R] + tabs + cost[M]
        return TOS
     
     
    # Capture le Flags
    def getFlags(data):
        flagR = {0: "0 - Reserved bit"}
        flagDF = {0: "0 - Fragment if necessary", 1: "1 - Do not fragment"}
        flagMF = {0: "0 - Last fragment", 1: "1 - More fragments"}
     
    #   prend le 1ier bit et va vers la droite
        R = data & 0x8000
        R >>= 15
    #   prend le 2ier bit et va vers la droite
        DF = data & 0x4000
        DF >>= 14
    #   prend le 3ier bit et va vers la droite
        MF = data & 0x2000
        MF >>= 13
     
        tabs = '\n\t\t\t'
        flags = flagR[R] + tabs + flagDF[DF] + tabs + flagMF[MF]
        return flags
     
     
    # Capture le protocol
    def getProtocol(protocolNr):
        protocolFile = open('Protocol.txt', 'r')
        protocolData = protocolFile.read()
        protocol = re.findall(r'\n' + str(protocolNr) + '.+\n', protocolData)
        if protocol:
            protocol = protocol[0]
            protocol = protocol.replace("\n", "")
            protocol = protocol.replace((str(protocolNr)+'.'), "")
            protocol = protocol.lstrip()
            return protocol
     
        else:
            return 'No such protocol.'
     
     
    ## Fonction qui effecture le travail sur le packet capturé par winpcapy
    def _packet_handler(param,header,pkt_data):
            ## convertie le timestamp pour être lisible et l'afficher
            local_tv_sec = header.contents.ts.tv_sec
            ltime=time.localtime(local_tv_sec);
            timestr=time.strftime("%H:%M:%S", ltime)
            print("%s,%.6d len:%d et caplen:%d" % (timestr, header.contents.ts.tv_usec, header.contents.len, header.contents.caplen))
     
            ## Ici nous avons les infos du header ethernet (mac addresse)
            print("\nVoici le header Ethernet")
            print("mac dest : %.2x-%.2x-%.2x-%.2x-%.2x-%.2x" % (pkt_data[0],pkt_data[1],pkt_data[2],pkt_data[3],pkt_data[4],pkt_data[5]))
            print("mac source : %.2x-%.2x-%.2x-%.2x-%.2x-%.2x" % (pkt_data[6],pkt_data[7],pkt_data[8],pkt_data[9],pkt_data[10],pkt_data[11]))
            print("Type : 0x%.2x%.2x" % (pkt_data[12],pkt_data[13]))
     
            ## Ici nous faisons un Unpack du niveau après le header ethernet soit
            ## le header IP
            unpackedData = struct.unpack('!BBHHHBBH4s4s',bytes(pkt_data[14:34]))
     
            version_IHL = unpackedData[0]
            version = version_IHL >> 4                  # version de IP
            IHL = version_IHL & 0xF                     # longeur du internet header
            TOS = unpackedData[1]                       # type of service
            totalLength = unpackedData[2]
            ID = unpackedData[3]                        # identification
            flags = unpackedData[4]
            fragmentOffset = unpackedData[4] & 0x1FFF
            TTL = unpackedData[5]                       # time to live
            protocolNr = unpackedData[6]
            checksum = unpackedData[7]
            sourceAddress = socket.inet_ntoa(unpackedData[8])
            destinationAddress = socket.inet_ntoa(unpackedData[9])
     
            print("\nVoici le header IP de size %s,%s" % (pkt_data[16],pkt_data[17]))
            print ("An IP packet with the size %i was captured." % (unpackedData[2]))
            print ("\nParsed data")
            print ("Version:\t\t" + str(version))
            print ("Header Length:\t\t" + str(IHL*4) + " bytes")
            print ("Type of Service:\t" + getTOS(TOS))
            print ("Length:\t\t\t" + str(totalLength))
            print ("ID:\t\t\t" + str(hex(ID)) + " (" + str(ID) + ")")
            print ("Flags:\t\t\t" + getFlags(flags))
            print ("Fragment offset:\t" + str(fragmentOffset))
            print ("TTL:\t\t\t" + str(TTL))
            print ("Protocol:\t\t" + getProtocol(protocolNr))
            print ("Checksum:\t\t" + str(checksum))
            print ("Source:\t\t\t" + sourceAddress)
            print ("Destination:\t\t" + destinationAddress)
            print ("Payload:\n" , pkt_data[34:(int(totalLength))])
            print ("\n\n\n")
     
     
     
    packet_handler=PHAND(_packet_handler)
    alldevs=POINTER(pcap_if_t)()
    errbuf= create_string_buffer(PCAP_ERRBUF_SIZE)
     
    ## Retrouver la liste des cartes réseaux
    if (pcap_findalldevs(byref(alldevs), errbuf) == -1):
            print ("Error in pcap_findalldevs: %s\n" % errbuf.value)
            sys.exit(1)
     
    ## Imprime la liste des cartes
    i=0
    try:
            d=alldevs.contents
    except:
            print ("Error in pcap_findalldevs: %s" % errbuf.value)
            print ("Maybe you need admin privilege?\n")
            sys.exit(1)
    while d:
            i=i+1
            print("%d. %s" % (i, d.name))
            if (d.description):
                    print (" (%s)\n" % (d.description))
            else:
                    print (" (No description available)\n")
            if d.next:
                    d=d.next.contents
            else:
                    d=False
     
    if (i==0):
            print ("\nNo interfaces found! Make sure WinPcap is installed.\n")
            sys.exit(-1)
    print ("Enter the interface number (1-%d):" % (i))
    inum= raw_input('--> ')
    if inum in string.digits:
            inum=int(inum)
    else:
            inum=0
    if ((inum < 1) | (inum > i)):
            print ("\nInterface number out of range.\n")
            ## Free the device list
            pcap_freealldevs(alldevs)
            sys.exit(-1)
     
    ## Jump à la carte sélectionné
    d=alldevs
    for i in range(0,inum-1):
            d=d.contents.next
     
    ## ouvrir la carte réseau
    d=d.contents
    adhandle = pcap_open_live(d.name,65536,PCAP_OPENFLAG_PROMISCUOUS,1000,errbuf)
    if (adhandle == None):
            print("\nUnable to open the adapter. %s is not supported by Pcap-WinPcap\n" % d.contents.name)
            ## Free the device list
            pcap_freealldevs(alldevs)
            sys.exit(-1)
    print("\nlistening on %s...\n" % (d.description))
     
    ## Ici nous n'avons plus besoin de la list des cartes, nous la livérons
    pcap_freealldevs(alldevs)
     
    ## Démmare la capture des packets ( le seconde paramêtre est le nombre de packet
    ## que vous voulez capturer, si vous incrivé -1, il sera illimté)
    pcap_loop(adhandle, 10, packet_handler, None)
    pcap_close(adhandle)

Discussions similaires

  1. sniffer un packet en python
    Par ewok2 dans le forum Général Python
    Réponses: 6
    Dernier message: 14/10/2014, 22h50
  2. sniffer en local avec ethereal
    Par ashram dans le forum Développement
    Réponses: 9
    Dernier message: 31/01/2007, 16h07
  3. Réponses: 15
    Dernier message: 04/01/2007, 11h15
  4. sniffer les messages sortant
    Par ashram dans le forum Développement
    Réponses: 3
    Dernier message: 08/07/2003, 11h31
  5. Packet forwarder
    Par Gabuzomeu dans le forum Développement
    Réponses: 3
    Dernier message: 03/06/2003, 17h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo