======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)