Appendix A: Tool Reference

This appendix provides comprehensive reference cards for the command-line tools used throughout this book. Each tool section includes its purpose, essential subcommands and flags, real command examples with representative output snippets, and security-specific usage patterns. These are the tools that appear in chapter exercises and real-world incident response workflows alike.

All commands in this appendix are meant to be run in a lab environment or against systems you own.
Running scanning or enumeration tools against systems without explicit authorization is illegal
in most jurisdictions and a violation of professional ethics.

openssl

Purpose: The Swiss Army knife of TLS/SSL, certificates, cryptographic operations, and key management. If it involves a certificate, a key, a hash, or encrypted data, openssl is almost certainly the tool you reach for first.

s_client — TLS Connection Testing

The s_client subcommand establishes a TLS connection to a remote server, displaying every detail of the handshake, certificate chain, and negotiated parameters. It is the single most useful command for debugging TLS issues.

# Connect to a server and display the full certificate chain
openssl s_client -connect example.com:443 -servername example.com

Representative output (abbreviated):

CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, CN = DigiCert Global Root G2
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
verify return:1
depth=0 CN = example.com
verify return:1
---
SSL handshake has read 3456 bytes and written 392 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
# Show certificate details without entering interactive mode
openssl s_client -connect example.com:443 -servername example.com \
    </dev/null 2>/dev/null | openssl x509 -noout -text

# Check certificate expiration dates
openssl s_client -connect example.com:443 -servername example.com \
    </dev/null 2>/dev/null | openssl x509 -noout -dates
# Output:
# notBefore=Jan 13 00:00:00 2025 GMT
# notAfter=Feb 12 23:59:59 2026 GMT

# Force a specific TLS version
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3

# Show the negotiated cipher suite
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | \
    grep "Cipher is"
# Output: New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384

# Test with client certificate (mTLS)
openssl s_client -connect api.internal.com:443 \
    -cert client.crt -key client.key -CAfile ca.crt

# Test STARTTLS for mail protocols
openssl s_client -connect mail.example.com:587 -starttls smtp
openssl s_client -connect mail.example.com:143 -starttls imap
openssl s_client -connect mail.example.com:110 -starttls pop3

# Display the full certificate chain (all certs)
openssl s_client -connect example.com:443 -showcerts </dev/null

# Check OCSP stapling support
openssl s_client -connect example.com:443 -status </dev/null 2>/dev/null | \
    grep -A 5 "OCSP Response"

# Verify against a specific CA bundle
openssl s_client -connect example.com:443 \
    -CAfile /etc/ssl/certs/ca-certificates.crt

# Test a specific cipher suite
openssl s_client -connect example.com:443 \
    -cipher 'ECDHE-RSA-AES256-GCM-SHA384'

Key flags:

FlagPurpose
-connect host:portServer to connect to
-servernameSNI hostname (required for virtual hosting)
-showcertsDisplay all certificates in the chain
-tls1_2, -tls1_3Force specific TLS version
-starttls protoSTARTTLS for smtp, imap, ftp, pop3, etc.
-cert, -keyClient certificate and private key (mTLS)
-CAfileCA certificate file for verification
-statusRequest OCSP stapling response
-cipherSpecify cipher suite to test
-briefCompact output format

x509 — Certificate Inspection and Conversion

The x509 subcommand reads, converts, and inspects X.509 certificates. Use it to examine any certificate in detail.

# View full certificate details
openssl x509 -in cert.pem -noout -text

# View specific fields
openssl x509 -in cert.pem -noout -subject -issuer -dates
# Output:
# subject=CN = example.com, O = Example Inc, C = US
# issuer=CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1, O = DigiCert Inc, C = US
# notBefore=Jan 13 00:00:00 2025 GMT
# notAfter=Feb 12 23:59:59 2026 GMT

# Get the SHA-256 fingerprint
openssl x509 -in cert.pem -noout -fingerprint -sha256
# Output: sha256 Fingerprint=3B:A1:...

# Extract the public key from a certificate
openssl x509 -in cert.pem -noout -pubkey > pubkey.pem

# Check if a certificate matches a private key (modulus comparison)
openssl x509 -in cert.pem -noout -modulus | openssl sha256
openssl rsa -in key.pem -noout -modulus | openssl sha256
# If the SHA-256 hashes match, the certificate and key correspond

# View Subject Alternative Names (SANs)
openssl x509 -in cert.pem -noout -ext subjectAltName
# Output: X509v3 Subject Alternative Name:
#     DNS:example.com, DNS:www.example.com, DNS:api.example.com

# Convert DER (binary) to PEM (base64)
openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM

# Convert PEM to DER
openssl x509 -in cert.pem -outform DER -out cert.der

# Verify a certificate against a CA chain
openssl verify -CAfile ca-chain.pem cert.pem
# Output: cert.pem: OK

req — Certificate Signing Requests

The req subcommand generates private keys, creates Certificate Signing Requests, and produces self-signed certificates for testing.

