Write Your Own Python Recon Scanner (Without Paying for Expensive Tools)

Learn how to build your own Python-powered network reconnaissance scanner for ethical hacking labs and security testing. This hands-on guide walks you through writing, customizing, and enhancing a lightweight recon tool — no expensive software or third-party dependencies required.

Write Your Own Python Recon Scanner (Without Paying for Expensive Tools)
Ai Image to represent my post (Not good with design)

Welcome to the Stacknnovare Cyber Blog – where we empower ethical hackers, cybersecurity analysts, and privacy warriors to build their own tools, take control of their defenses, and skip the overpriced software.

Today, we're giving you a full walkthrough on building a Python-powered reconnaissance scanner – a script you can run in your ethical hacking lab to map networks, discover hosts, and identify open ports. This will not be a copy-paste script, but a learning project designed to deepen your understanding of how network scanning works, why it matters, and how to wield it responsibly.


🔍 Why Use This Python Recon Script Instead of Nmap?

Nmap can, and is, an incredibly powerful, feature-rich tool – but when you write your own scanner:

    • You understand how scanning works under the hood (pinging, TCP connections, banner grabbing, etc).
    • You can customize behavior fully, even adding experimental features not supported by Nmap.
    • You gain coding and security engineering practice, which sharpens your analyst and red team skills

To make this post not too long, I just cited some of the advantages of building your OWN cybersecurity tools.


🏗️ What We're Building

Our Python recon scanner will:

✅ Take a subnet (e.g., 192.168.1.0/24) as input
✅ Scan for live hosts using ping sweeps
✅ Check for open common ports (e.g., 22, 80, 443)
✅ Output results in a clean, readable format

What we'll use:

  • ipaddress → For parsing IP ranges
  • subprocess or os → For sending ping commands
  • socket → For checking TCP port status
  • threading → To speed up scans without overloading your system

What we'll need:

  • Python 3.10+
  • Unix OS

Step 1: Set Up Your Environment

Make sure you have Python 3 installed. I recommend creating a virtual environment for clean dependencies:

python3 -m venv venv
source venv/bin/activate

Bash

No external libraries are needed for this project – we'll stick to the Python standard library.

Step 2: Write the Code

# Copyright (c) 2025 Stacknnovare
# Gabriel Correa dos Santos Barbosa - <gabriel.correasb@protonmail.com>
# Free to use

import ipaddress
import subprocess
import socket
import threading

# Defining target subnet
subnet = input("Enter target subnet (e.g., 192.168.1.0/24): ")

# Create a common port to scan list (can be improved for sure)
common_ports = [22,80,443,7690] # SSH, HTTP, HTTPS, RDP

# Lock for clean console output, preventing multiple threads from printing at the same time
print_lock = threading.Lock()

def is_host_alive(ip):
	"""
	Ping the IP to check if the host is alive.
	-c 1 sends 1 packet; -W 1 sets a 1-second timeout.
	On Windows, you'd use '-n 1' instead.
	"""
	try:
		output = subprocess.check_output(
			["ping", "-c", "1", "-W", "1", str(ip)],
			stderr=subprocess.DEVNULL) # Subprocess error output

		return True
	
	except subprocess.CalledProcessError:
		return False


def scan_port(ip, port):
	"""
	Attempt to connect to the specified port on the given IP.
	If successful, print that the port is open.
	"""
	with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
		s.settimeout(1) # 1-second timeout for connection
		try:
			s.connect((str(ip), port)) # Try connecting to the port
			with print_lock:
				print(f"[+] {ip}:{port} OPEN")
		except:
			# we ignore closed port or connection errors
			pass

def scan_host(ip):
	""""
	For each live host:
	- Print that the host is up
	- Spawn threads to check each common port
	"""
	if is_host_alive(ip):
		with print_lock:
			print(f"[+] Host up: {ip}")
		threads = []
		for port in common_ports:
			# create a thread for each port scan
			t = threading.Thread(target=scan_port, args=(ip, port))
			t.start()
			threads.append(t)
		# wait for all threads to finish
		for t in threads:
			t.join()

def main():
	"""
	Main function:
	- Parse the subnet using ipaddress
	- Loop over each IP and scan it
	"""
	network = ipaddress.ip_network(subnet, strict=False)
	for ip in network.hosts():
		scan_host(ip)

if __name__ == "__main__":
	main()

Some clarifications:

Why use threading?

Without threading, you'd scan ports sequentially, making the process painfully slow. Threads allow us to check multiple ports in parallel per host.

Why suppress ping errors?

We don't care if a ping fails or times out – we only act on success.

Why limit to only common ports?

Simply to be an example, when used in a controlled environment, or to test specific ports, the list can be changed, and even improved with an input instead of a defined object. And of course, scanning all 65535 ports would take FOREVER.


Understanding how it works:

  • ipaddress lets us iterate over all usable IPs in a subnet.
  • subprocess.check_output runs the ping command.
  • socket.connect checks if a port responds.
  • threading ensures each host and port scan runs concurrently, speeding up the process.

Step 3: Running the Scanner

After creating the script using the IDE of your choice, save and run the script in your terminal:

python3 recon_scanner.py

Bash

Enter a target subnet (e.g. 192.168.1.0/24), and watch as it identifies live hosts and open ports.

There you go! A brand new scanner, customizable and made to improve.

This project is more than just a few lines of code – It's a foundation for your skills. By building your own tools, you:

✅ Learn how attacks and defenses work
✅ Gain control over your testing environment
✅ Reduce dependence on commercial tools that may track or limit you
✅ Strengthen your ethical hacker and analyst skills

Remember, with great power comes great responsibility. Use your tools wisely, and always prioritize privacy, consent, and ethics.

Stay ethical. Stay secure.