Why Every Security Pro Uses Bash
The command line is your most powerful tool in cybersecurity. Whether you're running Kali Linux for pentesting, analyzing logs on a server, or competing in a CTF, bash proficiency separates beginners from practitioners. This guide assumes you're on Kali Linux — the go-to distro for security work. Open a terminal and follow along.
kali. Your home directory is /home/kali. The terminal is your best friend.Navigating the File System
These are the commands you'll run hundreds of times a day:
pwd
Print Working Directory — see exactly where you are
ls
List files in current directory
ls -la
List ALL files (including hidden .files) in long format
ls -lah
Same but with human-readable sizes (KB, MB, GB)
ls -lt
Sort by modification time, newest first
cd /path/to/dir
Change to an absolute path
cd ~
Jump to home directory (/home/kali)
cd -
Jump back to the previous directory
cd ..
Go up one directory level
tree -L 2
Visual directory tree, 2 levels deep (apt install tree)
File & Directory Operations
Creating, copying, moving, and deleting files. Note: Linux has no Recycle Bin — rm is permanent.
rm -rf / or rm -rf /* will delete your entire system with no undo. Always double-check before running rm -rf.touch file.txt
Create an empty file (or update its timestamp)
mkdir my_dir
Create a directory
mkdir -p a/b/c
Create nested directories, no error if they exist
cp file.txt copy.txt
Copy a file
cp -r dir/ backup/
Copy entire directory recursively
mv file.txt /tmp/
Move a file to /tmp/ (also used to rename)
mv old.txt new.txt
Rename a file
rm file.txt
Delete a file — no trash, gone forever
rm -rf dir/
⚠️ Recursively delete directory and all contents
ln -s /real/path link
Create a symbolic (soft) link
file mystery_file
Identify file type — ignores the extension
Viewing & Searching File Contents
Reading files and hunting for specific data — core skills for CTF forensics, log analysis, and recon:
cat file.txt
Print the entire file to terminal
cat -n file.txt
Print file with line numbers
less file.txt
Scroll through a file (q = quit, /word = search, n = next match)
head -n 20 file.txt
Show first 20 lines of a file
tail -n 20 file.txt
Show last 20 lines
tail -f /var/log/syslog
Live-follow a log file as it grows
xxd file.bin | head
Hex dump — see the raw bytes of any file
strings file.bin
Extract printable strings from a binary (key CTF skill!)
grep "pattern" file.txt
Search for a pattern inside a file
grep -r "password" .
Recursive search across all files in current directory
grep -i "admin" file.txt
Case-insensitive search
grep -n "error" file.txt
Show line numbers of matches
grep -v "nologin" /etc/passwd
Show lines that do NOT match (invert)
grep -E "flag\{.*\}" *.txt
Extended regex — hunt for CTF flags!
find / -name "*.conf" 2>/dev/null
Find all .conf files (hide permission errors)
find . -perm -4000
Find SUID files — common privilege escalation target
find / -user root -perm -4000 2>/dev/null
Find root-owned SUID binaries
locate secret.txt
Fast search using a database (run updatedb first)
Text Processing Power Tools
Transform, filter, and extract data from text streams. These are indispensable for log analysis, wordlist manipulation, and CTF challenges:
cut -d":" -f1 /etc/passwd
Cut field 1 using ":" as delimiter — extracts usernames
sort words.txt
Sort lines alphabetically
sort -n numbers.txt
Sort numerically (not lexicographically)
sort -u words.txt
Sort and remove duplicate lines
sort -rn scores.txt
Sort numerically in reverse (highest first)
uniq -c sorted.txt
Count occurrences of adjacent identical lines (sort first!)
wc -l file.txt
Count lines. -w = words, -c = bytes
sed "s/old/new/g" file.txt
Replace all "old" with "new" (g = global)
sed -n "10,20p" file.txt
Print only lines 10 through 20
awk '{print $1, $3}' file.txt
Print columns 1 and 3 (space-delimited)
awk -F: '{print $1}' /etc/passwd
Use ":" as field separator
tr "a-z" "A-Z" < file.txt
Translate all lowercase to uppercase
base64 -d encoded.txt
Decode base64 — extremely common in CTFs!
echo "hello" | rev
Reverse a string — classic CTF trick
echo "74657374" | xxd -r -p
Convert hex to ASCII
Piping & Redirection
Piping and redirection let you chain commands into powerful one-liners. Understanding stdin, stdout, and stderr is fundamental:
stdin (0) → input to a program
stdout (1) → normal output
stderr (2) → error messages
cat /etc/passwd | grep -v "nologin" | cut -d: -f1 | sort | tee users.txt→ Extract all real user accounts, sort them, display them, and save to users.txt — all at once.
cmd1 | cmd2
Pipe: stdout of cmd1 becomes stdin of cmd2
cmd > file.txt
Redirect stdout to file — OVERWRITES existing content
cmd >> file.txt
Append stdout to file — preserves existing content
cmd < file.txt
Use file contents as stdin
cmd 2>/dev/null
Discard error messages (/dev/null is the void)
cmd 2>&1
Redirect stderr to stdout — see ALL output together
cmd > out.txt 2>&1
Save all output (stdout + stderr) to file
cmd | tee file.txt
Display output AND simultaneously save it to file
cmd1 && cmd2
Run cmd2 only if cmd1 succeeds (exit code 0)
cmd1 || cmd2
Run cmd2 only if cmd1 fails
cmd1 ; cmd2
Run cmd2 after cmd1 regardless of success/failure
xargs
Build commands from stdin: cat urls.txt | xargs curl -O
File Permissions Deep Dive
Linux permissions control exactly who can read, write, and execute files. Understanding them is essential for both hardening systems and finding privesc paths:-rwxr-xr--
→ Char 1: type (-=file, d=dir, l=symlink)
→ Chars 2–4: owner permissions
→ Chars 5–7: group permissions
→ Chars 8–10: others permissions
chmod 755 script.sh
Owner: rwx, Group: r-x, Others: r-x
chmod 644 file.txt
Owner: rw-, Group: r--, Others: r-- (standard for files)
chmod 600 private.key
Owner: rw- only — REQUIRED for SSH private keys!
chmod 700 ~/.ssh
Owner only — REQUIRED for your .ssh directory!
chmod +x script.sh
Add execute permission (for all users)
chmod u+x,g-w file
Owner +execute, Group -write (symbolic notation)
chown kali:kali file.txt
Change owner to kali, group to kali
chown -R kali /opt/tools
Recursively change ownership of entire directory
find / -perm -4000 2>/dev/null
Find SUID files — a key privesc technique
find / -perm -2000 2>/dev/null
Find SGID files
find / -writable -type d 2>/dev/null
Find world-writable directories
Octal reference:
| Oct | Symbol | Meaning |
|---|---|---|
| 7 | rwx | Read + Write + Execute |
| 6 | rw- | Read + Write |
| 5 | r-x | Read + Execute |
| 4 | r-- | Read only |
| 3 | -wx | Write + Execute |
| 2 | -w- | Write only |
| 1 | --x | Execute only |
| 0 | --- | No permissions |
Common combinations:
| chmod | Result | Use Case |
|---|---|---|
| 755 | -rwxr-xr-x | Scripts/executables: owner full, others can run |
| 644 | -rw-r--r-- | Regular files: owner edits, others read |
| 700 | -rwx------ | Private dirs/scripts: only owner can access |
| 600 | -rw------- | Private files: SSH keys, config secrets |
| 777 | -rwxrwxrwx | ⚠️ Dangerous: everyone has full access |
Process Management
Monitoring and controlling running processes — essential for detecting malware, managing listeners, and sysadmin work:
ps aux
Show all running processes with user, PID, CPU, memory, command
ps aux | grep nginx
Filter processes by name
top
Live process monitor (press q to quit, k to kill by PID)
htop
Colour-coded interactive process viewer (apt install htop)
kill 1234
Send SIGTERM (graceful stop) to PID 1234
kill -9 1234
Send SIGKILL (force stop) — the process cannot ignore this
killall firefox
Kill all processes matching that name
pkill -f "python"
Kill processes by matching the full command string
cmd &
Run command in the background (gets a job number)
jobs
List all background jobs in this shell session
fg %1
Bring background job #1 to the foreground
bg %1
Resume a stopped job in the background
Ctrl+Z
Pause the current foreground process
nohup cmd &
Run command immune to hangup — survives terminal close
screen -S mysession
Create persistent named session (Ctrl+A, D to detach)
screen -r mysession
Reattach to a detached screen session
Networking Commands on Kali
These commands form your recon toolkit. Understanding your own network and probing target networks:
ip a
Show all network interfaces and assigned IP addresses
ip route
Show routing table — identify the default gateway
ifconfig
Classic network interface info (still common on older systems)
ping -c 4 8.8.8.8
Send 4 ICMP packets to test connectivity
traceroute 8.8.8.8
Trace the network path to a destination (each hop)
netstat -tulpn
Show listening TCP/UDP ports and their processes
ss -tulpn
Faster, modern replacement for netstat
curl -I https://example.com
Fetch HTTP response headers only (great for recon)
curl -s url | grep "flag"
Silently download and search content
wget -q https://example.com/file
Download a file quietly
nc -lvnp 4444
Listen on port 4444 — catch reverse shells here!
nc target.com 80
Connect to port 80 (manual banner grab)
dig google.com
Detailed DNS lookup (try dig @8.8.8.8 domain.com)
nslookup domain.com
Simple DNS query
whois domain.com
Domain registration info and CIDR ranges
arp -a
View ARP cache to discover hosts on local network
host domain.com
Quick DNS forward/reverse lookup
SSH & SSH Keys — The Complete Guide
SSH (Secure Shell) is how you securely access remote servers — and how you'll pivot between machines during pentests. Key-based authentication is far stronger than passwords and is what professionals use.
~/.ssh/id_ed25519). Your public key (~/.ssh/id_ed25519.pub) is safe to distribute — that's by design.Generate a Key Pair
# Ed25519 (modern, recommended) ssh-keygen -t ed25519 -C "you@email.com" # RSA (for legacy server compatibility) ssh-keygen -t rsa -b 4096 -C "you@email.com" # Accept default location or choose a custom path # Set a passphrase (recommended for extra protection!)
Creates two files:
~/.ssh/id_ed25519 ← PRIVATE key (never share!)
~/.ssh/id_ed25519.pub ← PUBLIC key (safe to distribute)
View & Verify Your Keys
# See your public key (safe to copy anywhere) cat ~/.ssh/id_ed25519.pub # List all SSH files and their permissions ls -la ~/.ssh/ # Fix permissions if SSH complains chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub
SSH is strict about permissions. If your private key is readable by others, SSH will refuse to use it.
Deploy Your Public Key to a Server
# Automatic method (if you can already log in) ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server # Manual method (append to authorized_keys) cat ~/.ssh/id_ed25519.pub | ssh user@server \ "mkdir -p ~/.ssh && chmod 700 ~/.ssh && \ cat >> ~/.ssh/authorized_keys && \ chmod 600 ~/.ssh/authorized_keys"
The server stores your PUBLIC key in ~/.ssh/authorized_keys. When you connect, SSH proves you hold the matching private key — without ever transmitting it.
Connect With Key Authentication
# Default (uses ~/.ssh/id_ed25519 automatically) ssh user@server # Specify a key explicitly ssh -i ~/.ssh/id_ed25519 user@server # Custom port ssh -p 2222 user@server # Run a remote command without interactive shell ssh user@server "cat /etc/os-release" ssh user@server "ls /var/www/html"
If you get Permission denied (publickey), verify the public key is in the server's ~/.ssh/authorized_keys and permissions are correct.
Create an SSH Config File (~/.ssh/config)
# ~/.ssh/config — alias multiple servers
Host kali-vm
HostName 192.168.1.100
User kali
IdentityFile ~/.ssh/id_ed25519
Port 22
Host ctf-box
HostName 10.10.10.5
User root
IdentityFile ~/.ssh/ctf_key
Port 22
# Set permissions!
chmod 600 ~/.ssh/config
# Now connect with just:
# ssh kali-vm
# ssh ctf-box
The config file saves you from typing long commands. You can have different keys for different hosts.
SSH Agent — Store Keys in Memory
# Start the ssh-agent daemon eval "$(ssh-agent -s)" # Add your key (enter passphrase once) ssh-add ~/.ssh/id_ed25519 # List keys currently loaded in agent ssh-add -l # Remove all keys from agent ssh-add -D # On Kali, add to ~/.bashrc for auto-start: echo 'eval "$(ssh-agent -s)"' >> ~/.bashrc
The agent holds your decrypted key in memory. You enter your passphrase once per session instead of on every connection.
SSH Port Forwarding (Tunneling)
# LOCAL forward: access a remote service locally # Access the server's port 80 at localhost:8080 ssh -L 8080:localhost:80 user@server # REMOTE forward: expose your local service on the server # Makes your local port 3000 reachable as server:9090 ssh -R 9090:localhost:3000 user@server # DYNAMIC SOCKS5 proxy (route browser traffic through server) ssh -D 1080 user@server # Then configure browser to use SOCKS5 proxy at 127.0.0.1:1080 # Keep-alive tunnel in background (pentest pivoting) ssh -fN -L 8080:internal-server:80 user@pivot-host
Port forwarding is a key technique in penetration testing for pivoting through network segments and accessing internal services.
Generate & Use Multiple Key Pairs
# Generate a dedicated key for a specific purpose
ssh-keygen -t ed25519 -f ~/.ssh/github_key -C "github"
ssh-keygen -t ed25519 -f ~/.ssh/ctf_key -C "ctf-labs"
# ~/.ssh/config for multiple identities
Host github.com
IdentityFile ~/.ssh/github_key
User git
Host *.htb
IdentityFile ~/.ssh/ctf_key
User root
# Copy a CTF target's private key and connect
chmod 600 id_rsa
ssh -i id_rsa user@target
Best practice: use a separate key pair for each context (work, CTFs, personal). If one is compromised, the others remain safe.
Package Management with APT
Kali uses APT (Advanced Package Tool) on top of Debian. Kali's repositories include hundreds of security tools ready to install:
kali-tools-top10 installs the 10 most-used tools. kali-linux-large installs the full toolkit. Start with top10.sudo apt update
Refresh the package index from repositories (do this first!)
sudo apt upgrade
Upgrade all installed packages to latest versions
sudo apt full-upgrade
Upgrade + handle dependency changes (safer for Kali)
sudo apt install nmap
Install a package (e.g., nmap)
sudo apt install -y nmap
Install without prompting for confirmation
sudo apt remove nmap
Remove a package (keeps config files)
sudo apt purge nmap
Remove package and all its configuration files
sudo apt autoremove
Clean up unused dependency packages
apt search keyword
Search for packages by keyword
apt show nmap
Show detailed info about a package
dpkg -i package.deb
Install a local .deb file directly
dpkg -l | grep nmap
Check if a package is installed
Bash Scripting Basics
Automating repetitive tasks with scripts multiplies your effectiveness enormously. Every security professional should be able to write basic bash scripts:
#!/bin/bash
Shebang — first line, tells OS to use bash to run this file
VAR="hello world"
Assign a variable — NO spaces around the = sign!
echo $VAR
Print a variable's value (prefix with $)
"$VAR"
Always quote variables to handle spaces safely
read -p "Enter name: " NAME
Prompt user for interactive input
$((5 + 3))
Arithmetic expansion — evaluates to 8
if [ -f file.txt ]; then ... fi
Conditional: -f = file exists, -d = dir exists, -z = empty string
if [ "$VAR" = "yes" ]; then ... fi
String comparison (use = not ==)
for i in $(seq 1 10); do ... done
Loop from 1 to 10
for f in *.txt; do echo "$f"; done
Loop over files matching a glob
while IFS= read -r line; do ... done < file
Loop over each line in a file (safest method)
function greet() { echo "Hello, $1!"; }
Define a function — $1 is first argument
chmod +x script.sh && ./script.sh
Make executable, then run it
#!/bin/bash
# Ping-sweep a subnet to find live hosts
# Usage: chmod +x discover.sh && ./discover.sh 192.168.1
TARGET=$1
# Check that an argument was provided
if [ -z "$TARGET" ]; then
echo "Usage: $0 <subnet>"
echo "Example: $0 192.168.1"
exit 1
fi
echo "[*] Scanning $TARGET.0/24 for live hosts..."
ALIVE=0
# Loop through all 254 host addresses
for i in $(seq 1 254); do
HOST="$TARGET.$i"
# -c 1 = one packet, -W 1 = 1s timeout, &>/dev/null = suppress output
if ping -c 1 -W 1 "$HOST" &>/dev/null; then
echo "[+] ALIVE: $HOST"
ALIVE=$((ALIVE + 1))
fi
done
echo "[*] Scan complete. Found $ALIVE live host(s)."
Bash lets you chain commands, automate tasks, and run the security tools in Kali. Start with the basics — moving around, running tools, simple scripts — and build from there. Every pro started exactly where you are now.