# Generate a private key and CSR in one command
openssl req -new -newkey rsa:2048 -nodes \
    -keyout server.key -out server.csr \
    -subj "/CN=example.com/O=MyOrg/C=US"

# Generate a CSR from an existing key
openssl req -new -key server.key -out server.csr

# Generate a self-signed certificate (testing only — never for production)
openssl req -x509 -newkey rsa:4096 -nodes \
    -keyout key.pem -out cert.pem -days 365 \
    -subj "/CN=localhost"

# Generate a CSR with Subject Alternative Names
openssl req -new -key server.key -out server.csr \
    -config <(cat <<EOF
[req]
distinguished_name = req_dn
req_extensions = v3_req
prompt = no
[req_dn]
CN = example.com
O = MyOrg
C = US
[v3_req]
subjectAltName = DNS:example.com,DNS:www.example.com,IP:10.0.1.50
EOF
)

# Inspect a CSR
openssl req -in server.csr -noout -text -verify
# Output: verify OK
# Certificate Request:
#     Data:
#         Subject: CN = example.com, O = MyOrg, C = US
#         Subject Public Key Info:
#             Public Key Algorithm: rsaEncryption
#                 Public-Key: (2048 bit)

# Generate an EC-based CSR (ECDSA P-256)
openssl ecparam -genkey -name prime256v1 -out ec.key
openssl req -new -key ec.key -out ec.csr \
    -subj "/CN=example.com/O=MyOrg/C=US"

dgst — Hash and Signature Operations

# Compute SHA-256 hash of a file
openssl dgst -sha256 firmware.bin
# Output: SHA2-256(firmware.bin)= 7b3f2a...

# Compute SHA-384 hash
openssl dgst -sha384 firmware.bin

# Compute HMAC with a secret key
openssl dgst -sha256 -hmac "my-secret-key" message.txt

# Sign a file with a private key (create a digital signature)
openssl dgst -sha256 -sign private.key -out file.sig file.bin

# Verify a digital signature
openssl dgst -sha256 -verify public.key -signature file.sig file.bin
# Output: Verified OK

# Compare file integrity across transfers
openssl dgst -sha256 original.tar.gz downloaded.tar.gz

enc — Symmetric Encryption and Encoding

# Encrypt a file with AES-256-CBC (password-based)
openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 \
    -in secrets.txt -out secrets.enc

# Decrypt
openssl enc -aes-256-cbc -d -pbkdf2 -iter 100000 \
    -in secrets.enc -out secrets.txt

# Encrypt with an explicit key and IV (for automated workflows)
KEY=$(openssl rand -hex 32)
IV=$(openssl rand -hex 16)
openssl enc -aes-256-cbc -K "$KEY" -iv "$IV" \
    -in plain.txt -out encrypted.bin

# Base64 encode and decode
openssl enc -base64 -in binary.dat -out encoded.txt
openssl enc -base64 -d -in encoded.txt -out binary.dat

# List all available ciphers
openssl enc -list
Never use `-pbkdf2` without specifying `-iter`. The default iteration count may be
too low. Use at least 100,000 iterations for password-based encryption.

pkcs12 — Certificate Bundle Management

PKCS#12 files (.p12 or .pfx) bundle a certificate, its private key, and optionally the CA chain into a single encrypted file. Common for importing into browsers, Java keystores, and Windows certificate stores.

# Create a PKCS#12 file from cert + key + CA chain
openssl pkcs12 -export -out bundle.p12 \
    -inkey server.key -in server.crt -certfile ca-chain.pem

# Extract the certificate from a PKCS#12 file
openssl pkcs12 -in bundle.p12 -clcerts -nokeys -out cert.pem

# Extract the private key from a PKCS#12 file
openssl pkcs12 -in bundle.p12 -nocerts -nodes -out key.pem

# Extract the CA certificates
openssl pkcs12 -in bundle.p12 -cacerts -nokeys -out ca.pem

# View the contents of a PKCS#12 file
openssl pkcs12 -in bundle.p12 -info -noout

verify — Certificate Chain Validation

# Verify a certificate against the system's default CA store
openssl verify cert.pem

# Verify against a specific CA file
openssl verify -CAfile ca.pem cert.pem

# Verify a full chain (intermediate + leaf)
openssl verify -CAfile root.pem -untrusted intermediate.pem leaf.pem
# Output: leaf.pem: OK

# Check a certificate's purpose
openssl verify -purpose sslserver -CAfile ca.pem server.pem

# Verbose verification (shows full chain)
openssl verify -verbose -CAfile ca.pem cert.pem

Key Generation

# Generate RSA key pair
openssl genrsa -out rsa_private.pem 4096
openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem

# Generate EC key pair (P-256, standard for TLS)
openssl ecparam -genkey -name prime256v1 -out ec_private.pem
openssl ec -in ec_private.pem -pubout -out ec_public.pem

# Generate Ed25519 key pair (modern, fast)
openssl genpkey -algorithm Ed25519 -out ed25519_private.pem
openssl pkey -in ed25519_private.pem -pubout -out ed25519_public.pem

