Blog 16: Automating Network Recon with Python
Reconnaissance is one of the most important parts of penetration testing. If your recon is weak, your understanding of the target will also be weak.
Many beginners jump directly into exploitation without understanding the target properly. Experienced penetration testers spend a lot of time collecting information first.
In this blog, we are going to build a Python-based recon automation framework that can automate many common information gathering tasks used during penetration testing.
What is Network Reconnaissance?
Network reconnaissance means collecting information about systems before attempting exploitation.
The goal is to understand:
- Which hosts are alive
- Which ports are open
- What services are running
- What technologies are being used
- What operating system is running
- What possible attack surfaces exist
Why Automate Recon?
Manual reconnaissance becomes slow very quickly when dealing with multiple systems.
Automation helps save time and organize collected information properly.
| Benefit | Why it Matters |
|---|---|
| Speed | Faster scanning and data collection |
| Consistency | Reduces human mistakes |
| Scalability | Can scan larger environments |
| Organization | Keeps results structured |
Installing Required Libraries
Install all required libraries first.
pip install python-nmap requests shodan scapy colorama
Step 1: Discovering Live Hosts
Before scanning ports, we first need to know which systems are alive.
from scapy.all import *
import ipaddress
network = ipaddress.ip_network("192.168.1.0/24")
for ip in network.hosts():
packet = IP(dst=str(ip))/ICMP()
response = sr1(packet, timeout=1, verbose=0)
if response:
print(f"[+] Host Alive: {ip}")
Explanation:
- ICMP packets are used to check if a system responds.
- This works similar to the ping command.
- If the host replies, it is probably alive.
Important Thing Beginners Should Know
Some systems block ICMP requests.
That means:
Step 2: Building a TCP Port Scanner
Now we check which ports are open on the target system.
import socket
target = "192.168.1.10"
ports = [21, 22, 80, 443, 3306]
for port in ports:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex((target, port))
if result == 0:
print(f"[+] Port {port} OPEN")
sock.close()
Explanation:
connect_ex()tries to connect to the port.- If the result is 0, the connection was successful.
- This means the port is open.
Why Open Ports Matter
Open ports expose services.
| Port | Service |
|---|---|
| 22 | SSH |
| 80 | HTTP |
| 443 | HTTPS |
| 3306 | MySQL |
Step 3: Faster Scanning with Threads
Scanning ports one by one is slow.
Threads help us scan multiple ports at the same time.
import socket
import threading
target = "192.168.1.10"
def scan(port):
sock = socket.socket()
sock.settimeout(1)
result = sock.connect_ex((target, port))
if result == 0:
print(f"[+] Port {port} OPEN")
sock.close()
for port in range(1, 1025):
thread = threading.Thread(target=scan, args=(port,))
thread.start()
Step 4: Banner Grabbing
Banner grabbing helps identify service versions.
Sometimes servers reveal useful information like software names and versions.
import socket
target = "192.168.1.10"
port = 80
sock = socket.socket()
sock.connect((target, port))
banner = sock.recv(1024)
print(banner.decode())
sock.close()
Why Banner Grabbing is Useful
Service versions can help identify known vulnerabilities.
Apache 2.4.49 → search for known vulnerabilities related to that version.
Step 5: Service Enumeration with Nmap
Instead of building everything manually, we can automate Nmap using Python.
import nmap
scanner = nmap.PortScanner()
target = "192.168.1.10"
scanner.scan(target, arguments="-sV")
for host in scanner.all_hosts():
for proto in scanner[host].all_protocols():
ports = scanner[host][proto].keys()
for port in ports:
service = scanner[host][proto][port]
print(f"""
Port: {port}
Service: {service['name']}
Product: {service.get('product')}
Version: {service.get('version')}
""")
What Does -sV Mean?
-sV tells Nmap to perform service version detection.
Step 6: OS Fingerprinting
Different operating systems behave differently on networks.
scanner.scan(target, arguments="-O")
Step 7: HTTP Header Analysis
Web servers often leak useful information through headers.
import requests
url = "http://example.com"
response = requests.get(url)
for key, value in response.headers.items():
print(f"{key}: {value}")
Interesting Headers
| Header | Purpose |
|---|---|
| Server | Shows web server software |
| X-Powered-By | Shows backend technology |
| Set-Cookie | Session handling information |
Step 8: Web Technology Fingerprinting
Detecting technologies helps understand what the website is built with.
import requests
response = requests.get("http://example.com")
html = response.text.lower()
if "wp-content" in html:
print("[+] WordPress detected")
if "django" in html:
print("[+] Django indicators found")
Step 9: Using Shodan API
Shodan collects information about internet-connected devices.
import shodan
API_KEY = "YOUR_API_KEY"
api = shodan.Shodan(API_KEY)
target = "8.8.8.8"
result = api.host(target)
print(f"""
Organization: {result.get('org')}
Operating System: {result.get('os')}
Open Ports: {result.get('ports')}
""")
Step 10: Saving Results
Good recon also means organizing your findings properly.
with open("recon_results.txt", "a") as file:
file.write("Port 80 OPEN\\n")
Full Recon Automation Script
Now we combine multiple techniques together.
import socket
import threading
import requests
import nmap
TARGET = "192.168.1.10"
OPEN_PORTS = []
def port_scan(port):
sock = socket.socket()
sock.settimeout(1)
result = sock.connect_ex((TARGET, port))
if result == 0:
OPEN_PORTS.append(port)
print(f"[+] Port {port} OPEN")
sock.close()
for port in range(1, 1025):
thread = threading.Thread(target=port_scan, args=(port,))
thread.start()
scanner = nmap.PortScanner()
scanner.scan(TARGET, arguments="-sV")
for host in scanner.all_hosts():
for proto in scanner[host].all_protocols():
ports = scanner[host][proto].keys()
for port in ports:
service = scanner[host][proto][port]
print(f"""
Port: {port}
Service: {service['name']}
Product: {service.get('product')}
Version: {service.get('version')}
""")
try:
response = requests.get(f"http://{TARGET}", timeout=3)
print(response.headers)
except:
pass
Common Mistakes Beginners Make
- Ignoring timeouts
- Scanning too aggressively
- Not handling errors properly
- Creating too many threads
- Not saving scan results
Practice Ideas
- Add UDP scanning support
- Export results into JSON format
- Add screenshot capture for websites
- Create a recon dashboard
- Add subdomain enumeration
Important Warning
Final Thoughts
Reconnaissance is one of the most valuable skills in penetration testing.
The better your understanding of the target, the better your decisions become later during testing.
Learning how to automate recon also improves your understanding of networking, protocols, threading, and service behavior.
Comments
Post a Comment