Code (Version 0.9.0)
Bug report: cinac@projet7.org







µito (à prononcer muito) est un programme permettant de forger des paquets TCP/IP sous Linux. Les paquets qu'il peut forger pour le moment peuvent être des protocols suivant: IP, ICMP, IGMP, TCP et UDP. D'autres protocols viendront s'ajouter par la suite notement ETH, ARP/RARP, DNS, OSPF, RIP.

Il est codé en C et utilise la lib Gdk/Gtk pour l'affichage sous X. Les paquets sont injectés en SOCK_RAW sans utilisation de la libnet ou de la libpcap.

Le but de ce projet était de faire un programme en mode graphique qui soit aussi puissant et paramètrable que pouvait l'être un programme en C utilisant les sockets de type RAW. Les difficultés rencontrées en chemin font que la version du programme actuellement disponible souffre de quelques limitations par rapport a ma vision initiale du but que je me fixait en le commencant.

Les limitations par rapport au programme que vous auriez pu coder vous même (remplissage de structures pour être bref) sont liées notemment au peu de protocols utilisables par rapport à la multitude existant. Par exemple dans le protocol ETH on a le choix entre plus de cent protocoles au niveau de la couche juste supérieur. Cette multitude est représenté par un choix de 65536 valeurs (16 bits) pour le champ ether type alors que dans µito je n'en implémente qu'une seule: IP. Les limitations sont aussi liées au fait que dans un paquet si on change une valeur dans un header cela peut influer sur l'ensemble des valeurs correctes à passer aux differents champs des headers de plus haut niveau ou du même niveau. Par exemple quand dans le header ICMP on change la valeur de icmp->type ca change les valeurs possibles dans icmp->code et influ sur la taille, le contenu possible et la signification du reste du paquet. De plus les valeurs possibles dans la norme ne sont pas toujours celles que l'on veut utiliser notemment pour provoquer des DoS. Il fallait aussi representer ce cas de figure. Il fallait aussi que mon programme puisse vous avertir si vous voulez utiliser une option du programme qui n'existe pas (du généralement aux limitations précédement énoncées) ou qui ne servirait à rien en TCP/IP. Car de fournir un programme en mode graphique (même sous Linux) donne acces à ce programme à des utilisateurs moins experimentés. Bref voici ce qu'il est possible, impossible, obligatoire et permi de faire:
 

* Tous les champs doivent être rempli sauf le champ data.
* Tous les valeurs des champs sont considérées comme étant en décimal sauf contre indication dans le programme pour certains champs. Le champ data est lui remplissable en char (la possibilité sera donnée entre char et hexa dans une prochaine version).
* Tous les champs ont des valeurs maximum et minimum défini en fonction du nombre de bits qui leur est reservé par le protocol dans le header. La valeur minimum est tres souvent (pour pas dire toujours) zéro.
* Il est possible pour certains champs de ne pas mettre de valeur mais des string du genre 'random' ou 'auto' qui permettent respectivement de générer une valeur aléatoire ou de laisser le programme calculer la valeur que le champ doit avoir dans la norme (ou la meilleure valeur).
 

ETH: (pas encore disponible pour cette version)
- source(48bits;6octets): adresse MAC source (de type 03:11:C5:3D:E9:AB ou 'auto')
    l'utilisation d'auto mettra l'adresse mac correspondant a l'adresse IP source du header IP.
- destination(48bits;6octets): adresse MAC de desination (de type 03:11:C5:3D:E9:AB ou 'auto')
    l'utilisation d'auto mettra l'adresse mac correspondant a l'adresse IP destination du header IP.
- type(16bits;2octets): type de protocol se trouvant sur la couche au dessus, ici il sagit de DOD IP (2048d;800h)
    la valeur de ce champ n'est pas changeable car ARP/RARP n'est pas encore implémenté, seul IP l'est.
 

IP:
- Version(4bits): Seul IPv4 est implémenté, cette valeur est donc de 4
- IHL(4bits): Aucune options IP n'est ajoutables, la valeur est donc de 5 (5*4 = 20octets = header IP sans option)
- TOS(8bits;1octet):
   * Préséance(3bits): Valeurs en binaire, choix parmis differentes entrées.
   * Délai(1bit):      Valeurs en binaire, choix parmis differentes entrées.
   * Débit(1bit):      Valeurs en binaire, choix parmis differentes entrées.
   * Fiabilité(1bit):  Valeurs en binaire, choix parmis differentes entrées.
   * Coût(1bit):       Valeurs en binaire, choix parmis differentes entrées.
   * MBZ(1bit):        Must Be Zero (doit être égal à 0) donc valeur non changeable.
- Total length(16bits;2octets): taille totale du paquet sans le header ETH. maximum 65535. (mais généralement limité à 1500 par le MTU)
    l'utilisation d'auto laissera le programme calculer la taille du paquet, data comprises.
- Identification(16bits;2octets): maximum 65535, possibilité d'utiliser 'random'.
- Fragmentation(16bits;2octets):
   * MBZ(1bit):        Must Be Zero (Doit être égal à 0) donc valeur non changeable.
   * DF(1bit):         Valeurs en binaire, choix parmis differentes entrées.
   * MF(1bit):         Valeurs en binaire, choix parmis differentes entrées.
   * Offset(13bits):   maximum 8191.
- TTL(8bits;1octet): maximum 255. Possibilité d'utiliser 'random'.
- Protocol(8bits;1octet): choix entre ICMP, IGMP, TCP et UDP.
    le choix d'une des entrées fera apparaitre l'onglet du protocol choisi ainsi que l'onglet data.