# Generate cryptographically secure random bytes
openssl rand -hex 32          # 32 random bytes as hex (64 hex chars)
openssl rand -base64 24       # 24 random bytes as base64

# List available elliptic curves
openssl ecparam -list_curves

# List supported cipher suites for TLS 1.3
openssl ciphers -v -tls1_3

curl

Purpose: Command-line HTTP/HTTPS client for testing web services, APIs, TLS configurations, and security headers. The most versatile tool for probing web-facing services.

TLS and Certificate Options

# Show full TLS handshake details (the most useful debugging flag)
curl -v https://example.com 2>&1 | grep -E 'TLS|SSL|subject|issuer|expire'
# Output (abbreviated):
# * TLSv1.3 (OUT), TLS handshake, Client hello (1):
# * TLSv1.3 (IN), TLS handshake, Server hello (2):
# * subject: CN=example.com
# * issuer: C=US; O=DigiCert Inc; CN=DigiCert Global G2 TLS RSA SHA256 2020 CA1
# * expire date: Feb 12 23:59:59 2026 GMT

# Force a maximum TLS version
curl --tls-max 1.2 https://example.com

# Require TLS 1.3 minimum
curl --tlsv1.3 https://example.com

# Specify a cipher suite to test
curl --ciphers 'ECDHE-RSA-AES256-GCM-SHA384' https://example.com

# Client certificate authentication (mTLS)
curl --cert client.crt --key client.key --cacert ca.crt \
    https://api.internal.com/v1/status

# Skip certificate verification (testing only — NEVER in production)
curl -k https://self-signed.local:8443

# Pin a specific public key
curl --pinnedpubkey 'sha256//YhKJG+V3fGQmo8qqfmHB2JBGZ8ygFcIDAR/0p3aDFkQ=' \
    https://example.com

# Show full certificate chain information
curl -vI https://example.com 2>&1 | \
    awk '/Server certificate/,/issuer:/'
# Output:
# * Server certificate:
# *  subject: CN=example.com
# *  start date: Jan 13 00:00:00 2025 GMT
# *  expire date: Feb 12 23:59:59 2026 GMT
# *  issuer: C=US; O=DigiCert Inc; CN=DigiCert Global G2 ...

# Test with a custom CA certificate (internal PKI)
curl --cacert /path/to/internal-ca.pem https://internal-service.corp:443

HTTP Headers and Authentication

# Bearer token authentication
curl -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
     -H "Content-Type: application/json" \
     https://api.example.com/v2/users

# Basic authentication
curl -u admin:secret https://api.example.com/health

# POST with JSON body
curl -X POST https://api.example.com/data \
     -H "Content-Type: application/json" \
     -d '{"username": "test", "role": "viewer"}'

# Follow redirects and show the redirect chain
curl -L -v https://short.url/abc 2>&1 | grep "< Location:"

# Show only response headers
curl -I https://example.com

# Audit security-relevant response headers
curl -sI https://example.com | grep -iE \
    'strict-transport|content-security|x-frame|x-content|referrer|permissions|x-xss'
# Output:
# strict-transport-security: max-age=31536000; includeSubDomains; preload
# content-security-policy: default-src 'self'; script-src 'self'
# x-frame-options: DENY
# x-content-type-options: nosniff
# referrer-policy: strict-origin-when-cross-origin

# Send a cookie header
curl -b "session=abc123def456" https://example.com/dashboard

# Save cookies from a login, reuse them
curl -c cookies.txt -X POST https://example.com/login \
     -d "user=admin&pass=secret"
curl -b cookies.txt https://example.com/dashboard

# Download a file and verify its checksum
curl -O https://releases.example.com/app-v2.3.tar.gz
echo "a1b2c3d4e5f6...expected_hash  app-v2.3.tar.gz" | sha256sum -c

Verbose Mode, Debugging, and Timing

# Detailed timing breakdown for performance analysis
curl -o /dev/null -s -w "\
DNS Lookup:  %{time_namelookup}s\n\
TCP Connect: %{time_connect}s\n\
TLS Handshake: %{time_appconnect}s\n\
First Byte:  %{time_starttransfer}s\n\
Total:       %{time_total}s\n" \
    https://example.com
# Output:
# DNS Lookup:  0.024s
# TCP Connect: 0.048s
# TLS Handshake: 0.127s
# First Byte:  0.198s
# Total:       0.213s

# Full verbose output (shows request and response headers + TLS details)
curl -v https://example.com 2>&1

# Bypass DNS and resolve to a specific IP
curl --resolve example.com:443:10.0.1.50 https://example.com

# Rate-limited download
curl --limit-rate 1M -O https://example.com/largefile.zip

# Retry on transient failures
curl --retry 3 --retry-delay 5 --retry-all-errors \
    https://api.example.com/health

# Send a request through a proxy (useful for intercepting with Burp/mitmproxy)
curl -x http://127.0.0.1:8080 https://example.com

