¿De qué país son los que intentan acceder ilegalmente a mi servidor por SSH?

9 min

language: ja bn en es hi pt ru zh-cn zh-tw

Hola, soy un inútil. Estoy publicando un servidor FreeBSD de Vultr de forma pública, y me preguntaba quiénes son las personas que intentan acceder por SSH, así que lo estoy investigando. Por cierto, en el caso de FreeBSD, te envía un "security run output" a tu propio dominio, informándote sobre los intentos que ha habido.

image

Así es como se ve. Así que, usando geoip, vamos a echar un vistazo a qué país pertenecen las direcciones IP globales de las personas que intentan esto. Por cierto, el comando geoiplookup se puede instalar de la siguiente manera:

sudo pacman -S geoip  
  

Este es el comando:

$ geoiplookup dirección IP  
GeoIP Country Edition: RU, Russian Federation  
  

Formateo de texto con bash

Primero, traeré la cadena de datos original "security run output" a mi ThinkPad (o a cualquier lugar) y luego la formatearé.

cat vultr | grep -oP "from.*port" | awk '{print $(NF-1)}' | sort | uniq > grepip  
  

En el caso anterior, extraigo la descripción que contiene la cadena 'from' hasta 'port' de la descripción "security run output" llamada 'vultr', utilizando el valor que coincide con 'grep -o' y la expresión regular de Perl con 'P'.
Se verá algo así:

from dirección IP port  
  

La razón por la que no usé awk en este punto es que la salida de error cambia si la contraseña es incorrecta o si el usuario objetivo no existe en mi servidor, si se usa el espacio como delimitador. Por lo tanto, extraje la cadena completa desde 'from' hasta 'port' para capturarlo todo. Luego, con awk, extraigo solo la dirección IP del primer registro al final, elimino las IP duplicadas con sort y uniq, y lo escribo en un archivo llamado grepip. Y luego, en bash, después de ejecutar geoiplookup en esta IP, haremos que nos dé un recuento ligero por país.

$ cat country.sh  
#!/bin/bash  
  
# Archivo de direcciones IP  
INPUT="grepip"  
  
# Archivo de salida  
OUTPUT="countries.log"  
  
# Inicialización  
> $OUTPUT  
  
# Ejecuta geoiplookup para cada dirección IP y obtiene la información del país  
while IFS= read -r ip; do  
    geoiplookup "$ip" | awk -F: '{print $2}' >> $OUTPUT  
done < "$INPUT"  
  
# Agrupa y muestra la información del país  
sort $OUTPUT | uniq -c | sort -tr  
  

Ahora le damos permisos de ejecución.

chmod +x ./country.sh  
  

Ahora solo hay que ejecutarlo.

$ ./country.sh  
      1  BE, Belgium  
      1  BG, Bulgaria  
      1  BR, Brazil  
      1  CH, Switzerland  
      1  HK, Hong Kong  
      1  HU, Hungary  
      1  IR, Iran, Islamic Republic of  
      1  IT, Italy  
      1  LT, Lithuania  
      1  MT, Malta  
      1  MX, Mexico  
      1  MY, Malaysia  
      1  NO, Norway  
      1  PA, Panama  
      1  PE, Peru  
      1  SE, Sweden  
      1  SK, Slovakia  
      1  TH, Thailand  
      1  TM, Turkmenistan  
      1  TZ, Tanzania, United Republic of  
      1  UZ, Uzbekistan  
      1  ZA, South Africa  
      2  RO, Romania  
      2  UA, Ukraine  
      3  PL, Poland  
      6  GB, United Kingdom  
      7  VN, Vietnam  
      8  CA, Canada  
      8  ID, Indonesia  
      9  RU, Russian Federation  
      9  SG, Singapore  
     10  FR, France  
     10  KR, Korea, Republic of  
     11  DE, Germany  
     11  NL, Netherlands  
     16  CN, China  
     18  IN, India  
     43  US, United States  
  

Interesante...

Visualización de gráficos con Matplotlib para mayor claridad

Bueno, se entiende por el texto, pero si el número es grande, se vuelve difícil de leer, ¿verdad? Así que queremos mostrarlo en un gráfico.
Además, si lo convertimos en un script, podemos hacer que se genere como un trabajo cron. Por lo tanto, mostraremos los gráficos con Matplotlib, una útil biblioteca de Python. Instalación y código:

pip install matplotlib  
  
cat AreYouFrom.py  
#!/usr/bin/python3  
  
import matplotlib.pyplot as plt  
import collections  
  
# Lee el archivo y cuenta los accesos por país  
country_counts = collections.Counter()  
  
with open('countries.txt', 'r') as file:  
    for line in file:  
        # Obtiene la información del país  
        country = line.strip().split(",")[1]  
        country_counts[country] += 1  
  
# Ordena los datos  
countries, counts = zip(*country_counts.most_common())  
  
# Crea el gráfico  
plt.figure(figsize=(10, 6))  
plt.bar(countries, counts, color='skyblue')  
plt.xlabel('Country')  
plt.ylabel('Accesses')  
plt.title('Accesses by Country')  
plt.xticks(rotation=90)  
plt.tight_layout()  
  
# Exporta la imagen como archivo png  
plt.savefig('accesses.png')  
  

Con esto, podemos generar el gráfico y exportarlo como imagen.

chmod +x AreYouFrom.py  
  

(¡Qué nombre de archivo tan de inglés de secundaria!)

image

¡Tachán! Parece que la mayoría proviene de Estados Unidos.

Agrupación por puertos a los que se intenta acceder por SSH

Ahora, investiguemos por los puertos a los que se intenta acceder.
Con esto, pude hacer grep solo para los puertos.

cat vultr | grep -oP "port [123456789].*ssh2$" | grep -oP "[123456789].* "  
  

Esto se exporta como ports.txt.
Sin embargo, dado que todos los números de puerto son diferentes, al generar el gráfico, los dividiremos en bloques.

$ cat AreYouPort.py  
#!/usr/bin/python3  
import matplotlib.pyplot as plt  
from collections import Counter  
  
# Lee los números de puerto del archivo  
with open('ports.txt', 'r') as file:  
    ports = [int(line.strip()) for line in file]  
  
# Calcula la distribución de frecuencia de los números de puerto  
counter = Counter(ports)  
  
blocks = {}  
for port, count in counter.items():  
    block = (port // 10000) * 10000  
    if block not in blocks:  
        blocks[block] = 0  
    blocks[block] += count  
  
# Crea el gráfico  
x = list(blocks.keys())  
y = list(blocks.values())  
  
plt.figure(figsize=(12, 6))  
plt.bar(x, y, width=6000, color='skyblue', edgecolor='black')  
plt.xlabel('Port Number')  
plt.ylabel('Frequency')  
plt.title('Port Numbers by Frequency')  
plt.xticks(x, [f'{i}-{i+9999}' for i in x], rotation=45)  
plt.grid(True, axis='y', linestyle='--', alpha=0.7)  
plt.tight_layout()  
  
# Guarda en un archivo PNG  
plt.savefig('port_numbers.png')  
  

Y entonces....
image
¿Por qué hay tantos intentos en números de puerto improbables, con valores superiores a 30,000...? Así que eso es todo por hoy. Nos vemos la próxima.

Related Posts