bashRecon & Automation#vulns
220 linhas05_vulns.sh

05_vulns.sh — Automated Vulnerability Discovery

Triagem automatizada de vulnerabilidades web conhecidas com nikto, templates nuclei, auditoria de configurações SSL/TLS e misconfigurations de CORS.

Destaques Operacionais

  • Scan direcionado por templates de severidade no nuclei
  • Testes de políticas de CORS permissivas com origens nulas ou arbitrárias
  • Integração com searchsploit para correlacionar versões descobertas a exploits públicos

Como Executar

./05_vulns.sh 10.10.10.1:443 ./output/10.10.10.1

* Ajuste as permissões de execução com chmod +x 05_vulns.sh se necessário.

Código Fonte — 05_vulns.sh
bash
#!/bin/bash
# ═══════════════════════════════════════════════════════
#  MÓDULO 05 — Vulnerability Scan
#  Uso standalone: ./05_vulns.sh <alvo> <output_dir>
# ═══════════════════════════════════════════════════════

set -uo pipefail

RED='\033[0;31m'; GRN='\033[0;32m'; YLW='\033[1;33m'
BLU='\033[0;34m'; CYN='\033[0;36m'; RST='\033[0m'; BOLD='\033[1m'

info()  { echo -e "${BLU}[*]${RST} $1"; }
ok()    { echo -e "${GRN}[+]${RST} $1"; }
warn()  { echo -e "${YLW}[!]${RST} $1"; }
fail()  { echo -e "${RED}[-]${RST} $1"; }
has()   { command -v "$1" &>/dev/null; }

TARGET="${1:?Uso: $0 <alvo> <output_dir>}"
OUTDIR="${2:?Uso: $0 <alvo> <output_dir>}/vulns"
mkdir -p "$OUTDIR"
CLEAN=$(echo "$TARGET" | sed 's|https\?://||;s|/.*||;s|:.*||')

if curl -sk --connect-timeout 3 "https://${CLEAN}" -o /dev/null 2>/dev/null; then
    BASE_URL="https://${CLEAN}"
else
    BASE_URL="http://${CLEAN}"
fi

echo -e "\n${CYN}━━━ 🛡️  MÓDULO 05 — Vulnerability Scan ━━━${RST}"
echo -e "${BLU}    URL: ${BASE_URL}${RST}\n"

# ── Nikto ──
if has nikto; then
    info "nikto (web vuln scan — pode demorar)..."
    nikto -h "$BASE_URL" -o "${OUTDIR}/nikto.txt" -Format txt 2>/dev/null || true
    ok "→ nikto.txt"

    # Mostrar findings
    vulns=$(grep -c "+" "${OUTDIR}/nikto.txt" 2>/dev/null || echo 0)
    echo -e "    ${YLW}Findings: ${vulns}${RST}"
else
    warn "nikto não instalado."
fi

# ── Nuclei ──
if has nuclei; then
    info "nuclei (template scan)..."
    nuclei -u "$BASE_URL" \
        -severity low,medium,high,critical \
        -o "${OUTDIR}/nuclei.txt" \
        -silent 2>/dev/null || true
    ok "→ nuclei.txt"

    if [[ -s "${OUTDIR}/nuclei.txt" ]]; then
        echo -e "\n${BOLD}  Nuclei findings:${RST}"
        cat "${OUTDIR}/nuclei.txt" | while read -r line; do
            if echo "$line" | grep -qi "critical"; then
                echo -e "    ${RED}🔴 $line${RST}"
            elif echo "$line" | grep -qi "high"; then
                echo -e "    ${RED}🟠 $line${RST}"
            elif echo "$line" | grep -qi "medium"; then
                echo -e "    ${YLW}🟡 $line${RST}"
            else
                echo -e "    ${BLU}🔵 $line${RST}"
            fi
        done
    fi
else
    warn "nuclei não instalado. Instale: go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest"
fi

# ── Searchsploit (se tiver services.txt do módulo 02) ──
PORTS_DIR="$(dirname "$OUTDIR")/ports"
if has searchsploit && [[ -f "${PORTS_DIR}/services.txt" ]]; then
    info "searchsploit (busca exploits para serviços encontrados)..."
    {
        echo "═══ Exploits para serviços detectados ═══"
        echo ""
        # Extrair nomes de serviço do nmap output
        grep -oP '\d+/tcp\s+open\s+\S+\s+\K.*' "${PORTS_DIR}/services.txt" 2>/dev/null \
            | sort -u | while read -r svc; do
            # Pegar só o nome/versão principal
            svc_clean=$(echo "$svc" | awk '{print $1, $2}' | head -1)
            if [[ -n "$svc_clean" ]]; then
                echo "── ${svc_clean} ──"
                searchsploit "$svc_clean" 2>/dev/null | head -15
                echo ""
            fi
        done
    } > "${OUTDIR}/searchsploit.txt"
    ok "→ searchsploit.txt"
elif has searchsploit; then
    info "searchsploit disponível mas sem services.txt. Rode o módulo 02 primeiro."
fi

# ── SSL/TLS check ──
if [[ "$BASE_URL" == https* ]]; then
    info "SSL/TLS check..."
    {
        echo "═══ Certificado SSL ═══"
        echo | openssl s_client -connect "${CLEAN}:443" -servername "$CLEAN" 2>/dev/null \
            | openssl x509 -noout -text 2>/dev/null | head -30
        echo ""
        echo "═══ Cifras fracas ═══"
        nmap --script ssl-enum-ciphers -p 443 "$CLEAN" 2>/dev/null | grep -A2 "TLSv\|SSLv" || echo "Nenhuma fraca encontrada."
    } > "${OUTDIR}/ssl_check.txt"
    ok "→ ssl_check.txt"