Key flags:

FlagPurpose
-vVerbose output (TLS handshake, headers, timing)
-sSilent mode (suppress progress bar)
-IHEAD request (response headers only)
-LFollow redirects
-o fileWrite response body to file
-OSave with remote filename
-H "Header: Value"Add custom request header
-d "data"Send POST data
-X METHODSpecify HTTP method (PUT, DELETE, PATCH)
-u user:passBasic auth credentials
-kSkip TLS certificate verification (insecure)
-w "format"Custom output format with variables
--cert, --keyClient certificate and key for mTLS
--cacertCustom CA certificate for verification
--resolve host:port:ipOverride DNS resolution
-x proxy_urlRoute request through a proxy

nmap

Purpose: Network scanner for host discovery, port scanning, service detection, and security assessment via the Nmap Scripting Engine (NSE). The standard tool for understanding what is running on a network and what is exposed.

Only run nmap against networks and systems you have explicit written authorization to scan.
Unauthorized scanning may violate laws such as the CFAA (US) or Computer Misuse Act (UK).

Scan Types

# TCP SYN scan — the default and most common (requires root)
# Sends SYN, waits for SYN-ACK (open) or RST (closed), never completes handshake
sudo nmap -sS 192.168.1.0/24

# TCP connect scan — completes the full handshake (no root required)
nmap -sT 192.168.1.0/24

# UDP scan — significantly slower than TCP (requires root)
sudo nmap -sU -p 53,123,161,500 192.168.1.100

# TCP ACK scan — determines firewall rulesets (filtered vs unfiltered)
sudo nmap -sA 192.168.1.100

# FIN scan — stealthier, may bypass simple packet filters
sudo nmap -sF 192.168.1.100

# Ping sweep — discover live hosts without port scanning
sudo nmap -sn 10.0.1.0/24

# Scan specific ports
nmap -p 22,80,443,3306,5432,6379,8080 192.168.1.100

# Scan a port range
nmap -p 1-1024 192.168.1.100

# Scan ALL 65535 ports
nmap -p- 192.168.1.100

# Fast scan (top 100 ports only)
nmap -F 192.168.1.0/24

# Timing templates: 0=paranoid, 1=sneaky, 2=polite, 3=normal, 4=aggressive, 5=insane
nmap -T4 192.168.1.0/24

# Skip host discovery (useful when ICMP is blocked)
nmap -Pn -p 80,443 192.168.1.100

Service and OS Detection

# Service version detection — probes open ports to identify running software
nmap -sV 192.168.1.100
# Output (example):
# PORT    STATE SERVICE  VERSION
# 22/tcp  open  ssh      OpenSSH 8.9p1 Ubuntu 3ubuntu0.6
# 80/tcp  open  http     nginx 1.24.0
# 443/tcp open  ssl/http nginx 1.24.0
# 3306/tcp open mysql    MySQL 8.0.36

# OS detection (requires root, needs at least one open and one closed port)
sudo nmap -O 192.168.1.100

# Aggressive scan — combines OS detection, version detection, scripts, and traceroute
nmap -A 192.168.1.100

# Increase version detection intensity (0-9, default 7)
nmap -sV --version-intensity 9 192.168.1.100

NSE Scripts (Nmap Scripting Engine)

NSE scripts extend nmap's capabilities for vulnerability detection, enumeration, and brute-force testing. Scripts are categorized: auth, broadcast, brute, default, discovery, dos, exploit, external, fuzzer, intrusive, malware, safe, version, vuln.

# Run default scripts (safe + version + discovery)
nmap -sC 192.168.1.100

# Enumerate SSL/TLS cipher suites and protocols
nmap --script ssl-enum-ciphers -p 443 example.com
# Output includes supported protocols, cipher suites, and strength ratings

# Check for Heartbleed vulnerability
nmap --script ssl-heartbleed -p 443 192.168.1.100

# Check for specific CVEs
nmap --script smb-vuln-ms17-010 -p 445 192.168.1.0/24
nmap --script http-vuln-cve2017-5638 -p 80,8080 192.168.1.100

# HTTP enumeration — titles, headers, methods, and server info
nmap --script http-title,http-headers,http-methods,http-server-header \
    -p 80,443,8080,8443 192.168.1.100

# DNS enumeration — brute-force subdomains
nmap --script dns-brute --script-args dns-brute.threads=10 example.com

# SSH enumeration — supported algorithms and auth methods
nmap --script ssh2-enum-algos,ssh-auth-methods -p 22 192.168.1.100

# Banner grabbing
nmap --script banner -p 21,22,25,80,110,143 192.168.1.100

# Run all vuln category scripts
nmap --script vuln 192.168.1.100

# Get help on a specific script
nmap --script-help ssl-enum-ciphers

# List available scripts matching a pattern
ls /usr/share/nmap/scripts/ | grep -i ssl
ls /usr/share/nmap/scripts/ | grep -i http

Output Formats

