mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-14 11:44:23 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
884c5bf0cd | ||
|
|
7e24d7cf4c | ||
|
|
d16b73656f | ||
|
|
8acbb7187c | ||
|
|
51bea90e6f | ||
|
|
4cb54b5b2e | ||
|
|
310f732a5b | ||
|
|
018fd8d959 | ||
|
|
07fa518fcc | ||
|
|
37dcd23353 | ||
|
|
748e7bffc9 | ||
|
|
681e0da041 | ||
|
|
667281ffb4 | ||
|
|
4b18675e8b | ||
|
|
f63aabfb7a | ||
|
|
b4c1df7f4a | ||
|
|
4c1a929867 | ||
|
|
0f1aa6f946 | ||
|
|
20684339d3 | ||
|
|
d53a3c58c9 | ||
|
|
5c7f0e3ad0 | ||
|
|
168f8db5ab | ||
|
|
91a6218692 | ||
|
|
02164e4580 | ||
|
|
5595530977 | ||
|
|
a30fd9bb50 | ||
|
|
6c6a79a843 | ||
|
|
298da8bfab |
@@ -26,6 +26,7 @@ Lancement de Defender :
|
|||||||
# VERSION 1
|
# VERSION 1
|
||||||
|
|
||||||
[02.01.2024]
|
[02.01.2024]
|
||||||
|
- Rajout de l'activation de la commande flood
|
||||||
- Les deux variables RESTART et INIT ont été déplacées vers le module Irc
|
- Les deux variables RESTART et INIT ont été déplacées vers le module Irc
|
||||||
- Nouvelle class Install:
|
- Nouvelle class Install:
|
||||||
- Le programme va vérifier si les 3 librairies sont installées (SQLAlchemy & requests & psutil)
|
- Le programme va vérifier si les 3 librairies sont installées (SQLAlchemy & requests & psutil)
|
||||||
|
|||||||
14
core/base.py
14
core/base.py
@@ -137,7 +137,7 @@ class Base:
|
|||||||
(:createdOn, :user, :password, :hostname, :vhost, :level)"""
|
(:createdOn, :user, :password, :hostname, :vhost, :level)"""
|
||||||
, mes_donnees)
|
, mes_donnees)
|
||||||
|
|
||||||
pass
|
return None
|
||||||
|
|
||||||
def create_timer(self, time_to_wait: float, func: object, func_args: tuple = ()) -> None:
|
def create_timer(self, time_to_wait: float, func: object, func_args: tuple = ()) -> None:
|
||||||
|
|
||||||
@@ -153,9 +153,15 @@ class Base:
|
|||||||
except AssertionError as ae:
|
except AssertionError as ae:
|
||||||
self.__debug(f'Assertion Error -> {ae}')
|
self.__debug(f'Assertion Error -> {ae}')
|
||||||
|
|
||||||
def create_thread(self, func:object, func_args: tuple = ()) -> None:
|
def create_thread(self, func:object, func_args: tuple = (), run_once:bool = False) -> None:
|
||||||
try:
|
try:
|
||||||
func_name = func.__name__
|
func_name = func.__name__
|
||||||
|
|
||||||
|
if run_once:
|
||||||
|
for thread in self.running_threads:
|
||||||
|
if thread.getName() == func_name:
|
||||||
|
return None
|
||||||
|
|
||||||
# if func_name in self.running_threads:
|
# if func_name in self.running_threads:
|
||||||
# print(f"HeartBeat is running")
|
# print(f"HeartBeat is running")
|
||||||
# return None
|
# return None
|
||||||
@@ -243,7 +249,7 @@ class Base:
|
|||||||
self.running_sockets.remove(soc)
|
self.running_sockets.remove(soc)
|
||||||
print(f"> Socket ==> closed {str(soc.fileno())}")
|
print(f"> Socket ==> closed {str(soc.fileno())}")
|
||||||
|
|
||||||
pass
|
return None
|
||||||
|
|
||||||
def db_init(self) -> tuple[Engine, Connection]:
|
def db_init(self) -> tuple[Engine, Connection]:
|
||||||
|
|
||||||
@@ -367,7 +373,7 @@ class Base:
|
|||||||
# Run Garbage Collector Timer
|
# Run Garbage Collector Timer
|
||||||
self.garbage_collector_timer()
|
self.garbage_collector_timer()
|
||||||
self.garbage_collector_thread()
|
self.garbage_collector_thread()
|
||||||
self.garbage_collector_sockets()
|
# self.garbage_collector_sockets()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
for key, value in self.periodic_func.items():
|
for key, value in self.periodic_func.items():
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
from typing import Literal, Dict, List
|
||||||
##########################################
|
##########################################
|
||||||
# CONFIGURATION FILE : #
|
# CONFIGURATION FILE : #
|
||||||
# Rename file to : configuration.py #
|
# Rename file to : configuration.py #
|
||||||
@@ -6,7 +7,7 @@ import os
|
|||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
|
||||||
DEFENDER_VERSION = '1.1.0' # MAJOR.MINOR.BATCH
|
DEFENDER_VERSION = '3.3.2' # MAJOR.MINOR.BATCH
|
||||||
DEFENDER_DB_PATH = 'db' + os.sep # Séparateur en fonction de l'OS
|
DEFENDER_DB_PATH = 'db' + os.sep # Séparateur en fonction de l'OS
|
||||||
DEFENDER_DB_NAME = 'defender' # Le nom de la base de données principale
|
DEFENDER_DB_NAME = 'defender' # Le nom de la base de données principale
|
||||||
SERVICE_NAME = 'defender' # Le nom du service
|
SERVICE_NAME = 'defender' # Le nom du service
|
||||||
@@ -37,7 +38,11 @@ class Config:
|
|||||||
SALON_JAIL_MODES = 'sS' # Mode du salon pot de miel
|
SALON_JAIL_MODES = 'sS' # Mode du salon pot de miel
|
||||||
SALON_LIBERER = '#welcome' # Le salon ou sera envoyé l'utilisateur clean
|
SALON_LIBERER = '#welcome' # Le salon ou sera envoyé l'utilisateur clean
|
||||||
|
|
||||||
|
API_TIMEOUT = 2 # Timeout des api's
|
||||||
|
|
||||||
PORTS_TO_SCAN = [3028, 8080, 1080, 1085, 4145, 9050] # Liste des ports a scanné pour une detection de proxy
|
PORTS_TO_SCAN = [3028, 8080, 1080, 1085, 4145, 9050] # Liste des ports a scanné pour une detection de proxy
|
||||||
|
WHITELISTED_IP = ['127.0.0.1'] # IP a ne pas scanner
|
||||||
|
GLINE_DURATION = '1d' # La durée du gline
|
||||||
|
|
||||||
DEBUG = 0 # Afficher l'ensemble des messages du serveurs dans la console
|
DEBUG = 0 # Afficher l'ensemble des messages du serveurs dans la console
|
||||||
|
|
||||||
|
|||||||
105
core/irc.py
105
core/irc.py
@@ -1,6 +1,6 @@
|
|||||||
import ssl, re, importlib, sys, time, threading, socket
|
import ssl, re, importlib, sys, time, threading, socket
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from typing import Union
|
||||||
from core.configuration import Config
|
from core.configuration import Config
|
||||||
from core.base import Base
|
from core.base import Base
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ class Irc:
|
|||||||
self.commands_level = {
|
self.commands_level = {
|
||||||
0: ['help', 'auth', 'copyright'],
|
0: ['help', 'auth', 'copyright'],
|
||||||
1: ['load','reload','unload', 'deauth', 'uptime'],
|
1: ['load','reload','unload', 'deauth', 'uptime'],
|
||||||
2: ['show_sessions','show_modules', 'show_timers', 'show_threads'],
|
2: ['show_modules', 'show_timers', 'show_threads', 'sentinel'],
|
||||||
3: ['quit', 'restart','addaccess','editaccess', 'delaccess']
|
3: ['quit', 'restart','addaccess','editaccess', 'delaccess']
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ class Irc:
|
|||||||
self.commands.append(command)
|
self.commands.append(command)
|
||||||
|
|
||||||
self.Base = Base(self.Config)
|
self.Base = Base(self.Config)
|
||||||
self.Base.create_thread(self.heartbeat, (self.beat, ))
|
self.Base.create_thread(func=self.heartbeat, func_args=(self.beat, ))
|
||||||
|
|
||||||
##############################################
|
##############################################
|
||||||
# CONNEXION IRC #
|
# CONNEXION IRC #
|
||||||
@@ -57,9 +57,9 @@ class Irc:
|
|||||||
self.IrcSocket.connect(connexion_information)
|
self.IrcSocket.connect(connexion_information)
|
||||||
|
|
||||||
# Créer un object ssl
|
# Créer un object ssl
|
||||||
ssl_context = self.__ssl_context()
|
# ssl_context = self.__ssl_context()
|
||||||
ssl_connexion = ssl_context.wrap_socket(self.IrcSocket, server_hostname=self.Config.SERVEUR_HOSTNAME)
|
# ssl_connexion = ssl_context.wrap_socket(self.IrcSocket, server_hostname=self.Config.SERVEUR_HOSTNAME)
|
||||||
self.IrcSocket = ssl_connexion
|
# self.IrcSocket = ssl_connexion
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -78,6 +78,7 @@ class Irc:
|
|||||||
self.load_existing_modules() # Charger les modules existant dans la base de données
|
self.load_existing_modules() # Charger les modules existant dans la base de données
|
||||||
|
|
||||||
while self.signal:
|
while self.signal:
|
||||||
|
try:
|
||||||
if self.RESTART == 1:
|
if self.RESTART == 1:
|
||||||
self.IrcSocket.shutdown(socket.SHUT_RDWR)
|
self.IrcSocket.shutdown(socket.SHUT_RDWR)
|
||||||
self.IrcSocket.close()
|
self.IrcSocket.close()
|
||||||
@@ -95,6 +96,7 @@ class Irc:
|
|||||||
# data = self.IrcSocket.recv(buffer_size).splitlines(True)
|
# data = self.IrcSocket.recv(buffer_size).splitlines(True)
|
||||||
|
|
||||||
data_in_bytes = self.IrcSocket.recv(buffer_size)
|
data_in_bytes = self.IrcSocket.recv(buffer_size)
|
||||||
|
|
||||||
count_bytes = len(data_in_bytes)
|
count_bytes = len(data_in_bytes)
|
||||||
|
|
||||||
while count_bytes > 4070:
|
while count_bytes > 4070:
|
||||||
@@ -105,23 +107,37 @@ class Irc:
|
|||||||
# print("========================================================")
|
# print("========================================================")
|
||||||
|
|
||||||
data = data_in_bytes.splitlines()
|
data = data_in_bytes.splitlines()
|
||||||
|
|
||||||
# print(f"{str(buffer_size)} - {str(len(data_in_bytes))}")
|
# print(f"{str(buffer_size)} - {str(len(data_in_bytes))}")
|
||||||
|
|
||||||
if not data:
|
if not data:
|
||||||
break
|
break
|
||||||
|
|
||||||
self.send_response(data)
|
self.send_response(data)
|
||||||
|
if self.IrcSocket.fileno() == -1:
|
||||||
|
print('restarting the socket')
|
||||||
|
self.RESTART = 1
|
||||||
|
|
||||||
|
except ssl.SSLEOFError as soe:
|
||||||
|
self.debug(f"SSLEOFError __connect_to_irc: {soe} - {data}")
|
||||||
|
except ssl.SSLError as se:
|
||||||
|
self.debug(f"SSLError __connect_to_irc: {se} - {data}")
|
||||||
|
except OSError as oe:
|
||||||
|
self.debug(f"SSLError __connect_to_irc: {oe} - {data}")
|
||||||
|
except Exception as e:
|
||||||
|
self.debug(f"Exception __connect_to_irc: {e} - {data}")
|
||||||
|
|
||||||
self.IrcSocket.shutdown(socket.SHUT_RDWR)
|
self.IrcSocket.shutdown(socket.SHUT_RDWR)
|
||||||
self.IrcSocket.close()
|
self.IrcSocket.close()
|
||||||
|
self.debug("--> Fermeture de Defender ...")
|
||||||
|
|
||||||
except AssertionError as ae:
|
except AssertionError as ae:
|
||||||
self.debug(f'Assertion error : {ae}')
|
self.debug(f'Assertion error : {ae}')
|
||||||
except ValueError as ve:
|
except ValueError as ve:
|
||||||
self.debug(f'Value Error : {ve}')
|
self.debug(f'Value Error : {ve}')
|
||||||
except OSError as oe:
|
except ssl.SSLEOFError as soe:
|
||||||
self.debug(f"OS Error : {oe}")
|
self.debug(f"OS Error __connect_to_irc: {soe}")
|
||||||
|
except Exception as e:
|
||||||
|
self.debug(f"Exception: {e}")
|
||||||
|
|
||||||
def __link(self, writer:socket.socket) -> None:
|
def __link(self, writer:socket.socket) -> None:
|
||||||
"""Créer le link et envoyer les informations nécessaires pour la
|
"""Créer le link et envoyer les informations nécessaires pour la
|
||||||
@@ -130,7 +146,6 @@ class Irc:
|
|||||||
Args:
|
Args:
|
||||||
writer (StreamWriter): permet l'envoi des informations au serveur.
|
writer (StreamWriter): permet l'envoi des informations au serveur.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nickname = self.Config.SERVICE_NICKNAME
|
nickname = self.Config.SERVICE_NICKNAME
|
||||||
username = self.Config.SERVICE_USERNAME
|
username = self.Config.SERVICE_USERNAME
|
||||||
realname = self.Config.SERVICE_REALNAME
|
realname = self.Config.SERVICE_REALNAME
|
||||||
@@ -151,8 +166,6 @@ class Irc:
|
|||||||
unixtime = self.Base.get_unixtime()
|
unixtime = self.Base.get_unixtime()
|
||||||
|
|
||||||
# Envoyer un message d'identification
|
# Envoyer un message d'identification
|
||||||
# strtobytes = bytes(":" + sid + " PASS :" + password + "\r\n", 'utf-8')
|
|
||||||
# self.IrcSocket.send(strtobytes)
|
|
||||||
writer.send(f":{sid} PASS :{password}\r\n".encode('utf-8'))
|
writer.send(f":{sid} PASS :{password}\r\n".encode('utf-8'))
|
||||||
writer.send(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS\r\n".encode('utf-8'))
|
writer.send(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS\r\n".encode('utf-8'))
|
||||||
writer.send(f":{sid} PROTOCTL EAUTH={link},,,{service_name}-v{version}\r\n".encode('utf-8'))
|
writer.send(f":{sid} PROTOCTL EAUTH={link},,,{service_name}-v{version}\r\n".encode('utf-8'))
|
||||||
@@ -164,9 +177,7 @@ class Irc:
|
|||||||
writer.send(f":{sid} MODE {chan} +{cmodes}\r\n".encode('utf-8'))
|
writer.send(f":{sid} MODE {chan} +{cmodes}\r\n".encode('utf-8'))
|
||||||
writer.send(f":{service_id} SAMODE {chan} +{umodes} {nickname}\r\n".encode('utf-8'))
|
writer.send(f":{service_id} SAMODE {chan} +{umodes} {nickname}\r\n".encode('utf-8'))
|
||||||
|
|
||||||
# writer.write(f"USER {nickname} {username} {username} {nickname} {username} :{username}\r\n".encode('utf-8'))
|
return None
|
||||||
# writer.write(f"USER {username} {username} {username} :{username}\r\n".encode('utf-8'))
|
|
||||||
# writer.write(f"NICK {nickname}\r\n".encode('utf-8'))
|
|
||||||
|
|
||||||
def send2socket(self, send_message:str) -> None:
|
def send2socket(self, send_message:str) -> None:
|
||||||
"""Envoit les commandes à envoyer au serveur.
|
"""Envoit les commandes à envoyer au serveur.
|
||||||
@@ -185,8 +196,12 @@ class Irc:
|
|||||||
self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace'))
|
self.IrcSocket.send(f"{send_message}\r\n".encode(self.CHARSET[0],'replace'))
|
||||||
except AssertionError as ae:
|
except AssertionError as ae:
|
||||||
self.debug(f"Assertion error : {ae}")
|
self.debug(f"Assertion error : {ae}")
|
||||||
|
except ssl.SSLEOFError as soe:
|
||||||
|
self.debug(f"SSLEOFError send2socket: {soe} - {send_message}")
|
||||||
|
except ssl.SSLError as se:
|
||||||
|
self.debug(f"SSLError send2socket: {se} - {send_message}")
|
||||||
except OSError as oe:
|
except OSError as oe:
|
||||||
self.debug(f"OS Error : {oe}")
|
self.debug(f"OSError send2socket: {oe} - {send_message}")
|
||||||
|
|
||||||
def send_response(self, responses:list[bytes]) -> None:
|
def send_response(self, responses:list[bytes]) -> None:
|
||||||
try:
|
try:
|
||||||
@@ -207,6 +222,7 @@ class Irc:
|
|||||||
##############################################
|
##############################################
|
||||||
# FIN CONNEXION IRC #
|
# FIN CONNEXION IRC #
|
||||||
##############################################
|
##############################################
|
||||||
|
|
||||||
def load_existing_modules(self) -> None:
|
def load_existing_modules(self) -> None:
|
||||||
"""Charge les modules qui existe déja dans la base de données
|
"""Charge les modules qui existe déja dans la base de données
|
||||||
|
|
||||||
@@ -348,6 +364,8 @@ class Irc:
|
|||||||
except ModuleNotFoundError as moduleNotFound:
|
except ModuleNotFoundError as moduleNotFound:
|
||||||
self.debug(f"MODULE_NOT_FOUND: {moduleNotFound}")
|
self.debug(f"MODULE_NOT_FOUND: {moduleNotFound}")
|
||||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}MODULE_NOT_FOUND{self.Config.CONFIG_COLOR['noire']} ]: {moduleNotFound}")
|
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}MODULE_NOT_FOUND{self.Config.CONFIG_COLOR['noire']} ]: {moduleNotFound}")
|
||||||
|
except Exception as e:
|
||||||
|
self.debug(f"Something went wrong with a module you want to load : {e}")
|
||||||
|
|
||||||
def insert_db_uid(self, uid:str, nickname:str, username:str, hostname:str, umodes:str, vhost:str, isWebirc: bool) -> None:
|
def insert_db_uid(self, uid:str, nickname:str, username:str, hostname:str, umodes:str, vhost:str, isWebirc: bool) -> None:
|
||||||
|
|
||||||
@@ -429,8 +447,6 @@ class Irc:
|
|||||||
vhost = self.db_uid[uid]['vhost']
|
vhost = self.db_uid[uid]['vhost']
|
||||||
level = int(level)
|
level = int(level)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.db_admin[uid] = {
|
self.db_admin[uid] = {
|
||||||
'nickname': nickname,
|
'nickname': nickname,
|
||||||
'username': username,
|
'username': username,
|
||||||
@@ -533,7 +549,7 @@ class Irc:
|
|||||||
self.debug(response)
|
self.debug(response)
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get_uid(self, uidornickname:str) -> str | None:
|
def get_uid(self, uidornickname:str) -> Union[str, None]:
|
||||||
|
|
||||||
uid_recherche = uidornickname
|
uid_recherche = uidornickname
|
||||||
response = None
|
response = None
|
||||||
@@ -546,7 +562,7 @@ class Irc:
|
|||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def get_nickname(self, uidornickname:str) -> str | None:
|
def get_nickname(self, uidornickname:str) -> Union[str, None]:
|
||||||
|
|
||||||
nickname_recherche = uidornickname
|
nickname_recherche = uidornickname
|
||||||
|
|
||||||
@@ -604,12 +620,16 @@ class Irc:
|
|||||||
|
|
||||||
def cmd(self, data:list) -> None:
|
def cmd(self, data:list) -> None:
|
||||||
try:
|
try:
|
||||||
cmd = data
|
cmd_to_send:list[str] = data.copy()
|
||||||
|
cmd = data.copy()
|
||||||
|
|
||||||
|
cmd_to_debug = data.copy()
|
||||||
|
cmd_to_debug.pop(0)
|
||||||
|
|
||||||
if len(cmd) == 0 or len(cmd) == 1:
|
if len(cmd) == 0 or len(cmd) == 1:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.debug(cmd)
|
self.debug(cmd_to_debug)
|
||||||
|
|
||||||
match cmd[0]:
|
match cmd[0]:
|
||||||
|
|
||||||
@@ -738,6 +758,9 @@ class Irc:
|
|||||||
|
|
||||||
self.insert_db_uid(uid, nickname, username, hostname, umodes, vhost, isWebirc)
|
self.insert_db_uid(uid, nickname, username, hostname, umodes, vhost, isWebirc)
|
||||||
|
|
||||||
|
for classe_name, classe_object in self.loaded_classes.items():
|
||||||
|
classe_object.cmd(cmd_to_send)
|
||||||
|
|
||||||
case 'PRIVMSG':
|
case 'PRIVMSG':
|
||||||
try:
|
try:
|
||||||
# Supprimer la premiere valeur
|
# Supprimer la premiere valeur
|
||||||
@@ -809,9 +832,10 @@ class Irc:
|
|||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if cmd[2] != 'UID':
|
||||||
# Envoyer la commande aux classes dynamiquement chargées
|
# Envoyer la commande aux classes dynamiquement chargées
|
||||||
for classe_name, classe_object in self.loaded_classes.items():
|
for classe_name, classe_object in self.loaded_classes.items():
|
||||||
classe_object.cmd(cmd)
|
classe_object.cmd(cmd_to_send)
|
||||||
|
|
||||||
except IndexError as ie:
|
except IndexError as ie:
|
||||||
self.debug(f"IRC CMD -> IndexError : {ie} - {cmd} - length {str(len(cmd))}")
|
self.debug(f"IRC CMD -> IndexError : {ie} - {cmd} - length {str(len(cmd))}")
|
||||||
@@ -1022,11 +1046,12 @@ class Irc:
|
|||||||
|
|
||||||
case 'unload':
|
case 'unload':
|
||||||
# unload mod_dktmb
|
# unload mod_dktmb
|
||||||
|
try:
|
||||||
module_name = str(cmd[1]).lower() # Le nom du module. exemple: mod_defender
|
module_name = str(cmd[1]).lower() # Le nom du module. exemple: mod_defender
|
||||||
class_name = module_name.split('_')[1].capitalize() # Nom de la class. exemple: Defender
|
class_name = module_name.split('_')[1].capitalize() # Nom de la class. exemple: Defender
|
||||||
|
|
||||||
if class_name in self.loaded_classes:
|
if class_name in self.loaded_classes:
|
||||||
|
self.loaded_classes[class_name].unload()
|
||||||
for level, command in self.loaded_classes[class_name].commands_level.items():
|
for level, command in self.loaded_classes[class_name].commands_level.items():
|
||||||
# Supprimer la commande de la variable commands
|
# Supprimer la commande de la variable commands
|
||||||
for c in self.loaded_classes[class_name].commands_level[level]:
|
for c in self.loaded_classes[class_name].commands_level[level]:
|
||||||
@@ -1039,13 +1064,17 @@ class Irc:
|
|||||||
self.Base.db_delete_module(module_name)
|
self.Base.db_delete_module(module_name)
|
||||||
|
|
||||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} supprimé")
|
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} supprimé")
|
||||||
|
except:
|
||||||
|
self.debug(f"Something went wrong with a module you want to load")
|
||||||
|
|
||||||
case 'reload':
|
case 'reload':
|
||||||
# reload mod_dktmb
|
# reload mod_dktmb
|
||||||
|
try:
|
||||||
module_name = str(cmd[1]).lower() # ==> mod_defender
|
module_name = str(cmd[1]).lower() # ==> mod_defender
|
||||||
class_name = module_name.split('_')[1].capitalize() # ==> Defender
|
class_name = module_name.split('_')[1].capitalize() # ==> Defender
|
||||||
|
|
||||||
if 'mods.' + module_name in sys.modules:
|
if 'mods.' + module_name in sys.modules:
|
||||||
|
self.loaded_classes[class_name].unload()
|
||||||
self.debug('Module Already Loaded ... reload the module ...')
|
self.debug('Module Already Loaded ... reload the module ...')
|
||||||
the_module = sys.modules['mods.' + module_name]
|
the_module = sys.modules['mods.' + module_name]
|
||||||
importlib.reload(the_module)
|
importlib.reload(the_module)
|
||||||
@@ -1069,6 +1098,8 @@ class Irc:
|
|||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} n'est pas chargé !")
|
self.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :Module {module_name} n'est pas chargé !")
|
||||||
|
except:
|
||||||
|
self.debug(f"Something went wrong with a module you want to reload")
|
||||||
|
|
||||||
case 'quit':
|
case 'quit':
|
||||||
try:
|
try:
|
||||||
@@ -1101,6 +1132,9 @@ class Irc:
|
|||||||
self.db_uid.clear() #Vider UID_DB
|
self.db_uid.clear() #Vider UID_DB
|
||||||
self.db_chan = [] #Vider les salons
|
self.db_chan = [] #Vider les salons
|
||||||
|
|
||||||
|
for class_name in self.loaded_classes:
|
||||||
|
self.loaded_classes[class_name].unload()
|
||||||
|
|
||||||
self.send2socket(f':{dnickname} NOTICE {fromuser} : Redémarrage du service {dnickname}')
|
self.send2socket(f':{dnickname} NOTICE {fromuser} : Redémarrage du service {dnickname}')
|
||||||
self.send2socket(f':{self.Config.SERVEUR_LINK} SQUIT {self.Config.SERVEUR_LINK} :{final_reason}')
|
self.send2socket(f':{self.Config.SERVEUR_LINK} SQUIT {self.Config.SERVEUR_LINK} :{final_reason}')
|
||||||
self.debug(f'Redémarrage du server {dnickname}')
|
self.debug(f'Redémarrage du server {dnickname}')
|
||||||
@@ -1132,7 +1166,12 @@ class Irc:
|
|||||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :Aucun timers en cours d'execution")
|
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :Aucun timers en cours d'execution")
|
||||||
|
|
||||||
case 'show_threads':
|
case 'show_threads':
|
||||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :{self.Base.running_threads}")
|
|
||||||
|
running_thread_name:list = []
|
||||||
|
for thread in self.Base.running_threads:
|
||||||
|
running_thread_name.append(f"{thread.getName()} ({thread.is_alive()})")
|
||||||
|
|
||||||
|
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :{str(running_thread_name)}")
|
||||||
|
|
||||||
case 'uptime':
|
case 'uptime':
|
||||||
uptime = self.get_defender_uptime()
|
uptime = self.get_defender_uptime()
|
||||||
@@ -1141,5 +1180,21 @@ class Irc:
|
|||||||
case 'copyright':
|
case 'copyright':
|
||||||
self.send2socket(f':{dnickname} NOTICE {fromuser} : # Defender V.{self.Config.DEFENDER_VERSION} Developped by adator® and dktmb® #')
|
self.send2socket(f':{dnickname} NOTICE {fromuser} : # Defender V.{self.Config.DEFENDER_VERSION} Developped by adator® and dktmb® #')
|
||||||
|
|
||||||
|
case 'sentinel':
|
||||||
|
# .sentinel on
|
||||||
|
activation = str(cmd[1]).lower()
|
||||||
|
service_id = self.Config.SERVICE_ID
|
||||||
|
|
||||||
|
channel_to_dont_quit = [self.Config.SALON_JAIL, dchanlog]
|
||||||
|
|
||||||
|
if activation == 'on':
|
||||||
|
for chan in self.db_chan:
|
||||||
|
if not chan in channel_to_dont_quit:
|
||||||
|
self.send2socket(f":{service_id} JOIN {chan}")
|
||||||
|
if activation == 'off':
|
||||||
|
for chan in self.db_chan:
|
||||||
|
if not chan in channel_to_dont_quit:
|
||||||
|
self.send2socket(f":{service_id} PART {chan}")
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import re, socket, psutil, requests, json
|
from typing import Union
|
||||||
|
import re, socket, psutil, requests, json, time
|
||||||
from core.irc import Irc
|
from core.irc import Irc
|
||||||
|
|
||||||
# Le module crée devra réspecter quelques conditions
|
# Le module crée devra réspecter quelques conditions
|
||||||
@@ -9,7 +10,10 @@ from core.irc import Irc
|
|||||||
# 2 . Récuperer la configuration dans une variable
|
# 2 . Récuperer la configuration dans une variable
|
||||||
# 3 . Définir et enregistrer les nouvelles commandes
|
# 3 . Définir et enregistrer les nouvelles commandes
|
||||||
# 4 . Créer vos tables, en utilisant toujours le nom des votre classe en minuscule ==> defender_votre-table
|
# 4 . Créer vos tables, en utilisant toujours le nom des votre classe en minuscule ==> defender_votre-table
|
||||||
# 3. une methode _hcmds(self, user:str, cmd: list) devra toujours etre crée.
|
# 3. Methode suivantes:
|
||||||
|
# cmd(self, data:list)
|
||||||
|
# _hcmds(self, user:str, cmd: list)
|
||||||
|
# unload(self)
|
||||||
|
|
||||||
class Defender():
|
class Defender():
|
||||||
|
|
||||||
@@ -18,6 +22,20 @@ class Defender():
|
|||||||
self.Irc = ircInstance # Ajouter l'object mod_irc a la classe ( Obligatoire )
|
self.Irc = ircInstance # Ajouter l'object mod_irc a la classe ( Obligatoire )
|
||||||
self.Config = ircInstance.Config # Ajouter la configuration a la classe ( Obligatoire )
|
self.Config = ircInstance.Config # Ajouter la configuration a la classe ( Obligatoire )
|
||||||
self.Base = ircInstance.Base # Ajouter l'objet Base au module ( Obligatoire )
|
self.Base = ircInstance.Base # Ajouter l'objet Base au module ( Obligatoire )
|
||||||
|
self.timeout = self.Config.API_TIMEOUT # API Timeout
|
||||||
|
|
||||||
|
self.freeipapi_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec freeipapi
|
||||||
|
self.cloudfilt_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec cloudfilt
|
||||||
|
self.abuseipdb_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec abuseipdb
|
||||||
|
self.psutil_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec psutil_scan
|
||||||
|
self.localscan_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec local_scan
|
||||||
|
|
||||||
|
self.abuseipdb_isRunning:bool = True
|
||||||
|
self.freeipapi_isRunning:bool = True
|
||||||
|
self.cloudfilt_isRunning:bool = True
|
||||||
|
self.psutil_isRunning:bool = True
|
||||||
|
self.localscan_isRunning:bool = True
|
||||||
|
self.reputationTimer_isRunning:bool = True
|
||||||
|
|
||||||
self.Irc.debug(f'Module {self.__class__.__name__} loaded ...')
|
self.Irc.debug(f'Module {self.__class__.__name__} loaded ...')
|
||||||
|
|
||||||
@@ -26,7 +44,7 @@ class Defender():
|
|||||||
0: ['code'],
|
0: ['code'],
|
||||||
1: ['join','part', 'info'],
|
1: ['join','part', 'info'],
|
||||||
2: ['q', 'dq', 'o', 'do', 'h', 'dh', 'v', 'dv', 'b', 'ub','k', 'kb'],
|
2: ['q', 'dq', 'o', 'do', 'h', 'dh', 'v', 'dv', 'b', 'ub','k', 'kb'],
|
||||||
3: ['reputation','proxy_scan', 'status', 'timer','show_reputation', 'show_users']
|
3: ['reputation','proxy_scan', 'flood', 'status', 'timer','show_reputation', 'show_users']
|
||||||
}
|
}
|
||||||
self.__set_commands(self.commands_level) # Enrigstrer les nouvelles commandes dans le code
|
self.__set_commands(self.commands_level) # Enrigstrer les nouvelles commandes dans le code
|
||||||
|
|
||||||
@@ -45,11 +63,28 @@ class Defender():
|
|||||||
"""
|
"""
|
||||||
for level, com in commands.items():
|
for level, com in commands.items():
|
||||||
for c in commands[level]:
|
for c in commands[level]:
|
||||||
|
if not c in self.Irc.commands:
|
||||||
self.Irc.commands_level[level].append(c)
|
self.Irc.commands_level[level].append(c)
|
||||||
self.Irc.commands.append(c)
|
self.Irc.commands.append(c)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def unload(self) -> None:
|
||||||
|
|
||||||
|
self.freeipapi_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec freeipapi
|
||||||
|
self.cloudfilt_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec cloudfilt
|
||||||
|
self.abuseipdb_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec abuseipdb
|
||||||
|
self.psutil_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec psutil_scan
|
||||||
|
self.localscan_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec local_scan
|
||||||
|
|
||||||
|
self.abuseipdb_isRunning:bool = False
|
||||||
|
self.freeipapi_isRunning:bool = False
|
||||||
|
self.cloudfilt_isRunning:bool = False
|
||||||
|
self.psutil_isRunning:bool = False
|
||||||
|
self.localscan_isRunning:bool = False
|
||||||
|
self.reputationTimer_isRunning:bool = False
|
||||||
|
return None
|
||||||
|
|
||||||
def __create_tables(self) -> None:
|
def __create_tables(self) -> None:
|
||||||
"""Methode qui va créer la base de donnée si elle n'existe pas.
|
"""Methode qui va créer la base de donnée si elle n'existe pas.
|
||||||
Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module
|
Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module
|
||||||
@@ -95,6 +130,7 @@ class Defender():
|
|||||||
self.flood_system = {} # Variable qui va contenir les users
|
self.flood_system = {} # Variable qui va contenir les users
|
||||||
self.reputation_first_connexion = {'ip': '', 'score': -1} # Contient les premieres informations de connexion
|
self.reputation_first_connexion = {'ip': '', 'score': -1} # Contient les premieres informations de connexion
|
||||||
self.abuseipdb_key = '13c34603fee4d2941a2c443cc5c77fd750757ca2a2c1b304bd0f418aff80c24be12651d1a3cfe674' # Laisser vide si aucune clé
|
self.abuseipdb_key = '13c34603fee4d2941a2c443cc5c77fd750757ca2a2c1b304bd0f418aff80c24be12651d1a3cfe674' # Laisser vide si aucune clé
|
||||||
|
self.cloudfilt_key = 'r1gEtjtfgRQjtNBDMxsg' # Laisser vide si aucune clé
|
||||||
|
|
||||||
# Rejoindre les salons
|
# Rejoindre les salons
|
||||||
self.join_saved_channels()
|
self.join_saved_channels()
|
||||||
@@ -108,6 +144,8 @@ class Defender():
|
|||||||
'local_scan': 0,
|
'local_scan': 0,
|
||||||
'psutil_scan': 0,
|
'psutil_scan': 0,
|
||||||
'abuseipdb_scan': 0,
|
'abuseipdb_scan': 0,
|
||||||
|
'freeipapi_scan': 0,
|
||||||
|
'cloudfilt_scan': 0,
|
||||||
'flood': 0,
|
'flood': 0,
|
||||||
'flood_message': 5,
|
'flood_message': 5,
|
||||||
'flood_time': 1,
|
'flood_time': 1,
|
||||||
@@ -117,6 +155,14 @@ class Defender():
|
|||||||
# Syncrhoniser la variable defConfig avec la configuration de la base de données.
|
# Syncrhoniser la variable defConfig avec la configuration de la base de données.
|
||||||
self.sync_db_configuration()
|
self.sync_db_configuration()
|
||||||
|
|
||||||
|
# Démarrer les threads pour démarrer les api
|
||||||
|
self.Base.create_thread(func=self.thread_freeipapi_scan)
|
||||||
|
self.Base.create_thread(func=self.thread_cloudfilt_scan)
|
||||||
|
self.Base.create_thread(func=self.thread_abuseipdb_scan)
|
||||||
|
self.Base.create_thread(func=self.thread_local_scan)
|
||||||
|
self.Base.create_thread(func=self.thread_psutil_scan)
|
||||||
|
self.Base.create_thread(func=self.thread_reputation_timer)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def sync_db_configuration(self) -> None:
|
def sync_db_configuration(self) -> None:
|
||||||
@@ -300,7 +346,6 @@ class Defender():
|
|||||||
exec_query = self.Base.db_execute_query(q_insert, mes_donnees)
|
exec_query = self.Base.db_execute_query(q_insert, mes_donnees)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def join_saved_channels(self) -> None:
|
def join_saved_channels(self) -> None:
|
||||||
|
|
||||||
result = self.Base.db_execute_query("SELECT id, channel FROM def_channels")
|
result = self.Base.db_execute_query("SELECT id, channel FROM def_channels")
|
||||||
@@ -349,7 +394,7 @@ class Defender():
|
|||||||
|
|
||||||
uptime = current_datetime - connected_time
|
uptime = current_datetime - connected_time
|
||||||
convert_to_minutes = uptime.seconds / 60
|
convert_to_minutes = uptime.seconds / 60
|
||||||
uptime_minutes = round(number=convert_to_minutes, ndigits=2)
|
uptime_minutes = round(number=convert_to_minutes, ndigits=0)
|
||||||
|
|
||||||
return uptime_minutes
|
return uptime_minutes
|
||||||
|
|
||||||
@@ -395,7 +440,7 @@ class Defender():
|
|||||||
|
|
||||||
self.Irc.debug(f"system_reputation : {jailed_nickname} à été capturé par le système de réputation")
|
self.Irc.debug(f"system_reputation : {jailed_nickname} à été capturé par le système de réputation")
|
||||||
# self.Irc.create_ping_timer(int(self.defConfig['reputation_timer']) * 60, 'Defender', 'system_reputation_timer')
|
# self.Irc.create_ping_timer(int(self.defConfig['reputation_timer']) * 60, 'Defender', 'system_reputation_timer')
|
||||||
self.Base.create_timer(int(self.defConfig['reputation_timer']) * 60, self.system_reputation_timer)
|
# self.Base.create_timer(int(self.defConfig['reputation_timer']) * 60, self.system_reputation_timer)
|
||||||
else:
|
else:
|
||||||
self.Irc.debug(f"system_reputation : {jailed_nickname} à été supprimé du système de réputation car connecté via WebIrc ou il est dans la 'Trusted list'")
|
self.Irc.debug(f"system_reputation : {jailed_nickname} à été supprimé du système de réputation car connecté via WebIrc ou il est dans la 'Trusted list'")
|
||||||
self.delete_db_reputation(uid)
|
self.delete_db_reputation(uid)
|
||||||
@@ -426,6 +471,7 @@ class Defender():
|
|||||||
if not self.db_reputation[uid]['isWebirc']: # Si il ne vient pas de WebIRC
|
if not self.db_reputation[uid]['isWebirc']: # Si il ne vient pas de WebIRC
|
||||||
self.Irc.debug(f"Nickname: {self.db_reputation[uid]['nickname']} | uptime: {self.get_user_uptime_in_minutes(uid)} | reputation time: {reputation_timer}")
|
self.Irc.debug(f"Nickname: {self.db_reputation[uid]['nickname']} | uptime: {self.get_user_uptime_in_minutes(uid)} | reputation time: {reputation_timer}")
|
||||||
if self.get_user_uptime_in_minutes(uid) >= reputation_timer and int(self.db_reputation[uid]['score']) <= int(reputation_seuil):
|
if self.get_user_uptime_in_minutes(uid) >= reputation_timer and int(self.db_reputation[uid]['score']) <= int(reputation_seuil):
|
||||||
|
self.Irc.debug('-----'*20)
|
||||||
self.Irc.send2socket(f":{service_id} PRIVMSG {dchanlog} :[{color_red} REPUTATION {color_black}] : Action sur {self.db_reputation[uid]['nickname']} aprés {str(reputation_timer)} minutes d'inactivité")
|
self.Irc.send2socket(f":{service_id} PRIVMSG {dchanlog} :[{color_red} REPUTATION {color_black}] : Action sur {self.db_reputation[uid]['nickname']} aprés {str(reputation_timer)} minutes d'inactivité")
|
||||||
# if not system_reputation_timer_action(cglobal['reputation_timer_action'], uid, self.db_reputation[uid]['nickname']):
|
# if not system_reputation_timer_action(cglobal['reputation_timer_action'], uid, self.db_reputation[uid]['nickname']):
|
||||||
# return False
|
# return False
|
||||||
@@ -447,6 +493,16 @@ class Defender():
|
|||||||
except AssertionError as ae:
|
except AssertionError as ae:
|
||||||
self.Irc.debug(f'Assertion Error -> {ae}')
|
self.Irc.debug(f'Assertion Error -> {ae}')
|
||||||
|
|
||||||
|
def thread_reputation_timer(self) -> None:
|
||||||
|
try:
|
||||||
|
while self.reputationTimer_isRunning:
|
||||||
|
self.system_reputation_timer()
|
||||||
|
time.sleep(5)
|
||||||
|
|
||||||
|
return None
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"thread_reputation_timer Error : {ve}")
|
||||||
|
|
||||||
def _execute_flood_action(self, action:str, channel:str) -> None:
|
def _execute_flood_action(self, action:str, channel:str) -> None:
|
||||||
"""DO NOT EXECUTE THIS FUNCTION WITHOUT THREADING
|
"""DO NOT EXECUTE THIS FUNCTION WITHOUT THREADING
|
||||||
|
|
||||||
@@ -533,6 +589,13 @@ class Defender():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def scan_ports(self, remote_ip: str) -> None:
|
def scan_ports(self, remote_ip: str) -> None:
|
||||||
|
"""local_scan
|
||||||
|
|
||||||
|
Args:
|
||||||
|
remote_ip (str): _description_
|
||||||
|
"""
|
||||||
|
if remote_ip in self.Config.WHITELISTED_IP:
|
||||||
|
return None
|
||||||
|
|
||||||
for port in self.Config.PORTS_TO_SCAN:
|
for port in self.Config.PORTS_TO_SCAN:
|
||||||
newSocket = ''
|
newSocket = ''
|
||||||
@@ -551,6 +614,8 @@ class Defender():
|
|||||||
self.Irc.debug(f"Le port {str(port)} est fermé")
|
self.Irc.debug(f"Le port {str(port)} est fermé")
|
||||||
except AttributeError as ae:
|
except AttributeError as ae:
|
||||||
self.Irc.debug(f"AttributeError : {ae}")
|
self.Irc.debug(f"AttributeError : {ae}")
|
||||||
|
except socket.gaierror as err:
|
||||||
|
self.Irc.debug(f"Address Info Error: {err}")
|
||||||
finally:
|
finally:
|
||||||
# newSocket.shutdown(socket.SHUT_RDWR)
|
# newSocket.shutdown(socket.SHUT_RDWR)
|
||||||
newSocket.close()
|
newSocket.close()
|
||||||
@@ -558,7 +623,37 @@ class Defender():
|
|||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def thread_local_scan(self) -> None:
|
||||||
|
try:
|
||||||
|
while self.localscan_isRunning:
|
||||||
|
|
||||||
|
list_to_remove:list = []
|
||||||
|
for ip in self.localscan_remote_ip:
|
||||||
|
self.scan_ports(ip)
|
||||||
|
list_to_remove.append(ip)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
for ip_to_remove in list_to_remove:
|
||||||
|
self.localscan_remote_ip.remove(ip_to_remove)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
return None
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"thread_local_scan Error : {ve}")
|
||||||
|
|
||||||
def get_ports_connexion(self, remote_ip: str) -> list[int]:
|
def get_ports_connexion(self, remote_ip: str) -> list[int]:
|
||||||
|
"""psutil_scan
|
||||||
|
|
||||||
|
Args:
|
||||||
|
remote_ip (str): _description_
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[int]: _description_
|
||||||
|
"""
|
||||||
|
if remote_ip in self.Config.WHITELISTED_IP:
|
||||||
|
return None
|
||||||
|
|
||||||
connections = psutil.net_connections(kind='inet')
|
connections = psutil.net_connections(kind='inet')
|
||||||
|
|
||||||
matching_ports = [conn.raddr.port for conn in connections if conn.raddr and conn.raddr.ip == remote_ip]
|
matching_ports = [conn.raddr.port for conn in connections if conn.raddr and conn.raddr.ip == remote_ip]
|
||||||
@@ -566,7 +661,26 @@ class Defender():
|
|||||||
|
|
||||||
return matching_ports
|
return matching_ports
|
||||||
|
|
||||||
def abuseipdb_scan(self, remote_ip:str) -> dict[str, any] | None:
|
def thread_psutil_scan(self) -> None:
|
||||||
|
try:
|
||||||
|
while self.psutil_isRunning:
|
||||||
|
|
||||||
|
list_to_remove:list = []
|
||||||
|
for ip in self.psutil_remote_ip:
|
||||||
|
self.get_ports_connexion(ip)
|
||||||
|
list_to_remove.append(ip)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
for ip_to_remove in list_to_remove:
|
||||||
|
self.psutil_remote_ip.remove(ip_to_remove)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
return None
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"thread_psutil_scan Error : {ve}")
|
||||||
|
|
||||||
|
def abuseipdb_scan(self, remote_ip:str) -> Union[dict[str, any], None]:
|
||||||
"""Analyse l'ip avec AbuseIpDB
|
"""Analyse l'ip avec AbuseIpDB
|
||||||
Cette methode devra etre lancer toujours via un thread ou un timer.
|
Cette methode devra etre lancer toujours via un thread ou un timer.
|
||||||
Args:
|
Args:
|
||||||
@@ -576,6 +690,8 @@ class Defender():
|
|||||||
dict[str, any] | None: les informations du provider
|
dict[str, any] | None: les informations du provider
|
||||||
keys : 'score', 'country', 'isTor', 'totalReports'
|
keys : 'score', 'country', 'isTor', 'totalReports'
|
||||||
"""
|
"""
|
||||||
|
if remote_ip in self.Config.WHITELISTED_IP:
|
||||||
|
return None
|
||||||
if self.defConfig['abuseipdb_scan'] == 0:
|
if self.defConfig['abuseipdb_scan'] == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -593,11 +709,14 @@ class Defender():
|
|||||||
'Key': self.abuseipdb_key
|
'Key': self.abuseipdb_key
|
||||||
}
|
}
|
||||||
|
|
||||||
response = requests.request(method='GET', url=url, headers=headers, params=querystring)
|
response = requests.request(method='GET', url=url, headers=headers, params=querystring, timeout=self.timeout)
|
||||||
|
|
||||||
# Formatted output
|
# Formatted output
|
||||||
decodedResponse = json.loads(response.text)
|
decodedResponse = json.loads(response.text)
|
||||||
try:
|
try:
|
||||||
|
if not 'data' in decodedResponse:
|
||||||
|
return None
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'score': decodedResponse['data']['abuseConfidenceScore'],
|
'score': decodedResponse['data']['abuseConfidenceScore'],
|
||||||
'country': decodedResponse['data']['countryCode'],
|
'country': decodedResponse['data']['countryCode'],
|
||||||
@@ -610,18 +729,196 @@ class Defender():
|
|||||||
color_red = self.Config.CONFIG_COLOR['rouge']
|
color_red = self.Config.CONFIG_COLOR['rouge']
|
||||||
color_black = self.Config.CONFIG_COLOR['noire']
|
color_black = self.Config.CONFIG_COLOR['noire']
|
||||||
|
|
||||||
self.Irc.send2socket(f":{service_id} PRIVMSG {service_chanlog} :[ {color_red}ABUSEIPDB_SCAN{color_black} ] : Connexion de {remote_ip} Score: {str(result['score'])} | Country : {result['country']} | Tor : {str(result['isTor'])} | Total Reports : {str(result['totalReports'])}")
|
self.Irc.send2socket(f":{service_id} PRIVMSG {service_chanlog} :[ {color_red}ABUSEIPDB_SCAN{color_black} ] : Connexion de {remote_ip} ==> Score: {str(result['score'])} | Country : {result['country']} | Tor : {str(result['isTor'])} | Total Reports : {str(result['totalReports'])}")
|
||||||
|
|
||||||
|
if result['isTor']:
|
||||||
|
self.Irc.send2socket(f":{service_id} GLINE +*@{remote_ip} {self.Config.GLINE_DURATION} This server do not allow Tor connexions {str(result['isTor'])} - Detected by Abuseipdb")
|
||||||
|
elif result['score'] >= 95:
|
||||||
|
self.Irc.send2socket(f":{service_id} GLINE +*@{remote_ip} {self.Config.GLINE_DURATION} You were banned from this server because your abuse score is = {str(result['score'])} - Detected by Abuseipdb")
|
||||||
|
|
||||||
response.close()
|
response.close()
|
||||||
|
|
||||||
return result
|
return result
|
||||||
except KeyError as ke:
|
except KeyError as ke:
|
||||||
self.Irc.debug(f"AbuseIpDb KeyError : {ke}")
|
self.Irc.debug(f"AbuseIpDb KeyError : {ke}")
|
||||||
|
except requests.ReadTimeout as rt:
|
||||||
|
self.Irc.debug(f"AbuseIpDb Timeout : {rt}")
|
||||||
|
except requests.ConnectionError as ce:
|
||||||
|
self.Irc.debug(f"AbuseIpDb Connection Error : {ce}")
|
||||||
|
|
||||||
|
def thread_abuseipdb_scan(self) -> None:
|
||||||
|
try:
|
||||||
|
while self.abuseipdb_isRunning:
|
||||||
|
|
||||||
|
list_to_remove:list = []
|
||||||
|
for ip in self.abuseipdb_remote_ip:
|
||||||
|
self.abuseipdb_scan(ip)
|
||||||
|
list_to_remove.append(ip)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
for ip_to_remove in list_to_remove:
|
||||||
|
self.abuseipdb_remote_ip.remove(ip_to_remove)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
return None
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"thread_abuseipdb_scan Error : {ve}")
|
||||||
|
|
||||||
|
def freeipapi_scan(self, remote_ip:str) -> Union[dict[str, any], None]:
|
||||||
|
"""Analyse l'ip avec Freeipapi
|
||||||
|
Cette methode devra etre lancer toujours via un thread ou un timer.
|
||||||
|
Args:
|
||||||
|
remote_ip (_type_): l'ip a analyser
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, any] | None: les informations du provider
|
||||||
|
keys : 'countryCode', 'isProxy'
|
||||||
|
"""
|
||||||
|
if remote_ip in self.Config.WHITELISTED_IP:
|
||||||
|
return None
|
||||||
|
if self.defConfig['freeipapi_scan'] == 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
service_id = self.Config.SERVICE_ID
|
||||||
|
service_chanlog = self.Config.SERVICE_CHANLOG
|
||||||
|
color_red = self.Config.CONFIG_COLOR['rouge']
|
||||||
|
color_black = self.Config.CONFIG_COLOR['noire']
|
||||||
|
|
||||||
|
url = f'https://freeipapi.com/api/json/{remote_ip}'
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
'Accept': 'application/json',
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.request(method='GET', url=url, headers=headers, timeout=self.timeout)
|
||||||
|
|
||||||
|
# Formatted output
|
||||||
|
decodedResponse = json.loads(response.text)
|
||||||
|
try:
|
||||||
|
status_code = response.status_code
|
||||||
|
if status_code == 429:
|
||||||
|
self.Irc.debug(f'Too Many Requests - The rate limit for the API has been exceeded.')
|
||||||
|
return None
|
||||||
|
elif status_code != 200:
|
||||||
|
print("salut salut")
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'countryCode': decodedResponse['countryCode'] if 'countryCode' in decodedResponse else None,
|
||||||
|
'isProxy': decodedResponse['isProxy'] if 'isProxy' in decodedResponse else None
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Irc.send2socket(f":{service_id} PRIVMSG {service_chanlog} :[ {color_red}FREEIPAPI_SCAN{color_black} ] : Connexion de {remote_ip} ==> Proxy: {str(result['isProxy'])} | Country : {str(result['countryCode'])}")
|
||||||
|
|
||||||
|
if result['isProxy']:
|
||||||
|
self.Irc.send2socket(f":{service_id} GLINE +*@{remote_ip} {self.Config.GLINE_DURATION} This server do not allow proxy connexions {str(result['isProxy'])} - detected by freeipapi")
|
||||||
|
response.close()
|
||||||
|
|
||||||
|
return result
|
||||||
|
except KeyError as ke:
|
||||||
|
self.Irc.debug(f"FREEIPAPI_SCAN KeyError : {ke}")
|
||||||
|
|
||||||
|
def thread_freeipapi_scan(self) -> None:
|
||||||
|
try:
|
||||||
|
while self.freeipapi_isRunning:
|
||||||
|
|
||||||
|
list_to_remove:list = []
|
||||||
|
for ip in self.freeipapi_remote_ip:
|
||||||
|
self.freeipapi_scan(ip)
|
||||||
|
list_to_remove.append(ip)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
for ip_to_remove in list_to_remove:
|
||||||
|
self.freeipapi_remote_ip.remove(ip_to_remove)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
return None
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"thread_freeipapi_scan Error : {ve}")
|
||||||
|
|
||||||
|
def cloudfilt_scan(self, remote_ip:str) -> Union[dict[str, any], None]:
|
||||||
|
"""Analyse l'ip avec cloudfilt
|
||||||
|
Cette methode devra etre lancer toujours via un thread ou un timer.
|
||||||
|
Args:
|
||||||
|
remote_ip (_type_): l'ip a analyser
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict[str, any] | None: les informations du provider
|
||||||
|
keys : 'countryCode', 'isProxy'
|
||||||
|
"""
|
||||||
|
if remote_ip in self.Config.WHITELISTED_IP:
|
||||||
|
return None
|
||||||
|
if self.defConfig['cloudfilt_scan'] == 0:
|
||||||
|
return None
|
||||||
|
if self.cloudfilt_key == '':
|
||||||
|
return None
|
||||||
|
|
||||||
|
service_id = self.Config.SERVICE_ID
|
||||||
|
service_chanlog = self.Config.SERVICE_CHANLOG
|
||||||
|
color_red = self.Config.CONFIG_COLOR['rouge']
|
||||||
|
color_black = self.Config.CONFIG_COLOR['noire']
|
||||||
|
|
||||||
|
url = f"https://developers18334.cloudfilt.com/"
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'ip': remote_ip,
|
||||||
|
'key': self.cloudfilt_key
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(url=url, data=data)
|
||||||
|
|
||||||
|
# Formatted output
|
||||||
|
decodedResponse = json.loads(response.text)
|
||||||
|
try:
|
||||||
|
status_code = response.status_code
|
||||||
|
if status_code != 200:
|
||||||
|
self.Irc.debug(f'Error connecting to cloudfilt API | Code: {str(status_code)}')
|
||||||
|
return None
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'countryiso': decodedResponse['countryiso'] if 'countryiso' in decodedResponse else None,
|
||||||
|
'listed': decodedResponse['listed'] if 'listed' in decodedResponse else None,
|
||||||
|
'listed_by': decodedResponse['listed_by'] if 'listed_by' in decodedResponse else None,
|
||||||
|
'host': decodedResponse['host'] if 'host' in decodedResponse else None
|
||||||
|
}
|
||||||
|
|
||||||
|
self.Irc.send2socket(f":{service_id} PRIVMSG {service_chanlog} :[ {color_red}CLOUDFILT_SCAN{color_black} ] : Connexion de {str(remote_ip)} ==> Host: {str(result['host'])} | country: {str(result['countryiso'])} | listed: {str(result['listed'])} | listed by : {str(result['listed_by'])}")
|
||||||
|
|
||||||
|
if result['listed']:
|
||||||
|
self.Irc.send2socket(f":{service_id} GLINE +*@{remote_ip} {self.Config.GLINE_DURATION} You connexion is listed as dangerous {str(result['listed'])} {str(result['listed_by'])} - detected by cloudfilt")
|
||||||
|
|
||||||
|
response.close()
|
||||||
|
|
||||||
|
return result
|
||||||
|
except KeyError as ke:
|
||||||
|
self.Irc.debug(f"CLOUDFILT_SCAN KeyError : {ke}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def thread_cloudfilt_scan(self) -> None:
|
||||||
|
try:
|
||||||
|
while self.cloudfilt_isRunning:
|
||||||
|
|
||||||
|
list_to_remove:list = []
|
||||||
|
for ip in self.cloudfilt_remote_ip:
|
||||||
|
self.cloudfilt_scan(ip)
|
||||||
|
list_to_remove.append(ip)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
for ip_to_remove in list_to_remove:
|
||||||
|
self.cloudfilt_remote_ip.remove(ip_to_remove)
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
return None
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"Thread_cloudfilt_scan Error : {ve}")
|
||||||
|
|
||||||
def cmd(self, data:list) -> None:
|
def cmd(self, data:list) -> None:
|
||||||
|
|
||||||
service_id = self.Config.SERVICE_ID # Defender serveur id
|
service_id = self.Config.SERVICE_ID # Defender serveur id
|
||||||
cmd = data
|
cmd = list(data).copy()
|
||||||
|
|
||||||
if len(cmd) < 2:
|
if len(cmd) < 2:
|
||||||
return None
|
return None
|
||||||
@@ -635,14 +932,21 @@ class Defender():
|
|||||||
self.reputation_first_connexion['score'] = cmd[3]
|
self.reputation_first_connexion['score'] = cmd[3]
|
||||||
|
|
||||||
# self.Base.scan_ports(cmd[2])
|
# self.Base.scan_ports(cmd[2])
|
||||||
if self.defConfig['local_scan'] == 1:
|
if self.defConfig['local_scan'] == 1 and not cmd[2] in self.Config.WHITELISTED_IP:
|
||||||
self.Base.create_thread(self.scan_ports, (cmd[2], ))
|
self.localscan_remote_ip.append(cmd[2])
|
||||||
|
|
||||||
if self.defConfig['psutil_scan'] == 1:
|
if self.defConfig['psutil_scan'] == 1 and not cmd[2] in self.Config.WHITELISTED_IP:
|
||||||
self.Base.create_thread(self.get_ports_connexion, (cmd[2], ))
|
self.psutil_remote_ip.append(cmd[2])
|
||||||
|
|
||||||
|
if self.defConfig['abuseipdb_scan'] == 1 and not cmd[2] in self.Config.WHITELISTED_IP:
|
||||||
|
self.abuseipdb_remote_ip.append(cmd[2])
|
||||||
|
|
||||||
|
if self.defConfig['freeipapi_scan'] == 1 and not cmd[2] in self.Config.WHITELISTED_IP:
|
||||||
|
self.freeipapi_remote_ip.append(cmd[2])
|
||||||
|
|
||||||
|
if self.defConfig['cloudfilt_scan'] == 1 and not cmd[2] in self.Config.WHITELISTED_IP:
|
||||||
|
self.cloudfilt_remote_ip.append(cmd[2])
|
||||||
|
|
||||||
if self.defConfig['abuseipdb_scan'] == 1:
|
|
||||||
self.Base.create_thread(self.abuseipdb_scan, (cmd[2], ))
|
|
||||||
# Possibilité de déclancher les bans a ce niveau.
|
# Possibilité de déclancher les bans a ce niveau.
|
||||||
except IndexError:
|
except IndexError:
|
||||||
self.Irc.debug(f'cmd reputation: index error')
|
self.Irc.debug(f'cmd reputation: index error')
|
||||||
@@ -656,29 +960,6 @@ class Defender():
|
|||||||
find_nickname = self.Irc.get_nickname(user_trigger)
|
find_nickname = self.Irc.get_nickname(user_trigger)
|
||||||
self.flood(find_nickname, channel)
|
self.flood(find_nickname, channel)
|
||||||
|
|
||||||
case 'SJOIN':
|
|
||||||
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
|
|
||||||
try:
|
|
||||||
cmd.pop(0)
|
|
||||||
parsed_chan = cmd[3]
|
|
||||||
self.Irc.insert_db_chan(parsed_chan)
|
|
||||||
|
|
||||||
if self.defConfig['reputation'] == 1:
|
|
||||||
parsed_UID = cmd[4]
|
|
||||||
pattern = fr'^:[@|%|\+|~|\*]*'
|
|
||||||
parsed_UID = re.sub(pattern, '', parsed_UID)
|
|
||||||
if parsed_UID in self.db_reputation:
|
|
||||||
# print(f"====> {str(self.db_reputation)}")
|
|
||||||
isWebirc = self.db_reputation[parsed_UID]['isWebirc']
|
|
||||||
if self.defConfig['reputation_ban_all_chan'] == 1 and not isWebirc:
|
|
||||||
if parsed_chan != self.Config.SALON_JAIL:
|
|
||||||
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b {self.db_reputation[parsed_UID]['nickname']}!*@*")
|
|
||||||
self.Irc.send2socket(f":{service_id} KICK {parsed_chan} {self.db_reputation[parsed_UID]['nickname']}")
|
|
||||||
|
|
||||||
self.Irc.debug(f'SJOIN parsed_uid : {parsed_UID}')
|
|
||||||
except KeyError as ke:
|
|
||||||
self.Irc.debug(f"key error SJOIN : {ke}")
|
|
||||||
|
|
||||||
case 'UID':
|
case 'UID':
|
||||||
|
|
||||||
if self.Irc.INIT == 1:
|
if self.Irc.INIT == 1:
|
||||||
@@ -723,21 +1004,51 @@ class Defender():
|
|||||||
self.system_reputation(uid)
|
self.system_reputation(uid)
|
||||||
self.Irc.debug('Démarrer le systeme de reputation')
|
self.Irc.debug('Démarrer le systeme de reputation')
|
||||||
|
|
||||||
|
case 'SJOIN':
|
||||||
|
# ['@msgid=F9B7JeHL5pj9nN57cJ5pEr;time=2023-12-28T20:47:24.305Z', ':001', 'SJOIN', '1702138958', '#welcome', ':0015L1AHL']
|
||||||
|
try:
|
||||||
|
cmd.pop(0)
|
||||||
|
parsed_chan = cmd[3]
|
||||||
|
self.Irc.insert_db_chan(parsed_chan)
|
||||||
|
|
||||||
|
if self.defConfig['reputation'] == 1:
|
||||||
|
parsed_UID = cmd[4]
|
||||||
|
pattern = fr'^:[@|%|\+|~|\*]*'
|
||||||
|
parsed_UID = re.sub(pattern, '', parsed_UID)
|
||||||
|
if parsed_UID in self.db_reputation:
|
||||||
|
# print(f"====> {str(self.db_reputation)}")
|
||||||
|
isWebirc = self.db_reputation[parsed_UID]['isWebirc']
|
||||||
|
if self.defConfig['reputation_ban_all_chan'] == 1 and not isWebirc:
|
||||||
|
if parsed_chan != self.Config.SALON_JAIL:
|
||||||
|
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b {self.db_reputation[parsed_UID]['nickname']}!*@*")
|
||||||
|
self.Irc.send2socket(f":{service_id} KICK {parsed_chan} {self.db_reputation[parsed_UID]['nickname']}")
|
||||||
|
|
||||||
|
self.Irc.debug(f'SJOIN parsed_uid : {parsed_UID}')
|
||||||
|
except KeyError as ke:
|
||||||
|
self.Irc.debug(f"key error SJOIN : {ke}")
|
||||||
|
|
||||||
case 'SLOG':
|
case 'SLOG':
|
||||||
# self.Base.scan_ports(cmd[7])
|
# self.Base.scan_ports(cmd[7])
|
||||||
cmd.pop(0)
|
cmd.pop(0)
|
||||||
if self.defConfig['local_scan'] == 1:
|
if self.defConfig['local_scan'] == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||||
self.Base.create_thread(self.scan_ports, (cmd[7], ))
|
self.localscan_remote_ip.append(cmd[7])
|
||||||
|
|
||||||
if self.defConfig['psutil_scan'] == 1:
|
if self.defConfig['psutil_scan'] == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||||
self.Base.create_thread(self.get_ports_connexion, (cmd[7], ))
|
self.psutil_remote_ip.append(cmd[7])
|
||||||
|
|
||||||
if self.defConfig['abuseipdb_scan'] == 1:
|
if self.defConfig['abuseipdb_scan'] == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||||
self.Base.create_thread(self.abuseipdb_scan, (cmd[7], ))
|
self.abuseipdb_remote_ip.append(cmd[7])
|
||||||
|
|
||||||
|
if self.defConfig['freeipapi_scan'] == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||||
|
self.freeipapi_remote_ip.append[cmd[7]]
|
||||||
|
|
||||||
|
if self.defConfig['cloudfilt_scan'] == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
|
||||||
|
self.cloudfilt_remote_ip.append(cmd[7])
|
||||||
|
|
||||||
case 'NICK':
|
case 'NICK':
|
||||||
# :0010BS24L NICK [NEWNICK] 1697917711
|
# :0010BS24L NICK [NEWNICK] 1697917711
|
||||||
# Changement de nickname
|
# Changement de nickname
|
||||||
|
try:
|
||||||
cmd.pop(0)
|
cmd.pop(0)
|
||||||
uid = str(cmd[0]).replace(':','')
|
uid = str(cmd[0]).replace(':','')
|
||||||
oldnick = self.db_reputation[uid]['nickname']
|
oldnick = self.db_reputation[uid]['nickname']
|
||||||
@@ -753,6 +1064,8 @@ class Defender():
|
|||||||
if chan != jail_salon:
|
if chan != jail_salon:
|
||||||
self.Irc.send2socket(f":{service_id} MODE {chan} -b {oldnick}!*@*")
|
self.Irc.send2socket(f":{service_id} MODE {chan} -b {oldnick}!*@*")
|
||||||
self.Irc.send2socket(f":{service_id} MODE {chan} +b {newnickname}!*@*")
|
self.Irc.send2socket(f":{service_id} MODE {chan} +b {newnickname}!*@*")
|
||||||
|
except KeyError as ke:
|
||||||
|
self.Irc.debug(f'cmd - NICK - KeyError: {ke}')
|
||||||
|
|
||||||
case 'QUIT':
|
case 'QUIT':
|
||||||
# :001N1WD7L QUIT :Quit: free_znc_1
|
# :001N1WD7L QUIT :Quit: free_znc_1
|
||||||
@@ -774,7 +1087,6 @@ class Defender():
|
|||||||
|
|
||||||
command = str(cmd[0]).lower()
|
command = str(cmd[0]).lower()
|
||||||
fromuser = user
|
fromuser = user
|
||||||
# print(command)
|
|
||||||
|
|
||||||
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
|
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
|
||||||
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
|
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
|
||||||
@@ -811,6 +1123,10 @@ class Defender():
|
|||||||
release_code = cmd[1]
|
release_code = cmd[1]
|
||||||
jailed_nickname = self.Irc.get_nickname(fromuser)
|
jailed_nickname = self.Irc.get_nickname(fromuser)
|
||||||
jailed_UID = self.Irc.get_uid(fromuser)
|
jailed_UID = self.Irc.get_uid(fromuser)
|
||||||
|
if not jailed_UID in self.db_reputation:
|
||||||
|
self.Irc.send2socket(f":{dnickname} NOTICE {fromuser} : No code is requested ...")
|
||||||
|
return False
|
||||||
|
|
||||||
jailed_IP = self.db_reputation[jailed_UID]['ip']
|
jailed_IP = self.db_reputation[jailed_UID]['ip']
|
||||||
jailed_salon = self.Config.SALON_JAIL
|
jailed_salon = self.Config.SALON_JAIL
|
||||||
reputation_seuil = self.defConfig['reputation_seuil']
|
reputation_seuil = self.defConfig['reputation_seuil']
|
||||||
@@ -847,7 +1163,9 @@ class Defender():
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
self.Irc.debug('_hcmd code: out of index')
|
self.Irc.debug('_hcmd code: out of index')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]')
|
||||||
pass
|
except KeyError as ke:
|
||||||
|
self.Irc.debug(f'_hcmd code: KeyError {ke}')
|
||||||
|
# self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} code [code]')
|
||||||
pass
|
pass
|
||||||
|
|
||||||
case 'reputation':
|
case 'reputation':
|
||||||
@@ -963,6 +1281,8 @@ class Defender():
|
|||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]')
|
||||||
|
|
||||||
option = str(cmd[2]).lower() # => local_scan, psutil_scan, abuseipdb_scan
|
option = str(cmd[2]).lower() # => local_scan, psutil_scan, abuseipdb_scan
|
||||||
action = str(cmd[3]).lower() # => on / off
|
action = str(cmd[3]).lower() # => on / off
|
||||||
@@ -1010,26 +1330,123 @@ class Defender():
|
|||||||
self.update_db_configuration(option, 0)
|
self.update_db_configuration(option, 0)
|
||||||
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}")
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}")
|
||||||
|
|
||||||
|
case 'freeipapi_scan':
|
||||||
|
if action == 'on':
|
||||||
|
if self.defConfig[option] == 1:
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated")
|
||||||
|
return None
|
||||||
|
self.update_db_configuration(option, 1)
|
||||||
|
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}")
|
||||||
|
elif action == 'off':
|
||||||
|
if self.defConfig[option] == 0:
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated")
|
||||||
|
return None
|
||||||
|
|
||||||
|
self.update_db_configuration(option, 0)
|
||||||
|
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}")
|
||||||
|
|
||||||
|
case 'cloudfilt_scan':
|
||||||
|
if action == 'on':
|
||||||
|
if self.defConfig[option] == 1:
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Already activated")
|
||||||
|
return None
|
||||||
|
self.update_db_configuration(option, 1)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_green}PROXY_SCAN {option.upper()}{color_black} ] : Activated by {fromuser}")
|
||||||
|
elif action == 'off':
|
||||||
|
if self.defConfig[option] == 0:
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Already Deactivated")
|
||||||
|
return None
|
||||||
|
self.update_db_configuration(option, 0)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {color_red}PROXY_SCAN {option.upper()}{color_black} ] : Deactivated by {fromuser}")
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]')
|
||||||
else:
|
else:
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set local_scan [ON/OFF]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set psutil_scan [ON/OFF]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set abuseipdb_scan [ON/OFF]')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set freeipapi_scan [ON/OFF]')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} proxy_scan set cloudfilt_scan [ON/OFF]')
|
||||||
|
|
||||||
|
case 'flood':
|
||||||
|
# .flood on/off
|
||||||
|
# .flood set flood_message 5
|
||||||
|
# .flood set flood_time 1
|
||||||
|
# .flood set flood_timer 20
|
||||||
|
try:
|
||||||
|
len_cmd = len(cmd)
|
||||||
|
|
||||||
|
if len_cmd == 2:
|
||||||
|
activation = str(cmd[1]).lower()
|
||||||
|
key = 'flood'
|
||||||
|
if activation == 'on':
|
||||||
|
if self.defConfig[key] == 1:
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Already activated")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.update_db_configuration(key, 1)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Activated by {fromuser}")
|
||||||
|
|
||||||
|
if activation == 'off':
|
||||||
|
if self.defConfig[key] == 0:
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Already Deactivated")
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.update_db_configuration(key, 0)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Deactivated by {fromuser}")
|
||||||
|
|
||||||
|
if len_cmd == 4:
|
||||||
|
set_key = str(cmd[2]).lower()
|
||||||
|
|
||||||
|
if str(cmd[1]).lower() == 'set':
|
||||||
|
match set_key:
|
||||||
|
case 'flood_message':
|
||||||
|
key = 'flood_message'
|
||||||
|
set_value = int(cmd[3])
|
||||||
|
print(f"{str(set_value)} - {set_key}")
|
||||||
|
self.update_db_configuration(key, set_value)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Flood message set to {set_value} by {fromuser}")
|
||||||
|
|
||||||
|
case 'flood_time':
|
||||||
|
key = 'flood_time'
|
||||||
|
set_value = int(cmd[3])
|
||||||
|
self.update_db_configuration(key, set_value)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Flood time set to {set_value} by {fromuser}")
|
||||||
|
|
||||||
|
case 'flood_timer':
|
||||||
|
key = 'flood_timer'
|
||||||
|
set_value = int(cmd[3])
|
||||||
|
self.update_db_configuration(key, set_value)
|
||||||
|
self.Irc.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}FLOOD{self.Config.CONFIG_COLOR['noire']} ] : Flood timer set to {set_value} by {fromuser}")
|
||||||
|
|
||||||
|
case _:
|
||||||
|
pass
|
||||||
|
|
||||||
|
except ValueError as ve:
|
||||||
|
self.Irc.debug(f"{self.__class__.__name__} Value Error : {ve}")
|
||||||
|
|
||||||
case 'status':
|
case 'status':
|
||||||
|
color_green = self.Config.CONFIG_COLOR['verte']
|
||||||
|
color_red = self.Config.CONFIG_COLOR['rouge']
|
||||||
|
color_black = self.Config.CONFIG_COLOR['noire']
|
||||||
try:
|
try:
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Reputation ==> {self.defConfig["reputation"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : [{color_green if self.defConfig["reputation"] == 1 else color_red}Reputation{color_black}] ==> {self.defConfig["reputation"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_seuil ==> {self.defConfig["reputation_seuil"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_seuil ==> {self.defConfig["reputation_seuil"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_ban_all_chan ==> {self.defConfig["reputation_ban_all_chan"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_ban_all_chan ==> {self.defConfig["reputation_ban_all_chan"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_timer ==> {self.defConfig["reputation_timer"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : reputation_timer ==> {self.defConfig["reputation_timer"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : [Proxy_scan]')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : [Proxy_scan]')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : local_scan ==> {self.defConfig["local_scan"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {color_green if self.defConfig["local_scan"] == 1 else color_red}local_scan{color_black} ==> {self.defConfig["local_scan"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : psutil_scan ==> {self.defConfig["psutil_scan"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {color_green if self.defConfig["psutil_scan"] == 1 else color_red}psutil_scan{color_black} ==> {self.defConfig["psutil_scan"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : abuseipdb_scan ==> {self.defConfig["abuseipdb_scan"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {color_green if self.defConfig["abuseipdb_scan"] == 1 else color_red}abuseipdb_scan{color_black} ==> {self.defConfig["abuseipdb_scan"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Flood ==> {self.defConfig["flood"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {color_green if self.defConfig["freeipapi_scan"] == 1 else color_red}freeipapi_scan{color_black} ==> {self.defConfig["freeipapi_scan"]}')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : {color_green if self.defConfig["cloudfilt_scan"] == 1 else color_red}cloudfilt_scan{color_black} ==> {self.defConfig["cloudfilt_scan"]}')
|
||||||
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : [{color_green if self.defConfig["flood"] == 1 else color_red}Flood{color_black}] ==> {self.defConfig["flood"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_action ==> Coming soon')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_action ==> Coming soon')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_message ==> {self.defConfig["flood_message"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_message ==> {self.defConfig["flood_message"]}')
|
||||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_time ==> {self.defConfig["flood_time"]}')
|
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : flood_time ==> {self.defConfig["flood_time"]}')
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ class Test():
|
|||||||
self.core.db_execute_query(self.session, table_logs)
|
self.core.db_execute_query(self.session, table_logs)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def unload(self) -> None:
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def _hcmds(self, user:str, cmd: list) -> None:
|
def _hcmds(self, user:str, cmd: list) -> None:
|
||||||
|
|
||||||
command = cmd[0].lower()
|
command = cmd[0].lower()
|
||||||
|
|||||||
Reference in New Issue
Block a user