¿Estamos bajo un ataque DoD o DDoS?


Esta tarde he estado leyendo esta entrada (y a la que le «he robado el título»). Como bien comenta el autor, una de las características que un ataque de denegación de servicio (DoS) presenta, ya sea distribuido o no, es el gran número de conexiones que recibirá nuestro sistema. En esta entrada, podéis consultar una serie de órdenes de shell que nos permiten obtener información sobre las conexiones de nuestro servidor y, en función de ésta, detectar un posible ataque.

Algo parecido hace el guión de Python que os copio debajo. Si le introducimos uno de los estados en los puede estar una conexión, nos indica, para cada IP que ha establecido contacto con nuestro servidor, cuantas conexiones están en ese estado (y para cualquier puerto). El guión da para mucho y, evidentemente, también para detectar situaciones anómalas en las que tenemos muchas conexiones «SYN_REC» que denotaría un posible DoS (o DDoS, dependiendo del número de IPs) e, incluso, un posible escaneo de puertos.

#!/usr/bin/python
#encoding:utf-8
try:
 import optparse, sys, re, socket
except:
 print("Error executing 'import optparse, sys, re, socket' command")
 exit(1)
try:
 import socket
 from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM
 import psutil
 from psutil._compat import print_
except:
 print "Error importing socket & psutil module. It is possible you need running 'apt-get install python-psutil'"
 exit(1)
def main():
 parser = optparse.OptionParser("usage%prog " + "-s <state>")
 parser.add_option('-s', dest = 'state', type = 'string', help = 'Please, specify the connection state to analize', default="ESTABLISHED")
 (options, args) = parser.parse_args()
 ipConnected = { }
 for conn in psutil.net_connections(kind='inet'):
 if conn.status == options.state:
 ip=conn.raddr[0]
 if (ip in ipConnected):
 ipConnected[ip]= ipConnected[ip]+1
 else:
 ipConnected[ip]=1
 print "Remote IP\t\t|# " + options.state + " connections"
 print "---------------------------------"
 for ip in ipConnected.keys():
 print "%s\t\t|%s" % (ip, str(ipConnected[ip]))
if __name__ == '__main__':
 main()

El guión admite muchas mejoras. Por ejemplo, y para el caso comentado, poner un límite a partir del cual nos avise o active un filtro para esa IP. También podríamos comprobar lo mismo, pero solo para un servicio (puerto) determinado y que podríamos introducir como parámetro de entrada.

¡Espero que os sea útil!

 

Deja un comentario