# Normal output to file
nmap -oN scan_results.txt 192.168.1.0/24

# XML output (for parsing and integration with other tools)
nmap -oX scan_results.xml 192.168.1.0/24

# Grepable output (one host per line, easy to script against)
nmap -oG scan_results.gnmap 192.168.1.0/24

# All three formats simultaneously
nmap -oA scan_results 192.168.1.0/24

# Append to output file (resume-friendly)
nmap --resume scan_results.xml

Key flags:

FlagPurpose
-sSTCP SYN scan (stealthy, requires root)
-sTTCP connect scan (no root needed)
-sUUDP scan (slow, requires root)
-snPing sweep (host discovery only)
-sVService version detection
-sCRun default NSE scripts
-OOS detection (requires root)
-AAggressive (OS + version + scripts + traceroute)
-p portsSpecify ports; -p- for all 65535
-T0-T5Timing template (paranoid to insane)
-FFast scan (top 100 ports)
-PnSkip host discovery (treat all hosts as up)
--script nameRun a specific NSE script
-oN/-oX/-oG/-oAOutput format (normal, XML, grepable, all)

Wireshark / tshark

Purpose: Packet capture and deep protocol analysis. Wireshark provides the GUI; tshark provides equivalent functionality on the command line. Both read and write pcap/pcapng files and understand hundreds of protocols.

Capture Filters vs. Display Filters

Wireshark uses two completely different filter languages. Capture filters (BPF syntax) are
applied during capture and determine what packets are saved. Display filters (Wireshark
syntax) are applied after capture and determine what is shown. You cannot use display filter
syntax as a capture filter or vice versa.

Capture Filters (BPF Syntax — Applied During Capture)

Capture filters reduce the volume of data written to disk. They use Berkeley Packet Filter syntax.

# Traffic to/from a specific host
host 192.168.1.100

# Only TCP traffic on port 443 (TLS)
tcp port 443

# Traffic on a subnet
net 10.0.1.0/24

# Only DNS traffic
port 53

# Only SYN packets (new TCP connections)
tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0

# Exclude noisy protocols
not arp and not icmp

# Combine: TLS traffic to/from a specific host
host 10.0.1.50 and tcp port 443

# Traffic between two specific hosts
host 10.0.1.50 and host 10.0.1.100

# Only HTTP traffic (unencrypted — useful for debugging)
tcp port 80

# Capture only traffic from a specific source
src host 10.0.1.50

# Capture DHCP traffic (client broadcasts)
udp port 67 or udp port 68

Display Filters (Wireshark Syntax — Applied After Capture)

Display filters operate on the decoded protocol fields and support rich comparison operators.

# --- Protocol filters ---
http                            # HTTP traffic
tls                             # TLS traffic
dns                             # DNS traffic
tcp                             # All TCP traffic
arp                             # ARP traffic
icmp                            # ICMP traffic
dhcp                            # DHCP traffic
kerberos                        # Kerberos authentication

# --- Address filters ---
ip.addr == 10.0.1.50           # Traffic to or from this IP
ip.src == 10.0.1.50            # Traffic from this IP
ip.dst == 10.0.1.50            # Traffic to this IP
eth.addr == aa:bb:cc:dd:ee:ff  # MAC address filter
ipv6.addr == fe80::1           # IPv6 address filter

# --- Port filters ---
tcp.port == 443                 # TCP port 443 (either direction)
tcp.dstport == 22               # Destination port 22 (SSH)
tcp.srcport == 8080             # Source port 8080
udp.port == 53                  # UDP port 53 (DNS)

# --- TCP flags and analysis ---
tcp.flags.syn == 1 && tcp.flags.ack == 0   # SYN only (new connections)
tcp.flags.rst == 1                          # RST packets (connection resets)
tcp.flags.fin == 1                          # FIN packets (connection teardown)
tcp.analysis.retransmission                 # Retransmitted segments
tcp.analysis.zero_window                    # Zero window events
tcp.analysis.duplicate_ack                  # Duplicate ACKs

# --- HTTP filters ---
http.request.method == "POST"               # POST requests
http.request.method == "GET"                # GET requests
http.response.code >= 400                   # Error responses (4xx, 5xx)
http.response.code == 401                   # Unauthorized responses
http.host contains "example"                # Requests to hostnames containing "example"
http.request.uri contains "/api"            # API requests
http.request.uri contains "passwd"          # Suspicious URI patterns
http.cookie contains "session"              # Requests with session cookies

# --- DNS filters ---
dns.qry.name contains "evil"               # Queries for suspicious domains
dns.flags.rcode == 3                        # NXDOMAIN responses
dns.qry.type == 1                           # A record queries
dns.qry.type == 28                          # AAAA record queries
dns.qry.type == 15                          # MX record queries
dns.qry.type == 255                         # ANY queries (often abuse)
dns.resp.len > 512                          # Large DNS responses (tunneling?)

