WINPCAPAI3 - Décodage des valeurs.

Aide et conseils concernant AutoIt et ses outils.
Règles du forum
.
Répondre
Avatar du membre
Barthandelus
Niveau 4
Niveau 4
Messages : 53
Enregistré le : mer. 02 janv. 2019 14:34
Status : Hors ligne

WINPCAPAI3 - Décodage des valeurs.

#1

Message par Barthandelus »

Bonjour,

Je travaille depuis peu avec l'AutoIT V3 (dernier build) et avec WinPCAPAI3, un script développé et disponible en open-source ici : http://opensource.grisambre.net/pcapau3/

En me basant sur la documentation et sur les exemples fournis, j'ai put créer mon propre "Wireshark-like" qui affiche les trames en temps réel, permet de les sauvegarder, permet d'avoir des statistiques détaillés pour les communications et même de limiter l'affichage à ma machine uniquement. L'outil développé à pour finalité non pas une supervision, mais de permettre, via l'IHM, de bloquer une adresse IP en ajoutant une règle de blocage de flux en direct dans le Par-feu Windows : chose que je n'ai pour le moment pas encore aborder ! :(

Je suis bloqué au préalable par une autre problématique : Le décodage même des trames reçues par l'outil WinPCAPAI3 (qui se base sur le même driver que WireShark pour la capture de trame). Dans les exemples fournis, deux fonctions majeures, natives à AutoItV3 sont utilisés : StringMid() (qui ressemble fortement à un substr()) et BinaryMid().

Hors je n'arrive pas à trouver les "index" correct pour venir "disséquer" ma trame.

Je me suis basé sur le cours suivant : http://www.gipsa-lab.grenoble-inp.fr/~c ... ices1.html
Ainsi, je pensais que de l'octet 1 à 6 incluts, j'obtiendrait l'adresse MAC de destination : que neni !

Le code suivant me donne l'adresse MAC de destination (disponible dans les exemples) :
Local $macdst = StringMid($data,3,2) & ":" & StringMid($data,5,2) & ":" & StringMid($data,7,2) & ":" & StringMid($data,9,2) & ":" & StringMid($data,11,2) & ":" & StringMid($data,13,2)
Ou $data est équivalent à $paquet[3], lui même équivalent à $packet = _PcapGetPacket($pcap).

Hors, en regardant bien, l'ethertype (qui semble déterminer le protocole dans les exemples) équivaut à ça :
Local $ethertype = BinaryMid( $data, 13 , 2)
Là ou mon mindf*ck commence, c'est de se dire que l'index 13 de $data juxtapose deux données ? $ethertype va se baser sur l'index 13 de $data pour obtenir un code hexadécimal permettant de déterminer le protocole utilisé (c'est en tout cas ce que je fais via une fonction que j'ai moi même établis). Mais l'index 13 de $macdst est aussi utilisé pour déterminer le dernier couple hexadécimal de l'adresse MAC destinataire (StringMid($data,13,2)).

A partir de là, c'est là que mon esprit est confus. Est-ce que les données impactées par BinaryMid() & StringMid() sont différentes ? Les données sont-elles juxtaposées ? Ou est-ce que le protocole se détermine simplement sur une déduction ?

Ma fonction :
Func GetProtocole($data)
   Local $e = BinaryMid($data, 13 , 2)
   If $e = "0x0806" Then
      return "ARP";
   ElseIf $e = "0x0800" Then
      Switch BinaryMid ($data, 24 ,1)
         Case "0x01"
            return "ICMP"
         Case "0x02"
            return "IGMP"
         Case "0x06"
            return "TCP"
         Case "0x11"
            return "UDP"
         Case "0x8137" OR "0x8138" OR "0x0022" OR "0x0025" OR "0x002A" OR "0x00E0" OR "0x00FF"
            return "IPX"
      EndSwitch
   Else
      return $e
   EndIf
EndFunc
Dans tout les cas, existe-t-il une documentation permettant de savoir sur quels index taper pour obtenir des valeurs que nous, humains, nous pouvons lire de nos yeux ? :lol:

N'hésitez pas à me dire si je me trompe quelque part : il s'agit de mon premier code en AutoIt.

En vous souhaitant une agréable année, meilleurs vœux !

Liens utiles :
- https://www.autoitscript.fr/autoit3/doc ... ingMid.htm
- https://www.autoitscript.com/autoit3/do ... aryMid.htm
Avatar du membre
mikell
Spammer !
Spammer !
Messages : 6292
Enregistré le : dim. 29 mai 2011 17:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: WINPCAPAI3 - Décodage des valeurs.

#2

Message par mikell »

Je t'avoue que j'ai pas tout lu, trop compliqué ... Image
Mais les index pour StringMid et BinaryMid ne sont pas les mêmes évidemment
En me basant sur la page de cours fournie ça donnerait quelque chose comme ça :

$data = "00 0a b7 a3 4a 00 00 01 02 6f 5e 9b 08 00 45 00 00 28 00 00 40 00 40 01 82 ae 84 e3 3d 17 c2 c7 49 0a 08 00 75 da 9c 7a 00 00 d4 45 a6 3a 62 2a 09 00 ff ff ff ff 00 00 00 00 00 00"
$data = "00 " & $data   ; <== bizarre mais sans ça, les StringMid devraient commencer à l'index 1
$data = StringStripWS($data, 8)

Local $macdst = StringMid($data,3,2) & ":" & StringMid($data,5,2) & ":" & StringMid($data,7,2) & ":" & StringMid($data,9,2) & ":" & StringMid($data,11,2) & ":" & StringMid($data,13,2)
Msgbox(0,"", $macdst)

$data = "0x" & $data
$ethertype = BinaryMid($data, 14, 2)  ; <== ou 13 mais là il faut enlever les 00 rajoutés avant. bizarre !
Msgbox(0,"", $ethertype)
Aucune idée si ça te sera utile ou pas :mrgreen:

Dans ta fonction :
Case "0x8137" OR "0x8138" OR "0x0022" OR ... etc
remplace les OR par des virgules ça ira mieux
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )
Avatar du membre
orax
Modérateur
Modérateur
Messages : 1479
Enregistré le : lun. 23 mars 2009 04:50
Localisation : ::1
Status : Hors ligne

