Project 1: Build Your Own Network Reconnaissance Toolkit

Project 1: Build Your Own Network Reconnaissance Toolkit

Project Overview

Attribute Value
Difficulty Beginner-Intermediate
Time Estimate 1-2 weeks
Programming Language Python
Primary Tool Scapy / Raw Sockets
Main Book โ€œBlack Hat Pythonโ€ by Justin Seitz
Knowledge Area Networking / Security

Learning Objectives

By completing this project, you will:

  1. Understand TCP/IP at the packet level - Not just conceptually, but what actual bytes travel over the wire
  2. Implement port scanning from scratch - Learn why Nmap works the way it does by building your own
  3. Master DNS enumeration techniques - Discover subdomains, mail servers, and zone transfer vulnerabilities
  4. Develop service fingerprinting skills - Identify whatโ€™s running on open ports by analyzing banners
  5. Build production-quality security tools - Handle threading, timeouts, and error conditions like professional tools

The Core Question

โ€œHow do attackers discover whatโ€™s running on a network before they even attempt exploitation?โ€

Reconnaissance is the foundation of every penetration test. Before you can hack anything, you need to know:

  • What hosts are alive on the network?
  • What ports are open on each host?
  • What services are running behind those ports?
  • What versions of software are exposed?

By building these tools yourself, youโ€™ll understand the mechanics of network discovery at a fundamental levelโ€”knowledge that makes you effective with tools like Nmap and helps you understand what defenders see.


Deep Theoretical Foundation

The TCP/IP Stack: Where Scanning Lives

Before writing a single line of code, you must understand how data travels across networks. The TCP/IP model has four layers, and your reconnaissance tools will operate primarily at Layer 3 (Network) and Layer 4 (Transport):

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        APPLICATION LAYER                            โ”‚
โ”‚  HTTP, HTTPS, SSH, FTP, DNS, SMTP, MySQL                           โ”‚
โ”‚  "What humans interact with"                                        โ”‚
โ”‚                                                                     โ”‚
โ”‚  Example: GET /index.html HTTP/1.1                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        TRANSPORT LAYER                              โ”‚
โ”‚  TCP (connection-oriented) / UDP (connectionless)                  โ”‚
โ”‚  "How data is segmented and guaranteed delivery"                   โ”‚
โ”‚                                                                     โ”‚
โ”‚  TCP Header Structure:                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                               โ”‚
โ”‚  โ”‚ Source Port    โ”‚ Dest Port      โ”‚ (16 bits each)                โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Sequence Number                  โ”‚ (32 bits)                    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Acknowledgment Number            โ”‚ (32 bits)                    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Data Offset,   โ”‚ Flags (URG,ACK, โ”‚                               โ”‚
โ”‚  โ”‚ Reserved       โ”‚ PSH,RST,SYN,FIN)โ”‚ โ—„โ”€โ”€ Port scanning uses these!โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Window Size                      โ”‚ (16 bits)                    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Checksum      โ”‚ Urgent Pointer   โ”‚                               โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        NETWORK LAYER                                โ”‚
โ”‚  IP (IPv4/IPv6), ICMP, Routing                                     โ”‚
โ”‚  "How packets find their way across networks"                      โ”‚
โ”‚                                                                     โ”‚
โ”‚  IPv4 Header:                                                       โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                               โ”‚
โ”‚  โ”‚ Version (4)    โ”‚ IHL           โ”‚ (4 bits each)                  โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ DSCP           โ”‚ ECN           โ”‚                                 โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Total Length                    โ”‚ (16 bits)                     โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Identification                   โ”‚ (16 bits)                    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Flags         โ”‚ Fragment Offset โ”‚                                โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ TTL           โ”‚ Protocol        โ”‚ โ—„โ”€โ”€ 6=TCP, 17=UDP, 1=ICMP    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Header Checksum                  โ”‚                               โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Source IP Address                โ”‚ (32 bits)                    โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค                               โ”‚
โ”‚  โ”‚ Destination IP Address           โ”‚ (32 bits)                    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
                              โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        LINK LAYER                                   โ”‚
โ”‚  Ethernet, WiFi, ARP                                               โ”‚
โ”‚  "Physical transmission on local network"                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

TCP/IP Stack - Network Protocol Layers for Port Scanning

The TCP Three-Way Handshake: Why Port Scanning Works

TCP is a connection-oriented protocol. Before any data transfer, client and server must establish a connection using a โ€œthree-way handshakeโ€:

