L'OSfingerprinting est l'art d'identifier le système d'exploitation d'un serveur distant. En pratique, cette étape fait souvent suite à un scan de port. Bien que les communications TCP/IP fassent l'objet de normes, les implémentations de ces protocoles sont différentes selon les OS. Découvrons ces différentes techniques permettant de distinguer les différents systèmes d'exploitations.

Techniques passives

Quelqu'un interroge ma machine! De qui s'agit-il ? Les techniques passives d'OSfingerprinting sont là pour répondre à cette question. Il s'agit d'analyser les paquets reçus pour identifier le système à l'origine de la communication. Les techniques passives sont utilisées par les administrateurs pour glaner un maximum d'information sur les attaquants.

Analyse d'un ping

Pour vérifier si une adresse IP est utilisée ou si le serveur fonctionne bien, il est courant d'utiliser la commande ping pour vérifier son état. Cette commande envoie un paquet ICMP echo-request et attend en réponse un ICMP echo-reply. La demande echo-request à la forme suivante:

+---------+-----------+----+
|Entête IP|Entête ICMP|Data|
+---------+-----------+----+

La partie Data peut contenir n'importe quelle donnée. Voici l'affichage d'un ping depuis un Linux avec en bleu la partie Data.

12:28:25.997190 172.18.100.33 > 172.18.100.31: icmp: echo request (DF)
0x0000   4500 0054 0000 4000 4001 1a44 ac12 6421        E..T..@.@..D..d!
0x0010   ac12 641f 0800 cb31 392f 0200 4927 983d        ..d....19/..I'.=
0x0020   1637 0f00 0809 0a0b 0c0d 0e0f 1011 1213        .7..............
0x0030   1415 1617 1819 1a1b 1c1d 1e1f 2021 2223        .............!"#
0x0040   2425 2627 2829 2a2b 2c2d 2e2f 3031 3233        $%&'()*+,-./0123
0x0050   3435                                           45

Même chose depuis un Windows

12:35:02.833558 172.18.100.32 > 172.18.100.33: icmp: echo request
0x0000   4500 003c 9d17 0000 2001 dd43 ac12 6420        E..<.......C..d.
0x0010   ac12 6421 0800 485c 0200 0300 6162 6364        ..d!..H\....abcd
0x0020   6566 6768 696a 6b6c 6d6e 6f70 7172 7374        efghijklmnopqrst
0x0030   7576 7761 6263 6465 6667 6869                  uvwabcdefghi

Le contenu des paquets est différent, c'est un moyen facile pour distinguer les ping Unix des ping Windows. Le système de détection d'intrusion Snort, http://www.snort.org, disponible aussi bien sous Linux que sous Windows, est capable de distinguer les signatures des Ping produits par de nombreux OS.

Analyse d'une demande de connexion

Une connexion TCP débute par l'envoi d'un paquet TCP avec l'indicateur SYN. p0f, http://www.stearns.org/p0f/, va étudier ces paquets pour déterminer le système d'exploitation. Etudions concrètement la capture d'un de ces paquets avec tcpdump, www.tcpdump.org, ou windump, http://windump.polito.it/, pour la version Windows.

[root@christophe root]# tethereal
Capturing on eth0
14:58:59.810579 christophe.global-secure.fr.32962 > www.google.com.http: S [tcp sum ok] 2718661544:2718661544(0) win 5840 <mss 1460,sackOK,timestamp 1876279 0,nop,wscale 0> (DF) (ttl 62, id 55967, len 60)

p0f s'intéresse

  Client	Serveur
Envoie de données
    1460  -->
    1460  -->
    1460  -->
    1460  -->
Attente d'acquittement
          <-- Acquittement
 Client -->  Routeur  -->  Routeur --> ....> Serveur
      TTL=64             TTL=63          TTL=62
Cas d'une connexion sur réseau Ethernet

+---------+----------+-----------------------+
|Entête IP|Entête TCP|       Données TCP     |
+---------+----------+-----------------------+

    20    +   20     +      1460     = 1500

Cas d'une connexion PPoE

+-----------+---------+----------+-----------+
|Entête PPoE|Entête IP|Entête TCP|Données TCP|
+-----------+---------+----------+-----------+

  8 +   20    +   20     +  1452     = 1500
 

Dans la syntaxe p0f, ces données s'écrivent sous la forme win:TTL:MSS:DF:wscale:sackOK:nop:taille, soit dans notre cas 5840:64:1460:1:0:1:1:60. D'après la base de connaissance de p0f, cette signature correspond à un Linux 2.4. Heureusement pour nous, p0f fait ces rapprochements tout seul comme un grand:

[root@christophe root]# p0f
p0f: passive os fingerprinting utility, version 1.8.2
(C) Michal Zalewski , William Stearns 
p0f: file: '/etc/p0f.fp', 150 fprints, iface: 'eth0', rule: 'all'.
172.18.100.33 [3 hops]: Linux 2.4.2 - 2.4.14 (1)

Par contre, la base de connaissance date un peu et cette méthode n'est pas infaillible.