- Checksum(16bits;2octets):maximum 65535. possibilité d'utilisation d'auto pour que le programme calcul le bon checksum.
- Adresse source(32bits;4octets): Adresse IP source. Doit être de type 192.168.0.1
- Adresse de destination(32bits;4octets): Adresse IP de destination. Doit être de type 192.168.0.1
 

ICMP:
- Type(8bits;1octet): les valeurs choisie dans ce champ parmi une liste influ sur la structure du paquet ICMP et donc sur les champs apparaissant à l'ecran. Les trois champs fixes sont "type", "code" et "checksum".
- Code(8bits;1octet): Valeurs à choisir parmi une liste qui varie en fonction de la valeur du champ "type".
- Checksum(16bits;2octets): maximum 65535. Possibilité d'utilisation d'auto pour que le programme calcul le bon checksum.
- Pointer(8bits;1octet): maximum 255.
- Unused(24ou32bits;3ou4octets): en fonction de la valeur du champ "type" la taille de ce champ change. Valeur ignorée par le programme.
- Router addr(32bits;4octets): Adresse IP du routeur. Doit être de type 192.168.0.1 (0.0.0.0 pour mettre à 0).
- Identification(16bits;2octets): maximum 65535, possibilité d'utiliser 'random'.
- sequence number(16bits;2octets): maximum 65535, possibilité d'utiliser 'random'.
 

IGMP:
- Version(4bits): maximum 15.
- Type(4bits): maximum 15.
- Unused(8bits;1octet): maximum 255. Normalement 0 et généralement ignoré à la réception.
- Checksum(16bits;2octets): maximum 65535. Possibilité d'utilisation d'auto pour que le programme calcul le bon checksum.
- Group address(32bits;4octets): Adresse IP du groupe de multidiffusion. Doit être de type 192.168.0.1 (0.0.0.0 pour mettre à 0).
 

TCP:
- Source port(16bits;2octets): maximum 65535, possibilité d'utiliser 'random'.
- Destination port(16bits;2octets): maximum 65535.
- Sequence number(32bits;4octets): maximum 4294967295, possibilité d'utiliser 'random'.
- Acknowledgment number(32bits;4octets): maximum 4294967295, possibilité d'utiliser 'random'.
- Data offset(4bits): Aucune options TCP n'est ajoutables, la valeur est donc de 5 (5*4 = 20octets = header TCP sans option)
- Reserved(6bits): Valeur imposée à 0. Champ réservé.
- Flags(6bits):
   * FIN: 0 ou 1 (valeur de 0x01 si spécifié seul)
   * SYN: 0 ou 1 (valeur de 0x02 si spécifié seul)
   *RST: 0 ou 1 (valeur de 0x04 si spécifié seul)
   * PSH: 0 ou 1 (valeur de 0x08 si spécifié seul)
   * ACK: 0 ou 1 (valeur de 0x10 si spécifié seul)
   * URG: 0 ou 1 (valeur de 0x20 si spécifié seul)
    j'ai préféré laisser la possibilité de faire la combinaison que l'ont veut de ces flags.
    Ainsi un paquet SYN/RST peut être créé ou un FIN/ACK/URG/PSH pourquoi pas.
- Window(16bits;2octets): maximum 65535, l'utilisation d'auto mettra la valeur de ce champ à 0x7d78 soit 32120 octets.
- Checksum(16bits;2octets): maximum 65535. possibilité d'utilisation d'auto pour que le programme calcul le bon checksum.
- Urgent position/pointer(16bits;2octets): maximum 65535, possibilité d'utiliser 'random'.
 

UDP:
- Source port(16bits;2octets): maximum 65535, possibilité d'utiliser 'random'.
- Destination port(16bits;2octets): maximum 65535.
- Total length(16bits;2octets): taille totale du paquet dans le header ETH. maximum 65535.
    l'utilisation d'auto laissera le programme calculer la taille du paquet, data comprises.
- Checksum(16bits;2octets): maximum 65535. possibilité d'utilisation d'auto pour que le programme calcul le bon checksum.
 

DATA:
  le champ n'est pas à remplir obligatoirement. La taille maximum de ce champ varie en fonction du protocole de plus bas nivo que vous avez choisi car la limite maximale en taille du paquet est fixée dans le programme non par la taille du champ total length mais par le MTU de votre interface (ETH_DATA_LEN). Vous pouvez y écrire ce que vous voulez mais sachez que ce que vous y écrirez sera considéré comme des char. Autrement dit si vous mettez 1, ce sera considéré comme le cractère 1 (0x31) et non le chiffre 1 (0x31 donne le caractère 1 en ASCII) et encodé pareillement dans la paquet. Ceci peut être génant pour le cas où vous voudriez vous servir du champ data pour mettre autre chose que du texte comme par exemple un protocol de plus haut niveau que TCP, UDP, ICMP ou IGMP comme DNS. Pour cela une prochaine version de µito permettra de choisir la facon dont les datas vont être interprétées, char ou hexa. Pour écrire le chiffre 1 vous devrez mettre 01 et pour le caractère 1 vous mettrez 31.
 
 
 

Références:
  RFC 791 IP
  RFC 792 ICMP
  RFC 1812 IGMP
  RFC 793 TCP
  RFC 768 UDP

Codes:
  µito version 0.9.0 (première version finalisée)