Manipulez Les Paquets Reseau Avec Scapy
Manipulez Les Paquets Reseau Avec Scapy
Manipulez Les Paquets Reseau Avec Scapy
Par FireZro
www.siteduzero.com
2/24
Sommaire
Sommaire ........................................................................................................................................... 2 Lire aussi ............................................................................................................................................ 1 Manipulez les paquets rseau avec Scapy ........................................................................................ 3
Installation et utilisation ..................................................................................................................................................... 3
Installation ................................................................................................................................................................................................................... 3 Utilisation ..................................................................................................................................................................................................................... 4
Q.C.M. ............................................................................................................................................................................. 22
Partager ..................................................................................................................................................................................................................... 23
www.siteduzero.com
Sommaire
3/24
Par
FireZro
212 visites depuis 7 jours, class 423/797 Scapy est un module pour Python permettant de forger, envoyer, rceptionner et manipuler des paquets rseau. Si le rseau vous intresse et que vous aimeriez mieux comprendre le fonctionnement des outils traditionnels (wireshark, dig, ping, traceroute, nmap...), alors ce tutoriel est fait pour vous ! La comprhension de ce tutoriel ncessite quelques prrequis : Des connaissances en Python (grosso modo les parties 1 et 2 du tutoriel officiel) Des connaissances de base en rseau (je vous conseille la lecture du tutoriel de elalitte) A l'issue de ce tutoriel, vous devriez tre en mesure de programmer par vous mme des utilitaires simples, et surtout de comprendre leur fonctionnement. Allez, l'assaut ! Sommaire du tutoriel :
Installation et utilisation Manipulation de paquets Les listes de paquets La fonction sniff() Import et export des rsultats Q.C.M.
Installation et utilisation
Profitant de la portabilit du langage Python, Scapy est multi-plateforme. Cela dit, je ne dtaillerai ici son installation et son utilisation que sous Linux, ne possdant que cet OS lors de l'criture de ce tutoriel. La procdure d'installation est dcrite ici pour Mac OS X et ici pour Windows. Par facilit, vous pouvez galement prfrer installer GNU/Linux en machine virtuelle.
Installation
Depuis les dpts de votre distribution
Pour les presss, l'installation minimale se fait avec la commande suivante : Code : Console $ sudo apt-get install python-scapy
Scapy ne fonctionne qu'avec la branche 2.x de Python (>= 2.5), la dernire version de cette branche tant Python 2.7. De plus, vous pouvez tendre les possibilits de Scapy (rapports pdf, traceroute 3D...) grce d'autres paquets. Pour une distribution base de Debian, l'installation complte se fait donc par cette ligne de commande :
www.siteduzero.com
4/24
Depuis Mercurial
Si vous souhaitez disposer de la toute dernire version de Scapy, vous pouvez l'installer depuis les sources en les rcuprant depuis le dpt mercurial. Si ce n'est pas dj fait, installez mercurial : Code : Console $ sudo apt-get install mercurial
Rcuprez les sources et installez Scapy : Code : Console $ hg clone http://hg.secdev.org/scapy $ cd scapy $ sudo python setup.py install
Scapy est maintenant install, c'est bien beau, mais passons son utilisation.
Utilisation
Depuis l'interprteur
Rien de plus simple, lancez la commande suivante : Code : Console $ sudo scapy
Scapy manipule des paquets rseaux, ce qui ncessite d'tre en root pour une majorit de tches
Si tout se passe bien, vous vous retrouvez devant l'interprteur python : Code : Console WARNING: No route found for IPv6 destination :: (no default route?) Welcome to Scapy (2.1.0) >>>
www.siteduzero.com
5/24
Aucun. Forger un paquet dsigne le fait de le construire en mettant les "mains dans le cambouis". Je m'explique. D'ordinaire, quand vous utilisez un logiciel orient rseau tel qu'un navigateur web, un logiciel de messagerie, etc, celui-ci change des paquets. Par exemple, votre navigateur, quand vous vous rendez sur http://www.siteduzero.com, change des paquets avec le serveur web du Site du Zro. Pour simplifier cet change, on peut dire que votre navigateur envoie un paquet "envoie moi cette page web s'il te plat", et que le serveur du Site du Zro lui renvoie le paquet "tiens, la voici : <html>Coucou</html>" (ne m'en veuillez pas pour cet exemple ). Si vous dcidez de programmer un tel logiciel, en pratique, vous n'aurez pas vous soucier du dtail de cette conversation par paquets. Par exemple, en C++, l'aide de la bibliothque Qt, afficher une page web se fait ainsi : Code : C++ QWebView *pageWeb = new QWebView; pageWeb->load(QUrl("http://www.siteduzero.com/"));
Comme vous le voyez, aucune connaissance en rseau n'est ncessaire pour raliser une telle chose, car on n'a pas rellement mis les mains dans le cambouis. Or, nous, ce qui nous intresse, avec Scapy, c'est de comprendre le dtail de ces mystrieuses conversations...
L'change de paquets avec un serveur web est loin d'tre simple, elle fait intervenir le protocole HTTP, le handshake TCP, l'entte IP, bref, nous allons rester plus basique. Commenons donc par crer et afficher une trame thernet dans l'interprteur Scapy : Code : Python >>> ma_trame = Ether() >>> ma_trame.show()
www.siteduzero.com
6/24
Comme on le voit, la cration d'une trame thernet se fait en instanciant la classe Ether(). Bien qu'on ne lui ai fournit aucun paramtre, on constate a l'appel de la mthode show() que les attributs dst, src et type ont des valeurs par dfaut. Que reprsentent ces diffrents attributs ?
Pour ceux qui ne connaitraient pas le protocole thernet, voici la structure qu'une trame thernet doit prsenter :
Nous venons de crer une trame thernet "pure", c'est dire qu'on a rien dans data. Le CRC permet le contrle d'intgrit de notre trame : si on le modifiait, notre trame deviendrait invalide et inutile. Il ne nous reste donc que 3 champs modifiables : dst : reprsente l'adresse mac du destinataire src : reprsente l'adresse mac de l'metteur type : reprsente le type de protocole (dpend du contenu de la partie "data" pour l'instant vide) Pour les modifier, c'est trs simple : Code : Python >>> ma_trame.dst = '00:19:4b:10:38:79' >>> ma_trame.show() ###[ Ethernet ]### dst= 00:19:4b:10:38:79 src= 00:00:00:00:00:00 type= 0x0 >>>
On aurait pu prciser l'adresse mac du destinataire lors de la cration de la trame : Code : Python >>> ma_trame = Ether(dst='00:19:4b:10:38:79')
Les attributs dst, src et type sont modifiables votre guise. Cela veut donc dire que vous pouvez facilement envoyer des trames en faisant croire que l'metteur est quelqu'un d'autre ! Les envoyer ? Non, je ne sais pas faire ...
Envoi de la trame
www.siteduzero.com
7/24
V oil, mon paquet a bien t envoy la machine dont j'avais prcis l'adresse mac. Gnial ! .. C'est tout ?
Je vous vois bien du. Ce que nous venons de faire ne prsentait gure d'intrt, je vous l'accorde. En effet, une trame thernet pure ne sert pratiquement rien ; pour pouvoir faire quelque chose d'intressant, il faudrait donc mettre quelque chose dans le "data" vu plus haut... Nous allons donc faire de l'encapsulation.
Encapsulons !
Citation : Wikipdia L'encapsulation, en informatique et spcifiquement pour les rseaux informatiques, est un procd consistant inclure les donnes d'un protocole dans un autre protocole.
On voit que par dfaut, l'instanciation de la classe ICMP() met le type du ping echo-request. On pourrait tout fait le modifier, tout comme les autres champs. Pour savoir ce qu'ils reprsentent, je vous renvoie l'article ICMP sur Wikipdia. Dans cet article, on peut notamment lire quelque chose d'intressant : un paquet ICMP est encapsul dans un datagramme IP. En effet, c'est dans le datagramme IP qu'on va pouvoir renseigner l'adresse IP du destinataire. L'encapsulation entre protocoles, dans Scapy, est ralise par l'oprateur / (slash). Rien voir avec une division, donc Code : Python .
www.siteduzero.com
8/24
>>> mon_ping = Ether() / IP(dst='192.168.1.1') / ICMP() >>> mon_ping.show() ###[ Ethernet ]### dst= 00:19:4b:10:38:79 src= 00:26:5e:17:00:6e type= 0x800 ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0 ttl= 64 proto= icmp chksum= None src= 192.168.1.14 dst= 192.168.1.1 \options\ ###[ ICMP ]### type= echo-request code= 0 chksum= None id= 0x0 seq= 0x0 >>>
On constate que, en prcisant simplement l'adresse IP du destinataire, Scapy a compris tout seul qu'il devait modifier les attributs dst, src et type de Ether() ainsi que l'adresse IP de l'metteur (src dans IP()) ! C'est trs pratique, mais videmment nous aurions pu forcer Scapy mettre les valeurs que l'on voulait.
V oyons maintenant si 192.168.1.1 (ma Livebox) va rpondre cela par un paquet ICMP echo-reply.
Envoi du paquet
L'envoi s'effectue comme auparavant : Code : Python >>> sendp(mon_ping) . Sent 1 packets. >>>
Oui et non ! Oui, car la fonction sendp() ne fait qu'envoyer, c'est vrai. Pour envoyer et recevoir, il faut utiliser les fonctions srp() et srp1(). Non, car dans le cas d'une trame thernet pure, srp() et srp1() n'auraient de toute faon rien reu ! srp() renvoie deux objets : le premier contient les paquets mis et leurs rponses associes, l'autre contient les paquets sans rponse. Code : Python
www.siteduzero.com
9/24
On voit qu'on a eu une rponse, zro checs, et que notre rponse est un paquet ICMP ! Examinons-le : Code : Python >>> rep.show() 0000 Ether / IP / ICMP 192.168.1.14 > 192.168.1.1 echo-request 0 ==> Ether / IP / ICMP 192.168.1.1 > 192.168.1.14 echo-reply 0 >>>
Bingo, on a bien reu un ICMP echo-reply ! rep contient en ralit une liste de couples de paquets. En l'occurence, la liste ne contient qu'un seul couple de paquets, qu'on peut afficher ainsi comme on afficherai n'importe quel lment d'une liste en Python : Code : Python >>> rep[0] (<Ether type=0x800 |<IP frag=0 proto=icmp dst=192.168.1.1 |<ICMP |>>>, <Ether dst=00:26:5e:17:00:6e src=00:19:4b:10:38:79 type=0x800 |<IP version=4L ihl=5L tos=0x0 len=28 id=58681 flags= frag=0L ttl=64 proto=icmp chksum=0x1248 src=192.168.1.1 dst=192.168.1.14 options=[] |<ICMP type=echo-reply code=0 chksum=0xffff id=0x0 seq=0x0 |>>>) >>>
Le rsultat est un couple (tuple deux valeurs). Pour afficher le paquet mis (notre ICMP echo-request), on fera donc rep[0][0].show(), et pour le paquet reu en rponse, rep[0][1].show() : Secret (cliquez pour afficher) Code : Python >>> rep[0][0].show() ###[ Ethernet ]### dst= 00:19:4b:10:38:79 src= 00:26:5e:17:00:6e type= 0x800 ###[ IP ]### version= 4 ihl= None tos= 0x0 len= None id= 1 flags= frag= 0
www.siteduzero.com
10/24
Pour simplifier tout cela, on peut prfrer ici la fonction srp1(). Cette fonction renvoie renvoie un seul objet : la premire rponse. Code : Python >>> rep = srp1(mon_ping) Begin emission: Finished to send 1 packets. * Received 1 packets, got 1 answers, remaining 0 packets >>> rep.show() ###[ Ethernet ]### dst= 00:26:5e:17:00:6e src= 00:19:4b:10:38:79 type= 0x800 ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 28 id= 3386 flags= frag= 0L ttl= 64 proto= icmp chksum= 0xea47 src= 192.168.1.1
www.siteduzero.com
11/24
Enfin, souvent galement, on ne s'intressera pas la partie thernet qui est de toute faon trs bien remplie de faon automatique par Scapy. Il existe donc des fonctions send(), sr() et sr1() quivalentes sendp(), srp() et srp1() mis part le fait qu'elles se chargent toutes seules d'ajouter l'en-tte thernet. Un exemple : Code : Python >>> rep = sr1(IP(dst='192.168.1.1') / ICMP()) Begin emission: Finished to send 1 packets. * Received 1 packets, got 1 answers, remaining 0 packets >>> rep.show() ###[ IP ]### version= 4L ihl= 5L tos= 0x0 len= 28 id= 3389 flags= frag= 0L ttl= 64 proto= icmp chksum= 0xea44 src= 192.168.1.1 dst= 192.168.1.14 \options\ ###[ ICMP ]### type= echo-reply code= 0 chksum= 0xffff id= 0x0 seq= 0x0 >>>
Quand on procde ainsi, on voit que mme dans la rponse, l'en-tte thernet n'apparat plus.
Essayons la mme chose sur un hte non existant : Code : Python >>> rep = sr1(IP(dst='192.168.1.2') / ICMP()) Begin emission: .WARNING: Mac address to reach destination not found. Using broadcast. Finished to send 1 packets. .....................^C Received 22 packets, got 0 answers, remaining 1 packets >>>
www.siteduzero.com
12/24
J'ai arrt manuellement (Ctrl-C) l'envoi au bout de 30 secondes. A l'issue de ce temps, la variable rep est vide : rien n'a t renvoy, comme le laissait deviner le "got 0 answers". On peut rajouter une limite de temps (en secondes) sr1() pour ne pas rester bloqu, grce au paramtre timeout. Code : Python >>> rep = sr1(IP(dst='192.168.1.2') / ICMP(), timeout=0.5) Begin emission: WARNING: Mac address to reach destination not found. Using broadcast. Finished to send 1 packets. Received 0 packets, got 0 answers, remaining 1 packets >>>
Pour voir les autres paramtres que peut prendre sr1(), faites help(sr1) Je vous encourage faire de mme pour sr() et send()
Pour savoir que le champ type d'ICMP valait 0 dans le cas de l'echo-reply, vous pouviez vous renseigner sur la page Wikipdia vue plus tt, ou faire ls(mon_ping) avec mon_ping de type echo-reply. ls(un_paquet) affiche en effet les attributs du paquet de manire numrique, et affiche galement leur nom, leur type et leur valeur par dfaut (entre parenthses) : Code : Python >>> ls(IP(dst='192.168.1.1') / ICMP(type='echo-reply')) version : BitField = 4 (4) ihl : BitField = None (None) tos : XByteField = 0 (0) len : ShortField = None (None) id : ShortField = 1 (1) flags : FlagsField = 0 (0) frag : BitField = 0 (0)
www.siteduzero.com
13/24
Liste simple
Prenons un cas concret : nous voulons savoir si un serveur web est accessible en http et en https. Nous pourrions tenter un scan des ports correspondant par dfaut : 80 et 443. Plutt que d'envoyer/recevoir deux fois en changeant simplement le port, nous allons utiliser une liste simple sur le port de destination en mettant : Code : Python dport=[80,443]
Je vais utiliser ici un scan SYN : pour ceux qui ne connaitraient pas, le principe est simple : j'envoie un paquet TCP sur le port dsir de la cible avec le flag SYN. Si son port accepte les connexions, il me renverra un paquet TCP avec les flags SYN et ACK.
Code : Python >>> ls(TCP) sport : dport : seq : ack : dataofs : reserved : flags : window : chksum : urgptr : options :
ShortEnumField ShortEnumField IntField IntField BitField BitField FlagsField ShortField XShortField ShortField TCPOptionsField
= = = = = = = = = = =
(20) (80) (0) (0) (None) (0) (2) (8192) (None) (0) ({})
www.siteduzero.com
14/24
Lors de la cration de mon_paquet, je prcise le port source, le port de destination et je positionne le flag SYN. J'envoie ce paquet (qui en ralit reprsente deux paquets), comme d'habitude, avec sr(). Le rsultat est compos des deux couples paquet mis / paquet reu. Le premier paquet reu correspond celui envoy sur le port 80. Les flags positionns sont bien SYN et ACK (SA) : le port est ouvert. Le second paquet reu correspond celui envoy sur le port 443. Les flags ne sont pas SYN et ACK mais RESET et ACK : le port est ferm.
Les rponses des htes aux paquets TCP peuvent parfois diffrer trs lgrement en fonction du systme d'exploitation. Par exemple, dans ce cas ci, je reois des paquets avec bourrage (padding), tandis qu'en envoyant les mme paquets sur ma Livebox, il n'y en a pas. Ces diffrences de comportement peuvent tre trs pratique pour savoir quel systme d'exploitation on a faire : on parle alors d'OS fingerprinting.
Rang
Et si la place de dport=[80,443], j'avais crit dport=(80,443) ? (des parenthses au lieu des crochets) Eh bien il n'y aurait pas eu 2 paquets d'envoys, mais 364 : un pour chaque port de 80 443. Code : Python
>>> mon_paquet = IP(dst='192.168.1.10') / TCP(sport=12345, dport=(80,443), flags='S' >>> rep,non_rep = sr(mon_paquet) Begin emission: .************************************************************************************** to send 364 packets. * Received 365 packets, got 364 answers, remaining 0 packets >>>
Et si on dsire afficher ceux ouverts : Code : Python >>> for emis,recu in rep : ... if recu[1].flags==18 : # 18 <=> SYN+ACK ... print 'port ouvert : ', recu[1].sport ... port ouvert : 80 port ouvert : 111 >>>
www.siteduzero.com
15/24
Prcisions : L'adresse IP de destination, '209.85.143.100', est celle d'un des nombreux datacenter de Google. J'encapsule dans mon paquet IP du TCP mais je pourrais y mettre de l'ICMP, de l'UDP, ou mme rien, mais les firewall des routeurs sur le chemin risqueraient de ne pas laisser passer certains protocoles. Je fais varier le ttl de 1 25, mais on voit qu'en pratique le datacenter est atteint au bout de 11 sauts seulement. Au passage, on peut voir que mes paquets traversent ma Livebox (routeur n1) et diffrents routeurs d'Orange et de Google.
La fonction sniff()
Nous savons maintenant envoyer et recevoir des paquets, mais pour progresser dans notre comprhension des outils rseau, il nous faudrait lire et dcortiquer leurs changes de paquets. Par exemple : comment procde rellement la commande ping ? Comment procde nmap pour scanner un port ? Comment procde firefox pour rcuprer http://www.siteduzero.com/index.html ?
Prsentation
V oil une simplification de la signature de cette fonction : Code : Python
www.siteduzero.com
16/24
Elle renvoie une liste de paquets (en comparaison, sr() renvoie deux listes de paquets). Ses paramtres sont : count : nombre de paquets capturer. 0 : pas de limite. timeout : stoppe le sniff aprs un temps donn. iface : dsigne l'interface sur laquelle sniffer. La liste de vos interfaces est donne par la commande ifconfig. filter : filtre les paquets garder d'aprs une chane de caractre. Exemple : filter="port 80" filtre les paquets ayant un lien avec le port 80. lfilter : mme chose, mais utilise une fonction plutt qu'une chane. Exemple : lfilter=lambda x: x[1].src=='192.168.1.14' filtre les paquets mis par 192.168.1.14. prn :fonction appliquer chaque paquet. Si la fonction retourne quelque chose, cela s'affiche. Exemple : prn = lambda x: x.show() va afficher le dtail de chaque paquet.
filter utilise un filtre BPF. Le filtre "(port 80 or port 443) and dst host 192.168.1.14" va slectionner les paquets envoys (dst) moi-mme (host 192.168.1.14) et qui ont un rapport avec les ports http ou https (port 80 or port 443).
Maintenant que les prsentations sont faites, passons l'tape suivante : explorons le rseau !
Utilisation
Que fait ping ?
Je lance mon sniff en filtrant sur la cible du ping, 192.168.1.10 : Code : Python >>> rep = sniff(filter="host 192.168.1.10")
Je vais voir les paquets sniffs : Code : Python >>> rep.show() 0000 Ether / IP / ICMP 192.168.1.14 > 192.168.1.10 echo-request 0 / Raw 0001 Ether / IP / ICMP 192.168.1.10 > 192.168.1.14 echo-reply 0 / Raw >>>
www.siteduzero.com
17/24
RAW dsigne le payload, les donnes encapsules dans les multiples en-ttes de notre paquet. Lorsque l'on tlcharge un gros fichier, par exemple, celui ci est dcoups en petits paquets, et pour le reconstituer la fin, on doit rassembler tous les RAW.
Code : Python
>>> rep[0].show() ###[ Ethernet ]### .... blabla .... ###[ Raw ]### load= 'B\xdd\xa5N\x14\xf7\x02\x00\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x !"#$%&\'()*+,-./01234567' >>>
. Visiblement, rien de trs pertinent ! Plus srieusement, cette suite trange de caractre peut permettre au destinataire de savoir qu'il a t la cible d'un ping effectu par la commande ping de Linux.
Les paquets sniffs sont alors : Code : Python >>> rep.show() 0000 Ether / ARP who has 192.168.1.10 says 192.168.1.14 0001 Ether / ARP is at 00:16:17:e3:ed:88 says 192.168.1.10 / Padding 0002 Ether / IP / TCP 192.168.1.14:50662 > 192.168.1.10:www S 0003 Ether / IP / TCP 192.168.1.10:www > 192.168.1.14:50662 SA / Padding 0004 Ether / IP / TCP 192.168.1.14:50662 > 192.168.1.10:www R >>>
Pour rappel, dans notre version du scan SYN, nous n'avions que les paquets avec les flags S et SA d'changs. Mais en ralit, des paquets ARP taient galement changs : ceux cis servent dterminer l'adresse mac de la cible. Eh oui, on s'conomise depuis longtemps l'encapsulation dans Ether(), mais Scapy le fait pour nous, et il a besoin de certaines informations. Quand au paquet RESET (R), nous ne nous en rendions pas compte, mais il tait galement envoy ! En effet, le noyau Linux voyait arriver un paquet SYN + ACK sans deviner que Scapy l'avait demand. Le noyau envoyait donc un paquet RESET pour fermer cette connection qu'il pensait inexistante. On peut empcher cet envoi de RESET par la commande $ sudo iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP . Finalement donc, nmap a fait comme nous !
www.siteduzero.com
18/24
Outch !
Les paquets 0 et 1 sont deux paquets DNS : l'mis et le reu. Il permettent firefox de connatre l'adresse IP de lalitte.com Les paquets 2,3 et 4 reprsentent le handshake TCP qui se fait entre firefox et le serveur web de lalitte.com. A l'issue de ce handshake, si tout s'est bien pass (ce qui se voit grce aux flags S / SA / A), le dialogue peut rellement commencer. Le paquet 5 est la requte HTTP mise par firefox. La preuve : Secret (cliquez pour afficher) Code : Python >>> r[5].show() ###[ Ethernet ]### dst= 00:19:4b:10:38:79 src= 00:26:5e:17:00:6e type= 0x800 ###[ IP ]###
www.siteduzero.com
19/24
version= 4L ihl= 5L tos= 0x0 len= 458 id= 46027 flags= DF frag= 0L ttl= 64 proto= tcp chksum= 0xe3ad src= 192.168.1.14 dst= 88.191.135.63 \options\ ###[ TCP ]### sport= 36578 dport= www seq= 1719662898 ack= 4036772261L dataofs= 8L reserved= 0L flags= PA window= 229 chksum= 0xb742 urgptr= 0 options= [('NOP', None), ('NOP', None), ('Timestamp', (10767110, 506925378))] ###[ Raw ]### load= 'GET /anciensite/double.html HTTP/1.1\r\nHost: lalitte.com\r\nUser-Agent: Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAcceptLanguage: fr-fr,en-us;q=0.7,en;q=0.3\r\nAccept-Encoding: gzip, deflate\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\n\r\n' >>>
Les paquets 7 18 reprsentent la rception de la page web par paquets. firefox envoie un accus de rception (ACK) pour chaque paquet de donne reu.
Je vous laisse trouver. Rponse : Secret (cliquez pour afficher) firefox recommence toute la manip' prcdente avec le site www.free-easy-counters.com, qui est un compteur de visiteurs pour sites web. En effet, la page que j'ai charge contient un compteur de visite
Je n'ai fait que survoler les rsultats de ce sniff ! vous d'approfondir et de comprendre comment forger vos propres requtes DNS, ou comment les attributs ack et seq des en-ttes IP voluent au fil des paquets quand ceux-cis sont fragments, par exemple...
www.siteduzero.com
20/24
Sauvegarder
Pour sauvegarder p (qui peut tre un unique paquet tout comme une liste de paquets) dans le fichier p.pcap, il faut utiliser la fonction wrpcap() (write pcap) : Code : Python >>> wrpcap('p.pcap', p)
Charger
Inversement, ici, il faut utiliser la fonction rdpcap() (read pcap) : Code : Python >>> p = rdpcap('p.pcap')
hexdump et pdfdump
p est le paquet suivant : Code : Python >>> p <Ether dst=00:19:4b:10:38:79 src=00:26:5e:17:00:6e type=0x800 |<IP version=4L ihl=5L tos=0x0 len=64 id=37095 flags=DF frag=0L ttl=64 proto=udp chksum=0x2666 src=192.168.1.14 dst=192.168.1.1 options=[] |<UDP sport=38897 dport=domain len=44 chksum=0x65a |<DNS id=28184 qr=0L opcode=QUERY aa=0L tc=0L rd=1L ra=0L z=0L rcode=ok qdcount=1 ancount=0 nscount=0 arcount=0 qd=<DNSQR qname='www.siteduzero.com.' qtype=A qclass=IN |> an=None ns=None ar=None |>>>>
V ous aurez peut tre reconnu une requte DNS demandant l'adresse IP du Site du Zro.
hexdump
La fonction hexdump() donne une reprsentation hexadcimale du paquet (ainsi qu'une reprsentation ASCII) et s'utilise ainsi : Code : Python >>> hexdump(p) 0000 00 19 4B 10 ..K.8y.&^..n..E. 0010 00 40 90 E7 .@..@.@.&f...... 0020 01 01 97 F1 .....5.,.Zn..... 0030 00 00 00 00
38 79 00 26 40 00 40 11 00 35 00 2C 00 00 03 77
5E 17 00 6E 08 00 45 00 26 66 C0 A8 01 0E C0 A8 06 5A 6E 18 01 00 00 01 77 77 0A 73 69 74 65 64
www.siteduzero.com
21/24
Nous voyons l quoi ressemble concrtement un paquet rseau, aux yeux de l'ordinateur !
pdfdump
Encore plus fort, il est possible d'avoir la fois la reprsentation aux yeux de l'ordinateur et aux yeux d'uun humain dans un mme fichier .pdf ! Pour cela, il vous faudra le paquet python-pyx install. Code : Python >>> p.pdfdump('p.pdf')
V oici le rsultat :
www.siteduzero.com
22/24
Comme vous le voyez, les paquets un peu longs et un peu trop embriqus son got sont simplifis, et toute l'information n'est pas affiche. Cela dit, c'est dj assez brouillon comme cela !
Q.C.M.
Le premier QCM de ce cours vous est offert en libre accs. Pour accder aux suivants Connectez-vous Inscrivez-vous Quelle est la diffrence entre les fonctions send() et sendp() ?
Aucune send() permet d'envoyer ET de recevoir send() se charge de l'ajout de l'en-tte thernet sendp() n'envoie que les trames thernet pures
Quel code ne fonctionnera pas pour recevoir et afficher un paquet ICMP echo-reply de la part de 192.168.1.1 ?
rep = sr1(IP(dst='192.168.1.1') / ICM P(), timeout=0.5)
www.siteduzero.com
23/24
Comment dois-je procder si je dsire faire un scan SYN sur tous les ports de 192.168.1.1 (des ports 0 65535) ?
dport=[0,65535] dport=(0,65535) dport='0-65535' Il faut obligatoirement passer par une boucle qui incrmente le port et envoie un paquet.
Plus difficile : comment devons nous appeler la fonction sniff() pour qu'elle rcupre les paquets TCP avec les flags SYN + ACK, destination de moi-mme (adresse IP 192.168.1.14) ?
r = sniff(filter="tcp and dst host 192.168.1.14",lfilter=lambda x: x[2].flags==18) r = sniff(filter="tcp and dst host 192.168.1.14",lfilter=lambda x: x[2].flags==24)
Correction !
Statistiques de rponses au Q CM
Ce tutoriel s'achve, et j'espre qu'il aura attis votre curiosit et vous aura permis de comprendre les mcanismes qui se cachent derrire les outils rseaux traditionnels V ous pouvez videmment approfondir vos connaissances grce la documentation officielle (en anglais), ou par la dcouverte d'autres protocoles (je vous laisse dcouvrir tous les protocoles que gre scapy : tapez la commande ls() dans l'interprteur )
Partager
www.siteduzero.com