Search code examples
pythonpython-3.xscapy

Scapy Port Scanner with CIDR/IP Range or Single IP/Domain input


I have the following code to scan a single host on the given range of ports. I want to modify this so that the input will also accept CIDR slash notation(e.g. google.com/34 or 8.8.8.8/34) (i.e. in addition to a single domain name or IP address).

How can I do this?

import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
import sys
from scapy.all import *

# Define end host and TCP port range
hostInput    = input("Enter a remote host to scan: ")
host  = socket.gethostbyname(hostInput)
port_range = [21,22,23,25,53,80,110,135,137,138,139,443,1433,1434,8080]

# Send SYN with random Src Port for each Dst port
for dst_port in port_range:
    src_port = random.randint(1025,65534)
    resp = sr1(
        IP(dst=host)/TCP(sport=src_port,dport=dst_port,flags="S"),timeout=1,
        verbose=0,
    )

    if resp is None:
        print(f"{host}:{dst_port} is filtered (silently dropped).")

    elif(resp.haslayer(TCP)):
        if(resp.getlayer(TCP).flags == 0x12):
            # Send a gratuitous RST to close the connection
            send_rst = sr(
                IP(dst=host)/TCP(sport=src_port,dport=dst_port,flags='R'),
                timeout=1,
                verbose=0,
            )
            print(f"{host}:{dst_port} is open.")

        elif (resp.getlayer(TCP).flags == 0x14):
            print(f"{host}:{dst_port} is closed.")

    elif(resp.haslayer(ICMP)):
        if(
            int(resp.getlayer(ICMP).type) == 3 and
            int(resp.getlayer(ICMP).code) in [1,2,3,9,10,13]
        ):
            print(f"{host}:{dst_port} is filtered (silently dropped).")

Solution

  • You can try using

    host = Net(hostInput)
    

    Net is the util class Scapy uses to handle IPv4 addresses formats. If you pass it to a packet, sr( will send a packet to each host.

    However I'm not sure how plug and play this is going to be: the use of sr1 restricts the output to a single packet, so you're probably going to have to change that to sr (which gives you a list of all answers)