Re: WINPCAPAI3 - Décodage des valeurs.

#3

Message par orax »

J'ai essayé l'exemple (Winpcap_demo.au3) pour mieux comprendre.
La variable $data, dans le code ci-dessous, correspond à ce que reçoit $paquet[3], lui même équivalent à $packet = _PcapGetPacket($pcap).

Code : Tout sélectionner

$data = Binary("0x000ab7a34a000001026f5e9b08004500002800004000400182ae84e33d17c2c7490a080075da9c7a0000d445a63a622a0900ffffffff000000000000")

; récupère l'adresse MAC de deux façon différentes

$macdst  = BinaryMid($data,1, 6)      ; $macdst = 0x000AB7A34A00 - $macdst est de type binaire (binary)
$macdst = StringTrimLeft($macdst, 2)  ; supprime "0x" - $macdst est converti en une variable de type chaîne de caractères (string)
ConsoleWrite($macdst & @CRLF)

$data = StringTrimLeft($data, 2)  ; supprime "0x"
$macdst = StringMid($data, 1, 12) ; pour récupérer 1 octet il faut récupérer 2 caractères
ConsoleWrite($macdst & @CRLF)
De petits détails peuvent faire toute la différence. — Quand la boule de neige commence à rouler… poussez-la. (Columbo)
Avatar du membre
Barthandelus
Niveau 4
Niveau 4
Messages : 53
Enregistré le : mer. 02 janv. 2019 14:34
Status : Hors ligne

Re: WINPCAPAI3 - Décodage des valeurs.

#4

Message par Barthandelus »

Bonjour,

Tout d'abord, merci pour vos réponses.

@mikell : Ce n'est pas forcément étrange pour StringMid(), la documentation montre bien que le paramètre "start" commence à 1 ("La position du caractère de départ. (1 = premier caractère)"). C'est aussi le cas pour BinaryMid ("The byte position to start. (1 = first byte)").

Sur l'exemple de ton code, la chaîne issu du cours n'est pas représentative d'une trame ethernet, ce qui explique que le traitement est différent.

J'ai modifier pour le case, effectivement, ça fais gagner en visibilité. :wink:

