I think if you run the interface in promiscuous mode, this script will defend a whole network, answering every SYN no matter what IP address it is directed to.
In order to make this script practical, you will need to add code to stop responding to any IP address & port combination that you are actually using. Otherwise this script will DoS your own network.
This is your Target Machine.
Use this command to find your Target IP address:
ifconfig
Your Target IP address should be 172.16.1.202.
On the Target Machine, open a Terminal window. In the Terminal window, execute this command:
iptables -L
If you see a rule in the OUTPUT section that drops RST packets,
as shown below on this page, your firewall is correctly
configured. If the rule is not there, execute this command
to add it:
iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
scapy
sniff(count=1)
Scapy sniffs a packet and shows you a summary of what it captured,
as shown below on this page.
If the colors are difficult to see, adjust them by clicking Edit, "Profile Preferences", Colors. I used "Black on light yellow".
p = sniff(count=100)
nmap 172.16.1.202
The scan finds no open ports,
as shown below.
p
Scapy prints the summary line, showing how many packets were of each type,
as shown below on this page.
You should see a lot of TCP packets.
On the Target machine, in scapy, enter this command:
p[50:70].summary()
Scapy prints out a handy summary of 20 packets,
as shown below on this page.
On the left side of each line the OSI model layer protocols are shown.
Layer 2: Every segment starts with Ether because we are using an Ethernet network interface, so no other layer 2 protocol can be received. And, of course, no one is sending anything else onto your LAN these days anyway.
Layer 3: Most of the packets are IP, but you may see some ARP packets as well.
Layer 4: Here you will see more variety, including TCP, UDP, and ICMP.
Find a TCP packet. In the figure below, the first packet shown, p[50], is a TCP packet.
Look at the right side of the line summarizing your TCP packet. It shows "S / Padding". The S means it's a SYN packet. To proceed, you need to find a TCP SYN packet to examine.
If you don't have any TCP SYN packets, try looking at the next 20 packets with
p[70:90].summary()
If that fails, just repeat the capture process and run the Nmap scan again.
p[50]
p[50].dst
Explanation:
p[50]
shows the whole frame, with all the layers,
as shown below on this page.
p[50].dst
shows the layer 2 destination address, (a MAC address),
also shown below on this page.
You can separate the layers easily. Execute these commands, replacing [50] with the number of a TCP SYN packet that you captured:
p[50][Ether]
p[50][IP]
p[50][TCP]
Explanation:
p[50][Ether]
shows the layer 2 frame and its contents,
which include all higher layers,
as shown below on this page.
p[50][IP]
shows the layer 3 packet and its contents,
which include all higher layers,
as shown below on this page.
p[50][TCP]
shows the layer 4 segment,
as shown below on this page.
Now let's look at the values in the TCP segment.
Execute these commands, replacing [50] with the number of a TCP SYN packet that you captured:
p[50][TCP].dport
p[50][TCP].seq
p[50][TCP].flags
p[50][TCP].sprintf("%flags%")
Explanation:
p[50][TCP].dport
shows the TCP destination port of the
captured packet,
as shown below on this page.
p[50][TCP].seq
shows the TCP sequence number of the
captured packet,
as shown below on this page.
p[50][TCP].flags
should show the flags, but they
show up as 2L, because the "flags" field has a non-printable data type.
p[50][TCP].sprintf("%flags%")
prints the flags into a
string variable, which is now printable,
as shown below on this page. My packet was a SYN packet, so the value is 'S'.
In scapy, execute this command:
exit()
On the Target machine, in a Terminal window, execute this command:
nano yesman
In the nano window, type this script. Be careful to keep the indentation consistent -- whitespace matters in Python!
#!/usr/bin/env python
import sys
from scapy.all import *
def findSYN(p):
flags = p.sprintf("%TCP.flags%")
if flags == "S": # Only respond to SYN Packets
ip = p[IP] # Received IP Packet
tcp = p[TCP] # Received TCP Segment
i = IP() # Outgoing IP Packet
i.dst = ip.src
i.src = ip.dst
t = TCP() # Outgoing TCP Segment
t.flags = "SA"
t.dport = tcp.sport
t.sport = tcp.dport
t.seq = tcp.ack
new_ack = tcp.seq + 1
print "SYN/ACK sent to ",i.dst,":",t.dport
send(i/t)
sniff(prn=findSYN)
Here is an image of the script, excluding the comments:
Save the file with Ctrl+X, Y, Enter.
The yesman file won't run until you give it Execute permission. To do that, on the Target machine, in the Terminal window, execute this command:
chmod a+x yesman
The scan should not take long to complete, and it should show only no open ports, as shown below on this page.
./yesman
Nmap finds every port open, and yesman prints a lot of "SYN/ACK sent" messages, as shown below on this page.
http://trac.secdev.org/scapy/wiki/BuildAndDissect
http://trac.secdev.org/scapy/wiki/FtpPasswordSniffer