DEV Community

Cover image for Stop Being a Script Kiddie: building a Port Scanner with Python 🐍
Shaluka Gimhan
Shaluka Gimhan

Posted on

Stop Being a Script Kiddie: building a Port Scanner with Python 🐍

We all start somewhere.

When I first got into cybersecurity, I was fascinated by tools like Nmap. I would type a command, watch the green text scroll by, and feel like a hacker in a movie. But eventually, I realized something important: running tools doesn't make you a hacker; understanding how they work does.

If you rely 100% on tools other people wrote, you are just a "Script Kiddie."

So, I decided to open the hood and see how network scanning actually works. Today, I want to share a simple Python script I wrote to understand the TCP Handshake process.

It’s not as fast as Nmap (yet!), but it’s mine. And building it taught me more than running nmap -sS ever did.

The Logic: How does it work?

The concept is surprisingly simple. A port scanner is just a program that knocks on doors.

  1. We pick a target (IP Address).
  2. We try to connect to a specific port (like Port 80 for Web).
  3. If the door opens (Connection Accepted) -> The Port is Open.
  4. If the door is locked or no one answers -> The Port is Closed.

We can do this easily using Python’s built-in socket library.

The Code

Here is the script. I kept it simple and added some error handling so it doesn't crash if I press Ctrl+C.

import socket
import sys
from datetime import datetime

# 1. Input Validation
if len(sys.argv) == 2:
    # Translate hostname to IPv4
    target = socket.gethostbyname(sys.argv[1]) 
else:
    print("Invalid amount of arguments.")
    print("Syntax: python scanner.py <ip>")
    sys.exit()

# 2. Adding a Banner (Because it looks cool)
print("-" * 50)
print(f"Scanning target: {target}")
print(f"Time started: {str(datetime.now())}")
print("-" * 50)

try:
    # 3. Scanning Ports
    # I'm scanning 1 to 1000, but you can change this range
    for port in range(1, 1000): 
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        socket.setdefaulttimeout(1) # Don't wait forever

        # connect_ex returns 0 if the connection is successful
        result = s.connect_ex((target, port)) 

        if result == 0:
            print(f"Found Open Port: {port}")
        s.close()

except KeyboardInterrupt:
    print("\nExiting program.")
    sys.exit()

except socket.gaierror:
    print("Hostname could not be resolved.")
    sys.exit()

except socket.error:
    print("Could not connect to server.")
    sys.exit()
Enter fullscreen mode Exit fullscreen mode

Breaking it Down

If you are new to Python networking, here is what the weird lines mean:

socket.AF_INET: This tells Python we are using IPv4 addresses.

socket.SOCK_STREAM: This means we are using TCP (Connection-based protocol), not UDP.

s.connect_ex(): This is the secret sauce. Unlike the normal connect() function which crashes your program if a connection fails, connect_ex() just gives you an error code. If it returns 0, we know we got in!

How to Run It
Save the code as scanner.py and run it in your terminal:

Bash
python scanner.py 192.168.1.1
(Make sure to test it on your own router or local machine first!)

What's Next?
This is just V1. The current version is "single-threaded," which means it checks one port at a time. It's a bit slow.

My next goal is to implement Threading to scan hundreds of ports simultaneously.

I hope this encourages you to stop just running commands and start writing your own tools. If you have any tips on how to optimize this code, drop a comment below!

Happy Hacking! πŸ’»πŸ›‘οΈ

Top comments (0)