mirror of
https://github.com/iio612/DEFENDER.git
synced 2026-02-14 19:54:21 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c8378a0e7 | ||
|
|
7be3f51bf4 | ||
|
|
e3b212ea88 | ||
|
|
2c0510b2a3 | ||
|
|
0c2a350d38 | ||
|
|
ee039322d4 | ||
|
|
8f08a1e77f | ||
|
|
c59dd16e87 | ||
|
|
1cea8d0601 | ||
|
|
652b400d5e | ||
|
|
2f8b965b59 | ||
|
|
3c043cefd8 | ||
|
|
59a75cecd8 | ||
|
|
71053437a7 | ||
|
|
7796d05206 | ||
|
|
5f2567f9e5 | ||
|
|
aaa1dd9a1a | ||
|
|
a02f2f9a26 | ||
|
|
d73adb6f0b | ||
|
|
b812e64992 | ||
|
|
9bd1f68df2 | ||
|
|
f44b08bf36 | ||
|
|
1a19e1613a | ||
|
|
cdc15b7b47 | ||
|
|
31fe9f62ec | ||
|
|
f0853e3afb | ||
|
|
6dade09257 | ||
|
|
9533b010b2 | ||
|
|
824db73590 | ||
|
|
96bf4b6f80 | ||
|
|
922336363e |
56
README.md
56
README.md
@@ -127,18 +127,8 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
|
||||
"SERVICE_HOST": "HOST.DE.TON.DEFENDER",
|
||||
|
||||
"OWNER": "TON_NICK_NAME",
|
||||
"PASSWORD": "admin",
|
||||
"PASSWORD": "admin"
|
||||
|
||||
"CONFIG_COLOR": {
|
||||
"blanche": "\\u0003\\u0030",
|
||||
"noire": "\\u0003\\u0031",
|
||||
"bleue": "\\u0003\\u0020",
|
||||
"verte": "\\u0003\\u0033",
|
||||
"rouge": "\\u0003\\u0034",
|
||||
"jaune": "\\u0003\\u0036",
|
||||
"gras": "\\u0002",
|
||||
"nogc": "\\u0002\\u0003"
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -147,10 +137,10 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
|
||||
```json
|
||||
{
|
||||
"SERVEUR_IP": "YOUR.SERVER.IP",
|
||||
"SERVEUR_HOSTNAME": "irc.deb.biz.st",
|
||||
"SERVEUR_LINK": "defenderdev.deb.biz.st",
|
||||
"SERVEUR_HOSTNAME": "YOUR.SERVER.HOST",
|
||||
"SERVEUR_LINK": "LINK.DE.TON.SERVER",
|
||||
"SERVEUR_PORT": 6901,
|
||||
"SERVEUR_PASSWORD": "yourpassword",
|
||||
"SERVEUR_PASSWORD": "YOUR_LINK_PASSWORD",
|
||||
"SERVEUR_ID": "10Z",
|
||||
"SERVEUR_SSL": true,
|
||||
|
||||
@@ -201,10 +191,46 @@ Pour Les prochains lancement de defender vous devez utiliser la commande suivant
|
||||
Le mot de passe de l'administrateur et le mot de passe du service doivent être modifiés pour des raisons de sécurité.
|
||||
Ne partagez pas vos informations de connexion au serveur IRC avec des tiers.
|
||||
a votre premiere connexion vous devez tapez
|
||||
|
||||
```
|
||||
/msg [NomDuService] auth [nickname] [password]
|
||||
-- Une fois identifié tapez la commande suivante
|
||||
/msg [NomDuService] editaccess [nickname] [Nouveau-Password] 5
|
||||
```
|
||||
# Unrealircd configuration
|
||||
```
|
||||
listen {
|
||||
ip *;
|
||||
port 6901;
|
||||
options { tls; serversonly; }
|
||||
}
|
||||
|
||||
link LINK.DE.TON.SERVER
|
||||
{
|
||||
|
||||
incoming {
|
||||
mask *;
|
||||
bind-ip *;
|
||||
port 6901;
|
||||
//options { tls; };
|
||||
}
|
||||
|
||||
outgoing {
|
||||
bind-ip *; /* ou une IP précise */
|
||||
hostname LINK.DE.TON.SERVER;
|
||||
port 6901;
|
||||
//options { tls; }
|
||||
}
|
||||
|
||||
password "YOUR_LINK_PASSWORD";
|
||||
|
||||
class servers;
|
||||
|
||||
}
|
||||
|
||||
ulines {
|
||||
LINK.DE.TON.SERVER;
|
||||
}
|
||||
```
|
||||
|
||||
# Extension:
|
||||
Le code est modulaire et conçu pour être facilement étendu. Vous pouvez ajouter de nouvelles commandes, de nouvelles fonctionnalités (mods/mod_test.py est un exemple pour bien demarrer la création de son module).
|
||||
|
||||
@@ -416,6 +416,7 @@ class Clones:
|
||||
realname: str
|
||||
channels: list
|
||||
vhost: str = None
|
||||
init: bool = True
|
||||
connected: bool = False
|
||||
|
||||
UID_CLONE_DB: list[CloneModel] = []
|
||||
|
||||
@@ -26,8 +26,6 @@ class Base:
|
||||
self.engine, self.cursor = self.db_init() # Initialisation de la connexion a la base de données
|
||||
self.__create_db() # Initialisation de la base de données
|
||||
|
||||
self.db_create_first_admin() # Créer un nouvel admin si la base de données est vide
|
||||
|
||||
def __set_current_defender_version(self) -> None:
|
||||
"""This will put the current version of Defender
|
||||
located in version.json
|
||||
|
||||
@@ -144,6 +144,11 @@ class Connection:
|
||||
self.Base.logs.error(f"OSError __connect_to_irc: {oe} - {data}")
|
||||
self.signal = False
|
||||
|
||||
self.IrcSocket.shutdown(socket.SHUT_WR)
|
||||
self.IrcSocket.shutdown(socket.SHUT_RD)
|
||||
self.currentCloneObject.init = False
|
||||
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> Clone Disconnected ...")
|
||||
|
||||
except AssertionError as ae:
|
||||
self.Base.logs.error(f'Assertion error : {ae}')
|
||||
except ValueError as ve:
|
||||
@@ -154,11 +159,6 @@ class Connection:
|
||||
self.Base.logs.critical(f"{atte}")
|
||||
except Exception as e:
|
||||
self.Base.logs.error(f"Exception: {e}")
|
||||
finally:
|
||||
self.IrcSocket.shutdown(socket.SHUT_WR)
|
||||
self.IrcSocket.shutdown(socket.SHUT_RD)
|
||||
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> Clone Disconnected ...")
|
||||
# self.IrcSocket.close()
|
||||
|
||||
def parser(self, cmd:list[bytes]):
|
||||
try:
|
||||
@@ -176,6 +176,9 @@ class Connection:
|
||||
case 'ERROR':
|
||||
error_value = str(response[1]).replace(':','')
|
||||
if error_value == 'Closing':
|
||||
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> {response} ...")
|
||||
self.currentCloneObject.connected = False
|
||||
else:
|
||||
self.Base.logs.info(f"<<{self.currentCloneObject.nickname}>> {response} ...")
|
||||
# self.signal = False
|
||||
|
||||
@@ -183,6 +186,7 @@ class Connection:
|
||||
case '376':
|
||||
# End of MOTD
|
||||
self.currentCloneObject.connected = True
|
||||
self.currentCloneObject.init = False
|
||||
for channel in self.channels:
|
||||
self.send2socket(f"JOIN {channel}")
|
||||
|
||||
@@ -192,6 +196,7 @@ class Connection:
|
||||
case '422':
|
||||
# Missing MOTD
|
||||
self.currentCloneObject.connected = True
|
||||
self.currentCloneObject.init = False
|
||||
for channel in self.channels:
|
||||
self.send2socket(f"JOIN {channel}")
|
||||
|
||||
|
||||
62
core/irc.py
62
core/irc.py
@@ -29,7 +29,7 @@ class Irc:
|
||||
|
||||
# Liste des commandes internes du bot
|
||||
self.commands_level = {
|
||||
0: ['help', 'auth', 'copyright', 'uptime'],
|
||||
0: ['help', 'auth', 'copyright', 'uptime', 'firstauth'],
|
||||
1: ['load','reload','unload', 'deauth', 'checkversion'],
|
||||
2: ['show_modules', 'show_timers', 'show_threads', 'show_channels', 'show_users', 'show_admins'],
|
||||
3: ['quit', 'restart','addaccess','editaccess', 'delaccess']
|
||||
@@ -1017,7 +1017,57 @@ class Irc:
|
||||
current_command = cmd[0]
|
||||
uid_to_deauth = self.User.get_uid(fromuser)
|
||||
self.delete_db_admin(uid_to_deauth)
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.User.get_nickname(fromuser)} est désormais déconnecter de {dnickname}")
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{str(current_command).upper()} ]{self.Config.CONFIG_COLOR['noire']} - {self.User.get_nickname(fromuser)} est désormais déconnecter de {dnickname}")
|
||||
|
||||
case 'firstauth':
|
||||
# firstauth OWNER_NICKNAME OWNER_PASSWORD
|
||||
current_nickname = self.User.get_nickname(fromuser)
|
||||
current_uid = self.User.get_uid(fromuser)
|
||||
current_command = str(cmd[0])
|
||||
|
||||
query = f"SELECT count(id) as c FROM {self.Config.table_admin}"
|
||||
result = self.Base.db_execute_query(query)
|
||||
result_db = result.fetchone()
|
||||
|
||||
if result_db[0] > 0:
|
||||
self.send2socket(f":{dnickname} NOTICE {fromuser} :You can't use this command anymore ! Please use [{self.Config.SERVICE_PREFIX}auth] instead")
|
||||
return False
|
||||
|
||||
if current_nickname is None:
|
||||
self.Base.logs.critical(f"This nickname [{fromuser}] don't exist")
|
||||
return False
|
||||
|
||||
# Credentials sent from the user
|
||||
cmd_owner = str(cmd[1])
|
||||
cmd_password = str(cmd[2])
|
||||
|
||||
# Credentials coming from the Configuration
|
||||
config_owner = self.Config.OWNER
|
||||
config_password = self.Config.PASSWORD
|
||||
|
||||
if current_nickname != cmd_owner:
|
||||
self.Base.logs.critical(f"The current nickname [{fromuser}] is different than the nickname sent [{cmd_owner}] !")
|
||||
self.send2socket(f":{dnickname} NOTICE {fromuser} :The current nickname [{fromuser}] is different than the nickname sent [{cmd_owner}] !")
|
||||
return False
|
||||
|
||||
if current_nickname != config_owner:
|
||||
self.Base.logs.critical(f"The current nickname [{current_nickname}] is different than the configuration owner [{config_owner}] !")
|
||||
self.send2socket(f":{dnickname} NOTICE {fromuser} :The current nickname [{current_nickname}] is different than the configuration owner [{config_owner}] !")
|
||||
return False
|
||||
|
||||
if cmd_owner != config_owner:
|
||||
self.Base.logs.critical(f"The nickname sent [{cmd_owner}] is different than the configuration owner [{config_owner}] !")
|
||||
self.send2socket(f":{dnickname} NOTICE {fromuser} :The nickname sent [{cmd_owner}] is different than the configuration owner [{config_owner}] !")
|
||||
return False
|
||||
|
||||
if cmd_owner == config_owner and cmd_password == config_password:
|
||||
self.Base.db_create_first_admin()
|
||||
self.insert_db_admin(current_uid, 5)
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}{str(current_command).upper()} ]{self.Config.CONFIG_COLOR['noire']} - {self.User.get_nickname(fromuser)} est désormais connecté a {dnickname}")
|
||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Connexion a {dnickname} réussie!")
|
||||
else:
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{str(current_command).upper()} ]{self.Config.CONFIG_COLOR['noire']} - {self.User.get_nickname(fromuser)} a tapé un mauvais mot de pass")
|
||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Mot de passe incorrecte")
|
||||
|
||||
case 'auth':
|
||||
# ['auth', 'adator', 'password']
|
||||
@@ -1039,10 +1089,10 @@ class Irc:
|
||||
if not user_from_db is None:
|
||||
uid_user = self.User.get_uid(user_to_log)
|
||||
self.insert_db_admin(uid_user, user_from_db[1])
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.User.get_nickname(fromuser)} est désormais connecté a {dnickname}")
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['verte']}{str(current_command).upper()} ]{self.Config.CONFIG_COLOR['noire']} - {self.User.get_nickname(fromuser)} est désormais connecté a {dnickname}")
|
||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Connexion a {dnickname} réussie!")
|
||||
else:
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{current_command}{self.Config.CONFIG_COLOR['noire']} ] - {self.User.get_nickname(fromuser)} a tapé un mauvais mot de pass")
|
||||
self.send2socket(f":{dnickname} PRIVMSG {dchanlog} :[ {self.Config.CONFIG_COLOR['rouge']}{str(current_command).upper()} ]{self.Config.CONFIG_COLOR['noire']} - {self.User.get_nickname(fromuser)} a tapé un mauvais mot de pass")
|
||||
self.send2socket(f":{self.Config.SERVICE_NICKNAME} NOTICE {fromuser} :Mot de passe incorrecte")
|
||||
|
||||
else:
|
||||
@@ -1051,6 +1101,10 @@ class Irc:
|
||||
case 'addaccess':
|
||||
try:
|
||||
# .addaccess adator 5 password
|
||||
if len(cmd) < 4:
|
||||
self.send2socket(f':{dnickname} NOTICE {fromuser} : Right command : /msg {dnickname} addaccess [nickname] [level] [password]')
|
||||
self.send2socket(f':{dnickname} NOTICE {fromuser} : level: from 1 to 4')
|
||||
|
||||
newnickname = cmd[1]
|
||||
newlevel = self.Base.int_if_possible(cmd[2])
|
||||
password = cmd[3]
|
||||
|
||||
@@ -151,14 +151,14 @@ class Config:
|
||||
configuration:dict[str, Union[str, int, list, dict]] = json.load(configuration_data)
|
||||
|
||||
config_dict = {"CONFIG_COLOR" : {
|
||||
"blanche": "\\u0003\\u0030",
|
||||
"noire": "\\u0003\\u0031",
|
||||
"bleue": "\\u0003\\u0020",
|
||||
"verte": "\\u0003\\u0033",
|
||||
"rouge": "\\u0003\\u0034",
|
||||
"jaune": "\\u0003\\u0036",
|
||||
"gras": "\\u0002",
|
||||
"nogc": "\\u0002\\u0003"
|
||||
"blanche": "\x0300",
|
||||
"noire": "\x0301",
|
||||
"bleue": "\x0302",
|
||||
"verte": "\x0303",
|
||||
"rouge": "\x0304",
|
||||
"jaune": "\x0306",
|
||||
"gras": "\x02",
|
||||
"nogc": "\x02\x03"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,6 +184,9 @@ class Config:
|
||||
print(f'FileNotFound: {fe}')
|
||||
print('Configuration file not found please create core/configuration.json')
|
||||
sys.exit(0)
|
||||
except KeyError as ke:
|
||||
print(f'Key Error: {ke}')
|
||||
print('The key must be defined in core/configuration.json')
|
||||
|
||||
def __load_service_configuration(self) -> ConfigDataModel:
|
||||
import_config = self.__load_json_service_configuration()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from dataclasses import dataclass, fields, field
|
||||
import random, faker, time
|
||||
import random, faker, time, logging
|
||||
from datetime import datetime
|
||||
from typing import Union
|
||||
from core.irc import Irc
|
||||
@@ -122,6 +122,25 @@ class Clone():
|
||||
|
||||
return None
|
||||
|
||||
def thread_clone_clean_up(self, wait: float):
|
||||
|
||||
activated = True
|
||||
|
||||
while activated:
|
||||
clone_to_kill: list[str] = []
|
||||
|
||||
for clone in self.Clone.UID_CLONE_DB:
|
||||
if not clone.connected and clone.alive and not clone.init:
|
||||
clone_to_kill.append(clone.nickname)
|
||||
clone.alive = False
|
||||
|
||||
for clone_nickname in clone_to_kill:
|
||||
if self.Clone.delete(clone_nickname):
|
||||
self.Logs.debug(f'<<{clone_nickname}>> object has been deleted')
|
||||
|
||||
del clone_to_kill
|
||||
time.sleep(wait)
|
||||
|
||||
def thread_change_hostname(self):
|
||||
|
||||
fake = faker.Faker('en_GB')
|
||||
@@ -142,6 +161,27 @@ class Clone():
|
||||
found = True
|
||||
clone.vhost = rand_ip
|
||||
break
|
||||
if not clone in self.Clone.UID_CLONE_DB:
|
||||
found = True
|
||||
break
|
||||
|
||||
def thread_create_clones_with_interval(self, number_of_clones:int, channels: list, connection_interval: float):
|
||||
|
||||
for i in range(number_of_clones):
|
||||
nickname, username, realname = self.generate_names()
|
||||
self.Base.create_thread(
|
||||
self.thread_create_clones,
|
||||
(nickname, username, realname, channels, 6697, True)
|
||||
)
|
||||
time.sleep(connection_interval)
|
||||
|
||||
self.Base.create_thread(
|
||||
self.thread_change_hostname
|
||||
)
|
||||
|
||||
# self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :{str(number_of_clones)} clones joined the network')
|
||||
|
||||
self.Base.create_thread(self.thread_clone_clean_up, (5, ), run_once=True)
|
||||
|
||||
def thread_create_clones(self, nickname: str, username: str, realname: str, channels: list, server_port: int, ssl: bool) -> None:
|
||||
|
||||
@@ -167,6 +207,7 @@ class Clone():
|
||||
|
||||
def generate_names(self) -> tuple[str, str, str]:
|
||||
try:
|
||||
logging.getLogger('faker').setLevel(logging.CRITICAL)
|
||||
fake = faker.Faker('en_GB')
|
||||
# nickname = fake.first_name()
|
||||
# username = fake.last_name()
|
||||
@@ -237,7 +278,7 @@ class Clone():
|
||||
case 'clone':
|
||||
|
||||
if len(cmd) == 1:
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6 2.5')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill [all | nickname]')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join [all | nickname] #channel')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone list')
|
||||
@@ -249,23 +290,16 @@ class Clone():
|
||||
case 'connect':
|
||||
try:
|
||||
number_of_clones = int(cmd[2])
|
||||
for i in range(number_of_clones):
|
||||
nickname, username, realname = self.generate_names()
|
||||
connection_interval = int(cmd[3]) if len(cmd) == 4 else 0.5
|
||||
self.Base.create_thread(
|
||||
self.thread_create_clones,
|
||||
(nickname, username, realname, [], 6697, True)
|
||||
self.thread_create_clones_with_interval,
|
||||
(number_of_clones, [], connection_interval)
|
||||
)
|
||||
|
||||
self.Base.create_thread(
|
||||
self.thread_change_hostname
|
||||
)
|
||||
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :{str(number_of_clones)} clones joined the network')
|
||||
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect [number of clone you want to connect]')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :Exemple /msg {dnickname} clone connect 6')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect [number of clone you want to connect] [Connection Interval]')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :Exemple /msg {dnickname} clone connect 6 2.5')
|
||||
|
||||
case 'kill':
|
||||
try:
|
||||
@@ -313,8 +347,10 @@ class Clone():
|
||||
|
||||
case 'list':
|
||||
try:
|
||||
clone_count = len(self.Clone.UID_CLONE_DB)
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Number of connected clones: {clone_count}')
|
||||
for clone_name in self.Clone.UID_CLONE_DB:
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Nickname: {clone_name.nickname} | Username: {clone_name.username}')
|
||||
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Nickname: {clone_name.nickname} | Username: {clone_name.username} | Realname: {clone_name.realname} | Vhost: {clone_name.vhost} | Connected: {clone_name.connected}')
|
||||
except Exception as err:
|
||||
self.Logs.error(f'{err}')
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "5.2.5"
|
||||
"version": "5.2.9"
|
||||
}
|
||||
Reference in New Issue
Block a user