======Connexion à un serveur TCP/IP avec Scapy (Bonus) ======
Le but de cet exercice est d'ouvrir une connexion TCP/IP vers un serveur SSH (port 22) en effectuant la traditionnelle poignée de main avec Scapy. Pour établir la connexion TCP/IP avec Scapy vers le serveur SSH, il faut réaliser la traditionnelle poignée de main TCP en trois étapes (envoi de SYN -> réception de SYN-ACK -> envoi de ACK). Toutes les machines du réseau virtuel dispose d'un serveur SSH.
* Sur une machine cliente, par exemple //immortal// :
- utilisez cette commande : iptables -A OUTPUT -p tcp --tcp-flags ALL RST -j DROP
- puis lancez Scapy.
* Complétez le programme ci-dessous en respectant les étapes suivantes :
- envoi du paquet SYN avec notamment les champs TCP sport=7777, dport=22, flags="S" et seq=0.
- réception du paquet SYNACK...
- envoi du paquet ACK avec les champs TCP flags="A", seq=SYNACK.ack, ack=SYNACK.seq+1, ...
- réception du message MSG envoyé par le serveur, qui doit contenir du texte indiquant la version du serveur OpenSSH, enfin si tout marche bien !
SYN = IP(???)/TCP(???)
SYNACK = sr1(SYN)
ACK = IP(???)/TCP(???)
MSG = sr1(ACK)
print MSG.load
__Attention__ : Il faut effectuer ces commandes rapidement pour éviter un "timeout" du serveur (sinon, le mieux est d'utiliser une fonction Python) ! De plus, pour effectuer plusieurs tests consécutifs, il faut changer à chaque fois le numéro du port source TCP (sport=5467,...) car on ne ferme pas les connexions correctement !
Pour aller plus loin : http://packetlife.net/blog/2010/jun/7/understanding-tcp-sequence-acknowledgment-numbers/
#!/usr/bin/env python
import sys
from scapy import *
### Warning: Do not forget to firewall you host to prevent your kernel
### sending a RST when receiving a SYN ACK for a SYN it knows nothing
### about.
###
### iptables --table filter -A OUTPUT -p tcp --tcp-flags ALL RST --dport 13 -j DROP
###
### CONNECT ###
def connect(dst,dport):
print "Opening connection..."
seq = RandShort() * 1
sport = RandShort() * 1
print "dst = %s" % dst
print "seq = %s" % seq
print "sport = %s" % sport
print "dport = %s" % dport
# SYN
a = IP(dst=dst)/TCP(sport=sport,dport=dport,seq=seq,flags="S")
# SYN/ACK
b = sr1(a,verbose=0)
# ACK
c = IP(dst=dst)/TCP(sport=sport,dport=dport,seq=b.ack,ack=b.seq+1,flags="A")
d = sr1(c,verbose=0)
return d
### CLOSE ###
def close(f):
print "Closing connection..."
# FIN/ACK
g = IP(dst=dst)/TCP(sport=sport,dport=dport,seq=f.ack,ack=f.seq+1,flags="FA")
# FIN/ACK
h = sr1(g,verbose=0)
return
# Après la fermeture, la connexion est dans un état TIME_WAIT... et il
# faut attendre un peu pour que la fermeture soit effective. C'est
# pourquoi on ne peut pas réutiliser immédiatement le même numéro de
# port source.
##################### TEST #####################
dport = 13
dst = "192.168.0.1"
# connect
d = connect(dst,dport)
print d.load
# ack
e = IP(dst=dst)/TCP(sport=sport,dport=dport,seq=d.ack,ack=d.seq+len(d.load),flags="A")
f = sr1(e,verbose=0)
# close
close(f)