De que país são os que estão tentando acessar meu servidor via SSH ilegalmente!

8 min

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

Olá, sou um incompetente. Estou publicando um servidor FreeBSD da Vultr publicamente, e fiquei curioso para saber quem são as pessoas que estão tentando acessá-lo via SSH. A propósito, no caso do FreeBSD, ele me envia um "security run output" para o meu próprio domínio, informando-me sobre as tentativas que ocorreram. image Assim. Então, vamos usar o geoip para descobrir de que país são os endereços IP globais das pessoas que estão tentando acessar. A propósito, o comando geoiplookup pode ser instalado da seguinte forma:

sudo pacman -S geoip  
  

O comando é este

$ geoiplookup endereço IP  
GeoIP Country Edition: RU, Russian Federation  
  

Formatação de texto com bash

Primeiro, vamos pegar a string de dados original "security run output" para o meu ThinkPad (ou qualquer outro lugar) e formatá-la.

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

No caso acima, extraímos a descrição que contém a string 'from' até 'port' do 'security run output' chamado 'vultr', usando a correspondência de grep com -o e expressões regulares Perl com -P.
Fica algo como a seguinte string.

from endereço IP port  
  

A razão pela qual não usei awk neste ponto é que a saída de erro muda se a senha estiver incorreta ou se o usuário de destino não existir no meu servidor, então extraí a string de 'from' a 'port' para pegar tudo. Em seguida, uso awk para extrair apenas o endereço IP no primeiro registro do final, removo IPs duplicados com sort e uniq, e gravo em um arquivo chamado grepip. Depois, vamos fazer com que o bash execute geoiplookup para esses IPs e faça uma contagem simples por país.

$ cat country.sh  
#!/bin/bash  
  
# Arquivo de endereços IP  
INPUT="grepip"  
  
# Arquivo de saída  
OUTPUT="countries.log"  
  
# Inicialização  
> $OUTPUT  
  
# Executa geoiplookup para cada endereço IP e obtém informações do país  
while IFS= read -r ip; do  
    geoiplookup "$ip" | awk -F: '{print $2}' >> $OUTPUT  
done < "$INPUT"  
  
# Agrega e exibe as informações do país  
sort $OUTPUT | uniq -c | sort -tr  
  

Agora, vamos dar permissão de execução.

chmod +x ./country.sh  
  

Basta executar.

$ ./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  
  

Entendi...

Exibindo gráficos com Matplotlib para facilitar a compreensão

Bem, embora seja compreensível como texto, torna-se difícil de ler quando o número é grande, então gostaríamos de exibir um gráfico, certo?
Além disso, se for um script, pode ser gerado como um trabalho cron. Portanto, vamos exibir um gráfico usando a útil biblioteca Python Matplotlib. Instalação e código

pip install matplotlib  
  
cat AreYouFrom.py  
#!/usr/bin/python3  
  
import matplotlib.pyplot as plt  
import collections  
  
# Lê o arquivo e agrega o número de acessos por país  
country_counts = collections.Counter()  
  
with open('countries.txt', 'r') as file:  
    for line in file:  
        # Obtém informações do país  
        country = line.strip().split(",")[1]  
        country_counts[country] += 1  
  
# Ordena os dados  
countries, counts = zip(*country_counts.most_common())  
  
# Cria o 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()  
  
# Salva a imagem como arquivo png  
plt.savefig('accesses.png')  
  

Com isso, você pode gerar o gráfico e a imagem.

chmod +x AreYouFrom.py  
  

(Que nome de arquivo parece inglês de ensino médio!)

image

Tcharam! Parece que a maioria é dos Estados Unidos.

Agregando por porta que está tentando SSH

Agora, vamos verificar por porta que está sendo acessada.
Com isso, consegui extrair apenas as portas com grep.

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

Isso é salvo como ports.txt.
No entanto, como todos os números de porta são diferentes, vamos separá-los em blocos para a saída do gráfico.

$ cat AreYouPort.py  
#!/usr/bin/python3  
import matplotlib.pyplot as plt  
from collections import Counter  
  
# Lê os números das portas do arquivo  
with open('ports.txt', 'r') as file:  
    ports = [int(line.strip()) for line in file]  
  
# Calcula a distribuição de frequência dos números das portas  
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  
  
# Cria o 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()  
  
# Salva como arquivo PNG  
plt.savefig('port_numbers.png')  
  

E então.... image
Por que há tantas tentativas em números de porta improváveis, com valores acima de 30.000...? Então, por hoje é só. Até a próxima.

Related Posts