Normal TCP Connection Establishment
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Client                                              Server
   โ”‚                                                   โ”‚
   โ”‚  SYN (Synchronize)                               โ”‚
   โ”‚  seq=100, ack=0, flags=SYN                       โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚  "I want to connect. My sequence starts at 100" โ”‚
   โ”‚                                                   โ”‚
   โ”‚                     SYN-ACK                       โ”‚
   โ”‚  seq=300, ack=101, flags=SYN+ACK                 โ”‚
   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
   โ”‚  "OK. My sequence starts at 300.                 โ”‚
   โ”‚   I expect your next byte to be 101"             โ”‚
   โ”‚                                                   โ”‚
   โ”‚  ACK (Acknowledge)                               โ”‚
   โ”‚  seq=101, ack=301, flags=ACK                     โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚  "Got it. Connection established."               โ”‚
   โ”‚                                                   โ”‚
   โ”‚  โ•โ•โ•โ•โ•โ•โ• CONNECTION ESTABLISHED โ•โ•โ•โ•โ•โ•โ•          โ”‚
   โ”‚                                                   โ”‚

Why this matters for scanning: By sending specific combinations of TCP flags, we can probe a portโ€™s state without completing a full connection:

Port States and What They Mean

OPEN PORT (Service Listening)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Scanner                                             Target
   โ”‚                                                   โ”‚
   โ”‚  SYN                                             โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚                                                   โ”‚
   โ”‚                     SYN-ACK                       โ”‚
   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
   โ”‚  "Yes, I'm listening on this port!"              โ”‚
   โ”‚                                                   โ”‚
   โ”‚  RST (or complete handshake)                     โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚                                                   โ”‚

Result: PORT IS OPEN
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


CLOSED PORT (Nothing Listening)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Scanner                                             Target
   โ”‚                                                   โ”‚
   โ”‚  SYN                                             โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚                                                   โ”‚
   โ”‚                     RST                          โ”‚
   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
   โ”‚  "Nothing running here. Go away!"                โ”‚
   โ”‚                                                   โ”‚

Result: PORT IS CLOSED
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


FILTERED PORT (Firewall Blocking)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Scanner                                             Target
   โ”‚                                                   โ”‚
   โ”‚  SYN                                             โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚                                              [Firewall]
   โ”‚  ... silence ...                                  X
   โ”‚  (timeout after 1-2 seconds)                     โ”‚
   โ”‚                                                   โ”‚

Result: PORT IS FILTERED (probably firewalled)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€


ALTERNATIVE: ICMP Unreachable
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
Scanner                                             Target
   โ”‚                                                   โ”‚
   โ”‚  SYN                                             โ”‚
   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚
   โ”‚                                              [Firewall]
   โ”‚                  ICMP Type 3                      โ”‚
   โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
   โ”‚  "Destination port unreachable"                   โ”‚
   โ”‚                                                   โ”‚

Result: PORT IS FILTERED (administratively blocked)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

TCP Port States - Open, Closed, and Filtered Detection

Types of Port Scans

Your toolkit will implement multiple scan types, each with different tradeoffs:

Scan Type How It Works Advantages Disadvantages
TCP Connect Complete 3-way handshake No root required, reliable Logged by target, slow
SYN Scan Send SYN, analyze response, send RST Faster, stealthier (no logging) Requires root/raw sockets
UDP Scan Send UDP packets, wait for response Finds UDP services (DNS, SNMP) Very slow, unreliable
ACK Scan Send ACK, analyze RST response Detects firewall rules Canโ€™t determine if port is open

DNS: The Reconnaissance Goldmine

DNS (Domain Name System) is often overlooked as an attack surface, but it contains a wealth of information:

DNS RECORD TYPES FOR RECONNAISSANCE
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

A Record:      Maps domain to IPv4 address
               example.com โ†’ 93.184.216.34

               Use: Discover IP addresses of hosts

AAAA Record:   Maps domain to IPv6 address
               example.com โ†’ 2606:2800:220:1:248:1893:25c8:1946

               Use: Often overlooked, may have different security

MX Record:     Mail server for domain
               example.com โ†’ mail.example.com (priority 10)

               Use: Identify mail servers (common phishing targets)

NS Record:     Authoritative nameservers
               example.com โ†’ ns1.example.com, ns2.example.com

               Use: Identify DNS infrastructure