17:50:54.767087 172.18.100.40.1494 > 172.18.100.33.telnet: S [tcp sum ok] 2476793080:2476793080(0) win 64512 <mss 1460,nop,nop,sackOK> (DF) (ttl 128, id 23456, len 48)
soit avec p0f: 172.18.100.40: UNKNOWN [64512:128:1460:1:-1:1:1:48]. Dans la base, aucune signature n'utilise une telle fenêtre TCP. En ignorant ce paramètre, on obtient une liste de six systèmes d'exploitation différents:

64240:128:1460:1:-1:1:1:48:Windows XP Pro, Windows 2000 Pro
5840:128:1460:1:-1:1:1:48:Windows 95 or early NT4
16384:128:1460:1:-1:1:1:48:Windows 2000 (9)
4288:128:1460:1:-1:1:1:48:Windows NT SP3 (1)
65535:128:1460:1:-1:1:1:48:Windows 98 (4)
8760:128:1460:1:-1:1:1:48:Windows NT 5.0 (2)
Selon toute vraisemblance, il s'agit d'un Windows et c'est bien le cas, c'est un Windows 2000 serveur.

Techniques actives

Les techniques actives consistent à envoyer des données sur le système que l'on souhaite identifier et à analyser les réponses. Les techniques actives sont principalement utilisées par les pirates ou par les administrateurs systèmes s'interrogeant sur une mystérieuse machine connectée sur leur réseau.

Technique liée à TCP

Pour identifier le système d'exploitation distant, Nmap, http://www.insecure.org/nmap/, envoie différents paquets sur un port TCP ouvert et sur un port TCP fermé. Il constate s'il reçoit une réponse et si c'est le cas, il vérifie au niveau IP

et au niveau TCP Nmap reconnaît les options TCP suivantes: Il ignore l'option permettant l'acquittement sélectif (option 4, SackOk) mais comme il n'envoie aucun paquet avec cette option, cela ne lui est pas nécessaire. Connaissant les options utilisées et donc la taille prise par ses options, il est possible de calculer la taille du paquet, on retrouve les valeurs utilisés par p0f, mais le système de Nmap est plus précis.

Nmap envoie 4 paquets sur un port TCP ouvert avec différents flags:

Les systèmes d'exploitation suivant le RFC 793 ne répondront pas au test T2. Windows ne le respecte pas et envoie une réponse.

Sur un port TCP fermé, Nmap envoie un SYN (T5) et un ACK (T6). Si le serveur est protégé par un firewall statefull (pare-feu de deuxième génération) correctement configuré, seul le paquet du test T1 passera. Remarque, Firewall-1 4.x laisse passer le test T3.

Technique liée à UDP et ICMP

Nmap envoie un paquet UDP sur un port fermé de façon à recevoir un message d'erreur ICMP. Tel que définis dans le RFC 1122, les messages d'erreurs ICMP inclus l'entête IP et au moins les 8 premiers octets du datagramme ayant provoqué l'erreur. Nmap analyse le paquet ICMP port unreachable

+---------+-----------+---------+----------+--------+
|Entête IP|Entête ICMP|Entête IP|Entête UDP|Data UDP|
+---------+-----------+---------+----------+--------+
DF         Port         RIPTL     RID         DAT
TOS        unreachable  RIPCK     UCK
IPLEN                             ULEN
et vérifie
au niveau de l'entête IP au niveau de l'entête IP du paquet UDP Ainsi on peut avoir une signature de la forme (assez indigeste):

PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)

Octet TOS

L'octet TOS, Type Of Service , se découpe ainsi

Bits 0-2:  Precedence.
Bit    3:  0 = Normal Delay,      1 = Low Delay.
Bits   4:  0 = Normal Throughput, 1 = High Throughput.
Bits   5:  0 = Normal Relibility, 1 = High Relibility.
Bit  6-7:  Reserved for Future Use.

0     1     2     3     4     5     6     7
+-----+-----+-----+-----+-----+-----+-----+-----+
|                 |     |     |     |     |     |
|   PRECEDENCE    |  D  |  T  |  R  |  0  |  0  |
|                 |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+-----+

Le RFC 791 indique que les routeurs doivent régler la précédence ou priorité d'un message d'erreur ICMP autre que ICMP source quench à 6 (Internetwork control) ou 7 (Network control). Les routeurs Cisco IOS 11.x ou 12.x et les Linux 2.x utilisent une priorité Internetwork control et l'octet TOS est donc à 0xC0.

ICMP Error Message Quoting Size

Tel que définis dans le RFC 1122, les messages d'erreurs ICMP inclus l'entête IP et au moins les 8 premiers octets du datagramme ayant provoqué l'erreur. La longueur du paquet, IPLEN, est donc de 56 octets minimum ( Entête IP:20, Entête ICMP:8, Entête IP:20 + 8). Windows et Mac OS X renvoient 8 octets, pas plus, la taille du paquet est donc de 56 (0x38 en hexadécimal). Le RFC 1812, plus récent, recommande d'inclure autant d'octets du datagramme d'origine sans excéder toutefois une taille maximale totale de 576 octets. Linux utilise cette limite mais comme le paquet UDP de Nmap est de 328 octets, la longueur du paquet ICMP est de 356 octets (0x164).

