Writing Exploit & Recon Scripts in Bash

⚠️ Safety & Ethics

These scripts are designed for lab use only (your VMs, CTF boxes, or explicitly authorized targets). They automate enumeration and provide defensive suggestions — they are not exploit payloads for attacking real systems. Running these against networks or hosts you do not own or have permission to test is illegal.

🧠 What this post covers

  • How to design modular recon/exploit-helper scripts

  • Best practices for argument parsing, logging, and safety

  • A reusable recon driver script (lab-only)

  • A “suggestions” engine that maps findings to safe next steps

  • Lab exercises to extend and harden the tools

⚙️ Design Principles (How pros structure recon scripts)

  1. Modularity: Break tasks into functions (gather_info, port_scan, banner_grab). Easier to test and reuse.

  2. Safety-first defaults: Default target = 127.0.0.1 or localhost. --target must be explicit.

  3. Idempotence: Running script twice should not corrupt data or flood the network.

  4. Logging & output: Save structured outputs (text files, optionally JSON) for later analysis.

  5. Limited aggression: Use light nmap flags by default; require --aggressive or --full to escalate scans (and still lab-only).

  6. Advisory suggestions: Provide defensive next steps (fix file perms, tighten sudo) — not exploit commands.

  7. Argument validation: Don’t accept arbitrary privileged targets unless running as a non-root user in a controlled lab.

🧩 Script Blueprint — lab_recon.sh (modular, safe)

Save as lab_recon.sh, chmod +x lab_recon.sh. Defaults to localhost. This script:

  • collects basic host info

  • runs a light nmap scan

  • grabs open banner info (ss + netcat banner grab with timeout)

  • produces a plain-text report and a short CSV summary

  • prints safe suggestions based on findings

				
					#!/usr/bin/env bash
set -euo pipefail
trap 'echo "Script failed at line $LINENO"; exit 1' ERR

USAGE() {
  cat <<EOF
lab_recon.sh - safe lab recon driver

Usage: $0 --target <ip|hostname> [--outdir DIR] [--full]

Defaults: target=127.0.0.1, outdir=./lab_recon_YYYYMMDD_HHMMSS

Options:
  --target    Target host (default: 127.0.0.1)
  --outdir    Output directory
  --full      Run additional checks (use in lab only)
  -h|--help   Show this help
EOF
}

# Defaults
TARGET="127.0.0.1"
OUTDIR=""
FULL=false

# Parse args (simple)
while [[ $# -gt 0 ]]; do
  case "$1" in
    --target) TARGET="$2"; shift 2;;
    --outdir) OUTDIR="$2"; shift 2;;
    --full) FULL=true; shift;;
    -h|--help) USAGE; exit 0;;
    *) echo "Unknown arg: $1"; USAGE; exit 2;;
  esac
done

if [[ -z "$OUTDIR" ]]; then
  OUTDIR="./lab_recon_$(date +%F_%H%M%S)_${TARGET//[:\/]/_}"
fi
mkdir -p "$OUTDIR"

log() { echo "[$(date +%T)] $*"; }

# Function: gather system/banner info
gather_basic() {
  log "Gathering basic system info for $TARGET"
  echo "Target: $TARGET" > "$OUTDIR/report.txt"
  echo "Scan time: $(date +%F_%T)" >> "$OUTDIR/report.txt"
  uname -a >> "$OUTDIR/report.txt" 2>/dev/null || true
  echo -e "\n-- Listening sockets (local view) --" >> "$OUTDIR/report.txt"
  ss -tulwn >> "$OUTDIR/report.txt" || true
}

# Function: nmap quick scan (non-aggressive)
port_scan() {
  if command -v nmap >/dev/null 2>&1; then
    log "Running light nmap scan (safe defaults)"
    nmap -sC -sV -oN "$OUTDIR/nmap_quick.txt" "$TARGET" || echo "nmap failure (nonfatal)" >> "$OUTDIR/report.txt"
  else
    echo "nmap not found; skipping nmap" >> "$OUTDIR/report.txt"
  fi
}

# Function: banner grab simple (non-blocking)
banner_grab() {
  log "Grabbing simple banners from open ports (lab-only)"
  # create a short CSV of host,port,banner
  echo "host,port,banner" > "$OUTDIR/banners.csv"
  if [[ -f "$OUTDIR/nmap_quick.txt" ]]; then
    # parse open ports (simple heuristic)
    grep -E "^[0-9]+/tcp" "$OUTDIR/nmap_quick.txt" | awk '{print $1,$3}' | while read -r port state; do
      pnum=$(echo "$port" | cut -d/ -f1)
      # attempt a quick banner with timeout using bash + /dev/tcp
      banner=$(timeout 2 bash -c "echo | nc -w 2 $TARGET $pnum" 2>/dev/null || true)
      banner_clean=$(echo "$banner" | tr '\n' ' ' | tr -d '\r' | sed 's/,/ /g')
      echo "${TARGET},${pnum},\"${banner_clean}\"" >> "$OUTDIR/banners.csv"
    done
  fi
}

# Function: basic suggestions engine (non-exploit)
suggestions() {
  log "Generating safe suggestions based on findings"
  echo -e "\n-- Suggestions (lab-only) --" >> "$OUTDIR/report.txt"
  # Suggest if world-writable dirs found (based on permission audit artifacts if present)
  if [[ -f "$OUTDIR/perm_audit.txt" ]]; then
    if grep -q "No such file" "$OUTDIR/perm_audit.txt" 2>/dev/null; then
      :
    fi
  fi

  # Nmap-based hints (very high-level)
  if [[ -f "$OUTDIR/nmap_quick.txt" ]]; then
    if grep -q "22/tcp" "$OUTDIR/nmap_quick.txt"; then
      echo "SSH (22) found: ensure key-based auth and disable password auth where possible." >> "$OUTDIR/report.txt"
    fi
    if grep -q "80/tcp" "$OUTDIR/nmap_quick.txt" || grep -q "443/tcp" "$OUTDIR/nmap_quick.txt"; then
      echo "Web service detected: review webserver permissions and config files; avoid world-readable secrets." >> "$OUTDIR/report.txt"
    fi
  fi

  echo "Review the report and cross-check file permissions and sudo rules in your lab VM." >> "$OUTDIR/report.txt"
}

# Run steps
gather_basic
port_scan
banner_grab
suggestions

log "Recon complete. Results in $OUTDIR"
echo "Report saved: $OUTDIR/report.txt"

				
			

🔍 How the script is safe / limited

  • Defaults to 127.0.0.1 if you forget --target.

  • Uses a lightweight nmap profile (-sC -sV) by default — not aggressive.

  • Banner grabbing uses short timeouts and nc with a limit; still requires lab discipline.

  • Suggestions are high-level defensive hints (no exploit payloads or commands).

🛠️ Extending the Script (Ideas for practice)

  1. Add --full to enable deeper scans (only lab): nmap -p- --script vuln — gated behind an explicit flag and an extra confirmation prompt.

  2. JSON output support — parse nmap XML to JSON for programmatic pipelines.

  3. Integrate permission audit — run the permission script from Part 7 and include perm_audit.txt so suggestions can include permission hardening.

  4. Add a results dashboard — simple static HTML output summarizing findings (useful for reporting during CTF writeups).

  5. Add rate-limiting or delays to avoid accidental DoS in poorly provisioned lab VMs.

🧪 Lab Exercises

  1. Run the driver on localhost

    • ./lab_recon.sh --target 127.0.0.1

    • Inspect report.txt, nmap_quick.txt, and banners.csv.

  2. Connect the permission audit

    • Run the permission audit from Part 7, save as perm_audit.txt into the same OUTDIR, and update lab_recon.sh to include findings in suggestions().

  3. Add argument parsing with getopts

    • Replace the simple parser with getopts and add --skip-nmap, --json, and --confirm-full flags.

  4. Create a non-root check

    • Add a runtime check that refuses to run if the script is launched as root unless --allow-root is explicitly provided. This prevents accidental damage.

  5. Build a modular library

    • Extract common functions (banner_grab, port_scan) into lib_recon.sh and source it from lab_recon.sh for reuse across tools.

✅ Best Practices Recap

  • Default to safe targets (localhost) and gentle scan settings.

  • Ask for explicit confirmation before running aggressive scans.

  • Always snapshot VMs before experiments and keep backups.

  • Log everything with timestamps and rotate logs.

  • Convert findings into defensive actions, not exploit commands.

  • Use version control and code reviews — treat automation like production code.

🎯 Coming Up Next

Part 9: Networking Basics Every Hacker Should Know — we’ll map the networking concepts that make recon meaningful: routes, interfaces, DNS, ARP, routing tables, and how to interpret them in the field (lab-first).

💬 Got Questions?

Drop them in the comments or join our community on Discord for exclusive hacking tips and resources.


Don’t worry — mastery comes with practice.
Just open your terminal and hack your brain into CLI mode daily.

Let’s keep building. 💻⚔️

Leave a comment

Index