TXT Record:    Arbitrary text (SPF, DKIM, verification)
               example.com โ†’ "v=spf1 include:_spf.google.com ~all"

               Use: Reveals email infrastructure, third-party services

CNAME Record:  Alias pointing to another domain
               www.example.com โ†’ cdn.cloudflare.net

               Use: Identifies CDNs, cloud providers

PTR Record:    Reverse DNS (IP to hostname)
               93.184.216.34 โ†’ example.com

               Use: Discover internal naming conventions

Zone Transfers: When DNS Gets Really Chatty

A zone transfer (AXFR) is meant for DNS server replication, but misconfigured servers allow anyone to request the entire zone:

ZONE TRANSFER ATTACK
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Normal Query (one record at a time):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Attacker: "What's the IP for www.target.com?"     โ”‚
โ”‚  DNS:      "93.184.216.34"                          โ”‚
โ”‚                                                     โ”‚
โ”‚  Attacker: "What's the IP for mail.target.com?"    โ”‚
โ”‚  DNS:      "93.184.216.35"                          โ”‚
โ”‚                                                     โ”‚
โ”‚  (Must guess each subdomain individually)           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Zone Transfer (get everything at once):
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Attacker: "Give me all records for target.com"     โ”‚
โ”‚  DNS:      "Here's 500 records:                     โ”‚
โ”‚             - www.target.com โ†’ 93.184.216.34       โ”‚
โ”‚             - mail.target.com โ†’ 93.184.216.35      โ”‚
โ”‚             - admin.target.com โ†’ 93.184.216.36     โ”‚
โ”‚             - dev-internal.target.com โ†’ 10.0.0.50  โ”‚  โ† Internal!
โ”‚             - jenkins.target.com โ†’ 10.0.0.51       โ”‚  โ† CI/CD server!
โ”‚             - vpn.target.com โ†’ 203.0.113.10        โ”‚
โ”‚             - ..."                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why this is devastating:
- Reveals ALL subdomains (including internal systems)
- Exposes infrastructure layout
- Identifies high-value targets (admin panels, CI/CD)
- No rate limiting or detection

Service Fingerprinting: Whatโ€™s Actually Running?

Knowing a port is open isnโ€™t enoughโ€”you need to know what service is running and what version:

BANNER GRABBING
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

Connect to port 22:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Server Response:                                    โ”‚
โ”‚  SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.5            โ”‚
โ”‚                                                     โ”‚
โ”‚  Information Revealed:                              โ”‚
โ”‚  - Protocol: SSH version 2                          โ”‚
โ”‚  - Software: OpenSSH 8.2p1                         โ”‚
โ”‚  - OS: Ubuntu (specific patch level)               โ”‚
โ”‚                                                     โ”‚
โ”‚  Now you can search: "OpenSSH 8.2p1 vulnerabilities"โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Connect to port 80:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Send: "GET / HTTP/1.0\r\n\r\n"                    โ”‚
โ”‚                                                     โ”‚
โ”‚  Response Headers:                                  โ”‚
โ”‚  HTTP/1.1 200 OK                                   โ”‚
โ”‚  Server: Apache/2.4.41 (Ubuntu)                    โ”‚
โ”‚  X-Powered-By: PHP/7.4.3                           โ”‚
โ”‚                                                     โ”‚
โ”‚  Information Revealed:                              โ”‚
โ”‚  - Web Server: Apache 2.4.41                       โ”‚
โ”‚  - Language: PHP 7.4.3                             โ”‚
โ”‚  - OS: Ubuntu                                       โ”‚
โ”‚                                                     โ”‚
โ”‚  Attack vector: Look for Apache 2.4.41 CVEs        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Project Specification

What Youโ€™re Building

A command-line toolkit with three main components:

network-recon-toolkit/
โ”œโ”€โ”€ scanner.py          # Port scanner (TCP connect + SYN scan)
โ”œโ”€โ”€ dns_enum.py         # DNS enumeration and zone transfer
โ”œโ”€โ”€ fingerprint.py      # Service fingerprinting and banner grabbing
โ”œโ”€โ”€ output/             # Scan results (JSON, CSV, HTML)
โ”œโ”€โ”€ wordlists/          # Subdomain wordlists
โ”‚   โ””โ”€โ”€ subdomains.txt
โ”œโ”€โ”€ requirements.txt    # Dependencies
โ””โ”€โ”€ README.md           # Usage documentation

Functional Requirements