# --- TLS filters ---
tls.handshake.type == 1                     # Client Hello
tls.handshake.type == 2                     # Server Hello
tls.handshake.type == 11                    # Certificate message
tls.handshake.extensions_server_name        # SNI (Server Name Indication)
tls.record.version == 0x0303               # TLS 1.2
tls.alert_message                           # TLS alerts (errors)

# --- Logical operators ---
ip.src == 10.0.1.50 && tcp.dstport == 443  # AND
dns || http                                  # OR
!(arp || icmp || dns)                        # NOT (exclude noisy traffic)
http.request || http.response                # All HTTP messages

tshark — Command-Line Packet Analysis

# Capture packets on an interface
sudo tshark -i eth0 -w capture.pcap

# Capture with a capture filter
sudo tshark -i eth0 -f "tcp port 443" -w tls_traffic.pcap

# Read and display a capture file
tshark -r capture.pcap

# Apply a display filter to a capture file
tshark -r capture.pcap -Y "http.request"

# Extract specific fields (tab-separated)
tshark -r capture.pcap -Y "dns.qry.name" \
    -T fields -e frame.time -e ip.src -e dns.qry.name
# Output:
# Jan 15, 2025 10:23:45  10.0.1.50  example.com
# Jan 15, 2025 10:23:46  10.0.1.50  api.example.com

# Protocol hierarchy statistics
tshark -r capture.pcap -q -z io,phs

# TCP conversation statistics
tshark -r capture.pcap -q -z conv,tcp

# Endpoint statistics (top talkers)
tshark -r capture.pcap -q -z endpoints,ip

# Follow a TCP stream (stream index 5)
tshark -r capture.pcap -q -z follow,tcp,ascii,5

# Export HTTP objects (files downloaded over HTTP)
tshark -r capture.pcap --export-objects http,/tmp/exported/

# Export TLS keys (if SSLKEYLOGFILE was set during capture)
tshark -r capture.pcap -o tls.keylog_file:keys.log -Y "http"

# Capture for a specific duration (60 seconds)
sudo tshark -i eth0 -a duration:60 -w one_minute.pcap

# Ring buffer capture (10 files of 100MB each — rotating)
sudo tshark -i eth0 -b filesize:100000 -b files:10 -w ring.pcap

# Count packets matching a filter
tshark -r capture.pcap -Y "dns" -q | wc -l

# Extract TLS Client Hello SNI values
tshark -r capture.pcap -Y "tls.handshake.type == 1" \
    -T fields -e tls.handshake.extensions_server_name

# Detect potential DNS tunneling (large TXT responses)
tshark -r capture.pcap -Y "dns.qry.type == 16 && dns.resp.len > 200" \
    -T fields -e ip.src -e dns.qry.name

dig

Purpose: DNS query tool for troubleshooting, investigating DNS records, verifying email authentication, and testing DNSSEC. The standard utility for any DNS-related investigation.

Query Types and Basic Usage

# Basic A record query
dig example.com
# Output (answer section):
# ;; ANSWER SECTION:
# example.com.        3600    IN      A       93.184.216.34

# Query specific record types
dig example.com A              # IPv4 address
dig example.com AAAA           # IPv6 address
dig example.com MX             # Mail exchange servers
dig example.com NS             # Authoritative nameservers
dig example.com TXT            # Text records (SPF, DKIM, DMARC, verification)
dig example.com SOA            # Start of Authority
dig example.com CNAME          # Canonical name (alias)
dig example.com CAA            # Certificate Authority Authorization
dig example.com SRV            # Service records (SIP, XMPP, etc.)
dig example.com ANY            # All record types (may be restricted by server)

# Short output — just the answer, nothing else
dig +short example.com
# Output: 93.184.216.34

dig +short example.com MX
# Output:
# 10 mail.example.com.
# 20 mail2.example.com.

# Query a specific nameserver
dig @8.8.8.8 example.com           # Google Public DNS
dig @1.1.1.1 example.com           # Cloudflare DNS
dig @9.9.9.9 example.com           # Quad9 (malware-filtering)

# Reverse DNS lookup (PTR record)
dig -x 93.184.216.34
# Output: 34.216.184.93.in-addr.arpa. 3600 IN PTR example.com.

Tracing Resolution and DNSSEC

# Trace the full DNS resolution path from root to authoritative
dig +trace example.com
# Output walks through: root servers → .com TLD → example.com authoritative
# Shows each delegation step and the NS records at each level

# Request DNSSEC records
dig +dnssec example.com
# Output includes RRSIG (signature) records if the domain is signed

# Query DNSKEY records (zone signing keys)
dig +short example.com DNSKEY

# Query DS records (Delegation Signer — links parent to child zone)
dig +short example.com DS

# Validate DNSSEC chain (check for ad flag = authenticated data)
dig +dnssec +short example.com | head -5

# Check if a resolver validates DNSSEC (query a known-bad domain)
dig @8.8.8.8 dnssec-failed.org
# A validating resolver returns SERVFAIL for a domain with broken DNSSEC

Email Authentication Records

