Python for Security¶
Python scripting for security professionals: socket programming for port scanning and banner grabbing, log analysis with regex, HTTP requests for web testing, subprocess for tool integration, and practical security script patterns.
Key Facts¶
- Python's
socketmodule provides raw TCP/UDP networking for port scanning and banner grabbing ThreadPoolExecutorenables parallel port scanning (100+ threads)requestslibrary routes through Burp proxy viaproxiesparameter for web testingargparseprovides professional CLI argument handling for security toolsremodule parses log files for IP extraction, auth failure analysis- Always use
withstatements for file/socket cleanup
Network Socket Basics¶
TCP Client / Banner Grabbing¶
import socket
def grab_banner(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3)
try:
sock.connect((host, port))
sock.send(b"HEAD / HTTP/1.1\r\nHost: %s\r\n\r\n" % host.encode())
return sock.recv(4096).decode(errors='ignore')
except:
return None
finally:
sock.close()
Threaded Port Scanner¶
import socket
from concurrent.futures import ThreadPoolExecutor
def check_port(host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
result = sock.connect_ex((host, port))
sock.close()
return port if result == 0 else None
def scan_host(host, ports=range(1, 1025), threads=100):
open_ports = []
with ThreadPoolExecutor(max_workers=threads) as executor:
futures = {executor.submit(check_port, host, p): p for p in ports}
for future in futures:
result = future.result()
if result:
open_ports.append(result)
return sorted(open_ports)
Log Analysis¶
Auth Log Parser¶
import re
def analyze_auth_log(filepath):
failed_attempts = {}
pattern = r'Failed password for (\w+) from ([\d.]+) port (\d+)'
with open(filepath) as f:
for line in f:
if "Failed password" in line:
match = re.search(r'from ([\d.]+)', line)
if match:
ip = match.group(1)
failed_attempts[ip] = failed_attempts.get(ip, 0) + 1
return dict(sorted(failed_attempts.items(), key=lambda x: x[1], reverse=True))
Regex Patterns for Security¶
import re
# Extract IP addresses
ips = re.findall(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', log_text)
# Match email addresses
emails = re.findall(r'[\w.+-]+@[\w-]+\.[\w.]+', text)
# Parse auth failures
pattern = r'Failed password for (\w+) from ([\d.]+) port (\d+)'
for match in re.finditer(pattern, auth_log):
user, ip, port = match.groups()
HTTP Requests for Web Testing¶
import requests
# GET request
resp = requests.get("https://api.example.com/endpoints", verify=True)
# POST with Burp proxy
resp = requests.post(
"https://target.com/login",
data={"username": "admin", "password": "test"},
headers={"User-Agent": "Mozilla/5.0"},
proxies={"http": "http://127.0.0.1:8080",
"https": "http://127.0.0.1:8080"},
allow_redirects=False
)
print(resp.status_code, resp.headers, resp.text[:500])
File I/O for Security Data¶
# Read log files
with open("/var/log/auth.log") as f:
for line in f:
if "Failed password" in line:
print(line.strip())
# JSON handling
import json
with open("scan_results.json") as f:
results = json.load(f)
# CSV output
import csv
with open("vulnerabilities.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=["cve", "severity", "host"])
writer.writeheader()
writer.writerows(findings)
Subprocess for Tool Integration¶
import subprocess
result = subprocess.run(
["nmap", "-sV", "-p", "1-1000", target],
capture_output=True, text=True, timeout=120
)
print(result.stdout)
# Ping sweep
def ping_host(ip):
result = subprocess.run(
["ping", "-c", "1", "-W", "1", ip],
capture_output=True, text=True
)
return result.returncode == 0
CLI Argument Parsing¶
import argparse
parser = argparse.ArgumentParser(description='Port Scanner')
parser.add_argument('target', help='Target IP address')
parser.add_argument('-p', '--ports', default='1-1024', help='Port range')
parser.add_argument('-t', '--threads', type=int, default=100)
parser.add_argument('-v', '--verbose', action='store_true')
args = parser.parse_args()
Practical Patterns¶
Password Strength Checker¶
import re
def check_password_strength(password):
checks = {
"length >= 12": len(password) >= 12,
"uppercase": bool(re.search(r'[A-Z]', password)),
"lowercase": bool(re.search(r'[a-z]', password)),
"digit": bool(re.search(r'\d', password)),
"special": bool(re.search(r'[!@#$%^&*]', password)),
}
return sum(checks.values()), checks
Error Handling¶
import socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)
sock.connect((host, port))
banner = sock.recv(1024).decode()
except socket.timeout:
print(f"Connection to {host}:{port} timed out")
except ConnectionRefusedError:
print(f"Port {port} is closed")
except Exception as e:
print(f"Error: {type(e).__name__}: {e}")
finally:
sock.close()
Gotchas¶
- Raw socket scanning may require root/admin privileges
socket.settimeout()is essential - without it, connections to filtered ports hang indefinitelyrequests.get()withverify=Falsedisables TLS validation - only for testing with Burp proxysubprocess.run()with shell=True is vulnerable to command injection - avoid with user input- Large thread counts in port scanning can exhaust file descriptors - use reasonable limits
See Also¶
- [[penetration-testing-methodology]] - tools Python scripts automate
- [[burp-suite-and-web-pentesting]] - routing requests through proxy
- [[network-traffic-analysis]] - complementary to Python scanning
- [[linux-system-hardening]] - log files Python scripts analyze