1. Port Scanner (scanner.py)

Must implement:

  • TCP Connect scan (no root required)
  • Scan single port, port range, or common ports list
  • Configurable timeout per connection
  • Multi-threaded scanning (100+ connections concurrent)
  • Output: JSON with host, port, state, response time

Should implement:

  • SYN scan (requires root/raw sockets)
  • UDP scan for common ports (DNS, SNMP, NTP)
  • Service version detection via banner grabbing
  • Rate limiting to avoid detection

Example usage:

# Scan single host, common ports
python scanner.py 192.168.1.1

# Scan port range with increased threads
python scanner.py 192.168.1.1 -p 1-1000 --threads 200

# Scan network range
python scanner.py 192.168.1.0/24 -p 22,80,443

# SYN scan (requires sudo)
sudo python scanner.py 192.168.1.1 --syn

2. DNS Enumerator (dns_enum.py)

Must implement:

  • Query A, AAAA, MX, NS, TXT, CNAME records
  • Subdomain enumeration via wordlist
  • Attempt zone transfer (AXFR)
  • Reverse DNS lookups

Should implement:

  • Multi-threaded subdomain bruteforcing
  • Wildcard detection (*.domain.com)
  • Integration with Certificate Transparency logs
  • Output to structured format

Example usage:

# Basic enumeration
python dns_enum.py example.com

# Subdomain bruteforce
python dns_enum.py example.com --wordlist wordlists/subdomains.txt

# Attempt zone transfer
python dns_enum.py example.com --zone-transfer

3. Service Fingerprinter (fingerprint.py)

Must implement:

  • HTTP/HTTPS banner grabbing
  • SSH version detection
  • FTP banner grabbing
  • Generic TCP banner grabbing
  • TLS certificate extraction

Should implement:

  • Service-specific probes (MySQL, PostgreSQL, Redis)
  • Custom fingerprint database
  • Version-to-CVE mapping suggestions

Example usage:

# Fingerprint all services on host
python fingerprint.py 192.168.1.1

# Fingerprint specific ports
python fingerprint.py 192.168.1.1 -p 22,80,443

# Deep fingerprinting (all probes)
python fingerprint.py 192.168.1.1 --deep

Non-Functional Requirements

  1. Performance: Scan 1000 ports in under 30 seconds
  2. Reliability: Handle network errors gracefully, never crash
  3. Accuracy: Match Nmap results for same targets
  4. Documentation: Clear help messages, README with examples
  5. Ethics: Include legal disclaimer, respect robots.txt

Solution Architecture

Component Design

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     RECONNAISSANCE TOOLKIT                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                              โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚                     โ”‚                     โ”‚
        โ–ผ                     โ–ผ                     โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Port Scanner  โ”‚    โ”‚ DNS Enumer.   โ”‚    โ”‚ Fingerprinter โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ - TCP Connect โ”‚    โ”‚ - Record      โ”‚    โ”‚ - Banner Grab โ”‚
โ”‚ - SYN Scan    โ”‚    โ”‚   Queries     โ”‚    โ”‚ - TLS Extract โ”‚
โ”‚ - UDP Scan    โ”‚    โ”‚ - Subdomain   โ”‚    โ”‚ - Service     โ”‚
โ”‚ - Threading   โ”‚    โ”‚   Bruteforce  โ”‚    โ”‚   Probes      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚ - Zone AXFR   โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚            โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜            โ”‚
        โ”‚                    โ”‚                    โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                             โ”‚
                             โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Output Engine โ”‚
                    โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
                    โ”‚ - JSON Export โ”‚
                    โ”‚ - CSV Export  โ”‚
                    โ”‚ - HTML Report โ”‚
                    โ”‚ - Console     โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Data Structures

# Port scan result
@dataclass
class PortResult:
    ip: str
    port: int
    state: Literal["open", "closed", "filtered"]
    service: Optional[str] = None
    banner: Optional[str] = None
    response_time_ms: Optional[float] = None

# DNS enumeration result
@dataclass
class DNSResult:
    domain: str
    record_type: str  # A, AAAA, MX, NS, TXT, CNAME
    value: str
    ttl: int

# Service fingerprint
@dataclass
class ServiceInfo:
    ip: str
    port: int
    protocol: str  # tcp, udp
    service_name: str  # ssh, http, mysql
    version: Optional[str] = None
    os_guess: Optional[str] = None
    cves: List[str] = field(default_factory=list)

