|
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)