[Table des matières] - [précédent?] - [suivant?]


Titre : Le protocole NTP
Option : -
Paquets utiles : -
Auteur : Nicolas Brunet


NTP, pour Network Time Protocol, est un protocole permettant de synchroniser la date et l'heure d'un système informatique avec un serveur.

ATTENTION : l'auteur de Scapy indique utiliser la RFC 1769, qui correspond à SNTP (Simple Network Time Protocol), une version simplifiée de NTP. De plus, les RFC 2030 et 4330 rendent la RFC 1769 obsolète.

L'entête d'un paquet NTP est défini ainsi :

Entête NTP

Voyons les différents champs de l'entête NTP que nous pouvons configurer dans Scapy (la valeur par défaut est entre parenthèses) :

>>> ls(NTP)
leap       : BitEnumField         = (0)
version    : BitField             = (3)
mode       : BitEnumField         = (3)
stratum    : BitField             = (2)
poll       : BitField             = (10)
precision  : BitField             = (0)
delay      : FloatField           = (0)
dispersion : FloatField           = (0)
id         : IPField              = ('127.0.0.1')
ref        : TimeStampField       = (0)
orig       : TimeStampField       = (-1)
recv       : TimeStampField       = (0)
sent       : TimeStampField       = (-1)

Voyons-les maintenant plus en détail :

  • leap : indicateur de saut. C'est un code d'avertissement de deux bits d'un saut de seconde à venir à insérer dans l'échelle de temps NTP. Les bits sont mis avant 23:59 le jour de l'insertion et remis à zéro après 00:00 le jour suivant. Cela provoque l'augmentation ou la diminution d'un du nombre de secondes (intervalle de débordement) le jour de l'insertion. Dans le cas de serveurs primaires, les bits sont établis par l'intervention d’un opérateur, alors que dans le cas de serveurs secondaires, les bits sont établis par le protocole. Sauf en condition d'alarme, NTP lui-même ne fait rien de ces bits, sauf les passer aux routines de conversion d'heure qui ne font pas partie de NTP. La condition d’alarme survient lorsque, pour une raison quelconque, l'horloge locale n'est pas synchronisée, comme lors d'une première mise en route ou après une longue période lorsque aucune source de référence primaire n'est disponible. Les valeurs possibles sont :
    • 0 : pas d'avertissement
    • 1 : la dernière minute a 61 secondes
    • 2 : la dernière minute a 59 secondes
    • 3 : condition d'alarme (horloge non synchronisée)
  • version : numéro de version de NTP; par défaut, 3.
  • mode : mode d'association, défini comme suit :
    • 0 : non spécifié
    • 1 : symétrie active
    • 2 : symétrie passive
    • 3 : client
    • 4 : serveur
    • 5 : diffusion
    • 6 : réservé pour messages de contrôle NTP
    • 7 : réservé pour utilisation privée
  • stratum : strate de l'horloge locale, définie comme suit :
    • 0 : non spécifié
    • 1 : référence primaire (par exemple, horloge atomique calibrée, horloge radio)
    • 2 à 255 : référence secondaire (via NTP)
  • poll : intervalle de consultation. C'est un entier signé qui indique l'intervalle minimum entre les messages transmis, en secondes comme une puissance de deux. Par exemple, une valeur de six indique un intervalle minimum de 64 secondes.
  • precision : c'est un entier signé qui indique la précision des diverses horloges, en secondes à la plus proche puissance de deux. La valeur doit être arrondie à la plus grande puissance de deux suivante. Par exemple, on allouera la valeur -5 (31,25 ms) à une horloge de puissance-fréquence 50 Hz (20 ms) ou 60 Hz (16,67 ms), alors qu'on allouera la valeur -9 (1,95 ms) à une horloge à contrôle cristal de 1000 Hz (1 ms).
  • delay : délai de racine. C'est un nombre algébrique à virgule fixe indiquant le délai d'aller-retour total de la source de référence primaire à la racine du sous réseau de synchronisation, en secondes. Noter que cette variable peut prendre des valeurs positives et négatives, selon la précision et le biais de l’horloge.
  • dispersion : dispersion de racine. C'est un nombre algébrique à virgule fixe indiquant l'erreur maximum par rapport à la source de référence primaire à la racine du sous réseau de synchronisation, en secondes. Seules les valeurs positives supérieures à zéro sont possibles.
  • id : identifiant d'horloge de référence. C'est un code de 32 bits qui identifie l'horloge de référence particulière. Dans le cas de strate 0 (non spécifiée) ou strate 1 (source de référence primaire), c'est une chaîne ASCII de quatre octets, justifiée à gauche, bourrée avec des zéros. Dans le cas de la strate 2 et au-dessus (référence secondaire) c'est l'adresse Internet de quatre octets de l'homologue choisi pour la synchronisation. Exemple : "11.12.13.14"
  • ref : horodatage de référence. C'est l'heure locale à laquelle l'horloge locale a été réglée ou corrigée. Le format de date est le suivant : "%a %b %d %H:%M:%S %Y". Exemple : "Mon Oct 13 15:06:00 2008".
  • orig : horodatage originel. C'est l'heure locale à laquelle la demande est partie de chez l'hôte client pour l'hôte de service. Le format de date est le suivant : "%a %b %d %H:%M:%S %Y". Exemple : "Mon Oct 13 15:06:00 2008".
  • recv : horodatage de réception. C'est l'heure locale à laquelle la demande est arrivée à l'hôte de service. Le format de date est le suivant : "%a %b %d %H:%M:%S %Y". Exemple : "Mon Oct 13 15:06:00 2008".
  • sent : horodatage d'émission. C'est l'heure locale à laquelle la réponse est partie de l'hôte de service pour l'hôte client. Le format de date est le suivant : "%a %b %d %H:%M:%S %Y". Exemple : "Mon Oct 13 15:06:00 2008".

