Python Cybersecurity & Ethical Hacking

Python has become an essential language for cybersecurity professionals and ethical hackers due to its simplicity, flexibility, and the vast ecosystem of security-focused libraries. This guide covers fundamental techniques, tools, and best practices for using Python in cybersecurity and ethical hacking.

⚠️ Important Disclaimer:

The techniques described in this guide should only be used on systems you own or have explicit permission to test. Unauthorized hacking is illegal and unethical. Always practice responsible disclosure and follow legal and ethical guidelines.

Network Scanning and Reconnaissance

Network Scanning with Scapy

Scapy is a powerful packet manipulation library that allows you to create, send, and analyze network packets. It's widely used for network scanning, probing, and building custom network tools.

# Install scapy
# pip install scapy

from scapy.all import *

# Basic ping scan (ICMP Echo Request)
def ping_scan(target_ip):
    """Simple ping scan to check if host is alive"""
    
    # Create ICMP Echo Request packet
    packet = IP(dst=target_ip)/ICMP()
    
    # Send packet and wait for response
    response = sr1(packet, timeout=2, verbose=0)
    
    if response:
        print(f"Host {target_ip} is up!")
        return True
    else:
        print(f"No response from {target_ip}")
        return False

# TCP SYN scan (half-open scan)
def syn_scan(target_ip, ports):
    """SYN scan to check for open ports"""
    
    open_ports = []
    
    for port in ports:
        # Create SYN packet
        packet = IP(dst=target_ip)/TCP(dport=port, flags="S")
        
        # Send packet and wait for response
        response = sr1(packet, timeout=1, verbose=0)
        
        if response and response.haslayer(TCP):
            # Check for SYN-ACK response (flag 0x12)
            if response.getlayer(TCP).flags == 0x12:
                # Send RST packet to close connection
                rst_packet = IP(dst=target_ip)/TCP(dport=port, flags="R")
                send(rst_packet, verbose=0)
                
                open_ports.append(port)
                print(f"Port {port} is open on {target_ip}")
    
    return open_ports

# Example usage
target = "192.168.1.1"  # Replace with your target IP

# First check if host is alive
if ping_scan(target):
    # Then scan common ports
    common_ports = [21, 22, 23, 25, 53, 80, 443, 445, 3389]
    open_ports = syn_scan(target, common_ports)
    
    if open_ports:
        print(f"Found {len(open_ports)} open ports: {open_ports}")
    else:
        print("No open ports found")

Web Application Security

Web Application Testing

Python offers several libraries for testing web application security, including requests for basic HTTP interactions and more specialized tools for vulnerability scanning.

# Install required packages
# pip install requests beautifulsoup4

import requests
from bs4 import BeautifulSoup
import re
import urllib.parse

# Function to find potential XSS vulnerabilities
def scan_for_xss(url):
    """Basic scanner to identify potential XSS vulnerabilities in forms"""
    
    print(f"Scanning {url} for potential XSS vulnerabilities...")
    
    try:
        # Request the page
        response = requests.get(url)
        response.raise_for_status()
        
        # Parse HTML
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # Find all forms
        forms = soup.find_all('form')
        print(f"Found {len(forms)} forms on the page")
        
        for i, form in enumerate(forms, 1):
            print(f"\nAnalyzing form #{i}:")
            
            # Get form action
            action = form.get('action', '')
            method = form.get('method', 'get').lower()
            
            # Resolve relative URL
            if action.startswith('/'):
                parsed_url = urllib.parse.urlparse(url)
                base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
                form_url = base_url + action
            elif action.startswith('http'):
                form_url = action
            else:
                form_url = url + '/' + action
            
            print(f"Form action: {form_url}")
            print(f"Form method: {method}")
            
            # Find input fields
            inputs = form.find_all(['input', 'textarea'])
            print(f"Input fields found: {len(inputs)}")
            
            for input_field in inputs:
                field_type = input_field.get('type', 'text')
                field_name = input_field.get('name', '')
                
                if field_type.lower() in ['text', 'search', 'url', 'textarea', 'password']:
                    print(f"  Potential XSS point: {field_name} (type: {field_type})")
        
        # Check for URL parameters
        parsed_url = urllib.parse.urlparse(url)
        if parsed_url.query:
            print("\nURL parameters detected (potential XSS points):")
            params = urllib.parse.parse_qs(parsed_url.query)
            for param, value in params.items():
                print(f"  Parameter: {param}")
        
    except requests.exceptions.RequestException as e:
        print(f"Error scanning {url}: {e}")