@orax : J'aime beaucoup ta démonstration. Dans la première partie de ton code, on voit bien qu'avec les paramètres que tu définis, tu viens impacter l'octet 1 + 5 (Paramètre count "6" incluant l'octet du paramètre start), on retombe bien sur le schéma des trames ethernets connus. Le second exemple de ton code explique aussi pourquoi les index partaient si haut avec l'usage de StringMid(). Cela signifie aussi que l'adresse physique de destination et l'adresse physique source sont affichés sans aucun chiffrement dans la trame récupérer par WINPCAP, ce que j'ignorais. Je pensais que l'ensemble des données étaient converties en Hexadécimal. Je me demande si ces données sont toujours affichés en dur ou si cela peut varier ?

En découpe on obtient donc, toujours en suivant le même exemple :

; Différentes sections.
$macdst  = BinaryMid($data, 1, 6) ; Octets : 1, 2, 3, 4, 5, 6
$macsrc = BinaryMid($data, 7, 6) ; Octets : 7, 8, 9, 10, 11, 12
$ethertype = BinaryMid($data, 13, 2) ; Octets : 13, 14 || équivaut au "type".
$pad_data = BinaryMid($data, 15) ; Octets partant de 15 à MINIMUM 61, MAXIMUM 1515. Sans l'argument count : [i][optional] The number of bytes to extract. By default the entire remainder of the binary data.[/i]
$ip_header = BinaryMid($pad_data, 1, 20) ; Cette fois rechercher dans $pad_data.
$data_trame = BinaryMid($pad_data, 21, 20) ; Obtient la section DATA de données PAD. Cette fonction devrait se baser sur l'ensemble restant - 6 octets, en vérité.
$pad = BinaryMid($pad_data, 41, 6) ; Ou ici aussi, l'argument "start" devrait commencer sur l'ensemble restant - 6 octets.

Actuellement pour obtenir l'adresse IP, mon code (et celui présent dans la démo) est :

Local $source = Number(BinaryMid($packet[3], 27 , 1)) & "." & Number(BinaryMid($packet[3], 28 ,1)) & "." & Number(BinaryMid($packet[3], 29 , 1)) & "." & Number(BinaryMid($packet[3], 30 , 1))
Local $destination = Number(BinaryMid($packet[3], 31 , 1)) & "." & Number(BinaryMid($packet[3], 32 ,1)) & "." & Number(BinaryMid($packet[3], 33 , 1)) & "." & Number(BinaryMid($packet[3], 34 , 1))

A noter que dans mon exemple ci-dessus, aucun traitement n'est fait sur $packet entre temps. ($packet = _PcapGetPacket($pcap))

Il y a tout de même un petit différentiel, mais je ne sais pas tout ce que contient les Entêtes IP pour savoir si je dois m'inquiéter ou non. Si quelqu'un pouvait me renseigner ? De même, quelqu'un sait si les données présentes dans $data_trame sont encodés, et si oui de quelle façon ? Ceci afin de pouvoir les afficher à la manière de WireShark. A noter que si les données dépendent d'une clé de chiffrement, je ne chercherais pas à les déchiffrer, mais je souhaite avoir une visibilité dessus pour voir tout ce qui part et vient et qui serait en claire (représentant donc, à mon sens, une menace).

Selon le cours que j'ai cité plus haut les adresses IP se définissent à la fin de $ip_header, donc je pense qu'on tombe juste. Ce qui est étonnant c'est que c'est aussi dans $ip_header qu'est définit le Protocole, alors que l'exemple de WINPCAPAI3 l'obtient sur $ethertype qui correspond aux bytes 13 & 14, donc en dehors de $ip_header.

EDIT ERRATUM : Je me permet de partager ce que je découvre à la communauté, en espérant que ça servira aux autres. L'ethertype doit bien être utilisé pour déterminer le protocole utilisé. Ce dernier n'est pas écrit en clair, évidemment, il faut donc le déterminer fonction de son code, comme je l'ai fais dans mon premier poste.

L'intitulé "Protocole" de $ip_header correspond au type de protocole (Exemple : IPv4), et n'a donc rien à voir avec $ethertype.

Image
Répondre