#!/usr/bin/env bash # Script: check_abuseipdb.sh # Descripción: Este script automatiza la comprobación de direcciones IP contra # la base de datos AbuseIPDB. Para cada IP proporcionada, el script # obtiene información sobre su abuso potencial, utilizando la API # de AbuseIPDB. Registra los resultados en un archivo de log. # Además, proporciona detalles sobre el país, ISP, tipo de uso y # categorías de ataque asociadas con la IP. Los resultados se # clasifican como "Sospechosa" o "No sospechosa" basándose en # el puntaje de abuso. # Requisitos: # - jq, curl. # - Añadir la API key de AbuseIPDB en la variable de entorno API_KEY_ipabuse o # introducirla al inicio del script. Conseguir API en plan individual Free: # https://www.abuseipdb.com/pricing # - Añadir la lista de IPs a comprobar en la variable de entorno IPS_LIST_abuseipdb # o introducirlas al inicio del script (una IP por línea). # Author: Manuel Vergara # Web: https://vergaracarmona.es # set -euo pipefail # Variables de configuración MAX_AGE_DAYS=90 # Número de días de historial a comprobar SLEEP_BETWEEN=1 # Tiempo de espera entre las comprobaciones de IPs THRESHOLD=50 # Umbral de score para considerar una IP sospechosa # Colores para salida COLOR_RED='\e[31m' # Color para mensajes de error COLOR_GREEN='\e[32m' # Color para mensajes exitosos COLOR_YELLOW='\e[33m' # Color para mensajes informativos COLOR_BLUE='\e[34m' # Color para títulos y encabezados COLOR_RESET='\e[0m' # Resetea el color al valor predeterminado # Archivo de log (cambiar la ubicación a un directorio accesible) LOG_FILE="./check_ips_script.log" # Cambiado a un directorio accesible para el usuario # Función para manejar la salida con Ctrl + C function ctrl_c() { echo -e "${COLOR_RED}\n\n[!] Saliendo... \n${COLOR_RESET}" tput cnorm log_message "El script se ha detenido debido a una interrupción del usuario." exit 1 } # Configurar Ctrl+C para detener el script trap ctrl_c SIGINT # Función para registrar mensajes en el archivo de log function log_message() { local message="$1" echo "$(date '+%Y-%m-%d %H:%M:%S') - $message" >>"$LOG_FILE" } # Función para imprimir títulos con formato y colores function print_title { local title="$1" local title_length=${#title} local total_length=22 local margin_length=$(((total_length - title_length - 4) / 2)) local left_padding=$((margin_length)) local right_padding=$((margin_length + (title_length % 2))) echo -e "${COLOR_BLUE}\n$(printf '#%.0s' $(seq 1 $left_padding))#### $title ####$(printf '#%.0s' $(seq 1 $right_padding))\n${COLOR_RESET}" } # Comprobación de dependencias necesarias for cmd in jq curl; do if ! command -v "$cmd" >/dev/null 2>&1; then echo -e "${COLOR_RED}Error: '$cmd' no está instalado. Instálalo y vuelve a ejecutar.${COLOR_RESET}" >&2 log_message "Error: '$cmd' no está instalado." exit 2 fi done log_message "Iniciando el script de comprobación de IPs." # Leer API_KEY desde variable de entorno o pedir al usuario API_KEY="${API_KEY_ipabuse:-}" if [[ -z "$API_KEY" ]]; then read -rp "Introduce tu API key de AbuseIPDB: " API_KEY if [[ -z "$API_KEY" ]]; then echo -e "${COLOR_RED}Error: la API key es obligatoria.${COLOR_RESET}" >&2 log_message "Error: No se proporcionó API Key." exit 1 fi fi # Leer lista de IPs desde variable de entorno o pedir al usuario IPS_LIST="${IPS_LIST_abuseipdb:-}" if [[ -z "$IPS_LIST" ]]; then echo -e "${COLOR_YELLOW}Introduce el listado de IPs (una por línea). Finaliza con Ctrl+D:${COLOR_RESET}" IPS_LIST="$(cat)" if [[ -z "$IPS_LIST" ]]; then echo -e "${COLOR_RED}Error: no se proporcionaron IPs.${COLOR_RESET}" >&2 log_message "Error: No se proporcionaron IPs." exit 1 fi fi # Convertir lista de IPs multilínea a array para procesar cada IP mapfile -t iterator <<< "$IPS_LIST" # Imprimir el título principal del script print_title "Comprobando IPs en AbuseIPDB" # Procesar cada IP for ip in "${iterator[@]}"; do ip=$(echo "$ip" | xargs) # Eliminar espacios en blanco extra [[ -z "$ip" ]] && continue # Saltar si la IP está vacía echo -e "${COLOR_BLUE}=== IP: $ip ===${COLOR_RESET}" # Hacer la solicitud a la API de AbuseIPDB resp=$(curl -sS -G "https://api.abuseipdb.com/api/v2/check" \ --data-urlencode "ipAddress=$ip" \ --data-urlencode "maxAgeInDays=$MAX_AGE_DAYS" \ --data-urlencode "verbose=true" \ -H "Key: $API_KEY" \ -H "Accept: application/json") # Controlar si no se obtiene respuesta de la API if [[ -z "$resp" ]]; then echo -e "${COLOR_RED}❌ Sin respuesta de la API.${COLOR_RESET}" log_message "Error: No se recibió respuesta para la IP $ip." continue fi # Verificar si hay errores en la respuesta de la API if echo "$resp" | jq -e '.errors? != null' >/dev/null; then echo -e "${COLOR_RED}❌ Error de API:${COLOR_RESET}" echo "$resp" | jq '.errors' log_message "Error de API para la IP $ip: $(echo "$resp" | jq -r '.errors')" continue fi # Extraer datos importantes de la respuesta JSON abuseScore=$(echo "$resp" | jq -r '.data.abuseConfidenceScore // 0') totalReports=$(echo "$resp" | jq -r '.data.totalReports // 0') lastReported=$(echo "$resp" | jq -r '.data.lastReportedAt // "N/A"') country=$(echo "$resp" | jq -r '.data.countryCode // "N/A"') isp=$(echo "$resp" | jq -r '.data.isp // "N/A"') usage=$(echo "$resp" | jq -r '.data.usageType // "N/A"') # Mostrar los resultados de la IP echo " País: $country" echo " ISP: $isp" echo " Uso: $usage" echo " Total reportes: $totalReports" echo " Último reporte: $lastReported" echo " Score abuso: $abuseScore" # Contar categorías de ataques reportados if (( totalReports > 0 )); then echo -e "${COLOR_YELLOW} Categorías reportadas:${COLOR_RESET}" declare -A category_map=( [3]="Fraude en pedidos" [4]="Ataque DDoS" [5]="Fuerza bruta FTP" [6]="Ping of Death" [7]="Phishing" [8]="Fraude VoIP" [9]="Proxy abierto" [10]="Spam en web" [11]="Spam por email" [12]="Spam en blogs" [13]="VPN" [14]="Escaneo de puertos" [15]="Hacking" [16]="SQL Injection" [17]="Spoofing" [18]="Fuerza bruta" [19]="Bot malicioso" [20]="Host explotado" [21]="Ataque a app web" [22]="Acceso SSH" [23]="Objetivo IoT" ) # Mostrar las categorías de ataque reportadas echo "$resp" | jq -r '.data.reports[].categories[]' | sort | uniq -c | sort -rn | while read -r count cat; do description="${category_map[$cat]:-Desconocida}" echo " - $description (Categoría $cat): $count veces" done fi # Evaluar si la IP es sospechosa en base al score if (( abuseScore >= THRESHOLD )); then echo -e "${COLOR_RED} 🔴 Resultado: SOSPECHOSA (score >= $THRESHOLD)${COLOR_RESET}" log_message "IP: $ip - Resultado: SOSPECHOSA (score >= $THRESHOLD)" else echo -e "${COLOR_GREEN} 🟢 Resultado: OK / No sospechosa (score < $THRESHOLD)${COLOR_RESET}" log_message "IP: $ip - Resultado: OK / No sospechosa (score < $THRESHOLD)" fi echo sleep "$SLEEP_BETWEEN" # Pausar entre cada consulta de IP done # Mensaje final de éxito echo -e "${COLOR_GREEN}✅ Comprobación finalizada.${COLOR_RESET}" log_message "El script se ejecutó correctamente."