# Function to test for SQL injection vulnerabilities
def test_sql_injection(url, params=None):
    """Basic test for SQL injection by adding a single quote to parameters"""
    
    print(f"Testing {url} for SQL injection vulnerabilities...")
    
    # SQL error patterns to look for
    sql_errors = [
        "SQL syntax", "mysql_fetch", "ORA-", "Oracle", 
        "SQLSTATE", "PostgreSQL", "SQLite3::", "Microsoft SQL"
    ]
    
    try:
        # If no params provided, try to extract from URL
        if not params:
            parsed_url = urllib.parse.urlparse(url)
            params = dict(urllib.parse.parse_qsl(parsed_url.query))
        
        if not params:
            print("No parameters found to test")
            return
        
        # Test each parameter
        for param in params:
            # Create a copy and modify the parameter value with a single quote
            test_params = params.copy()
            test_params[param] = params[param] + "'"
            
            response = requests.get(url, params=test_params)
            
            # Check for SQL error messages
            for error in sql_errors:
                if error in response.text:
                    print(f"Potential SQL injection found in parameter: {param}")
                    print(f"Error pattern matched: {error}")
                    print(f"Test URL: {response.url}")
                    return
        
        print("No obvious SQL injection vulnerabilities detected")
    
    except requests.exceptions.RequestException as e:
        print(f"Error testing {url}: {e}")

# Example usage
target_url = "http://example.com/login"  # Replace with your target URL
scan_for_xss(target_url)

# Test SQL injection on a URL with parameters
sql_test_url = "http://example.com/search"
test_params = {"q": "test", "page": "1"}
test_sql_injection(sql_test_url, test_params)

Password Cracking and Hash Analysis

Python can be used for password cracking, hash generation, and cryptographic analysis.

# Install required packages
# pip install hashlib passlib

import hashlib
import string
import itertools
import time
from passlib.hash import bcrypt

# Function to generate MD5 hash
def md5_hash(text):
    """Generate MD5 hash for a given string"""
    return hashlib.md5(text.encode()).hexdigest()

# Function to verify bcrypt hash
def verify_bcrypt(password, hashed):
    """Verify if a password matches a bcrypt hash"""
    return bcrypt.verify(password, hashed)

# Dictionary attack
def dictionary_attack(hash_to_crack, dictionary_file, hash_function=md5_hash):
    """Perform a dictionary attack on a hash"""
    
    start_time = time.time()
    attempts = 0
    
    print(f"Starting dictionary attack on hash: {hash_to_crack}")
    
    try:
        with open(dictionary_file, 'r', encoding='utf-8', errors='ignore') as file:
            for line in file:
                password = line.strip()
                attempts += 1
                
                # Calculate hash
                password_hash = hash_function(password)
                
                # Check if hashes match
                if password_hash == hash_to_crack:
                    elapsed_time = time.time() - start_time
                    print(f"Password found: {password}")
                    print(f"Attempts: {attempts}")
                    print(f"Time elapsed: {elapsed_time:.2f} seconds")
                    return password
                
                # Progress update every 100,000 attempts
                if attempts % 100000 == 0:
                    print(f"Tried {attempts} passwords...")
        
        elapsed_time = time.time() - start_time
        print(f"Password not found after {attempts} attempts")
        print(f"Time elapsed: {elapsed_time:.2f} seconds")
        return None
        
    except FileNotFoundError:
        print(f"Dictionary file not found: {dictionary_file}")
        return None

# Brute force attack (for demonstration - very inefficient for longer passwords)
def brute_force(hash_to_crack, charset=string.ascii_lowercase, max_length=4, hash_function=md5_hash):
    """Perform a brute force attack on a hash"""
    
    start_time = time.time()
    attempts = 0
    
    print(f"Starting brute force attack on hash: {hash_to_crack}")
    print(f"Character set: {charset}")
    print(f"Maximum password length: {max_length}")
    
    # Try different password lengths
    for length in range(1, max_length + 1):
        print(f"Trying passwords of length {length}...")
        
        # Generate all possible combinations
        for password_tuple in itertools.product(charset, repeat=length):
            password = ''.join(password_tuple)
            attempts += 1
            
            # Calculate hash
            password_hash = hash_function(password)
            
            # Check if hashes match
            if password_hash == hash_to_crack:
                elapsed_time = time.time() - start_time
                print(f"Password found: {password}")
                print(f"Attempts: {attempts}")
                print(f"Time elapsed: {elapsed_time:.2f} seconds")
                return password
            
            # Progress update every 1,000,000 attempts
            if attempts % 1000000 == 0:
                print(f"Tried {attempts} passwords...")
    
    elapsed_time = time.time() - start_time
    print(f"Password not found after {attempts} attempts")
    print(f"Time elapsed: {elapsed_time:.2f} seconds")
    return None

