Three-way handshake captured using tcpdump
192.168.56.1.35555 > 192.168.56.102.4444: Flags [S] seq=12345 192.168.56.102.4444 > 192.168.56.1.35555: Flags [S.], seq=9998 ack=12346 192.168.56.1.35555 > 192.168.56.102.4444: Flags [.] seq=12346 ack=9999
A note on tcpdump output:
- A port number is appended to the IP address with an additional dot. 192.168.56.1.35555 is IP 192.168.56.1 port 35555.
- An ACK bit is represented by a . so [S.] is SYN-ACK, [.] is ACK.
To craft three-way handshake we need to be able to record the response of the server and craft our responses based on server response.
- Craft an IP header with the source and destination IP addresses.
- Craft a TCP header where we generate the TCP source port, assign the destination port that the server listens on, set the TCP flags to turn the SYN bit on, and generate the client’s ISN.
ip=IP(src="10.0.0.1", dst="220.127.116.11") syn_packet = TCP(sport=1500, dport=80, flags="S", seq=100)
- Save the server’s response. (ideally the response should be syn-ack)
- Extract the server’s TCP sequence number and increment the value by one.
synack_packet = sr1(ip/syn_packet) my_ack = syn_ack.seq+1
- IP header has the same source and destination as the intial SYN packet.
- TCP header has the same TCP source and destination ports as syn packet, only ACK bit is set, increment the client’s ISN by one since the SYN packet consumes one sequence number, set the acknowledgement value to the incremented server’s sequence number value.
ack_packet = TCP(sport=1500, dport=80, flags="A", seq=101, ack=my_ack) send(ip/TCP_ACK)
If everything went right, we have just sucessfully established TCP three-way handshake.
If you have noticed whenever we recieve a packet, our machine automatically responds with an RST packet.
The kernel is not aware of what Scapy is doing behind it’s back(Scapy is userland program). If Scapy sends a SYN, the target replies with a SYN-ACK and your kernel sees it as unsolicited packet, it will reply with an RST.
To prevent this, use local firewall rules (e.g. NetFilter/IPtables for Linux). Scapy does not mind about local firewalls.
iptables -A OUTPUT -p tcp --tcp-flags RST RST -s 192.168.1.1 -j DROP
- We send packets using
- The response is just a single packet
- We use Scapy’s
sprintfmethod to print interesting fields in the response. (
SAflags indicates open ports,
RAflags indicates closed ports)
>>> syn_packet = IP(dst='192.168.56.102')/TCP(dport=4444,flags='S') >>> resp = sr1(syn_packet) >>> resp.sprintf('%TCP.src% \t %TCP.sport% \t %TCP.flags%') '192.168.56.102 4444 SA'
- We use
srfunction to send our packets
srreturns answered probes and unanswered probes that we assign to two variables
anshas all the answered probes in stimulus/response pairs(a tuple)
- We use a simple lambda function to loop over the answered probes and print interesting fields
In the below example, each entry in ans i.e. a stimuli response pair is passed on to a lambda function (stimuli & response as
r respectively). Inside lambda function, we use
sprintf to extract interesting fields.
>>> ans, unans = sr(IP(dst="192.168.56.90")/TCP(dport=(20,24),flags="S")) >>> ans.summary( lambda(s,r): r.sprintf("%TCP.sport% \t %TCP.flags%") ) 'ftp_data RA' '21 RA 'ssh SA' 'telnet RA' '24 RA'
make_tableis an advanced feature in scapy that helps you visualize larger and complex scans
make_tabletakes three values - for rows, coloumns and the table data
In the below example, target IPs are on x-axis, target ports on y-axis and the TCP flags in response are tabular data.
>>> ans,unans = sr(IP(dst=["scanme.nmap.org","egadz.metasploit.com"])/TCP(dport=[10,20,30],flags="S")) >>> >>> ans.make_table(lambda(s,r): (s.dst, s.dport,r.sprintf("%TCP.flags%"))) 18.104.22.168 22.214.171.124 10 RA SA 20 RA SA 30 RA SA
>>> fin_packet = IP(dst='192.168.56.102')/TCP(dport=4444,flags='F') >>> resp = sr1(fin_packet) Begin emission: Finished to send 1 packets. ^C Received 0 packets, got 0 answers, remaining 1 packets
>>> fin_packet = IP(dst='192.168.56.102')/TCP(dport=6767,flags='F') >>> resp = sr1(fin_packet) >>> resp.sprintf('%TCP.flags%') 'RA'
Please solve Exercise 2 - Misc exercises
In 1998, security researcher Antirez posted to the Bugtraq mailing list an ingenious new port scanning technique. Idle scan, as it has become known, allows for completely blind port scanning. Attackers can actually scan a target without sending a single packet to the target from their own IP address! Instead, a clever side-channel attack allows for the scan to be bounced off a dumb “zombie host”. Intrusion detection system (IDS) reports will finger the innocent zombie as the attacker.
Idle scan can be explained in following steps:
- One way to determine whether a TCP port is open is to send a SYN (session establishment) packet to the port. The target machine will respond with a SYN/ACK (session request acknowledgment) packet if the port is open, and RST (reset) if the port is closed. This is the basis of the previously discussed SYN scan.
- A machine that receives an unsolicited SYN/ACK packet will respond with a RST. An unsolicited RST will be ignored.
- Every IP packet on the Internet has a fragment identification number (IP ID). Since many operating systems simply increment this number for each packet they send, probing for the IP ID can tell an attacker how many packets have been sent since the last probe.
By combining these traits, it is possible to scan a target network while forging your identity so that it looks like an innocent zombie machine did the scanning.
Please solve Exercise 3 & 4 - Misc exercises