fi

# ── CORS check ──
info "CORS misconfiguration check..."
{
    echo "═══ CORS Test ═══"
    for origin in "https://evil.com" "null" "https://${CLEAN}.evil.com"; do
        echo "Origin: ${origin}"
        resp=$(curl -sk -H "Origin: ${origin}" -I "$BASE_URL" 2>/dev/null)
        acao=$(echo "$resp" | grep -i "access-control-allow-origin" || echo "  Não refletido")
        echo "  $acao"
        echo ""
    done
} > "${OUTDIR}/cors_check.txt"
ok "→ cors_check.txt"

# Verificar se CORS está vulnerável (só nas linhas de ACAO, não no arquivo todo)
if grep -i "access-control-allow-origin" "${OUTDIR}/cors_check.txt" 2>/dev/null | grep -qi "evil.com\|\bnull\b"; then
    echo -e "    ${RED}⚠️  Possível CORS misconfiguration!${RST}"
fi

# ── Resumo ──
echo ""
info "Resumo de vulnerabilidades:"
for f in "${OUTDIR}"/*.txt; do
    if [[ -f "$f" ]] && [[ -s "$f" ]]; then
        echo -e "    ${GRN}→${RST} $(basename "$f")"
    fi
done

# ── HTML Report ──
HELPERS="$(dirname "$0")/_html_helpers.sh"
if [[ -f "$HELPERS" ]]; then
    source "$HELPERS"
    HTML="${OUTDIR}/report.html"

    html_head "⚠️ Vulnerability Scan — ${CLEAN}" > "$HTML"

    # Stats
    local nikto_count=0 nuclei_count=0 ssl_ok="N/A" cors_vuln="Não"
    [[ -f "${OUTDIR}/nikto.txt" ]] && nikto_count=$(grep -c "^+" "${OUTDIR}/nikto.txt" 2>/dev/null || echo 0)
    [[ -f "${OUTDIR}/nuclei.txt" ]] && nuclei_count=$(wc -l < "${OUTDIR}/nuclei.txt" 2>/dev/null || echo 0)
    if grep -qi "evil.com\|\\bnull\\b" <(grep -i "access-control-allow-origin" "${OUTDIR}/cors_check.txt" 2>/dev/null) 2>/dev/null; then
        cors_vuln="Sim ⚠️"
    fi

    cat >> "$HTML" <<EOF
<h1>⚠️ Vulnerability Scan</h1>
<p class="meta">Alvo: <strong>${BASE_URL}</strong> — $(date '+%Y-%m-%d %H:%M:%S')</p>

<div class="stats">
$(html_stat "$nikto_count" "Nikto findings" "yellow")
$(html_stat "$nuclei_count" "Nuclei findings" "red")
$(html_stat "$cors_vuln" "CORS Vuln" "purple")
</div>
EOF

    # Nuclei
    if [[ -s "${OUTDIR}/nuclei.txt" ]]; then
        html_section_start "🎯 Nuclei Findings (${nuclei_count})" >> "$HTML"
        echo '<table><tr><th>Severidade</th><th>Finding</th></tr>' >> "$HTML"
        while IFS= read -r line; do
            local sev_class="vuln-low" sev_badge
            if echo "$line" | grep -qi "critical"; then
                sev_class="vuln-critical"; sev_badge=$(html_badge "CRITICAL" "red")
            elif echo "$line" | grep -qi "high"; then
                sev_class="vuln-high"; sev_badge=$(html_badge "HIGH" "orange")
            elif echo "$line" | grep -qi "medium"; then
                sev_class="vuln-medium"; sev_badge=$(html_badge "MEDIUM" "yellow")
            else
                sev_badge=$(html_badge "LOW" "blue")
            fi
            echo "<tr class=\"${sev_class}\"><td>${sev_badge}</td><td>$(echo "$line" | _esc)</td></tr>" >> "$HTML"
        done < "${OUTDIR}/nuclei.txt"
        echo '</table>' >> "$HTML"
        html_section_end >> "$HTML"
    fi

    # Nikto
    if [[ -s "${OUTDIR}/nikto.txt" ]]; then
        html_section_start "🔍 Nikto (${nikto_count} findings)" >> "$HTML"
        html_file_pre "${OUTDIR}/nikto.txt" 100 >> "$HTML"
        html_section_end >> "$HTML"
    fi

    # Searchsploit
    if [[ -s "${OUTDIR}/searchsploit.txt" ]]; then
        html_section_start "💣 Searchsploit (exploits)" >> "$HTML"
        html_file_pre "${OUTDIR}/searchsploit.txt" 80 >> "$HTML"
        html_section_end >> "$HTML"
    fi

    # SSL
    if [[ -s "${OUTDIR}/ssl_check.txt" ]]; then
        html_section_start "🔒 SSL/TLS Check" >> "$HTML"
        html_file_pre "${OUTDIR}/ssl_check.txt" 50 >> "$HTML"
        html_section_end >> "$HTML"
    fi

    # CORS
    if [[ -s "${OUTDIR}/cors_check.txt" ]]; then
        html_section_start "🌐 CORS Check" >> "$HTML"
        html_file_pre "${OUTDIR}/cors_check.txt" 30 >> "$HTML"
        html_section_end >> "$HTML"
    fi

    html_foot >> "$HTML"
    ok "→ report.html"
fi

echo -e "\n${GRN}━━━ Módulo 05 concluído ━━━${RST}"