# Example usage
# hash_to_crack = "5f4dcc3b5aa765d61d8327deb882cf99"  # MD5 hash of "password"
# dictionary_file = "wordlist.txt"  # Replace with path to your wordlist
# recovered_password = dictionary_attack(hash_to_crack, dictionary_file)

# For very short passwords, you might use brute force
# simple_hash = "900150983cd24fb0d6963f7d28e17f72"  # MD5 hash of "abc"
# brute_force(simple_hash, max_length=3)

System Security and Privilege Escalation

Python provides tools for system security analysis and privilege escalation testing.

# System security analysis tools
import os
import platform
import subprocess
import psutil
import pwd
import grp

# Function to gather system information
def system_info():
    """Gather basic system information"""
    
    info = {
        "System": platform.system(),
        "Node": platform.node(),
        "Release": platform.release(),
        "Version": platform.version(),
        "Machine": platform.machine(),
        "Processor": platform.processor()
    }
    
    print("System Information:")
    for key, value in info.items():
        print(f"  {key}: {value}")
    
    return info

# Function to check for SUID binaries (Linux only)
def find_suid_binaries():
    """Find SUID binaries that might be used for privilege escalation"""
    
    if platform.system() != "Linux":
        print("This function is only supported on Linux systems")
        return []
    
    try:
        # Find SUID binaries
        command = "find /usr /bin /sbin /var -type f -perm -4000 2>/dev/null"
        result = subprocess.run(command, shell=True, capture_output=True, text=True)
        
        suid_binaries = result.stdout.strip().split('\n')
        
        print(f"Found {len(suid_binaries)} SUID binaries:")
        for binary in suid_binaries:
            if binary:  # Skip empty lines
                print(f"  {binary}")
        
        return suid_binaries
        
    except subprocess.SubprocessError as e:
        print(f"Error executing command: {e}")
        return []

# Function to check for writable directories
def find_writable_dirs():
    """Find world-writable directories"""
    
    try:
        if platform.system() == "Linux" or platform.system() == "Darwin":
            command = "find / -type d -perm -o+w 2>/dev/null"
            result = subprocess.run(command, shell=True, capture_output=True, text=True)
            
            writable_dirs = result.stdout.strip().split('\n')
            
            print(f"Found {len(writable_dirs)} world-writable directories:")
            for directory in writable_dirs[:10]:  # Show only first 10
                if directory:  # Skip empty lines
                    print(f"  {directory}")
            
            if len(writable_dirs) > 10:
                print(f"  ... and {len(writable_dirs) - 10} more")
            
            return writable_dirs
        else:
            print("This function is best supported on Linux/Unix systems")
            return []
            
    except subprocess.SubprocessError as e:
        print(f"Error executing command: {e}")
        return []

# Example usage
# system_info()
# find_suid_binaries()
# find_writable_dirs()

Encryption and Secure Communications

Python provides libraries for encryption, decryption, and establishing secure communications.

# Install required packages
# pip install cryptography

from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import serialization, hashes

# Symmetric encryption with Fernet
def symmetric_encryption_example():
    """Example of symmetric encryption using Fernet"""
    
    # Generate a key
    key = Fernet.generate_key()
    print(f"Symmetric Key: {key.decode()}")
    
    # Create a Fernet instance
    cipher = Fernet(key)
    
    # Message to encrypt
    message = b"Sensitive information that needs to be encrypted"
    
    # Encrypt the message
    encrypted = cipher.encrypt(message)
    print(f"Encrypted: {encrypted.decode()}")
    
    # Decrypt the message
    decrypted = cipher.decrypt(encrypted)
    print(f"Decrypted: {decrypted.decode()}")
    
    return key, encrypted, decrypted

