Annonce

Réduire
Aucune annonce.

Script de mitigation d'attaque DDOS

Réduire
X
 
  • Filtre
  • Heure
  • Afficher
Tout nettoyer
nouveaux messages

  • Script de mitigation d'attaque DDOS

    Si vous suivez Hackademics sur Twitter, vous savez probablement que nous avons subit une attaque DDOS hier soir.

    Les admins et moi même avons rapidement réglé le soucis et la situation est bien vite rentrée dans l'ordre malgré un filtrage d'adresse IP un tout petit peu trop restrictif entre hier 23h et ce matin 6h.

    Je ferai dans les quelques jours à venir un article plus détaillé sur le déroulement de l'attaque, sa découverte et sa mitigation mais aujourd'hui, j'aimerais vous présenter le programme que j'ai écrit pour éviter de re-mettre en place des blocages trop restrictifs dans le cas d'une future occurence.

    Je définirais ce code comme un outils de mitigation d'attaque DDOS dans la mesure où il est capable de :
    1. Grouper les logs de connexion sur un serveur NGINX en série temporelle pour définir quand l'attaque à commencé (à partir de cette tranche temporelle, le nombre de connexion devrait augmenter très significativement)
    2. Retrouver les adresses IP s'étant connecté à votre serveur dans une tranche temporelle que vous définissez

    Un exemple d'utilisation lors d'une attaque serait alors de :
    1. Découvrir le début de l'attaque via le premier point de la liste précédente
    2. Relever les IPs attaquantes via le second point de la liste précédente tout en fixant le début au début de l'attaque et la fin à un moment que vous choisissez. Remarquez quand même que mettre un point de fin éloigné du point de début augmente le nombre d'IPs attaquantes que vous allez sélectionner mais augmente également le nombre d'IPs légitimes que vous prendrez avec
    3. Créer des règles firewall de banissement sur les IPs découvertes
    Le code en lui même est disponible en fin d'article et sur GitHub

    Voici de plus le manuel du programme (qui est écrit en Python 3 et sans dépendances) :
    Code:
    usage: mitigate_DDOS.py [-h] -f NGINX_LOG_FILE [-a] [-t TIME] [-i]
                            [-b BEGIN_TIMESTAMP] [-e END_TIMESTAMP]
    
    Analyzes web server logs to find begin and mitigate DDOS attack
    
    optional arguments:
      -h, --help          show this help message and exit
      -f NGINX_LOG_FILE   The nginx log file
      -a                  Analysis task
      -t TIME             Time split for log blocks (default 10)
      -i                  Get IPs between two timestamps
      -b BEGIN_TIMESTAMP  Begin timestamp (in seconds) for IP gathering
      -e END_TIMESTAMP    Begin timestamp (in seconds) for IP gathering
    Le code du programme


    Notez que le code pourrait être modifié sur GitHub mais ne le sera dans ce cas pas sur cette page

    Code:
    """Script to mitigate a ddos attack by analyzing web log log file"""
    
    
    import os
    import sys
    from collections import namedtuple
    import datetime
    import argparse
    
    
    LogLine = namedtuple("LogLine", "ip time")
    
    
    class NginxLogDao():
        """Data access object for NginxLog"""
    
        def __init__(self, filename):
            """Initialises this with given filename"""
    
            assert filename is not None
            assert os.path.exists(filename)
    
            self.filename = filename
    
        def log_lines(self):
            """Reads logs lines and returns them as named tuples"""
    
            with open(self.filename) as f:
                for line in f:
                    ip = line.split("-")[0].strip()
                    date_str = line.split("[")[1].split("]")[0].split(" ")[0]
                    date = datetime.datetime.strptime(
                        date_str, '%d/%b/%Y:%H:%M:%S')
                    yield LogLine(ip=ip, time=date)
    
        def time_grouped(self, time_size=10):
            """Returns log lines grouped in time groups with blocks
               of time_size seconds"""
    
            block = None
            block_begin = None
            for log_line in self.log_lines():
                if block_begin is None or log_line.time > block_begin \
                        + datetime.timedelta(seconds=time_size):
                    if block_begin is not None:
                        yield block
    
                    block_begin = log_line.time
                    block = list()
    
                block.append(log_line)
    
        def ips_between(self, dt1, dt2):
            """Returns set of ip addresses between two timestamps"""
    
            ips = set()
            for log_line in self.log_lines():
                if dt1 <= log_line.time <= dt2:
                    ips.add(log_line.ip)
                elif log_line.time > dt2:
                    break
    
            return list(ips)
    
    
    if __name__ == '__main__':
        parser = argparse.ArgumentParser(
            description='Analyzes web server logs to find begin and mitigate DDOS attack')
        parser.add_argument('-f', action="store", dest="nginx_log_file",
                            help="The nginx log file", required=True)
        parser.add_argument('-a', action="store_true", dest="analyze",
                            help="Analysis task")
        parser.add_argument('-t', action="store", dest="time",
                            help="Time split for log blocks (default 10)",
                            default=10)
        parser.add_argument('-i', action="store_true", dest="get_ip",
                            help="Get IPs between two timestamps")
        parser.add_argument('-b', action="store", dest="begin_timestamp",
                            help="Begin timestamp (in seconds) for IP gathering")
        parser.add_argument('-e', action="store", dest="end_timestamp",
                            help="Begin timestamp (in seconds) for IP gathering")
        params = parser.parse_args()
    
        if params.analyze:
            time = int(params.time)
            blocks = NginxLogDao(
                params.nginx_log_file).time_grouped(time_size=time)
            for block in blocks:
                block_start = block[0].time
                timestamp = int(block_start.timestamp())
                print("{} - {} - {}".format(block_start, timestamp, len(block)))
        elif params.get_ip:
            if params.begin_timestamp is None or params.end_timestamp is None:
                print("With option -i you must provide option -b and -e")
                sys.exit(1)
    
            begin_timestamp = datetime.datetime.fromtimestamp(int(params.begin_timestamp))
            end_timestamp = datetime.datetime.fromtimestamp(int(params.end_timestamp))
    
            ips = NginxLogDao(params.nginx_log_file).ips_between(begin_timestamp,
                                                                 end_timestamp)
            for ip in ips:
                print(ip)
    Cet article est apparu en primeur sur mon site web : spidermind.be
    Dernière modification par Anonyme77, 19 décembre 2017, 10h09.

  • #2
    Notez que le code pourrait être modifié sur GitHub
    Ouais mais pour ça faudrait voir la gueule d'un log

    Commentaire


    • #3
      C'est un log par défaut de Nginx. Ça se trouve facilement .
      En voici quand même un pour exemple :
      Code:
      127.0.0.1 - - [19/Dec/2017:18:15:58 +0100] "GET / HTTP/1.0" 200 102 "-" "check_http/v2.2.1 (nagios-plugins 2.2.1)"

      Commentaire


      • #4
        J'ai fais une proposition de modif

        Bonne soirée

        Commentaire


        • #5
          Hello,

          Je l'ai vue et commentée à plusieurs endroits. Pour ne pas polluer le thread je te propose d'en parler en commentaire sur GitHub

          Bien à toi

          A77

          Commentaire


          • #6
            Oui je l'ai vu juste après avoir envoyé mon message ici

            Commentaire

            Chargement...
            X