Python for Cybersecurity Engineers
Overview
Python is the de facto scripting language of the security industry. Whether you are automating log analysis, building custom OSINT tools, interacting with threat intelligence APIs, or writing proof-of-concept exploits, Python's rich ecosystem and readable syntax make it the right tool for almost every security task.
This reference covers practical Python for security practitioners - not an introduction to programming, but a focused guide to the patterns, libraries, and scripts that security engineers actually use on the job.
Why Python for Security?
| Use Case | Python Advantage | Key Libraries |
|---|---|---|
| Log analysis and parsing | Regex, file I/O, data manipulation | re, json, csv, pandas |
| Network reconnaissance | Low-level socket control, packet crafting | socket, scapy, nmap |
| OSINT automation | HTTP requests, HTML parsing, API calls | requests, BeautifulSoup, shodan |
| Threat intel integration | REST API consumption, JSON handling | requests, json, vt-py |
| File and malware analysis | Binary parsing, hash computation | hashlib, pefile, yara-python |
| Cryptography | Hashing, encoding, cipher operations | hashlib, base64, cryptography |
| Exploit development | Binary manipulation, struct packing | struct, ctypes, pwntools |
| Security tool automation | Subprocess control, API wrappers | subprocess, python-nmap, impacket |
Python Essentials for Security Work
These core Python patterns appear constantly in security scripts. Master these before moving on to specialized libraries.
File Operations
# Read file line by line (memory efficient for large logs)
with open('access.log', 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
line = line.strip()
# process line
# Read entire file
with open('config.txt', 'r') as f:
content = f.read()
# Write output
with open('findings.txt', 'w') as f:
f.write('Finding: SQL injection at /api/users\n')
# Append to file
with open('results.log', 'a') as f:
f.write(f'[{timestamp}] Scanned {target}\n')
# Read binary file
with open('suspicious.bin', 'rb') as f:
data = f.read()
print(data[:16].hex()) # First 16 bytes as hex
Regular Expressions
import re
# Extract IP addresses from text
text = "Connection from 192.168.1.100 to 10.0.0.5 blocked"
ip_pattern = r'\b(?:\d{1,3}\.){3}\d{1,3}\b'
ips = re.findall(ip_pattern, text)
print(ips) # ['192.168.1.100', '10.0.0.5']
# Extract email addresses
email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
emails = re.findall(email_pattern, text)
# Extract URLs
url_pattern = r'https?://[^\s<>"{}|\\^`\[\]]+'
urls = re.findall(url_pattern, text)
# Extract domains
domain_pattern = r'(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}'
domains = re.findall(domain_pattern, text)
# Named groups for structured extraction
log_pattern = r'(?P\d+\.\d+\.\d+\.\d+).*?(?P\d{3}).*?(?P\d+)'
match = re.search(log_pattern, '192.168.1.1 - - [26/Aug/2026] "GET /" 200 1234')
if match:
print(match.group('ip'), match.group('status'))
Working with JSON and CSV
import json
import csv
# Parse JSON response
with open('api_response.json', 'r') as f:
data = json.load(f)
print(data['malicious']) # Access nested fields
# Parse JSON string
response_text = '{"ip": "1.2.3.4", "malicious": true}'
parsed = json.loads(response_text)
# Write JSON output
findings = [{"ip": "1.2.3.4", "severity": "high"}]
with open('output.json', 'w') as f:
json.dump(findings, f, indent=2)
# Parse CSV log
with open('firewall.csv', 'r') as f:
reader = csv.DictReader(f)
for row in reader:
if row['action'] == 'deny':
print(f"Blocked: {row['src_ip']} -> {row['dst_ip']}:{row['dst_port']}")
# Write CSV results
fieldnames = ['ip', 'count', 'threat_level']
with open('results.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'ip': '1.2.3.4', 'count': 52, 'threat_level': 'high'})
Log Parsing
Log parsing is one of the most common Python use cases for security analysts. Python excels at processing large volumes of structured and semi-structured log data quickly.
Apache / Nginx Access Log Parser
import re
from collections import Counter
LOG_PATTERN = re.compile(
r'(?P\S+)\s+\S+\s+\S+\s+\[(?P
Windows Event Log Parser
import json
from datetime import datetime
# Parse Windows Event Log JSON export (from Security Onion / ELK)
ALERT_EVENT_IDS = {
4625: 'Failed Logon',
4648: 'Explicit Credential Logon',
4688: 'Process Creation',
4698: 'Scheduled Task Created',
4720: 'User Account Created',
4776: 'NTLM Auth Attempt',
7045: 'New Service Installed'
}
def analyze_windows_events(filepath):
failed_logons = {}
alerts = []
with open(filepath, 'r') as f:
for line in f:
try:
event = json.loads(line)
except json.JSONDecodeError:
continue
event_id = event.get('EventID')
if event_id not in ALERT_EVENT_IDS:
continue
# Track failed logon attempts per source IP
if event_id == 4625:
src_ip = event.get('IpAddress', 'unknown')
failed_logons[src_ip] = failed_logons.get(src_ip, 0) + 1
# Alert on brute force threshold
if failed_logons[src_ip] >= 5:
alerts.append({
'type': 'Potential Brute Force',
'source_ip': src_ip,
'attempts': failed_logons[src_ip]
})
else:
alerts.append({
'type': ALERT_EVENT_IDS[event_id],
'event_id': event_id,
'details': event
})
return alerts, failed_logons
Network Scripting
Python provides powerful tools for network reconnaissance, port scanning, and packet analysis. Always use these tools only on networks and systems you own or have explicit written authorization to test.
Port Scanner
import socket
import concurrent.futures
from datetime import datetime
def scan_port(host, port, timeout=1):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(timeout)
result = sock.connect_ex((host, port))
sock.close()
return port if result == 0 else None
except Exception:
return None
def port_scan(host, ports=None, max_workers=100):
if ports is None:
ports = range(1, 1025) # Top 1024 ports
open_ports = []
print(f"Scanning {host} - {datetime.now()}")
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
results = executor.map(lambda p: scan_port(host, p), ports)
open_ports = [port for port in results if port is not None]
print(f"Open ports: {sorted(open_ports)}")
return sorted(open_ports)
# Common port ranges
COMMON_PORTS = [21,22,23,25,53,80,110,143,443,445,
993,995,1433,1521,3306,3389,5432,5985,8080,8443]
open_ports = port_scan('192.168.1.1', COMMON_PORTS)
Banner Grabbing
import socket
def grab_banner(host, port, timeout=3):
try:
sock = socket.socket()
sock.settimeout(timeout)
sock.connect((host, port))
# Send HTTP request for web ports
if port in [80, 8080, 8000]:
sock.send(b'HEAD / HTTP/1.0\r\n\r\n')
elif port == 443:
# Would need ssl.wrap_socket for HTTPS
pass
else:
sock.send(b'\r\n')
banner = sock.recv(1024).decode('utf-8', errors='ignore').strip()
sock.close()
return banner
except Exception as e:
return f"Error: {e}"
# Check for vulnerable service versions
targets = [('192.168.1.10', 22), ('192.168.1.10', 80), ('192.168.1.10', 21)]
for host, port in targets:
banner = grab_banner(host, port)
print(f"[{host}:{port}] {banner[:100]}")
Scapy - Packet Crafting
# pip install scapy
from scapy.all import *
# ARP scan - discover live hosts on subnet
def arp_scan(network):
arp = ARP(pdst=network)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp
result = srp(packet, timeout=3, verbose=0)[0]
hosts = []
for sent, received in result:
hosts.append({'ip': received.psrc, 'mac': received.hwsrc})
return hosts
hosts = arp_scan("192.168.1.0/24")
for host in hosts:
print(f"IP: {host['ip']:15} MAC: {host['mac']}")
# TCP SYN scan (stealth scan)
def syn_scan(target, ports):
open_ports = []
for port in ports:
pkt = IP(dst=target)/TCP(dport=port, flags='S')
resp = sr1(pkt, timeout=1, verbose=0)
if resp and resp.haslayer(TCP):
if resp[TCP].flags == 0x12: # SYN-ACK
open_ports.append(port)
send(IP(dst=target)/TCP(dport=port, flags='R'), verbose=0)
return open_ports
# DNS lookup
def dns_lookup(domain, record_type='A'):
result = sr1(IP(dst='8.8.8.8')/UDP()/DNS(rd=1, qd=DNSQR(qname=domain, qtype=record_type)), verbose=0)
if result and result.haslayer(DNS):
return result[DNS].an
Web Requests & OSINT Automation
The requests library is essential for interacting with web applications and APIs. Combined with BeautifulSoup for HTML parsing, it powers most Python-based OSINT and web reconnaissance workflows.
HTTP Requests Essentials
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
# Session with retry logic and timeout
def create_session(retries=3, backoff=0.3, timeout=10):
session = requests.Session()
retry = Retry(total=retries, backoff_factor=backoff,
status_forcelist=[429, 500, 502, 503, 504])
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
session.headers.update({
'User-Agent': 'Mozilla/5.0 (compatible; SecurityScanner/1.0)'
})
return session, timeout
session, timeout = create_session()
# GET request
response = session.get('https://target.com', timeout=timeout, verify=False)
print(response.status_code)
print(dict(response.headers)) # Check security headers
# POST request (login form)
payload = {'username': 'admin', 'password': 'test'}
response = session.post('https://target.com/login', data=payload, timeout=timeout)
# Check for missing security headers
security_headers = ['X-Frame-Options', 'X-Content-Type-Options',
'Content-Security-Policy', 'Strict-Transport-Security']
for header in security_headers:
status = '✓' if header in response.headers else '✗ MISSING'
print(f"{status} {header}")
Subdomain Enumeration
import requests
import concurrent.futures
def check_subdomain(subdomain, domain, timeout=3):
url = f"https://{subdomain}.{domain}"
try:
resp = requests.get(url, timeout=timeout, verify=False,
allow_redirects=True)
return {
'subdomain': f"{subdomain}.{domain}",
'status': resp.status_code,
'title': extract_title(resp.text)
}
except requests.exceptions.RequestException:
return None
def extract_title(html):
import re
match = re.search(r']*>([^<]+) ', html, re.IGNORECASE)
return match.group(1).strip() if match else 'No title'
def enumerate_subdomains(domain, wordlist_path, max_workers=50):
with open(wordlist_path, 'r') as f:
subdomains = [line.strip() for line in f if line.strip()]
found = []
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {executor.submit(check_subdomain, sub, domain): sub
for sub in subdomains}
for future in concurrent.futures.as_completed(futures):
result = future.result()
if result:
found.append(result)
print(f"[+] {result['subdomain']} ({result['status']})")
return found
Web Scraping for OSINT
# pip install requests beautifulsoup4
import requests
from bs4 import BeautifulSoup
import re
def extract_emails_from_url(url):
try:
response = requests.get(url, timeout=10,
headers={'User-Agent': 'Mozilla/5.0'})
soup = BeautifulSoup(response.text, 'html.parser')
# Extract from text
emails = set(re.findall(
r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}',
soup.get_text()
))
# Extract from mailto links
for link in soup.find_all('a', href=True):
href = link['href']
if href.startswith('mailto:'):
emails.add(href[7:].split('?')[0])
return emails
except Exception as e:
print(f"Error: {e}")
return set()
def extract_metadata(url):
response = requests.get(url, timeout=10)
soup = BeautifulSoup(response.text, 'html.parser')
metadata = {}
# Meta tags
for meta in soup.find_all('meta'):
name = meta.get('name', meta.get('property', ''))
content = meta.get('content', '')
if name and content:
metadata[name] = content
# Technology fingerprinting from headers
headers = dict(response.headers)
tech_headers = ['X-Powered-By', 'Server', 'X-Generator', 'X-AspNet-Version']
for h in tech_headers:
if h in headers:
metadata[h] = headers[h]
return metadata
Threat Intelligence API Integration
Python makes it straightforward to integrate with major open source and free-tier threat intelligence platforms. These scripts allow analysts to automate IOC enrichment and reputation lookups at scale.
VirusTotal API
import requests
import time
VT_API_KEY = 'YOUR_API_KEY'
VT_BASE = 'https://www.virustotal.com/api/v3'
def vt_check_ip(ip):
headers = {'x-apikey': VT_API_KEY}
response = requests.get(f"{VT_BASE}/ip_addresses/{ip}", headers=headers)
if response.status_code == 200:
data = response.json()['data']['attributes']
stats = data.get('last_analysis_stats', {})
return {
'ip': ip,
'malicious': stats.get('malicious', 0),
'suspicious': stats.get('suspicious', 0),
'harmless': stats.get('harmless', 0),
'country': data.get('country', 'Unknown'),
'asn': data.get('asn', 'Unknown')
}
return None
def vt_check_hash(file_hash):
headers = {'x-apikey': VT_API_KEY}
response = requests.get(f"{VT_BASE}/files/{file_hash}", headers=headers)
if response.status_code == 200:
data = response.json()['data']['attributes']
stats = data.get('last_analysis_stats', {})
return {
'hash': file_hash,
'malicious': stats.get('malicious', 0),
'name': data.get('meaningful_name', 'Unknown'),
'type': data.get('type_description', 'Unknown'),
'size': data.get('size', 0)
}
return None
def bulk_ip_lookup(ip_list, delay=15):
# Free tier: 4 lookups/minute
results = []
for i, ip in enumerate(ip_list):
result = vt_check_ip(ip)
if result:
results.append(result)
flag = '🔴 MALICIOUS' if result['malicious'] > 0 else '✅ Clean'
print(f"{flag} {ip} - {result['malicious']} detections")
if i < len(ip_list) - 1:
time.sleep(delay) # Respect rate limits
return results
Shodan API
# pip install shodan
import shodan
SHODAN_API_KEY = 'YOUR_API_KEY'
api = shodan.Shodan(SHODAN_API_KEY)
def shodan_lookup_ip(ip):
try:
host = api.host(ip)
return {
'ip': host['ip_str'],
'org': host.get('org', 'Unknown'),
'os': host.get('os', 'Unknown'),
'country': host.get('country_name', 'Unknown'),
'open_ports': [item['port'] for item in host['data']],
'banners': [(item['port'], item.get('data', '')[:100])
for item in host['data']],
'vulns': list(host.get('vulns', {}).keys())
}
except shodan.APIError as e:
return {'error': str(e)}
def shodan_search(query, limit=10):
try:
results = api.search(query, limit=limit)
hosts = []
for result in results['matches']:
hosts.append({
'ip': result['ip_str'],
'port': result['port'],
'org': result.get('org', 'Unknown'),
'banner': result.get('data', '')[:200]
})
return hosts
except shodan.APIError as e:
print(f"Shodan error: {e}")
return []
# Example queries
results = shodan_search('apache 2.4.51 vuln:CVE-2021-41773')
results = shodan_search('product:nginx version:1.14')
results = shodan_search('org:"Target Company" port:3389')
AbuseIPDB API
import requests
ABUSEIPDB_KEY = 'YOUR_API_KEY'
def check_abuseipdb(ip, max_age_days=90):
url = 'https://api.abuseipdb.com/api/v2/check'
headers = {'Accept': 'application/json', 'Key': ABUSEIPDB_KEY}
params = {'ipAddress': ip, 'maxAgeInDays': max_age_days, 'verbose': True}
response = requests.get(url, headers=headers, params=params)
if response.status_code == 200:
data = response.json()['data']
return {
'ip': data['ipAddress'],
'abuse_score': data['abuseConfidenceScore'],
'country': data['countryCode'],
'isp': data['isp'],
'total_reports': data['totalReports'],
'is_whitelisted': data['isWhitelisted'],
'domain': data.get('domain', 'Unknown')
}
return None
def bulk_abuse_check(ip_list):
for ip in ip_list:
result = check_abuseipdb(ip)
if result:
score = result['abuse_score']
level = '🔴 HIGH' if score > 80 else '🟡 MEDIUM' if score > 25 else '🟢 LOW'
print(f"{level} {ip} - Score: {score} | Reports: {result['total_reports']}")
File & Hash Analysis
import hashlib
import os
def hash_file(filepath):
hashes = {
'md5': hashlib.md5(),
'sha1': hashlib.sha1(),
'sha256': hashlib.sha256()
}
with open(filepath, 'rb') as f:
while chunk := f.read(8192):
for h in hashes.values():
h.update(chunk)
return {algo: h.hexdigest() for algo, h in hashes.items()}
def hash_directory(dirpath, extensions=None):
results = []
for root, dirs, files in os.walk(dirpath):
for filename in files:
filepath = os.path.join(root, filename)
if extensions and not any(filename.endswith(e) for e in extensions):
continue
try:
hashes = hash_file(filepath)
results.append({
'path': filepath,
'size': os.path.getsize(filepath),
**hashes
})
except (PermissionError, OSError):
continue
return results
# Extract strings from binary
def extract_strings(filepath, min_length=4):
with open(filepath, 'rb') as f:
data = f.read()
import re
# ASCII strings
ascii_strings = re.findall(
rb'[\x20-\x7e]{' + str(min_length).encode() + rb',}', data
)
return [s.decode('ascii') for s in ascii_strings]
# Check file against known malicious hashes (threat intel feed)
def check_hash_blocklist(filepath, blocklist_path):
file_hash = hash_file(filepath)['sha256']
with open(blocklist_path, 'r') as f:
blocklist = {line.strip().lower() for line in f}
return file_hash.lower() in blocklist
Cryptography Basics
import hashlib
import base64
import binascii
# Hashing
def hash_string(text, algorithm='sha256'):
h = hashlib.new(algorithm)
h.update(text.encode('utf-8'))
return h.hexdigest()
print(hash_string('password123', 'md5'))
print(hash_string('password123', 'sha256'))
# Base64 encode/decode
encoded = base64.b64encode(b'Hello, World!').decode()
decoded = base64.b64decode(encoded).decode()
# URL-safe Base64
url_encoded = base64.urlsafe_b64encode(b'data').decode()
# Hex encode/decode
hex_str = binascii.hexlify(b'Hello').decode() # '48656c6c6f'
raw = binascii.unhexlify(hex_str) # b'Hello'
# ROT13 (common CTF encoding)
import codecs
rot13 = codecs.encode('Hello', 'rot_13')
# XOR - common in malware
def xor_decode(data, key):
if isinstance(data, str):
data = bytes.fromhex(data)
key_bytes = key.encode() if isinstance(key, str) else key
return bytes(b ^ key_bytes[i % len(key_bytes)] for i, b in enumerate(data))
# Symmetric encryption with Fernet (modern, safe)
# pip install cryptography
from cryptography.fernet import Fernet
key = Fernet.generate_key()
f = Fernet(key)
token = f.encrypt(b"Secret message")
decrypted = f.decrypt(token)
Automation Scripts
IOC Extractor from Text
import re
def extract_iocs(text):
iocs = {
'ips': [],
'domains': [],
'urls': [],
'emails': [],
'hashes': {'md5': [], 'sha1': [], 'sha256': []}
}
# IPs (exclude private ranges for external IOCs)
ip_pattern = r'\b(?!10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.)(?:\d{1,3}\.){3}\d{1,3}\b'
iocs['ips'] = list(set(re.findall(ip_pattern, text)))
# Domains (basic pattern)
domain_pattern = r'\b(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+(?:com|net|org|io|ru|cn|cc|xyz|top|info)\b'
iocs['domains'] = list(set(re.findall(domain_pattern, text, re.IGNORECASE)))
# URLs
url_pattern = r'https?://[^\s<>"\'{}|\\^`\[\]]+'
iocs['urls'] = list(set(re.findall(url_pattern, text)))
# Email addresses
email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
iocs['emails'] = list(set(re.findall(email_pattern, text)))
# File hashes
iocs['hashes']['md5'] = list(set(re.findall(r'\b[a-fA-F0-9]{32}\b', text)))
iocs['hashes']['sha1'] = list(set(re.findall(r'\b[a-fA-F0-9]{40}\b', text)))
iocs['hashes']['sha256'] = list(set(re.findall(r'\b[a-fA-F0-9]{64}\b', text)))
return iocs
# Usage
with open('threat_report.txt', 'r') as f:
content = f.read()
iocs = extract_iocs(content)
print(f"IPs: {len(iocs['ips'])}")
print(f"Domains: {len(iocs['domains'])}")
print(f"SHA256: {len(iocs['hashes']['sha256'])}")
Automated Security Header Checker
import requests
import json
SECURITY_HEADERS = {
'Strict-Transport-Security': 'HSTS not set - vulnerable to SSL stripping',
'Content-Security-Policy': 'CSP missing - XSS risk increased',
'X-Frame-Options': 'Clickjacking protection missing',
'X-Content-Type-Options': 'MIME sniffing attacks possible',
'Referrer-Policy': 'Referrer data may leak to third parties',
'Permissions-Policy': 'Browser features not restricted'
}
def check_security_headers(url):
try:
resp = requests.get(url, timeout=10, verify=False,
allow_redirects=True)
headers = {k.lower(): v for k, v in resp.headers.items()}
findings = []
for header, risk in SECURITY_HEADERS.items():
if header.lower() not in headers:
findings.append({
'header': header,
'status': 'MISSING',
'risk': risk,
'severity': 'Medium'
})
else:
findings.append({
'header': header,
'status': 'Present',
'value': headers[header.lower()]
})
# Check for information disclosure
info_headers = ['Server', 'X-Powered-By', 'X-AspNet-Version']
for h in info_headers:
if h.lower() in headers:
findings.append({
'header': h,
'status': 'EXPOSES INFO',
'value': headers[h.lower()],
'severity': 'Low'
})
return findings
except Exception as e:
return [{'error': str(e)}]
# Check multiple targets
targets = ['https://example.com', 'https://target.org']
for url in targets:
print(f"\n=== {url} ===")
for finding in check_security_headers(url):
status = finding.get('status', '')
if status == 'MISSING':
print(f" ✗ {finding['header']}: {finding['risk']}")
elif status == 'EXPOSES INFO':
print(f" ! {finding['header']}: {finding['value']}")
else:
print(f" ✓ {finding['header']}")
Reusable Script Templates
Standard Security Script Template
#!/usr/bin/env python3
"""
Script Name: security_tool.py
Description: [What this script does]
Author: CMTA Cyber
Usage: python3 security_tool.py -t TARGET -o output.json
"""
import argparse
import json
import logging
import sys
from datetime import datetime
from pathlib import Path
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
handlers=[
logging.StreamHandler(sys.stdout),
logging.FileHandler('script.log')
]
)
log = logging.getLogger(__name__)
def parse_args():
parser = argparse.ArgumentParser(description='Security Tool')
parser.add_argument('-t', '--target', required=True, help='Target host or file')
parser.add_argument('-o', '--output', default='output.json', help='Output file')
parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output')
parser.add_argument('--timeout', type=int, default=10, help='Timeout in seconds')
return parser.parse_args()
def main():
args = parse_args()
if args.verbose:
logging.getLogger().setLevel(logging.DEBUG)
log.info(f"Starting scan against {args.target}")
start_time = datetime.now()
results = {
'target': args.target,
'timestamp': start_time.isoformat(),
'findings': []
}
try:
# Main logic here
pass
except KeyboardInterrupt:
log.warning("Scan interrupted by user")
except Exception as e:
log.error(f"Unexpected error: {e}")
sys.exit(1)
finally:
duration = (datetime.now() - start_time).seconds
log.info(f"Completed in {duration}s - {len(results['findings'])} findings")
# Save results
output_path = Path(args.output)
with open(output_path, 'w') as f:
json.dump(results, f, indent=2, default=str)
log.info(f"Results saved to {output_path}")
if __name__ == '__main__':
main()
Essential Security Libraries
| Library | Purpose | Install |
|---|---|---|
| requests | HTTP client - web app testing, API calls | pip install requests |
| scapy | Packet crafting, network analysis, ARP scanning | pip install scapy |
| python-nmap | Nmap automation and result parsing | pip install python-nmap |
| BeautifulSoup4 | HTML parsing for web scraping and OSINT | pip install beautifulsoup4 |
| shodan | Shodan API client for internet-wide scanning | pip install shodan |
| vt-py | VirusTotal API client | pip install vt-py |
| impacket | Windows network protocols - SMB, Kerberos, NTLM | pip install impacket |
| pwntools | CTF and exploit development toolkit | pip install pwntools |
| cryptography | Modern cryptographic operations | pip install cryptography |
| yara-python | YARA rule scanning for malware detection | pip install yara-python |
| pefile | Windows PE file analysis | pip install pefile |
| volatility3 | Memory forensics framework | pip install volatility3 |
| pandas | Data analysis for large log datasets | pip install pandas |
| paramiko | SSH client for remote automation | pip install paramiko |
| python-whois | WHOIS lookups for domain intelligence | pip install python-whois |
| dnspython | DNS queries and zone transfer testing | pip install dnspython |
python3 -m venv venv && source venv/bin/activate before installing any security library.