Tools decide what you can find; scripting decides how fast and how repeatably you find it. This page covers the two languages that carry most security work — Python and Bash — the core tool categories of an offensive/defensive workflow, worked command examples you can actually run in a lab, and the concepts that turn a one-off hack into a reusable capability.
A manual task done once is a task. Done a hundred times across a /16 subnet, it's a liability — slow, inconsistent, and impossible to hand to a teammate. Scripting converts skill into an artifact: something that runs the same way every time, documents your method, and scales from one host to ten thousand without extra effort.
A loop enumerates 254 hosts while you read the first result. Recon that took an afternoon becomes a coffee break.
The script never forgets a flag or mistypes a target. Findings become reproducible — which is what evidence requires.
Parameterise once, run forever. A good wrapper outlives the engagement it was written for.
Every command on this page assumes a system you own or are explicitly contracted to test. In the UK, unauthorised access or testing is an offence under the Computer Misuse Act 1990. Scope and written permission come before any tool runs.
Python dominates security work because it reads like pseudocode, ships a large standard library, and has a mature ecosystem for everything from raw packet crafting to web automation. You can prototype a tool in minutes and still have it be maintainable.
| Library | Used for | Typical task |
|---|---|---|
requests | HTTP client | API interaction, web enumeration, auth flows |
scapy | Packet crafting / sniffing | Custom scans, ARP work, protocol fuzzing |
pwntools | Exploit development | Binary exploitation, CTFs, shellcode, I/O |
impacket | Windows protocols | SMB, Kerberos, secretsdump, psexec, wmiexec |
paramiko | SSH client/server | Automated SSH, SFTP, remote command runners |
beautifulsoup4 / lxml | HTML/XML parsing | Scraping, OSINT, response parsing |
cryptography / pycryptodome | Crypto primitives | Hashing, symmetric/asymmetric, token work |
argparse | CLI parsing (stdlib) | Turning a script into a proper tool |
The standard library alone is enough for a usable scanner. This one uses a thread pool so it finishes in seconds rather than scanning serially, and takes its target and range from the command line.
#!/usr/bin/env python3
import socket, sys, argparse
from concurrent.futures import ThreadPoolExecutor
def probe(host, port, timeout=0.6):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.settimeout(timeout)
if s.connect_ex((host, port)) == 0:
try: banner = s.recv(64).decode(errors="ignore").strip()
except OSError: banner = ""
return port, banner
def main():
ap = argparse.ArgumentParser()
ap.add_argument("host")
ap.add_argument("-p", "--ports", default="1-1024")
a = ap.parse_args()
lo, hi = (int(x) for x in a.ports.split("-"))
with ThreadPoolExecutor(max_workers=200) as ex:
for r in ex.map(lambda p: probe(a.host, p), range(lo, hi+1)):
if r: print(f"[+] {r[0]:>5}/tcp open {r[1]}")
if __name__ == "__main__":
main()
Run with python3 scanner.py 10.10.10.10 -p 1-65535. For real engagements you'd reach for nmap (below) — but writing your own teaches you exactly what a connect-scan is, which is the point.
Wrap network I/O in try/except and a timeout every time. On a real network, hosts hang, reset, and lie. A scanner that crashes on the first unreachable host is useless.
Bash is rarely where the logic lives, but it's where tools get connected. Its superpower is the pipeline: the output of one program becomes the input of the next, so a handful of small, focused utilities compose into something larger. Master grep, awk, sed, cut, sort, uniq, xargs and you can reshape almost any text.
| Tool | Job | Example |
|---|---|---|
grep | Filter lines by pattern | grep -Eo '[0-9.]+' hosts.txt |
awk | Field extraction & logic | awk '{print $1}' access.log |
sed | Stream find/replace | sed 's/http:/https:/g' |
cut | Split on a delimiter | cut -d: -f1 /etc/passwd |
sort | uniq -c | Count unique values | sort | uniq -c | sort -rn |
xargs | Turn lines into arguments | cat ips.txt | xargs -P10 -I{} nmap {} |
#!/usr/bin/env bash
# usage: ./recon.sh targets.txt (one host/CIDR per line)
set -euo pipefail # fail fast, catch unset vars
out="loot/$(date +%F_%H%M)"; mkdir -p "$out"
while read -r target; do
[[ -z "$target" ]] && continue # skip blank lines
echo "[*] scanning $target"
nmap -sV -sC -oA "$out/${target//\//_}" "$target" \
| grep -E 'open|Nmap scan'
done < "$1"
echo "[+] results written to $out/"
set -euo pipefail — exit on error, on unset variables, and on failures inside a pipe. Quote every variable ("$var") so spaces and glob characters don't wreck you. And prefer [[ ]] over [ ] for tests.
You don't need to memorise every tool — you need to know which category a problem falls into, then pick the sharpest tool in it. The table below maps the standard kit to the phase of work it serves, with the invocation you'll reach for most.
| Category | Go-to tools | One command to know |
|---|---|---|
| Recon & enumeration passive + active | nmap, masscan, amass, subfinder, dnsx | subfinder -d target.com | dnsx -a |
| Web & API | Burp Suite, ffuf, feroxbuster, nikto, sqlmap, curl, jq | ffuf -u URL/FUZZ -w list.txt -mc 200,301 |
| Credential attacks | hashcat, John the Ripper, hydra, netexec | hashcat -m 1000 hashes rockyou.txt |
| Exploitation & post-exp | Metasploit, impacket, evil-winrm, sliver | impacket-secretsdump dom/u:p@host |
| Network & traffic | Wireshark, tcpdump, tshark, netcat | tcpdump -i eth0 -w cap.pcap port 445 |
| OSINT & recon-ng | theHarvester, sherlock, maltego, Google dorks | theHarvester -d target.com -b all |
| Automation | python, bash, cron, docker, ansible | 0 */6 * * * /opt/recon/run.sh |
Nmap is the recon workhorse. Knowing a handful of flags well beats knowing fifty badly. The scan type controls how packets are sent; the options control what else nmap does with what it finds.
-sS SYN / "half-open" — fast, default as root-sT full TCP connect — no root needed-sU UDP — slow but finds DNS, SNMP, etc.-sn ping sweep — host discovery only-sV service/version detection-sC default NSE scripts (safe recon)-O OS fingerprinting-p- all 65,535 ports · -T4 faster timing-oA base output in all 3 formats# stage 1: fast — find which ports are open at all
nmap -sS -p- --min-rate 5000 -oN ports.txt 10.10.10.10
# stage 2: deep — version + scripts on just those ports
ports=$(grep open ports.txt | cut -d/ -f1 | paste -sd,)
nmap -sV -sC -p"$ports" -oA full 10.10.10.10
The two-stage pattern — a fast sweep to find open ports, then a slow deep scan on only those — is the single most useful nmap habit. It turns an hour-long -p- -sV into a couple of minutes.
Cracking recovers plaintext from a captured hash by hashing guesses and comparing. Whether it succeeds in seconds or never comes down to two things: the hash algorithm (fast hashes like NTLM fall quickly; slow ones like bcrypt resist) and the attack mode.
| Mode | Attack | What it does |
|---|---|---|
-a 0 | Straight (dictionary) | Each wordlist entry, optionally mutated by rules |
-a 1 | Combinator | Joins two wordlists together |
-a 3 | Mask (brute-force) | Charset patterns, e.g. ?u?l?l?l?d?d |
-a 6 / -a 7 | Hybrid | Wordlist + mask (append or prepend) |
-m)# dictionary + best64 mutation rules against NTLM hashes
hashcat -m 1000 -a 0 hashes.txt rockyou.txt -r rules/best64.rule
# show what cracked
hashcat -m 1000 hashes.txt --show
If a fast hash (MD5, NTLM, unsalted SHA1) protects your passwords, length is your only real defence — and attackers crack short ones in minutes on a single GPU. This is why modern systems use slow, salted hashes (bcrypt, Argon2, scrypt) and why credential-stuffing works so well against reused passwords.
Pattern-matching text — extracting IPs, hashes, tokens and emails from noise. \b\d{1,3}(\.\d{1,3}){3}\b finds IPv4 addresses. Learn them on regex101.
Almost every modern service speaks JSON over HTTP. Parsing responses (jq in shell, json/requests in Python) is how you automate against them.
Networks fail constantly. Code that assumes success breaks on the first dropped packet. Timeouts, retries and graceful failure aren't optional.
Track changes, roll back mistakes, share tooling. git is also how you pull the thousands of community tools that live on GitHub.
The difference between someone who uses tools and someone who builds them is a short feedback loop. The cycle is the same whether you're writing a 10-line wrapper or a full framework:
--help. This is what separates a script from a tool.cron, a container, or a pipeline so it runs without you.PayloadsAllTheThings and HackTricks are the two reference libraries most practitioners keep open. Read the code, understand it, adapt it — don't paste blindly.