Quelques exemples d'utilisation :

>>> ans,unans=sr(IP(src="192.168.208.33",dst="88.191.75.243")/UDP(sport=123,dport=123)/NTP(leap=3,version=4,mode=3,stratum=0,id='',sent='Sun Oct 12 12:06:00 2008'))
Begin emission:
Finished to send 1 packets.
*
Received 1 packets, got 1 answers, remaining 0 packets
>>> ans
<Results: UDP:1 ICMP:0 TCP:0 Other:0>
>>> ans[0]
(<IP  frag=0 proto=udp src=192.168.208.33 dst=88.191.75.243 |<UDP  sport=ntp dport=ntp |<NTP  leap=notsync version=4 mode=client 
stratum=0 id=0.0.0.0 sent='Sun Oct 12 12:06:00 2008' |>>>, <IP  version=4L ihl=5L tos=0x0 len=76 id=0 flags=DF frag=0L ttl=52 
proto=udp chksum=0x1125 src=88.191.75.243 dst=192.168.208.33 options='' |<UDP  sport=ntp dport=ntp len=56 chksum=0xa9b |<NTP  
leap=nowarning version=4L mode=server stratum=2L poll=10L precision=236L delay=0.00750732421875 dispersion=0.0109710693359375 
id=193.190.230.66 ref='Mon, 13 Oct 2008 13:29:47 +0000' orig='Sun, 12 Oct 2008 11:06:00 +0000' recv='Mon, 13 Oct 2008 13:35:06 +0000' 
sent='Mon, 13 Oct 2008 13:35:06 +0000' |>>>)

Analysons cet exemple :

  • leap=3 : je ne suis pas encore synchronisé
  • version=4 : il s'agit de la dernière version de NTP (elle ne dispose pas encore d'une RFC)
  • mode=3 : j'utilise le mode client pour me synchroniser à un serveur
  • stratum=0 : je ne définis pas de strate
  • id='' : je n'initialise pas l'identifiant d'horloge de référence
  • sent='Sun Oct 12 12:06:00 2008' : date d'envoi de la demande, ici le dimanche 12 octobre 2008 à midi six

Ici, j'envoie un paquet NTP en mode client car je veux me synchroniser à un serveur. J'utilise le protocole UDP et me sers du port 123, le port par défaut pour NTP. J'envoie tout ça depuis mon poste (192.168.208.33) vers le serveur NTP 0.debian.pool.ntp.org (88.191.75.243). Le serveur me répond bien.

Il faut savoir que même si je reçois une réponse, ma machine n'est pas synchronisée avec le serveur. J'utilise ntpd, qui écoute bien sur le port 123, mais comme ce n'est pas lui qui a demandé une synchronisation, il ne traite pas la réponse. Ceci est un mécanisme de sécurité de ntpd pour éviter les attaques comme le déni de service.

Sources :

Attachments