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.
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.
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.
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
Don't Fragment
pas
d'opération
, bourrent les champs à un multiple de 4 octets.
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.
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.
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
Nmap envoie 4 paquets sur un port TCP ouvert avec différents flags:
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.
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 ULENet vérifie
Don't Fragment
.Type Of Service
IPLEN
RIPTL
RIPCK
RID
UCK
ULEN
.DAT
PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
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.
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).
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.
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).
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).
Le checksum UDP peut être à zéro ou à une valeur incorrecte sur certains OS.
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.
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.
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
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:
Retries | Linux 2.2.14 | Linux 2.4 | Windows 98 | Win 2K | FreeBSD 4.4 |
1st | 3,5 | 4,26 | 3 | 3 | 3 |
2nd | 6,5 | 6 | 6 | 6 | 6 |
3rd | 12,5 | 12 | 12 | No more retries | 12 |
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 | ||||
8th | No more retries |
Cette technique est très intéressante lorsqu'un firewall protége un serveur et que seul un port TCP est accessible.