Stealth scanning with Scapy

The following steps demonstrate scanning with Scapy:

  1. To demonstrate how a SYN scan is performed, we craft a TCP SYN request using Scapy and identify the responses associated with an open port, closed port, and non-responsive system.
  2. To send a TCP SYN request to any given port, we first need to build the layers of this request. The first layer that we need to construct is the IP layer:
  1. To build the IP layer for our request, we need to assign the IP object to the i variable. By calling the display() function, we identify the attribute configurations for the object. By default, both the sending and receiving addresses are set to the loopback address, 127.0.0.1. These values can be modified by changing the destination address, by setting i.dst equal to the string value of the address that we wish to scan. By calling the display() function again, we see that not only has the destination address been updated, but Scapy also automatically updates the source IP address to the address associated with the default interface.
  2. Now that we have constructed the IP layer for the request, we can proceed to the TCP layer:
  1. To build the TCP layer for our request, we use the same technique that we used for the IP layer. In the example provided, the TCP object was assigned to the t variable. As mentioned previously, we can identify the default configurations by calling the display() function. Here, we can see that the default value for the destination port is the HTTP port 80. For our initial scan, we leave the default TCP configuration as is.
  2. Now that we have created both the IP and TCP layers, we need to construct the request by stacking these layers as follows:
  1. We can stack the IP and TCP layers by separating the variables with a forward slash. These layers can then be set equal to a new variable that will represent the entire request. We can then call the display() function to view the configurations for the request. Once the request has been built, it can then be passed to the sr1() function so that we can analyze the response, as follows:
  1. We can perform this same request without independently building and stacking each layer. Instead, we can use a single, one-line command by calling the functions directly and passing them the appropriate arguments, as follows:
  1. Note that when a SYN packet is sent to the TCP port 80 of a target web server, which is running an HTTP service on that port, the response has a TCP flag value of SA, which indicates that both the SYN and ACK flag bits are activated. This response indicates that the specified destination port is open and accepting connections. A different response will be returned if the same type of packet is sent to a port that is not accepting connections:
  1. When a SYN request is sent to a closed port, a response is returned with a TCP flag value of RA, which indicates that both the RST and ACK flag bits are activated. The ACK bit is merely used to acknowledge that the request was received, and the RST bit is used to discontinue the communication because the port is not accepting connections. Alternatively, if a SYN packet is sent to a system that is down or behind a firewall that is filtering such requests, it is likely that no response will be received. Due to this, a timeout option should always be used when the sr1() function is used in a script, to ensure that the script does not get hung up on unresponsive hosts:
  1. If the timeout value is not specified when this function is used against an unresponsive host, the function will continue indefinitely. In the demonstration, a timeout value of 1 second was provided for the completion of the function. The response value can be evaluated to determine whether a reply was received. Let's check that out.
  1. Using Python makes it easy to test the variable to identify whether a value has been assigned to it by the sr1() function. This can be used as a preliminary check to determine whether any responses are being received. For responses that are received, subsequent checks can be performed to determine whether the response is indicating a port that is open or closed. All of this can easily be sequenced in a Python script, as follows:
        #!/usr/bin/python

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *
import sys

if len(sys.argv) != 4:
print "Usage - ./syn_scan.py [Target-IP] [First Port]
[Last Port]"
print "Example - ./syn_scan.py 10.0.0.5 1 100"
print "Example will TCP SYN scan ports 1 through
100 on 10.0.0.5"
sys.exit()
else:
ip = sys.argv[1]
start = int(sys.argv[2])
end = int(sys.argv[3])

for port in range(start,end):
ans = sr1(IP(dst=ip)/TCP(dport=port),timeout=1,verbose =0)
if ans == None:
pass
else:
if int(ans[TCP].flags) == 18:
print port
else:
pass
  1. In the provided Python script, the user is prompted to enter an IP address, and the script then performs a SYN scan on the defined port sequence. The script then evaluates the response from each connection attempt to determine whether the response has the SYN and ACK TCP flags activated. The TCP flag for SYN+ACK is 0x12, which translates to 18 in decimal. If these flags, and only these flags, are present in the response, the corresponding port number received is then output:
  1. Upon running the script, the output will indicate any of the first 100 ports that are open on the system by providing the IP address:
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset