#!/usr/bin/env bash set -euo pipefail # Script Name: web-recon.sh # Description: Web application reconnaissance with tmux orchestration # Usage: web-recon # Creates tmux window with parallel web scans (nuclei, feroxbuster, katana, arjun) VERSION="2.0.0" # Colors readonly RED='\033[0;31m' readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly BLUE='\033[0;34m' readonly CYAN='\033[0;36m' readonly MAGENTA='\033[0;35m' readonly BOLD='\033[1m' readonly NC='\033[0m' # Status indicators readonly GREENPLUS="${GREEN}[+]${NC}" readonly GREENSTAR="${YELLOW}[*]${NC}" readonly REDMINUS="${RED}[-]${NC}" readonly REDEXCLAIM="${RED}[!]${NC}" show_help() { echo -e "${BOLD}web-recon${NC} - Web Application Reconnaissance v${VERSION}" echo echo -e "${BOLD}USAGE:${NC}" echo " web-recon " echo echo -e "${BOLD}DESCRIPTION:${NC}" echo " Creates tmux window with 4 panes running parallel/pipelined web reconnaissance:" echo " - Pane 1 (top-left): nuclei (vulnerability scanner)" echo " - Pane 2 (top-right): feroxbuster → arjun (pipeline)" echo " - Pane 3 (bottom-left): katana (web crawler with JS parsing)" echo " - Pane 4 (bottom-right): live results dashboard" echo echo -e "${BOLD}EXAMPLES:${NC}" echo " web-recon http://target.htb" echo " web-recon https://example.com" echo " web-recon 10.10.10.5" echo echo -e "${BOLD}OUTPUT:${NC}" echo " All results saved to: ./web-recon--/" echo echo -e "${BOLD}WORKFLOW:${NC}" echo " - Nuclei & Katana: Run in parallel immediately" echo " - Feroxbuster (5 min) → Arjun: Pipeline (arjun waits for feroxbuster)" echo " - httpx: Live monitoring - probes URLs as they're discovered" } # Check required tools check_tools() { local missing=() local optional_missing=() # Core tools command -v tmux &>/dev/null || missing+=("tmux") # Web tools (all optional but warn) command -v nuclei &>/dev/null || optional_missing+=("nuclei") command -v feroxbuster &>/dev/null || optional_missing+=("feroxbuster") command -v katana &>/dev/null || optional_missing+=("katana") command -v arjun &>/dev/null || optional_missing+=("arjun") if [[ ${#missing[@]} -gt 0 ]]; then echo -e "${RED}Error:${NC} Missing required tools: ${missing[*]}" exit 1 fi if [[ ${#optional_missing[@]} -gt 0 ]]; then echo -e "${YELLOW}⚠${NC} Optional tools missing (scans will be skipped): ${optional_missing[*]}" echo -e "${CYAN}Install with:${NC}" for tool in "${optional_missing[@]}"; do case "$tool" in nuclei) echo " go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest" ;; feroxbuster) echo " cargo install feroxbuster (or: sudo apt install feroxbuster)" ;; katana) echo " go install github.com/projectdiscovery/katana/cmd/katana@latest" ;; arjun) echo " pipx install arjun" ;; esac done echo fi } # Create output directory setup_output_dir() { local url="$1" local timestamp=$(date +%Y%m%d-%H%M%S) local clean_url=$(echo "$url" | tr '/:' '_' | tr -d 'http') OUTPUT_DIR="web-recon-${clean_url}-${timestamp}" mkdir -p "$OUTPUT_DIR" echo -e "${GREEN}✓${NC} Output directory: ${BOLD}$OUTPUT_DIR${NC}" } # Main web-recon function run_web_recon() { local url="$1" # Ensure URL has http:// or https:// if [[ ! "$url" =~ ^https?:// ]]; then url="http://$url" echo -e "${YELLOW}⚠${NC} No protocol specified, using: $url" fi echo -e "${CYAN}${BOLD}" echo "╔════════════════════════════════════════════════════════════╗" echo "║ Web Application Reconnaissance ║" echo "║ Target: $url" echo "╚════════════════════════════════════════════════════════════╝" echo -e "${NC}" # Create output directory setup_output_dir "$url" # Check if in tmux if [[ -z "${TMUX:-}" ]]; then echo -e "${YELLOW}⚠${NC} Not in tmux session - running sequentially" run_scans_sequential "$url" return fi # Create tmux window WINDOW_NAME="--> Web: ${url:0:20}... <--" tmux new-window -n "$WINDOW_NAME" # Split into 4 panes with explicit targeting # Layout: 2x2 grid with pipelines and live monitoring # ACTUAL pane numbers after splits: 1, 2, 3, 4 (no pane 0!) # [1: nuclei] [2: feroxbuster → arjun] # [3: katana] [4: live dashboard] # Create 2x2 grid layout # CRITICAL: Tmux pane numbering behavior discovered through testing: # Step 1: split-window -h creates [0:left] [1:right] # Step 2: select pane 0, split-window -v creates [0:TL] [1:BL] [2:right] # Step 3: select pane 2, split-window -v creates [1:TL] [2:TR] [3:BL] [4:BR] # # PANE 0 DISAPPEARS during this process! Final panes are numbered 1, 2, 3, 4 # Split horizontally first (left | right) tmux split-window -h # Split left column vertically tmux select-pane -t 0 tmux split-window -v # Split right column vertically (target pane 2 after left split) tmux select-pane -t 2 tmux split-window -v # Force tiled layout for perfect 2x2 grid (equal-sized panes) tmux select-layout tiled # Final verified pane layout after tmux renumbering and tiled layout: # 1 (top-left) 2 (top-right) # 3 (bottom-left) 4 (bottom-right) # Send commands to each pane with ACTUAL pane numbers after splits # After all splits complete, tmux renumbers panes as: 1 (TL), 2 (TR), 3 (BL), 4 (BR) # (pane 0 disappears during the splitting process) # Pane 1 (top-left): nuclei tmux select-pane -t 1 if command -v nuclei &>/dev/null; then tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} Starting nuclei vulnerability scan...${NC}' && nuclei -u '$url' -o nuclei.txt && echo -e '${GREEN}✓ Nuclei complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ nuclei not installed - skipping${NC}'" C-m fi # Pane 2 (top-right): feroxbuster THEN arjun (pipeline) tmux select-pane -t 2 if command -v feroxbuster &>/dev/null; then # Run feroxbuster, then arjun on discovered URLs if command -v arjun &>/dev/null; then tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} Starting feroxbuster (5 min limit, default wordlist)...${NC}' && echo -e '${YELLOW}💡 Tip: Install SecLists for better wordlists: sudo apt install seclists${NC}' && timeout 300 feroxbuster -u '$url' -d 3 --force-recursion -C 404 -o feroxbuster.txt 2>&1 | tee feroxbuster-stderr.log || echo 'Feroxbuster exited' && echo -e '${GREEN}✓ Feroxbuster complete${NC}' && cat feroxbuster.txt 2>/dev/null | grep -oE 'http[s]?://[^[:space:]]+' >> urls.txt || true && echo -e '${GREENSTAR} Starting arjun parameter discovery...${NC}' && arjun -u '$url' -oT arjun_main.txt 2>&1 | tee arjun.log && if [ -f urls.txt ] && [ -s urls.txt ]; then echo -e '${GREENSTAR} Running arjun on discovered URLs...${NC}' && arjun -i urls.txt -oT arjun_urls.txt 2>&1 | tee -a arjun.log || true; fi && echo -e '${GREEN}✓ Arjun complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} Starting feroxbuster (5 min limit, default wordlist)...${NC}' && echo -e '${YELLOW}💡 Tip: Install SecLists for better wordlists: sudo apt install seclists${NC}' && timeout 300 feroxbuster -u '$url' -d 3 --force-recursion -C 404 -o feroxbuster.txt 2>&1 | tee feroxbuster-stderr.log || echo 'Feroxbuster exited' && echo -e '${GREEN}✓ Feroxbuster complete${NC}' && cat feroxbuster.txt 2>/dev/null | grep -oE 'http[s]?://[^[:space:]]+' >> urls.txt || true" C-m fi else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ feroxbuster not installed - skipping${NC}' && touch urls.txt" C-m fi # Pane 3 (bottom-left): katana (web crawler with all output formats) tmux select-pane -t 3 if command -v katana &>/dev/null; then # Full katana with all output formats as originally requested tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} Starting katana crawler (full output)...${NC}' && katana -u '$url' -jc -kf all -aff -d 10 -o katana.txt 2>&1 | tee katana.log && katana -u '$url' -jc -kf all -aff -d 10 -f path -o katana_paths.txt && katana -u '$url' -jc -kf all -aff -d 10 -f url -o katana_urls.txt && katana -u '$url' -jc -kf all -aff -d 10 -f udir -o katana_dirs.txt && cat katana_dirs.txt 2>/dev/null | sort -u >> urls.txt && cat katana_paths.txt 2>/dev/null | sed 's/^.//g' >> paths.txt && echo -e '${GREEN}✓ Katana complete (all formats)${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ katana not installed - skipping${NC}'" C-m fi # Pane 4 (bottom-right): Live results dashboard tmux select-pane -t 4 # Watch output files and show live statistics tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${CYAN}╔══════════════════════════════════════════════╗${NC}' && echo -e '${CYAN}║ LIVE SCAN RESULTS DASHBOARD ║${NC}' && echo -e '${CYAN}╚══════════════════════════════════════════════╝${NC}' && echo -e '${YELLOW}[*] Monitoring output files...${NC}' && while true; do clear; echo -e '${CYAN}═══ Scan Progress ═══${NC}'; echo; echo -e '${GREEN}Nuclei:${NC}'; [ -f nuclei.txt ] && echo \" Found: \$(wc -l < nuclei.txt 2>/dev/null || echo 0) findings\" || echo ' Waiting...'; echo; echo -e '${GREEN}Feroxbuster:${NC}'; [ -f feroxbuster.txt ] && echo \" Found: \$(grep -c '200\\|301\\|302\\|403' feroxbuster.txt 2>/dev/null || echo 0) endpoints\" || echo ' Waiting...'; echo; echo -e '${GREEN}Katana:${NC}'; [ -f katana.txt ] && echo \" Crawled: \$(wc -l < katana.txt 2>/dev/null || echo 0) URLs\" || echo ' Waiting...'; echo; echo -e '${GREEN}URLs Discovered:${NC}'; [ -f urls.txt ] && echo \" Total: \$(sort -u urls.txt 2>/dev/null | wc -l) unique URLs\" && echo && echo -e '${CYAN}Latest URLs:${NC}' && tail -5 urls.txt 2>/dev/null || echo ' None yet'; echo; echo -e '${YELLOW}[Press Ctrl+C to stop monitoring]${NC}'; sleep 3; done" C-m # Focus back on top-left pane (nuclei) tmux select-pane -t 1 echo echo -e "${GREEN}✓${NC} Tmux web-recon window created" echo -e "${CYAN}[*]${NC} Switch to window: ${BOLD}--> Web: ${url:0:20}... <--${NC}" echo -e "${CYAN}[*]${NC} Results will be in: ${BOLD}$OUTPUT_DIR${NC}" echo echo -e "${YELLOW}Note:${NC} Feroxbuster will auto-stop after 5 minutes" echo -e "${YELLOW}Note:${NC} Arjun waits 10 seconds before starting" } # Sequential execution (when not in tmux) run_scans_sequential() { local url="$1" cd "$OUTPUT_DIR" echo -e "\n${GREENSTAR} Running nuclei...${NC}" command -v nuclei &>/dev/null && nuclei -u "$url" -o nuclei.txt || echo "nuclei not installed" echo -e "\n${GREENSTAR} Running feroxbuster (5 min timeout)...${NC}" if command -v feroxbuster &>/dev/null; then timeout 300 feroxbuster -u "$url" -d 3 --smart --silent --force-recursion -o feroxbuster.txt 2>/dev/null || true cat feroxbuster.txt 2>/dev/null | awk '{print $1}' >> urls.txt fi echo -e "\n${GREENSTAR} Running katana...${NC}" if command -v katana &>/dev/null; then katana -u "$url" -jc -kf all -aff -d 10 -o katana.txt cat katana.txt 2>/dev/null | sort -u >> urls.txt fi echo -e "\n${GREENSTAR} Running arjun...${NC}" if command -v arjun &>/dev/null; then arjun -u "$url" -oT arjun_main.txt 2>&1 | tee arjun.log [ -f urls.txt ] && [ -s urls.txt ] && arjun -i urls.txt -oT arjun_urls.txt 2>&1 | tee -a arjun.log || true fi cd .. echo -e "\n${GREEN}✓${NC} Web recon complete! Results in: ${BOLD}$OUTPUT_DIR${NC}" } # Parse arguments if [[ $# -eq 0 ]] || [[ "$1" =~ ^(-h|--help|help)$ ]]; then show_help exit 0 fi url="$1" # Validate URL if [[ -z "$url" ]]; then echo -e "${RED}Error:${NC} URL required" echo "Usage: web-recon " exit 1 fi # Check tools check_tools # Run web reconnaissance run_web_recon "$url"