Threading Model for Port Scanning

PRODUCER-CONSUMER PATTERN
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Target Queue โ”‚
                    โ”‚ (ports to    โ”‚
                    โ”‚  scan)       โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚                  โ”‚                  โ”‚
        โ–ผ                  โ–ผ                  โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Worker 1    โ”‚  โ”‚   Worker 2    โ”‚  โ”‚   Worker N    โ”‚
โ”‚               โ”‚  โ”‚               โ”‚  โ”‚               โ”‚
โ”‚ - Get port    โ”‚  โ”‚ - Get port    โ”‚  โ”‚ - Get port    โ”‚
โ”‚ - Attempt     โ”‚  โ”‚ - Attempt     โ”‚  โ”‚ - Attempt     โ”‚
โ”‚   connect     โ”‚  โ”‚   connect     โ”‚  โ”‚   connect     โ”‚
โ”‚ - Report      โ”‚  โ”‚ - Report      โ”‚  โ”‚ - Report      โ”‚
โ”‚   result      โ”‚  โ”‚   result      โ”‚  โ”‚   result      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                  โ”‚                  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
                           โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Result Queue โ”‚
                    โ”‚ (completed   โ”‚
                    โ”‚  scans)      โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Phased Implementation Guide

Phase 1: Basic TCP Connect Scanner (Days 1-2)

Goal: Scan a single port on a single host

Implementation steps:

  1. Create a function that attempts to connect to a TCP port:
    def scan_port(ip: str, port: int, timeout: float = 1.0) -> PortResult:
     """
     Attempt TCP connection to ip:port
    
     Returns:
         PortResult with state='open' if connection succeeds
         PortResult with state='closed' if connection refused
         PortResult with state='filtered' if timeout
     """
     # Use socket.socket() with SO_REUSEADDR
     # Set timeout with socket.settimeout()
     # Try connect_ex() for non-blocking connect
     # Map return codes to states:
     #   0 = open
     #   111 (ECONNREFUSED) = closed
     #   110 (ETIMEDOUT) = filtered
    
  2. Add CLI argument parsing:
    • Target IP/hostname
    • Port number or range
    • Timeout value
  3. Test against your local machine:
    • Start a local HTTP server: python -m http.server 8080
    • Scan port 8080 (should be open)
    • Scan port 8081 (should be closed)

Verification: Can you correctly identify an open port on localhost?

Phase 2: Multi-Threaded Scanning (Days 2-3)

Goal: Scan 1000 ports in under 30 seconds

Implementation steps:

  1. Use concurrent.futures.ThreadPoolExecutor: ```python from concurrent.futures import ThreadPoolExecutor, as_completed

def scan_ports(ip: str, ports: List[int], threads: int = 100) -> List[PortResult]: results = [] with ThreadPoolExecutor(max_workers=threads) as executor: futures = { executor.submit(scan_port, ip, port): port for port in ports } for future in as_completed(futures): results.append(future.result()) return results


2. Add progress indicator (tqdm or simple counter)

3. Implement rate limiting to avoid overwhelming target

**Verification**: Scan ports 1-1000 on a target in under 30 seconds

### Phase 3: DNS Enumeration (Days 3-4)

**Goal**: Enumerate all DNS record types and attempt zone transfer

**Implementation steps**:

1. Use the `dnspython` library for queries:
```python
import dns.resolver
import dns.zone
import dns.query

def query_records(domain: str, record_type: str) -> List[DNSResult]:
    """Query specific DNS record type"""
    resolver = dns.resolver.Resolver()
    try:
        answers = resolver.resolve(domain, record_type)
        return [DNSResult(domain, record_type, str(rdata), answers.ttl)
                for rdata in answers]
    except dns.resolver.NXDOMAIN:
        return []  # Domain doesn't exist
    except dns.resolver.NoAnswer:
        return []  # No records of this type
  1. Implement subdomain enumeration:
    • Read subdomain wordlist
    • Query A record for each: subdomain.domain.com
    • Track which ones resolve
  2. Implement zone transfer attempt:
    def attempt_zone_transfer(domain: str) -> Optional[List[DNSResult]]:
     """Attempt AXFR zone transfer"""
     # Get NS records for domain
     # For each NS, attempt: dns.query.xfr(ns, domain)
     # If successful, extract all records
    

Verification: Enumerate google.com and see A, MX, NS, TXT records

Phase 4: Service Fingerprinting (Days 4-5)

