Files
websec-audit/install.sh
T
2026-03-23 11:10:48 +01:00

304 lines
13 KiB
Bash

#!/usr/bin/env bash
# =============================================================================
#
# install.sh — Dependency installer for websec-audit
# Supported: Debian 11/12/13, Ubuntu 20.04/22.04/24.04
#
# Author : davidalvarezp
# Version : 1.0.1
# License : MIT
# GitHub : https://github.com/davidalvarezp/websec-audit
#
# =============================================================================
set -euo pipefail
readonly SCRIPT_VERSION="1.0.1"
readonly INSTALL_LOG="/tmp/websec_install_$(date +%Y%m%d_%H%M%S).log"
# ── Colors ────────────────────────────────────────────────────────────────────
C_RED='\033[0;31m'; C_GREEN='\033[0;32m'; C_YELLOW='\033[1;33m'
C_CYAN='\033[0;36m'; C_BLUE='\033[0;34m'; C_BOLD='\033[1m'; C_RESET='\033[0m'
ok() { echo -e "${C_GREEN} [✔]${C_RESET} $1" | tee -a "$INSTALL_LOG"; }
info() { echo -e "${C_BLUE} [i]${C_RESET} $1" | tee -a "$INSTALL_LOG"; }
warn() { echo -e "${C_YELLOW} [!]${C_RESET} $1" | tee -a "$INSTALL_LOG"; }
err() { echo -e "${C_RED} [✘]${C_RESET} $1" | tee -a "$INSTALL_LOG" >&2; }
step() { echo -e "\n${C_BOLD}${C_CYAN} ── $1 ──${C_RESET}" | tee -a "$INSTALL_LOG"; }
has_tool() { command -v "$1" &>/dev/null; }
# ── Privilege check ───────────────────────────────────────────────────────────
[[ $EUID -ne 0 ]] && { err "Run as root: sudo $0"; exit 1; }
echo -e "${C_BOLD}${C_CYAN}"
cat << 'BANNER'
╔═════════════════════════════════════════════════╗
║ websec-audit — Dependency Installer ║
║ Debian / Ubuntu ║
╚═════════════════════════════════════════════════╝
BANNER
echo -e "${C_RESET}"
echo " Install log: $INSTALL_LOG"
echo ""
# ── System check ──────────────────────────────────────────────────────────────
step "System Verification"
OS_ID=$(grep "^ID=" /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "unknown")
OS_VER=$(grep "^VERSION_ID=" /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "?")
ARCH=$(uname -m)
info "OS: $OS_ID $OS_VER | Arch: $ARCH"
[[ "$OS_ID" =~ ^(debian|ubuntu|kali|parrot)$ ]] || warn "Untested OS: $OS_ID — proceeding anyway"
# ── APT packages ──────────────────────────────────────────────────────────────
step "APT Package Installation"
info "Updating package lists..."
apt-get update -qq 2>>"$INSTALL_LOG"
APT_PACKAGES=(
# Core tools
curl wget git nmap
# Web scanners
nikto sqlmap dirb
# DNS & network
dnsutils bind9-dnsutils whois dnsmap
# Fingerprinting & WAF
whatweb wafw00f
# SSL
sslscan openssl
# Wordlists
wordlists
# Languages & build deps
python3 python3-pip jq
ruby ruby-dev build-essential libssl-dev libffi-dev
# gobuster (if packaged)
gobuster
)
for pkg in "${APT_PACKAGES[@]}"; do
if apt-get install -y -qq "$pkg" >>"$INSTALL_LOG" 2>&1; then
ok "$pkg"
else
warn "$pkg — install failed or not available (will try alternative)"
fi
done
# ── WPScan (gem) ──────────────────────────────────────────────────────────────
step "WPScan"
if has_tool wpscan; then
ok "wpscan already installed ($(wpscan --version 2>/dev/null | head -1))"
else
info "Installing wpscan via gem..."
if gem install wpscan --no-document >>"$INSTALL_LOG" 2>&1; then
ok "wpscan installed"
else
warn "wpscan installation failed"
fi
fi
# ── testssl.sh ────────────────────────────────────────────────────────────────
step "testssl.sh"
if has_tool testssl.sh; then
ok "testssl.sh already installed"
else
info "Installing testssl.sh from GitHub..."
if [[ -d /opt/testssl.sh ]]; then
git -C /opt/testssl.sh pull -q >>"$INSTALL_LOG" 2>&1 || true
else
git clone --depth 1 https://github.com/drwetter/testssl.sh.git /opt/testssl.sh \
>>"$INSTALL_LOG" 2>&1
fi
ln -sf /opt/testssl.sh/testssl.sh /usr/local/bin/testssl.sh
chmod +x /opt/testssl.sh/testssl.sh
ok "testssl.sh installed → /usr/local/bin/testssl.sh"
fi
# ── Go binary installer helper ────────────────────────────────────────────────
install_go_binary() {
local name="$1" url="$2" binary="${3:-$1}"
if has_tool "$name"; then
ok "$name already installed"
return 0
fi
info "Downloading $name..."
local tmp; tmp=$(mktemp)
local ext="${url##*.}"
if wget -q "$url" -O "$tmp" >>"$INSTALL_LOG" 2>&1; then
case "$ext" in
gz)
tar -xzf "$tmp" -C /usr/local/bin/ "$binary" >>"$INSTALL_LOG" 2>&1 && \
chmod +x "/usr/local/bin/$binary" && ok "$name installed" || warn "$name: extraction failed" ;;
zip)
unzip -q -o "$tmp" "$binary" -d /usr/local/bin/ >>"$INSTALL_LOG" 2>&1 && \
chmod +x "/usr/local/bin/$binary" && ok "$name installed" || warn "$name: extraction failed" ;;
*)
mv "$tmp" "/usr/local/bin/$binary"
chmod +x "/usr/local/bin/$binary" && ok "$name installed" || warn "$name: install failed" ;;
esac
else
warn "$name: download failed"
fi
rm -f "$tmp"
}
# Detect arch for Go binaries
case "$ARCH" in
x86_64|amd64) BIN_ARCH="amd64" ;;
aarch64|arm64) BIN_ARCH="arm64" ;;
armv7*) BIN_ARCH="arm" ;;
*) BIN_ARCH="amd64"; warn "Unknown arch $ARCH — assuming amd64" ;;
esac
# ── gobuster ──────────────────────────────────────────────────────────────────
step "gobuster"
if ! has_tool gobuster; then
install_go_binary "gobuster" \
"https://github.com/OJ/gobuster/releases/latest/download/gobuster_Linux_${BIN_ARCH}.tar.gz" \
"gobuster"
fi
# ── ffuf ─────────────────────────────────────────────────────────────────────
step "ffuf"
if ! has_tool ffuf; then
install_go_binary "ffuf" \
"https://github.com/ffuf/ffuf/releases/latest/download/ffuf_$(curl -s https://api.github.com/repos/ffuf/ffuf/releases/latest 2>/dev/null | grep -oP '"tag_name": "v\K[^"]+' | head -1 || echo '2.1.0')_linux_${BIN_ARCH}.tar.gz" \
"ffuf"
fi
# ── subfinder ─────────────────────────────────────────────────────────────────
step "subfinder"
if ! has_tool subfinder; then
install_go_binary "subfinder" \
"https://github.com/projectdiscovery/subfinder/releases/latest/download/subfinder_linux_${BIN_ARCH}.zip" \
"subfinder"
fi
# ── dalfox ────────────────────────────────────────────────────────────────────
step "dalfox (XSS scanner)"
if ! has_tool dalfox; then
local DALFOX_VER
DALFOX_VER=$(curl -s https://api.github.com/repos/hahwul/dalfox/releases/latest 2>/dev/null | grep -oP '"tag_name": "v\K[^"]+' | head -1 || echo "2.9.1")
install_go_binary "dalfox" \
"https://github.com/hahwul/dalfox/releases/download/v${DALFOX_VER}/dalfox_linux_${BIN_ARCH}.tar.gz" \
"dalfox"
fi
# ── subjack ───────────────────────────────────────────────────────────────────
step "subjack (subdomain takeover)"
if ! has_tool subjack; then
if wget -q "https://github.com/haccer/subjack/releases/latest/download/subjack-linux-${BIN_ARCH}" \
-O /usr/local/bin/subjack >>"$INSTALL_LOG" 2>&1; then
chmod +x /usr/local/bin/subjack
ok "subjack installed"
else
warn "subjack download failed"
fi
fi
# ── nuclei ────────────────────────────────────────────────────────────────────
step "nuclei"
if ! has_tool nuclei; then
install_go_binary "nuclei" \
"https://github.com/projectdiscovery/nuclei/releases/latest/download/nuclei_linux_${BIN_ARCH}.zip" \
"nuclei"
fi
if has_tool nuclei; then
info "Updating Nuclei templates..."
nuclei -update-templates -silent >>"$INSTALL_LOG" 2>&1 || warn "Template update failed (try: nuclei -update-templates)"
ok "Nuclei templates updated"
fi
# ── amass ─────────────────────────────────────────────────────────────────────
step "amass"
if ! has_tool amass; then
if apt-get install -y -qq amass >>"$INSTALL_LOG" 2>&1; then
ok "amass installed via apt"
else
local AMASS_VER
AMASS_VER=$(curl -s https://api.github.com/repos/owasp-amass/amass/releases/latest 2>/dev/null | grep -oP '"tag_name": "v\K[^"]+' | head -1 || echo "4.2.0")
install_go_binary "amass" \
"https://github.com/owasp-amass/amass/releases/download/v${AMASS_VER}/amass_Linux_${BIN_ARCH}.zip" \
"amass"
fi
fi
# ── droopescan ────────────────────────────────────────────────────────────────
step "droopescan (Drupal/Joomla scanner)"
if ! has_tool droopescan; then
if pip3 install droopescan --quiet >>"$INSTALL_LOG" 2>&1; then
ok "droopescan installed"
else
warn "droopescan installation failed"
fi
fi
# ── SecLists wordlists ────────────────────────────────────────────────────────
step "SecLists Wordlists"
if [[ -d /usr/share/seclists ]]; then
ok "SecLists already present at /usr/share/seclists"
else
# Try apt first
if apt-get install -y -qq seclists >>"$INSTALL_LOG" 2>&1; then
ok "SecLists installed via apt"
else
info "Cloning SecLists from GitHub (this may take a while)..."
if git clone --depth 1 https://github.com/danielmiessler/SecLists.git \
/usr/share/seclists >>"$INSTALL_LOG" 2>&1; then
ok "SecLists installed at /usr/share/seclists"
else
warn "SecLists clone failed — install manually"
fi
fi
fi
# Decompress rockyou if needed
[[ -f /usr/share/wordlists/rockyou.txt.gz && ! -f /usr/share/wordlists/rockyou.txt ]] && \
gunzip /usr/share/wordlists/rockyou.txt.gz && ok "rockyou.txt decompressed"
# ── dnsrecon ──────────────────────────────────────────────────────────────────
step "dnsrecon"
if ! has_tool dnsrecon; then
apt-get install -y -qq dnsrecon >>"$INSTALL_LOG" 2>&1 || \
pip3 install dnsrecon --quiet >>"$INSTALL_LOG" 2>&1 || \
warn "dnsrecon not installed"
has_tool dnsrecon && ok "dnsrecon installed"
fi
# ── Final summary ─────────────────────────────────────────────────────────────
echo ""
echo -e "${C_BOLD}${C_CYAN} ═══════════════════════════════════════════════════${C_RESET}"
echo -e "${C_BOLD} Installation Summary${C_RESET}"
echo ""
TOOLS=(
"curl" "nmap" "nikto" "sqlmap" "gobuster" "ffuf" "dirb"
"whatweb" "wafw00f" "sslscan" "testssl.sh" "wpscan"
"subfinder" "amass" "dnsrecon" "dalfox" "subjack" "nuclei"
"droopescan" "dig" "host" "whois" "jq" "python3" "ruby"
)
installed=0; missing=0
for t in "${TOOLS[@]}"; do
if has_tool "$t"; then
printf " ${C_GREEN}${C_RESET} %-20s %s\n" "$t" "($(command -v "$t"))"
installed=$((installed + 1))
else
printf " ${C_YELLOW}${C_RESET} %-20s %s\n" "$t" "(not found)"
missing=$((missing + 1))
fi
done
echo ""
echo -e " ${C_BOLD}Installed: ${C_GREEN}${installed}${C_RESET} | ${C_BOLD}Missing: ${C_YELLOW}${missing}${C_RESET}"
echo ""
echo -e " ${C_DIM}Full log: ${INSTALL_LOG}${C_RESET}"
echo ""
echo -e " ${C_BOLD}Usage:${C_RESET}"
echo " chmod +x websec-audit.sh"
echo " ./websec-audit.sh -t https://target.com"
echo " ./websec-audit.sh -t https://target.com --aggressive -T 20"
echo ""