# Asymmetric encryption with RSA
def asymmetric_encryption_example():
    """Example of asymmetric encryption using RSA"""
    
    # Generate private key
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048
    )
    
    # Extract public key
    public_key = private_key.public_key()
    
    # Serialize keys to PEM format
    private_pem = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.PKCS8,
        encryption_algorithm=serialization.NoEncryption()
    )
    
    public_pem = public_key.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo
    )
    
    print("RSA Key Pair Generated:")
    print(f"Private Key: {private_pem.decode()[:64]}...")
    print(f"Public Key: {public_pem.decode()[:64]}...")
    
    # Message to encrypt
    message = b"Secret message for asymmetric encryption"
    
    # Encrypt with public key
    encrypted = public_key.encrypt(
        message,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    
    print(f"Encrypted: {encrypted[:20]}...")
    
    # Decrypt with private key
    decrypted = private_key.decrypt(
        encrypted,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=hashes.SHA256()),
            algorithm=hashes.SHA256(),
            label=None
        )
    )
    
    print(f"Decrypted: {decrypted.decode()}")
    
    return private_key, public_key, encrypted, decrypted

# Example usage
# symmetric_encryption_example()
# asymmetric_encryption_example()

Ethical Hacking Tools and Frameworks

Python provides several specialized frameworks and libraries for ethical hacking and security testing.

Tool/Framework Purpose Installation
Scapy Network packet crafting and analysis pip install scapy
Nmap-Python Network discovery and security auditing pip install python-nmap
Impacket Network protocols implementation pip install impacket
Requests HTTP library for web testing pip install requests
BeautifulSoup HTML parsing for web scraping pip install beautifulsoup4
PyCryptodome Cryptographic toolkit pip install pycryptodome
Paramiko SSH implementation pip install paramiko
# Example using python-nmap for port scanning
# pip install python-nmap

import nmap

# Initialize scanner
scanner = nmap.PortScanner()

# Function to perform a comprehensive scan
def nmap_scan(target, scan_type='-sV'):
    """
    Perform an nmap scan on the target
    scan_type options:
        -sV: Version detection
        -sS: SYN scan
        -A: OS detection, version detection, script scanning, and traceroute
        -T4: Faster execution
    """
    
    print(f"Starting Nmap scan of {target} with options: {scan_type}")
    
    try:
        # Perform the scan
        scanner.scan(target, '22-443', arguments=scan_type)
        
        # Print scan info
        print(f"Nmap version: {scanner.nmap_version()}")
        print(f"Scan info: {scanner.scaninfo()}")
        
        # Print results for each host
        for host in scanner.all_hosts():
            print(f"\nHost: {host}")
            print(f"State: {scanner[host].state()}")
            
            # Print protocols
            for proto in scanner[host].all_protocols():
                print(f"\nProtocol: {proto}")
                
                # Get all open ports
                ports = sorted(scanner[host][proto].keys())
                
                for port in ports:
                    service = scanner[host][proto][port]
                    print(f"Port {port}: {service['state']}")
                    
                    # Print service details if available
                    if 'product' in service:
                        print(f"  Service: {service['product']}")
                    if 'version' in service:
                        print(f"  Version: {service['version']}")
        
        return scanner
        
    except nmap.PortScannerError as e:
        print(f"Scan failed: {e}")
        return None
    except Exception as e:
        print(f"An error occurred: {e}")
        return None

# Example usage
# target_ip = "192.168.1.1"  # Replace with your target IP
# nmap_scan(target_ip, '-sV -T4')

Best Practices and Ethics

Ethical Guidelines

  • Always obtain proper authorization before testing any system
  • Define the scope of your testing clearly and stay within boundaries
  • Document all activities and findings thoroughly
  • Practice responsible disclosure of vulnerabilities
  • Never damage or disrupt systems during testing
  • Protect sensitive data discovered during testing
  • Follow all applicable laws and regulations

Technical Best Practices

  • Use dedicated test environments whenever possible
  • Implement rate limiting in your scripts to avoid DoS
  • Secure your own tools and ensure they can't be weaponized
  • Keep comprehensive logs of all security testing
  • Test during off-peak hours to minimize impact
  • Have a rollback plan in case of unexpected issues
  • Use secure channels for communicating findings

Practice Exercises

Practice your cybersecurity skills in controlled environments:

  1. Create a basic port scanner with Scapy or python-nmap
  2. Build a tool to detect common web vulnerabilities in a test environment
  3. Implement a basic encryption and decryption program
  4. Create a password strength checker
  5. Set up a controlled environment using virtual machines to practice ethical hacking

Legal Training Environments

  • OWASP WebGoat: Deliberately vulnerable web application for learning
  • Hack The Box: Online platform for testing and advancing cybersecurity skills
  • TryHackMe: Hands-on cybersecurity training platform
  • VulnHub: Provides vulnerable VMs for practice
  • Capture The Flag (CTF) competitions: Practice in competitive environments