Goal: Identify services running on open ports

Implementation steps:

  1. Implement banner grabbing:
    def grab_banner(ip: str, port: int, timeout: float = 2.0) -> Optional[str]:
     """Connect and read initial response"""
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock.settimeout(timeout)
     try:
         sock.connect((ip, port))
         # Some services send banner immediately (SSH, FTP)
         # Others need us to send something first (HTTP)
         banner = sock.recv(1024)
         return banner.decode('utf-8', errors='ignore')
     except:
         return None
     finally:
         sock.close()
    
  2. Add service-specific probes:
    • HTTP: Send GET / HTTP/1.0\r\n\r\n
    • MySQL: Parse greeting packet
    • TLS: Extract certificate info
  3. Build a simple service detection database:
    SERVICE_SIGNATURES = {
     "ssh": re.compile(r"SSH-[\d.]+-"),
     "http": re.compile(r"HTTP/[\d.]+"),
     "ftp": re.compile(r"220.*FTP"),
     "smtp": re.compile(r"220.*SMTP"),
    }
    

Verification: Correctly identify SSH, HTTP, and MySQL on test servers

Phase 5: SYN Scanning with Scapy (Days 5-6)

Goal: Implement stealthy SYN scanning (requires root)

Implementation steps:

  1. Install Scapy: pip install scapy

  2. Implement SYN scan: ```python from scapy.all import IP, TCP, sr1, conf

def syn_scan(ip: str, port: int) -> str: โ€œโ€โ€ SYN scan using raw packets Requires root privileges โ€œโ€โ€ conf.verb = 0 # Disable Scapy output

# Craft SYN packet
syn = IP(dst=ip)/TCP(dport=port, flags='S')

# Send and wait for response
response = sr1(syn, timeout=1)

if response is None:
    return "filtered"
elif response.haslayer(TCP):
    if response[TCP].flags == 0x12:  # SYN-ACK
        # Send RST to close (stealth)
        rst = IP(dst=ip)/TCP(dport=port, flags='R')
        send(rst, verbose=0)
        return "open"
    elif response[TCP].flags == 0x14:  # RST
        return "closed"
return "filtered" ```
  1. Add sudo detection and privilege check

Verification: Compare SYN scan results to TCP connect results

Phase 6: Output and Reporting (Days 6-7)

Goal: Generate professional reports

Implementation steps:

  1. JSON output:
    def export_json(results: List[PortResult], filepath: str):
     data = [asdict(r) for r in results]
     with open(filepath, 'w') as f:
         json.dump(data, f, indent=2)
    
  2. CSV output for spreadsheet analysis

  3. HTML report with styling: ```html
Scan Report - {target}

Network Reconnaissance Report

Target: {target}

Scan Time: {timestamp}

Open Ports

PortServiceBanner

4. Compare output to Nmap format

**Verification**: Generate all three output formats for a scan

---

## Testing Strategy

### Unit Tests

```python
# test_scanner.py
import pytest
from scanner import scan_port, parse_port_range

def test_parse_port_range():
    assert parse_port_range("80") == [80]
    assert parse_port_range("1-5") == [1, 2, 3, 4, 5]
    assert parse_port_range("22,80,443") == [22, 80, 443]

def test_scan_localhost_open_port():
    # Start a server on port 9999 before test
    result = scan_port("127.0.0.1", 9999)
    assert result.state == "open"

def test_scan_localhost_closed_port():
    result = scan_port("127.0.0.1", 9998)  # Nothing running
    assert result.state == "closed"

Integration Tests

  1. Against known targets:
    • Scan scanme.nmap.org (Nmap provides this for testing)
    • Compare results to Nmap output
    • Verify same open ports detected
  2. DNS tests:
    • Enumerate google.com (should find A, MX, NS records)
    • Test zone transfer against intentionally vulnerable server
  3. Fingerprinting tests:
    • Correctly identify Apache vs Nginx
    • Correctly identify OpenSSH version

Performance Tests

import time

def test_scan_performance():
    start = time.time()
    results = scan_ports("192.168.1.1", range(1, 1001), threads=100)
    elapsed = time.time() - start

    assert elapsed < 30, f"Scan took {elapsed}s, should be under 30s"

Common Pitfalls and Debugging

1. โ€œMy scanner is too slowโ€

Problem: Scanning takes minutes instead of seconds

