Scapy 3 way handshake
Creating a 3 Way Handshake
Cooked vs. Raw sockets
 
Normally, the Linux kernel takes care of setting up and sending and receiving network traffic. It automatically sets appropriate header values and even knows how to complete a TCP 3 way handshake. Uising the kernel services in this way is using a "cooked" socket.
 
Scapy does not use these kernel services. It creates a "raw" socket. The entire TCP/IP stack of the OS is circumvented. Because of this, Scapy give us compete control over the traffic. Traffic to and from Scapy will not be filtered by iptables. Also, we will have to take care of the TCP 3 way handshake ourselves.
 
Sending a TCP SYN
 
We send on the wireshark or tcpdump capture following packets:
- SYN (outgoing)
- SYN ACK(incomming)
- RST/ACK (outgonig)
 
The RST Packet is from the Kernel, because no listen Port on the Source Port. (Scapy is not unsing RAW Socket)
 
iptables to supress the RST
 
	iptables -A OUTPUT -p tcp --tcp-flags RST RST -s {our IP} -d {dest IP} -dport {source port} -j DROP
	iptables -A OUTPUT -s {our IP} -d {dest IP} -p ICMP --icmp-type port-unreachable -j DROP
Replace {our IP} / {dest IP} and {source port} with your parameters
 
TCP 3 Way Basics
 
s_ip = IP ; s_port = port ; s_seq = seq # ; s_ack = ack #
d_ip = IP ; d_port = port ; d_seq = seq # ; d_ack = ack #
 
handshake
s_ip:s_port -> d_ip:d_port, SYN, s_seq, s_ack
d:ip:d_port -> s_ip:s_port, SYN/ACK, d_seq, d_ack=(s_seq + 1)
s_ip:s_port -> d_ip:d_port, ACK, d_seq + 1, s_ack=(d_seq + 1)
 
Sample Script
 
#!/usr/bin/python
from scapy.all import *

ip=IP(src="10.0.0.1", dst="20.0.0.2")
TCP_SYN=TCP(sport=1500, dport=80, flags="S", seq=100)
TCP_SYNACK=sr1(ip/TCP_SYN)

my_ack = TCP_SYNACK.seq + 1
TCP_ACK=TCP(sport=1500, dport=80, flags="A", seq=101, ack=my_ack)
send(ip/TCP_ACK)

my_payload="space for rent!"
TCP_PUSH=TCP(sport=1500, dport=80, flags="PA", seq=102, ack=my_ack)
send(ip/TCP_PUSH/my_payload)

(c) 2009 by packetlevel.ch / last update: 21.01.2010