# Check SPF record
dig TXT example.com +short
# Output: "v=spf1 include:_spf.google.com ~all"

# Check DMARC policy
dig TXT _dmarc.example.com +short
# Output: "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"

# Check DKIM record (requires knowing the selector)
dig TXT selector1._domainkey.example.com +short
# Output: "v=DKIM1; k=rsa; p=MIIBIjANBgkqhk..."

# Check MTA-STS policy record
dig TXT _mta-sts.example.com +short

# Check BIMI record (Brand Indicators for Message Identification)
dig TXT default._bimi.example.com +short

Advanced Usage

# Show only the answer section (clean output)
dig +noall +answer example.com

# Show answer + authority + additional sections
dig +noall +answer +authority +additional example.com

# TCP query (useful when UDP responses are truncated or blocked)
dig +tcp example.com

# Set timeout and retry count
dig +time=5 +tries=3 example.com

# Simulate geo-location with EDNS Client Subnet
dig +subnet=203.0.113.0/24 cdn.example.com

# Batch query from a file
dig -f domains.txt +short

# Check DNS propagation across multiple resolvers
for ns in 8.8.8.8 1.1.1.1 9.9.9.9 208.67.222.222; do
    echo "=== $ns ==="
    dig @$ns +short example.com
done

# Query with specific EDNS buffer size
dig +bufsize=4096 example.com

# Measure query time
dig example.com | grep "Query time"
# Output: ;; Query time: 24 msec

# Check for DNS-over-HTTPS availability (DoH)
curl -sH 'accept: application/dns-json' \
    'https://cloudflare-dns.com/dns-query?name=example.com&type=A'

Key flags:

FlagPurpose
@serverQuery a specific nameserver
+shortConcise output (answer only)
+traceTrace the full delegation path
+dnssecRequest DNSSEC records (RRSIG, DNSKEY)
+tcpUse TCP instead of UDP
-x ipReverse DNS lookup (PTR)
+noall +answerShow only the answer section
+time=NSet query timeout in seconds
+tries=NSet number of retry attempts
+subnet=ip/maskEDNS Client Subnet (simulate geo)
-f fileRead domain list from file

tcpdump

Purpose: Command-line packet capture tool. The standard, universally available utility for capturing network traffic on Unix and Linux systems. Produces pcap files that can be analyzed with Wireshark or tshark.

Basic Capture and Output

# Capture on a specific interface
sudo tcpdump -i eth0

# List available interfaces
sudo tcpdump -D

# Capture to a pcap file (the most common usage)
sudo tcpdump -i eth0 -w capture.pcap

# Read and display a pcap file
tcpdump -r capture.pcap

# Capture a limited number of packets
sudo tcpdump -i eth0 -c 1000 -w capture.pcap

# Capture full packets (don't truncate — default snaplen may cut off data)
sudo tcpdump -i eth0 -s 0 -w full_capture.pcap

# Capture only headers (save disk space for high-volume captures)
sudo tcpdump -i eth0 -s 96 -w headers_only.pcap

Capture Filters

tcpdump uses BPF (Berkeley Packet Filter) syntax — the same syntax as Wireshark capture filters.

# Filter by host
sudo tcpdump -i eth0 host 10.0.1.50
sudo tcpdump -i eth0 src host 10.0.1.50
sudo tcpdump -i eth0 dst host 10.0.1.50

# Filter by network
sudo tcpdump -i eth0 net 10.0.1.0/24

# Filter by port
sudo tcpdump -i eth0 port 443
sudo tcpdump -i eth0 dst port 22
sudo tcpdump -i eth0 portrange 8000-9000

# Filter by protocol
sudo tcpdump -i eth0 tcp
sudo tcpdump -i eth0 udp
sudo tcpdump -i eth0 icmp

# Combine filters with and/or/not
sudo tcpdump -i eth0 'host 10.0.1.50 and tcp port 443'
sudo tcpdump -i eth0 'src net 10.0.0.0/8 and not dst port 53'
sudo tcpdump -i eth0 'tcp port 80 or tcp port 443'

# Capture only TCP SYN packets (new connections)
sudo tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn) != 0'

# Capture only TCP SYN packets (excluding SYN-ACK)
sudo tcpdump -i eth0 'tcp[tcpflags] & (tcp-syn) != 0 and tcp[tcpflags] & (tcp-ack) == 0'

# Capture only RST packets (connection resets — useful for debugging)
sudo tcpdump -i eth0 'tcp[tcpflags] & (tcp-rst) != 0'

# Exclude noisy traffic
sudo tcpdump -i eth0 'not arp and not icmp and not port 53'

Output Formatting

# Don't resolve hostnames (faster output)
sudo tcpdump -i eth0 -n

# Don't resolve hostnames or port names
sudo tcpdump -i eth0 -nn

# Verbose output (show TTL, IP options, checksum)
sudo tcpdump -i eth0 -v

# Very verbose (full protocol decode)
sudo tcpdump -i eth0 -vvv