RIPTL

Le paquet UDP envoyé sur un port UDP fermé est de 328 octets (0x148). On devrait donc retrouver cette taille dans l'entête IP encapsulé dans le message ICMP d'erreur. Certains systèmes bogués indiquent une mauvaise taille. L'erreur classique est qu'ils ajoutent (IBM AIX) ou soustraient (OpenBSD) 20 octets correspondant à la taille de l'entête IP.

Checksum IP: RIPCK

Entre l'émission du paquet et sa réception, le TTL est décrémenté à chaque routeur, et en conséquence, le checksum est recalculé. Dans la copie du paquet, le checksum est parfois invalide (IBM AIX) ou mis à zéro (BSDI, HP, OpenBSD <= 2.3).

Recopie de l'ID: RID

L'ID est parfois mal recopié. Ce bug peut apparaître dû à une différence entre l'ordre des octets sur le réseau et au niveau de l'architecture processeur (big versus little endian).

Checksum UDP: UCK

Le checksum UDP peut être à zéro ou à une valeur incorrecte sur certains OS.

Intégrité

Tous les OS connus de Nmap renvoient la bonne longueur du paquet UDP, soit 0x134. Il semblerait qu'aucun OS n'est buggué au point d'altérer cette valeur mais quelques systèmes rares altéreraient les données.

Numéro de séquence, d'id et timestamp

Un moyen d'identifier le système d'exploitation est de déterminer l'algorithme utilisé pour générer les numéros de séquences. Pour cela, quelques paquets SYN sont envoyés sur un port ouvert et les numéros de séquences contenus dans les paquets SYN/ACK sont étudiés.

Les grandes familles de générateurs de numéro de séquence sont

De la même manière, on peut étudier la génération du numéro d'ID, numéros utilisés pour gérer la fragmentation TCP des paquets.

L'analyse de l'option TCP Timestamp permet de déterminer avec quelle fréquence d'horloge est gérée la couche réseau.

En pratique

Dans la pratique, le scanner de port nmap parviendra dans la majorité des cas à identifier le système d'exploitation sans qu'il soit nécessaire de décortiquer les paquets à la main.

[root@christophe root]# nmap -O -sS -p 80,130-140 192.168.1.15 -n -vv

Starting nmap V. 3.10ALPHA9 ( www.insecure.org/nmap/ )
Host 192.168.1.15 appears to be up ... good.
Initiating SYN Stealth Scan against 192.168.1.15
Adding open port 139/tcp
Adding open port 135/tcp
The SYN Stealth Scan took 0 seconds to scan 12 ports.
For OSScan assuming that port 135 is open and port 80 is closed and neither are firewalled
Interesting ports on 192.168.1.15:
(The 10 ports scanned but not shown below are in state: closed)
Port       State       Service
135/tcp    open        loc-srv
139/tcp    open        netbios-ssn
Remote operating system guess: Windows Millennium Edition (Me), Win 2000, or WinXP
OS Fingerprint:
TSeq(Class=RI%gcd=1%SI=959%IPID=I%TS=0)
T1(Resp=Y%DF=Y%W=FC00%ACK=S++%Flags=AS%Ops=MNWNNT)
T2(Resp=Y%DF=N%W=0%ACK=S%Flags=AR%Ops=)
T3(Resp=Y%DF=Y%W=FC00%ACK=S++%Flags=AS%Ops=MNWNNT)
T4(Resp=Y%DF=N%W=0%ACK=O%Flags=R%Ops=)
T5(Resp=Y%DF=N%W=0%ACK=S++%Flags=AR%Ops=)
T6(Resp=Y%DF=N%W=0%ACK=O%Flags=R%Ops=)
T7(Resp=Y%DF=N%W=0%ACK=S++%Flags=AR%Ops=)
PU(Resp=Y%DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)

TCP Sequence Prediction: Class=random positive increments
                         Difficulty=2393 (Medium)
TCP ISN Seq. Numbers: 6B8F4294 6B90952C 6B91D4F5 6B9326DE 6B948356 6B95D04C
IPID Sequence Generation: Incremental

Nmap run completed -- 1 IP address (1 host up) scanned in 1.105 seconds

Tempo

La dernière méthode en date est de contacter avec un SYN un port TCP ouvert et de vérifier le délai entre les retransmissions des SYN/ACK et bien sûr leur nombre. Cette idée a donné lieu au programme Ring, http://www.intranode.com/pdf/techno/ring-0.0.1-Linux-2.4.tar.gz, dont voici quelques résultats:

RetriesLinux 2.2.14Linux 2.4Windows 98Win 2KFreeBSD 4.4
1st 3,5 4,26 3 3 3
2nd 6,5 6 6 6 6
3rd 12,5 12 12No more retries12
4th 24,5 24 No more retries 24
5th 48,5 48,2    Reset after 30s
6th 96,5 No more retries    
7th 120,5       
8thNo more retries       

Cette technique est très intéressante lorsqu'un firewall protége un serveur et que seul un port TCP est accessible.