Debug steps:

  1. Check thread count (increase to 100-200)
  2. Check timeout (decrease to 0.5-1s)
  3. Look for blocking operations in main thread
  4. Use cProfile to find bottleneck

Solution: Use ThreadPoolExecutor properly, donโ€™t wait sequentially

2. โ€œI get โ€˜Permission deniedโ€™ for SYN scanโ€

Problem: Raw socket access requires root

Debug steps:

  1. Run with sudo
  2. Check if Scapy is installed correctly
  3. Verify raw socket capability

Solution: Either use sudo or fall back to TCP connect scan

3. โ€œDNS zone transfer always failsโ€

Problem: Most servers have zone transfers disabled

This is expected! Zone transfers are a security misconfiguration. For testing:

  1. Use intentionally vulnerable DNS servers (set up your own)
  2. Zonetransfer.me is a test server that allows AXFR

4. โ€œBanner grabbing returns emptyโ€

Problem: Some services need a prompt before responding

Debug steps:

  1. Check if connection succeeds
  2. Try sending a probe (like HTTP GET)
  3. Increase timeout
  4. Handle binary protocols (MySQL handshake)

Solution: Implement service-specific probes

5. โ€œResults donโ€™t match Nmapโ€

Problem: Different scan techniques yield different results

Debug steps:

  1. Compare exact scan types (Nmap -sT for TCP connect)
  2. Check timing/timeout differences
  3. Verify target hasnโ€™t changed between scans
  4. Consider rate limiting differences

Extensions and Challenges

Beginner Extensions

  1. Add color output: Green for open, red for closed
  2. Progress bar: Show scan progress with tqdm
  3. Save/resume: Allow resuming interrupted scans

Intermediate Extensions

  1. OS Detection: Analyze TCP/IP stack quirks to guess OS
  2. Service probes: Add MySQL, PostgreSQL, Redis detection
  3. Rate limiting: Avoid triggering IDS/IPS

Advanced Extensions

  1. Evasion techniques: Fragmented packets, timing variations
  2. IPv6 support: Scan IPv6 addresses
  3. Web interface: Flask dashboard for results
  4. Parallel host scanning: Scan entire subnets efficiently

Real-World Connections

How Nmap Does It

Your scanner is a simplified Nmap. The real Nmap:

  • Uses a sophisticated timing engine
  • Has 600+ service probes
  • Includes 600+ NSE scripts
  • Does OS fingerprinting via TCP/IP stack analysis

After this project, read the Nmap source code to see professional implementation.

Shodan and Censys

Commercial services like Shodan scan the entire internet continuously. They use:

  • Distributed scanning nodes
  • Massive parallelization
  • Historical data tracking

Your skills translate to understanding how these services work.

Bug Bounty Applications

Many bug bounties start with reconnaissance:

  • Subdomain enumeration reveals forgotten assets
  • Open ports expose services you didnโ€™t know existed
  • Banner grabbing identifies vulnerable versions

Self-Assessment Checklist

Before considering this project complete, verify:

Core Functionality

  • TCP connect scan correctly identifies open/closed/filtered ports
  • Multi-threaded scanning completes 1000 ports in < 30 seconds
  • DNS enumeration returns A, MX, NS, TXT records
  • Zone transfer attempt works (even if server refuses)
  • Banner grabbing returns version strings for SSH, HTTP

Code Quality

  • CLI has โ€“help with clear usage
  • Errors are handled gracefully (no crashes)
  • Output is structured (JSON export works)
  • Code is documented with docstrings

Understanding

  • Can explain TCP three-way handshake whiteboard-style
  • Can explain difference between SYN and connect scans
  • Understand why zone transfers are security issues
  • Know which scan types require root and why

Comparison

  • Results match Nmap for same target/options
  • Performance is comparable for connect scans
  • Output is parseable by other tools

Resources

Primary Reading

  • โ€œTCP/IP Illustrated, Volume 1โ€ by W. Richard Stevens - Chapters 17-18 (TCP Connection)
  • โ€œBlack Hat Pythonโ€ by Justin Seitz - Chapter 3 (Network Scanning)
  • โ€œThe Linux Programming Interfaceโ€ by Michael Kerrisk - Chapters 56-61 (Sockets)

Online Resources

Practice Targets

  • scanme.nmap.org - Nmap provides this for testing
  • Your own VMs - Set up services to scan
  • TryHackMe/HTB - Use recon tools on CTF challenges

This project is part of the Ethical Hacking & Penetration Testing learning path.