Cours Scapy
Cours Scapy
Cours Scapy
P-F. Bonnefoi
Version du 16 janvier 2013
5
6
7
8
9
10
16
17
18
19
20
21
22
23
24
25
26
27
28
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
57
58
59
61
62
63
65
66
73
75
76
77
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).
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.
. 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).
? leur enchanement :
un schma peut tre ralis suivant des temps plus ou moins long et peut, ainsi, sentrelacer
? 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.
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
10
? etc.
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
External
Network
External
Network
Router
Hub
Collision Domain
Router
Switch
Hub
Collision Domain
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
. le port mirroring :
11/14/06
9:27 AM
Page 28
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
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
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).
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
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
. 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
# ping -c 1 -b 172.16.0.255
Certains switch protgent lassociation entre une @MAC et un port la premire adresse reue.
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).
? 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).
65
Comment
viter
dtre dcouvert
Figure 2.16 One-Way
Data Cable
15
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.
rponses ARP.
ff:ff:00:00:00:00.
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 denvoi de ces paquets et de rception des paquets rponses associs : cela
autorise la conception simplifie doutils efficaces ;
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
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.
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
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.
19
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 .
Pour avoir plus doptions, vous pouvez consulter la documentation du module trace de
Python.
20
$ 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
Pour pouvoir utiliser les fonctions Scapy dans un programme Python il faut importer la bibliothque Scapy :
1
#!/usr/bin/python
# coding= latin1
# 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).
nombre_de_personnes = 0
# variable de classe
self.name = name
self.age = age
Personne.nombre_de_personnes += 1
11
12
13
10
21
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 !
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
7
8
9
self._nom = indefini
self._nom = val
nom = property(fget = _getNom, fset = _setNom, doc = Nom)
p1 = Personne2()
10
11
12
Complments :
Python intgre un garbage collector ou ramasse miettes,
il est possible de faire de lhritage multiple.
Pour accder une mthode danctre : ancetre.__init__().
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)
def ma_fonction():
pass
> help(ma_fonction)
Sur un objet, la fonction help, affiche lintgralit de laide disponible sur ses attributs (mthodes ou variables).
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).
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]
return x = x + 3
print liste_transformee
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
\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).
27
Il est trs utile de pouvoir examiner les possibilits offertes par chaque couche protocolaire
laide de la commande ls() :
> 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.
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)
...
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.
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
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\
>
> 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.).
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()
> p
<IP
Ici, des champs de la couche IP ont t surcharges , par celle de la couche suprieure
UDP.
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
> p.payload
<UDP
|>
> p[UDP].dport = 22
> p
<IP
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)
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.
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
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.
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
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>
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).
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>
35
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).
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
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
version=4L ihl=5L tos=0x0 len=40 id=1 flags= frag=0L ttl=64 proto=tcp chksum=0x14c4
<Ether
type=0x800 |<IP
sport=domain |<DNS
|<DNSQR
|>
37
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))
38
Attention
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
Les paquets de niveau 3 peuvent tre de type IP, ARP, ICMP, etc.
40
cible_mac = getmacbyip(cible)
sendp(p)
Du DNS spoofing :
1
# on va sniffer le rseau sur eth0 et ragir sur des paquets vers ou depuis le port 53
def procPacket(p):
eth_layer = p.getlayer(Ether)
ip_layer = p.getlayer(IP)
11
udp_layer = p.getlayer(UDP)
12
Ici, le paramtre filter est exprim dans la mme syntaxe que celle de loutil TCPdump. On
peut utiliser une lambda fonction Python la place.
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
15
d.arcount = 0
16
d.qd = str(dns_layer.qd)
18
19
21
22
23
scapy.sendp(spoofed, iface_hint=src_ip)
41
42
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
flags=SA |
> m.ttl=(10,13)
> m
<IP
flags=SA |
[<IP
dport=www flags=SA |,
<IP
dport=ssh flags=SA |,
<IP
dport=www flags=SA |,
<IP
dport=ssh flags=SA |,
<IP
dport=www flags=SA |,
<IP
dport=ssh flags=SA |,
<IP
dport=www flags=SA |,
<IP
dport=ssh flags=SA |]
43
#!/usr/bin/python
10
11
12
13
14
15
17
18
19
21
22
wrpcap("handshake.pcap", p_list)
44
45
a,b=sr(IP(dst="www.unilim.fr")/TCP(sport=[RandShort()]*100))
gp = Gnuplot.Gnuplot(persist=1)
gp.xlabel("Numero paquet")
gp.ylabel("ISN")
gp.plot(data)
10
gp.hardcopy(isn_distribution.ps)
2644000000
Envoi de SYN
2625392796
2642000000
2640000000
2644210715
2638000000
> gp.set_range(yrange,(2625392796,2644210715))
ISN
2636000000
2634000000
2632000000
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 = [
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).
http://www.bortzmeyer.org/5389.html
48
Ce qui donne :
1
name = "STUNPacket"
class STUN(Packet):
10
11
XIntField("MagicCookie", 0),
12
49
50
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. . .
51
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
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.
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
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
H
unsigned short, c--d sur 16 bits, cest la valeur par dfaut utilise par Scapy
B
Les fourberies de Scapy
I
unsigned int, c--d sur 32 bits
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"
4
5
6
7
8
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: .
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
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:].
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.
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
10
11
12
XIntField("MagicCookie", 0),
13
14
15
length_from=lambda x: x.Taille)]
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.
58
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 !
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
5
7
name = "MAPPED-ADDRESS"
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.
0x0002: "STUN_Attribut2",
...
0x8022: "STUN_Attribut7"
10
cls = Raw
11
if len(p) >= 2:
12
13
14
t = struct.unpack("!H", p[:2])[0]
15
16
cls = globals()[clsname]
18
60
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
Attention : cette approche ne pourrait pas fonctionner dans le cas de notre protocole STUN et
de ses extentions. . .
62
63
# http://trac.secdev.org/scapy/ticket/31
> execfile("mpls.py")
> p=Ether()/MPLS()/IP()
> p
# scapy.contrib.description = MPLS
# scapy.contrib.status = loads
<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
id= 1
18
bind_layers(MPLS, IP)
flags=
frag= 0
ttl= 64
proto= ip
chksum= None
src= 127.0.0.1
dst= 127.0.0.1
\options\
ff:ff:ff:ff:ff:ff
00:00:00:00:00:00
0x8847
MPLS
label
cos
s
ttl
3L
0L
1L
0
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
65
sendp(Ether()/IPv6()/ICMPv6ND_RA()/
ICMPv6NDOptPrefixInfo(prefix="2001:db8:cafe:deca::", prefixlen=64)
66
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
68
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
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.
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
-log-prefix : permet dajouter un prfixe pour faciliter la recherche (avec la commande grep par
exemple)
1
#!/usr/bin/python
3
4
6
7
8
9
10
11
12
13
14
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
71
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
pkt[TCP].window = throughput
del pkt[TCP].chksum
prot opt in
304K
tcp
16M NFQUEUE
out
source
bridge_dmz *
0.0.0.0/0
destination
0.0.0.0/0
[ ID] Interval
Transfer
Bandwidth
1.50 MBytes
1.20 Mbits/sec
3]
0.0-10.5 sec
[ ID] Interval
Transfer
Bandwidth
5.62 MBytes
4.65 Mbits/sec
3]
0.0-10.1 sec
[ ID] Interval
Transfer
Bandwidth
16.2 MBytes
13.6 Mbits/sec
3]
0.0-10.0 sec
[ ID] Interval
Transfer
Bandwidth
16.5 MBytes
13.8 Mbits/sec
3]
0.0-10.0 sec
72
20 Utilisation de dnsmasq
73
? 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
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
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
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
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
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. . .
met au container laccs au rseau au travers dun bridge Linux mais qui ne permet pas
lchange entre les containers eux-mmes ;
77
78