Blog 14: Crafting Custom Network Scanners with Scapy in Python

Building Custom Network Scanners with Scapy

Building Custom Network Scanners with Scapy

Scapy is a powerful packet manipulation framework for Python that allows you to craft, send, and analyze network packets. In this post, you’ll learn how to create lightweight, custom network scanners that go beyond what typical tools like Nmap offer.

Introduction to Scapy

Scapy gives you control at the packet level — you can create custom packets, define scanning logic, and analyze raw responses. This flexibility makes it invaluable for penetration testers, researchers, and network engineers.

Installing Scapy

pip install scapy

Example 1: Basic ICMP Ping Sweep

This scanner checks which hosts are alive on your network using ICMP echo requests.

from scapy.all import ICMP, IP, sr1

subnet = '192.168.1.'
for i in range(1, 255):
    ip = subnet + str(i)
    pkt = IP(dst=ip)/ICMP()
    reply = sr1(pkt, timeout=0.5, verbose=0)
    if reply:
        print(f"Host {ip} is alive")
    

Explanation:

  • sr1(): Sends a packet and receives a single response.
  • timeout: Controls how long to wait for a reply.

Example 2: TCP SYN Scanner

A SYN scan determines open ports by sending TCP SYN packets and analyzing responses.

from scapy.all import IP, TCP, sr1

target = "192.168.1.10"
ports = [22, 80, 443]

for port in ports:
    pkt = IP(dst=target)/TCP(dport=port, flags='S')
    resp = sr1(pkt, timeout=1, verbose=0)
    if resp and resp.haslayer(TCP):
        if resp[TCP].flags == 0x12:
            print(f"Port {port} is open")
        elif resp[TCP].flags == 0x14:
            print(f"Port {port} is closed")
    
  • flags='S': Sends a SYN packet.
  • 0x12: SYN-ACK — indicates an open port.
  • 0x14: RST-ACK — indicates a closed port.

Example 3: Multi-threaded Port Scanner

To increase speed, use Python threads for parallel scans.

import threading
from scapy.all import IP, TCP, sr1

def scan_port(ip, port):
    pkt = IP(dst=ip)/TCP(dport=port, flags='S')
    resp = sr1(pkt, timeout=0.5, verbose=0)
    if resp and resp.haslayer(TCP) and resp[TCP].flags == 0x12:
        print(f"[+] Port {port} open on {ip}")

target = '192.168.1.10'
ports = range(20, 1025)

for p in ports:
    t = threading.Thread(target=scan_port, args=(target, p))
    t.start()
    

Tips for Advanced Use

  • Use sr() to send and receive multiple packets at once.
  • Combine with ARP to map local networks.
  • Implement rate limiting to avoid detection.
  • Capture responses with sniff() for deeper analysis.

Conclusion

Scapy allows you to write powerful, customizable scanners that mimic or even outperform conventional tools when tuned correctly. Understanding how packets flow at this level makes you a sharper, more capable penetration tester.

Comments