# Show packet contents in hex and ASCII
sudo tcpdump -i eth0 -X
# Output:
# 0x0000:  4500 003c 1c46 4000 4006 b1e6 0a00 0132  E..<.F@.@......2
# 0x0010:  0a00 0164 c4a6 01bb 9e4c 0001 0000 0000  ...d.....L......

# Show packet contents in ASCII only (useful for HTTP)
sudo tcpdump -i eth0 -A

# Show link-layer (Ethernet) headers
sudo tcpdump -i eth0 -e

# Human-readable timestamps
sudo tcpdump -i eth0 -tttt
# Output: 2025-01-15 10:23:45.123456 IP 10.0.1.50.54321 > 93.184.216.34.443: ...

# Unix epoch timestamps (for log correlation)
sudo tcpdump -i eth0 -tt

Saving and Rotating Captures

# Time-based rotation (new file every hour)
sudo tcpdump -i eth0 -G 3600 -w 'capture_%Y%m%d_%H%M%S.pcap'

# Size-based rotation (100MB per file, keep 20 files)
sudo tcpdump -i eth0 -C 100 -W 20 -w capture.pcap

# Capture duration limit (capture for 5 minutes)
sudo timeout 300 tcpdump -i eth0 -w five_minutes.pcap

Security-Specific Recipes

# Capture DNS queries (monitor for suspicious lookups)
sudo tcpdump -i eth0 -nn 'udp port 53' -l | \
    awk '/A\?/ {print strftime("%H:%M:%S"), $NF}'

# Capture HTTP GET requests (unencrypted traffic — should not exist in production)
sudo tcpdump -i eth0 -A -s 0 'tcp port 80' | \
    grep -E 'GET |POST |Host:'

# Monitor for ARP spoofing (watch for duplicate IP-to-MAC mappings)
sudo tcpdump -i eth0 -nn arp

# Detect SYN flood (high rate of SYN without SYN-ACK completion)
sudo tcpdump -i eth0 -nn 'tcp[tcpflags] == tcp-syn' -c 100 -w syn_flood_check.pcap

# Capture traffic to known-bad IP (threat intelligence feed hit)
sudo tcpdump -i eth0 'host 203.0.113.66' -w suspicious.pcap

Key flags:

FlagPurpose
-i ifaceCapture on specific interface (-i any for all)
-w fileWrite raw packets to pcap file
-r fileRead from pcap file
-c countStop after capturing N packets
-s snaplenBytes to capture per packet (0 = full packet)
-nDon't resolve hostnames
-nnDon't resolve hostnames or port names
-v/-vv/-vvvIncreasing verbosity
-AShow ASCII content
-XShow hex and ASCII content
-eShow link-layer (Ethernet) headers
-G secondsRotate capture file by time interval
-C megabytesRotate capture file by size
-W countLimit the number of rotated files
-lLine-buffered output (for piping to other commands)
-ttttHuman-readable timestamps
-DList available capture interfaces

Quick Reference: Common Security Tasks

The following table maps common security investigation tasks to the appropriate tool and command pattern.

graph LR
    A[Security Task] --> B{What layer?}
    B -->|TLS/Certificates| C[openssl s_client<br>curl -v]
    B -->|DNS| D[dig<br>tshark]
    B -->|Network/Ports| E[nmap<br>tcpdump]
    B -->|HTTP/API| F[curl<br>tshark]
    B -->|Packet Analysis| G[wireshark<br>tshark<br>tcpdump]
TaskToolCommand Pattern
Check TLS certificateopenssl / curlopenssl s_client -connect host:443 or curl -v
Test specific cipher suiteopensslopenssl s_client -cipher SUITE
Scan open portsnmapnmap -sS target or nmap -sT target
Detect service versionsnmapnmap -sV target
Enumerate TLS configurationnmapnmap --script ssl-enum-ciphers -p 443
Query DNS recordsdigdig example.com TYPE
Trace DNS resolutiondigdig +trace example.com
Verify DNSSECdigdig +dnssec example.com
Check email auth (SPF/DMARC)digdig TXT _dmarc.example.com
Capture network traffictcpdump / tsharktcpdump -i eth0 -w file.pcap
Analyze packet capturewireshark / tsharktshark -r file.pcap -Y "filter"
Audit security headerscurlcurl -sI url | grep header
Test API authenticationcurlcurl -H "Authorization: Bearer ..."
Test mTLS connectioncurlcurl --cert c.crt --key c.key --cacert ca.crt
Generate secure randomopensslopenssl rand -base64 32
Hash a fileopensslopenssl dgst -sha256 file
Verify a certificate chainopensslopenssl verify -CAfile ca.pem cert.pem
Create a CSRopensslopenssl req -new -key key.pem -out csr.pem
Export objects from pcaptsharktshark -r file.pcap --export-objects http,dir/
Scan for vulnerabilitiesnmapnmap --script vuln target
Monitor DNS queries livetcpdumptcpdump -nn 'udp port 53'