Sunday, August 26, 2018

TCP open connection with scapy

Today, I am going to try to create TCP 3-way connection with the help of scapy and iperf.  The full wireshark capture is
TCP 3-way Connection

192.168.1.10 (client: port 40508: scapy) ------->> 192.168.1.200 (server: port 5000: iperf)

As we donot have a conventional TCP client program running on the client side.  Whenever server sends SYN-ACK packet to client, the kernel on the client responds with Reset TCP connection.  To avoid this, we should place a rule in IPTables, to drop any Reset's packets initiated from client side.  This can be done using the following command on the client side:

# iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.10 -j DROP

On the server side, we create a server listening on port 5000, using 

# iperf -s -p 5000
------------------------------------------------------------
Server listening on TCP port 5000
TCP window size: 85.3 KByte (default)
------------------------------------------------------------

In another session, observe that the output of netstat command, its in listen state

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN

On the client side, we open scapy session, send a TCP SYN packet and receive the response.  sr1 implies send (ip/SYN) and wait till ONE response is received.


# scapy
INFO: Can't import python gnuplot wrapper . Won't be able to plot.
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
INFO: Can't import python Crypto lib. Won't be able to decrypt WEP.
INFO: Can't import python Crypto lib. Disabled certificate manipulation tools
Welcome to Scapy (2.2.0)
>>>
>>> ip=IP(src="192.168.1.10",dst="192.168.1.200")
>>> SYN=TCP(sport=40508,dport=5000,flags="S",seq=0)
>>> SYNACK=sr1(ip/SYN)
Begin emission:
.......Finished to send 1 packets.
.*
Received 9 packets, got 1 answers, remaining 0 packets

Netstat on the server side, the state would have been

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.200:5000      192.168.1.10:40508      SYN_RECV

Now, on the client, we create and send the 3rd handshake message ACK to complete the TCP connection. This has to be sent as quick as possible, because there is a chance that the server may have timed out and dropped the TCP connection.

>>> ACK=TCP(sport=40508,dport=5000,flags="A",seq=SYNACK.ack+1,ack=SYNACK.seq+1)
>>> send(ip/ACK)
.
Sent 1 packets.

Netstat shows that the TCP connection is established.

# netstat -na | grep 5000
tcp        0      0 0.0.0.0:5000            0.0.0.0:*               LISTEN
tcp        0      0 192.168.1.200:5000      192.168.1.10:40508      ESTABLISHED