8 Commits

Author SHA1 Message Date
adator
c1c0b480ce V5.2.3 If missing MOTD 2024-09-16 21:14:04 +02:00
adator
66ea492593 removing old code 2024-09-16 00:57:27 +02:00
adator
d459fd662f Changing hostname modification 2024-09-16 00:41:43 +02:00
adator
5d3a2b0e64 Changing Proxy_scan to PSUTIL_scan 2024-09-15 23:32:44 +02:00
adator
2f681db2d7 Adding Geoip to the UserModel 2024-09-15 23:29:32 +02:00
adator
7585db4f62 V5.2.2 2024-09-15 22:39:34 +02:00
adator
1984511db8 V5.2.1 2024-09-15 03:08:49 +02:00
adator
ce47739a93 update mode clone 2024-09-15 02:49:42 +02:00
6 changed files with 277 additions and 192 deletions

View File

@@ -10,12 +10,15 @@ class User:
uid: str uid: str
nickname: str nickname: str
username: str username: str
realname: str
hostname: str hostname: str
umodes: str umodes: str
vhost: str vhost: str
isWebirc: bool isWebirc: bool
isWebsocket: bool
remote_ip: str remote_ip: str
score_connexion: int score_connexion: int
geoip: str = None
connexion_datetime: datetime = field(default=datetime.now()) connexion_datetime: datetime = field(default=datetime.now())
UID_DB: list[UserModel] = [] UID_DB: list[UserModel] = []
@@ -410,6 +413,8 @@ class Clones:
alive: bool alive: bool
nickname: str nickname: str
username: str username: str
realname: str
connected: bool = False
UID_CLONE_DB: list[CloneModel] = [] UID_CLONE_DB: list[CloneModel] = []

View File

@@ -7,13 +7,15 @@ from typing import Union
class Connection: class Connection:
def __init__(self, server_port: int, nickname: str, username: str, channels:list[str], CloneObject: Clones, ssl:bool = False) -> None: def __init__(self, server_port: int, nickname: str, username: str, realname: str, channels:list[str], CloneObject: Clones, ssl:bool = False) -> None:
self.Config = Config().ConfigObject self.Config = Config().ConfigObject
self.Base = Base(self.Config) self.Base = Base(self.Config)
self.IrcSocket: Union[socket.socket, SSLSocket] = None self.IrcSocket: Union[socket.socket, SSLSocket] = None
self.nickname = nickname self.nickname = nickname
self.username = username self.username = username
self.realname = realname
self.chanlog = '#clones'
self.channels:list[str] = channels self.channels:list[str] = channels
self.CHARSET = ['utf-8', 'iso-8859-1'] self.CHARSET = ['utf-8', 'iso-8859-1']
self.Clones = CloneObject self.Clones = CloneObject
@@ -97,10 +99,11 @@ class Connection:
try: try:
nickname = self.nickname nickname = self.nickname
username = self.username username = self.username
realname = self.realname
# Envoyer un message d'identification # Envoyer un message d'identification
writer.send(f"USER {nickname} {username} {username} {nickname} {username} :{username}\r\n".encode('utf-8')) writer.send(f"USER {nickname} {username} {username} {nickname} {username} :{username}\r\n".encode('utf-8'))
writer.send(f"USER {username} {username} {username} :{username}\r\n".encode('utf-8')) writer.send(f"USER {username} {username} {username} :{realname}\r\n".encode('utf-8'))
writer.send(f"NICK {nickname}\r\n".encode('utf-8')) writer.send(f"NICK {nickname}\r\n".encode('utf-8'))
self.Base.logs.debug('Link information sent to the server') self.Base.logs.debug('Link information sent to the server')
@@ -162,6 +165,7 @@ class Connection:
for data in cmd: for data in cmd:
response = data.decode(self.CHARSET[0]).split() response = data.decode(self.CHARSET[0]).split()
self.signal = self.currentCloneObject.alive self.signal = self.currentCloneObject.alive
current_clone_nickname = self.currentCloneObject.nickname
# print(response) # print(response)
match response[0]: match response[0]:
@@ -176,14 +180,31 @@ class Connection:
match response[1]: match response[1]:
case '376': case '376':
# End of MOTD
self.currentCloneObject.connected = True
for channel in self.channels: for channel in self.channels:
self.send2socket(f"JOIN {channel}") self.send2socket(f"JOIN {channel}")
return None return None
case '422':
# Missing MOTD
self.currentCloneObject.connected = True
for channel in self.channels:
self.send2socket(f"JOIN {channel}")
return None
case 'PRIVMSG': case 'PRIVMSG':
self.Base.logs.debug(response) self.Base.logs.debug(response)
self.Base.logs.debug(f'{self.currentCloneObject.nickname} - {self.currentCloneObject.alive}') self.Base.logs.debug(f'{self.currentCloneObject.nickname} - {self.currentCloneObject.alive}')
fullname = str(response[0]).replace(':', '') fullname = str(response[0]).replace(':', '')
nickname = fullname.split('!')[0].replace(':','') nickname = fullname.split('!')[0].replace(':','')
if response[2] == current_clone_nickname:
message = []
for i in range(3, len(response)):
message.append(response[i])
final_message = ' '.join(message)
self.send2socket(f"PRIVMSG {self.chanlog} :{fullname} => {final_message[1:]}")
if nickname == self.Config.SERVICE_NICKNAME: if nickname == self.Config.SERVICE_NICKNAME:
command = str(response[3]).replace(':','') command = str(response[3]).replace(':','')

View File

@@ -591,7 +591,7 @@ class Irc:
self.send2socket(f':{dnickname} NOTICE {fromuser} : Please run (git pull origin main) in the current folder') self.send2socket(f':{dnickname} NOTICE {fromuser} : Please run (git pull origin main) in the current folder')
else: else:
self.send2socket(f':{dnickname} NOTICE {fromuser} : You have the latest version of defender') self.send2socket(f':{dnickname} NOTICE {fromuser} : You have the latest version of defender')
return None return None
def cmd(self, data: list[str]) -> None: def cmd(self, data: list[str]) -> None:
@@ -813,44 +813,67 @@ class Irc:
self.Base.logs.error(f'Index Error: {ie}') self.Base.logs.error(f'Index Error: {ie}')
case 'UID': case 'UID':
# ['@s2s-md/geoip=cc=GB|cd=United\\sKingdom|asn=16276|asname=OVH\\sSAS;s2s-md/tls_cipher=TLSv1.3-TLS_CHACHA20_POLY1305_SHA256;s2s-md/creationtime=1721564601', try:
# ':001', 'UID', 'albatros', '0', '1721564597', 'albatros', 'vps-91b2f28b.vps.ovh.net', # ['@s2s-md/geoip=cc=GB|cd=United\\sKingdom|asn=16276|asname=OVH\\sSAS;s2s-md/tls_cipher=TLSv1.3-TLS_CHACHA20_POLY1305_SHA256;s2s-md/creationtime=1721564601',
# '001HB8G04', '0', '+iwxz', 'Clk-A62F1D18.vps.ovh.net', 'Clk-A62F1D18.vps.ovh.net', 'MyZBwg==', ':...'] # ':001', 'UID', 'albatros', '0', '1721564597', 'albatros', 'vps-91b2f28b.vps.ovh.net',
if 'webirc' in original_response[0]: # '001HB8G04', '0', '+iwxz', 'Clk-A62F1D18.vps.ovh.net', 'Clk-A62F1D18.vps.ovh.net', 'MyZBwg==', ':...']
isWebirc = True
else:
isWebirc = False
uid = str(original_response[8]) isWebirc = True if 'webirc' in original_response[0] else False
nickname = str(original_response[3]) isWebsocket = True if 'websocket' in original_response[0] else False
username = str(original_response[6])
hostname = str(original_response[7])
umodes = str(original_response[10])
vhost = str(original_response[11])
if not 'S' in umodes:
remote_ip = self.Base.decode_ip(str(original_response[13]))
else:
remote_ip = '127.0.0.1'
score_connexion = self.first_score uid = str(original_response[8])
nickname = str(original_response[3])
username = str(original_response[6])
hostname = str(original_response[7])
umodes = str(original_response[10])
vhost = str(original_response[11])
self.User.insert( if not 'S' in umodes:
self.User.UserModel( remote_ip = self.Base.decode_ip(str(original_response[13]))
uid=uid, else:
nickname=nickname, remote_ip = '127.0.0.1'
username=username,
hostname=hostname, # extract realname
umodes=umodes, realname_list = []
vhost=vhost, for i in range(14, len(original_response)):
isWebirc=isWebirc, realname_list.append(original_response[i])
remote_ip=remote_ip,
score_connexion=score_connexion, realname = ' '.join(realname_list)[1:]
connexion_datetime=datetime.now()
# Extract Geoip information
pattern = r'^.*geoip=cc=(\S{2}).*$'
geoip_match = re.match(pattern, original_response[0])
if geoip_match:
geoip = geoip_match.group(1)
else:
geoip = None
score_connexion = self.first_score
self.User.insert(
self.User.UserModel(
uid=uid,
nickname=nickname,
username=username,
realname=realname,
hostname=hostname,
umodes=umodes,
vhost=vhost,
isWebirc=isWebirc,
isWebsocket=isWebsocket,
remote_ip=remote_ip,
geoip=geoip,
score_connexion=score_connexion,
connexion_datetime=datetime.now()
)
) )
)
for classe_name, classe_object in self.loaded_classes.items(): for classe_name, classe_object in self.loaded_classes.items():
classe_object.cmd(original_response) classe_object.cmd(original_response)
except Exception as err:
self.Base.logs.error(f'General Error: {err}')
case 'PRIVMSG': case 'PRIVMSG':
try: try:
@@ -1342,7 +1365,7 @@ class Irc:
case 'show_users': case 'show_users':
for db_user in self.User.UID_DB: for db_user in self.User.UID_DB:
self.send2socket(f":{dnickname} NOTICE {fromuser} :UID : {db_user.uid} - isWebirc: {db_user.isWebirc} - Nickname: {db_user.nickname} - Connection: {db_user.connexion_datetime}") self.send2socket(f":{dnickname} NOTICE {fromuser} :UID : {db_user.uid} - isWebirc: {db_user.isWebirc} - isWebSocket: {db_user.isWebsocket} - Nickname: {db_user.nickname} - Connection: {db_user.connexion_datetime}")
case 'show_admins': case 'show_admins':
for db_admin in self.Admin.UID_ADMIN_DB: for db_admin in self.Admin.UID_ADMIN_DB:

View File

@@ -122,9 +122,26 @@ class Clone():
return None return None
def thread_create_clones(self, nickname: str, username: str, channels: list, server_port: int, ssl: bool) -> None: def thread_change_hostname(self):
Connection(server_port=server_port, nickname=nickname, username=username, channels=channels, CloneObject=self.Clone, ssl=ssl) fake = faker.Faker('en_GB')
for clone in self.Clone.UID_CLONE_DB:
rand_1 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8)
rand_2 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8)
rand_3 = fake.random_elements(['A','B','C','D','E','F','0','1','2','3','4','5','6','7','8','9'], unique=True, length=8)
rand_ip = ''.join(rand_1) + '.' + ''.join(rand_2) + '.' + ''.join(rand_3) + '.IP'
found = False
while not found:
if clone.connected:
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} CHGHOST {clone.nickname} {rand_ip}')
found = True
break
def thread_create_clones(self, nickname: str, username: str, realname: str, channels: list, server_port: int, ssl: bool) -> None:
Connection(server_port=server_port, nickname=nickname, username=username, realname=realname, channels=channels, CloneObject=self.Clone, ssl=ssl)
return None return None
@@ -140,33 +157,38 @@ class Clone():
self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone.nickname} :JOIN {channel_name}') self.Irc.send2socket(f':{self.Config.SERVICE_NICKNAME} PRIVMSG {clone.nickname} :JOIN {channel_name}')
time.sleep(wait) time.sleep(wait)
def generate_names(self) -> tuple[str, str]: def generate_names(self) -> tuple[str, str, str]:
try: try:
fake = faker.Faker('en_GB') fake = faker.Faker('en_GB')
nickname = fake.first_name() nickname = fake.first_name()
username = fake.last_name() # username = fake.last_name()
# Generate Username
chaine = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
new_username = fake.random_sample(chaine, 9)
username = ''.join(new_username)
# Create realname XX F|M Department
gender = fake.random_choices(['F','M'], 1)
gender = ''.join(gender)
age = random.randint(20, 60)
fake_fr = faker.Faker(['fr_FR', 'en_GB'])
department = fake_fr.department_name()
realname = f'{age} {gender} {department}'
if self.Clone.exists(nickname=nickname): if self.Clone.exists(nickname=nickname):
caracteres = '0123456789' caracteres = '0123456789'
randomize = ''.join(random.choice(caracteres) for _ in range(2)) randomize = ''.join(random.choice(caracteres) for _ in range(2))
nickname = nickname + str(randomize) nickname = nickname + str(randomize)
self.Clone.insert( self.Clone.insert(
self.Clone.CloneModel(alive=True, nickname=nickname, username=username) self.Clone.CloneModel(alive=True, nickname=nickname, username=username, realname=realname)
) )
else: else:
self.Clone.insert( self.Clone.insert(
self.Clone.CloneModel(alive=True, nickname=nickname, username=username) self.Clone.CloneModel(alive=True, nickname=nickname, username=username, realname=realname)
) )
# if not nickname in self.ModConfig.clone_nicknames: return (nickname, username, realname)
# self.ModConfig.clone_nicknames.append(nickname)
# else:
# caracteres = '0123456789'
# randomize = ''.join(random.choice(caracteres) for _ in range(2))
# nickname = nickname + str(randomize)
# self.ModConfig.clone_nicknames.append(nickname)
return (nickname, username)
except AttributeError as ae: except AttributeError as ae:
self.Logs.error(f'Attribute Error : {ae}') self.Logs.error(f'Attribute Error : {ae}')
@@ -188,117 +210,128 @@ class Clone():
def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: def _hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower() try:
fromuser = user command = str(cmd[0]).lower()
fromuser = user
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
match command: match command:
case 'clone': case 'clone':
option = str(cmd[1]).lower()
if len(command) == 1: 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 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')
match option:
case 'connect':
try:
number_of_clones = int(cmd[2])
for i in range(number_of_clones):
nickname, username = self.generate_names()
self.Base.create_thread(
self.thread_create_clones,
(nickname, username, [], 6697, True)
)
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')
case 'kill':
try:
# clone kill [all | nickname]
clone_name = str(cmd[2])
clone_to_kill: list[str] = []
if clone_name.lower() == 'all':
for clone in self.Clone.UID_CLONE_DB:
self.Irc.send2socket(f':{dnickname} PRIVMSG {clone.nickname} :KILL')
clone_to_kill.append(clone.nickname)
clone.alive = False
for clone_nickname in clone_to_kill:
self.Clone.delete(clone_nickname)
del clone_to_kill
else:
if self.Clone.exists(clone_name):
self.Irc.send2socket(f':{dnickname} PRIVMSG {clone_name} :KILL')
self.Clone.kill(clone_name)
self.Clone.delete(clone_name)
except Exception as err:
self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill all')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill clone_nickname')
case 'join':
try:
# clone join [all | nickname] #channel
clone_name = str(cmd[2])
clone_channel_to_join = str(cmd[3])
if clone_name.lower() == 'all':
self.Base.create_thread(self.thread_join_channels, (clone_channel_to_join, 2))
else:
self.Base.create_thread(self.thread_join_channels, (clone_channel_to_join, 2, clone_name))
except Exception as err:
self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join all #channel')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join clone_nickname #channel')
case 'list':
try:
for clone_name in self.Clone.UID_CLONE_DB:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> {clone_name.nickname} | {clone_name.username}')
pass
except Exception as err:
self.Logs.error(f'{err}')
case 'say':
try:
# clone say clone_nickname #channel message
clone_name = str(cmd[2])
clone_channel = str(cmd[3]) if self.Base.Is_Channel(str(cmd[3])) else None
message = []
for i in range(4, len(cmd)):
message.append(cmd[i])
final_message = ' '.join(message)
if clone_channel is None or not self.Clone.exists(clone_name):
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone say [clone_nickname] #channel message')
return None
if self.Clone.exists(clone_name):
self.Irc.send2socket(f':{dnickname} PRIVMSG {clone_name} :SAY {clone_channel} {final_message}')
except Exception as err:
self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone say [clone_nickname] #channel message')
case _:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill [all | nickname]') 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 join [all | nickname] #channel')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone say [clone_nickname] #channel [message]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone list') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone list')
option = str(cmd[1]).lower()
match option:
case 'connect':
try:
number_of_clones = int(cmd[2])
for i in range(number_of_clones):
nickname, username, realname = self.generate_names()
self.Base.create_thread(
self.thread_create_clones,
(nickname, username, realname, ['#clones'], 6697, True)
)
self.Base.create_thread(
self.thread_change_hostname,
run_once=True
)
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')
case 'kill':
try:
# clone kill [all | nickname]
clone_name = str(cmd[2])
clone_to_kill: list[str] = []
if clone_name.lower() == 'all':
for clone in self.Clone.UID_CLONE_DB:
self.Irc.send2socket(f':{dnickname} PRIVMSG {clone.nickname} :KILL')
clone_to_kill.append(clone.nickname)
clone.alive = False
for clone_nickname in clone_to_kill:
self.Clone.delete(clone_nickname)
del clone_to_kill
else:
if self.Clone.exists(clone_name):
self.Irc.send2socket(f':{dnickname} PRIVMSG {clone_name} :KILL')
self.Clone.kill(clone_name)
self.Clone.delete(clone_name)
except Exception as err:
self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill all')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone kill clone_nickname')
case 'join':
try:
# clone join [all | nickname] #channel
clone_name = str(cmd[2])
clone_channel_to_join = str(cmd[3])
if clone_name.lower() == 'all':
self.Base.create_thread(self.thread_join_channels, (clone_channel_to_join, 2))
else:
self.Base.create_thread(self.thread_join_channels, (clone_channel_to_join, 2, clone_name))
except Exception as err:
self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join all #channel')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone join clone_nickname #channel')
case 'list':
try:
for clone_name in self.Clone.UID_CLONE_DB:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :>> Nickname: {clone_name.nickname} | Username: {clone_name.username}')
except Exception as err:
self.Logs.error(f'{err}')
case 'say':
try:
# clone say clone_nickname #channel message
clone_name = str(cmd[2])
clone_channel = str(cmd[3]) if self.Base.Is_Channel(str(cmd[3])) else None
message = []
for i in range(4, len(cmd)):
message.append(cmd[i])
final_message = ' '.join(message)
if clone_channel is None or not self.Clone.exists(clone_name):
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone say [clone_nickname] #channel message')
return None
if self.Clone.exists(clone_name):
self.Irc.send2socket(f':{dnickname} PRIVMSG {clone_name} :SAY {clone_channel} {final_message}')
except Exception as err:
self.Logs.error(f'{err}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone say [clone_nickname] #channel message')
case _:
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone connect 6')
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 say [clone_nickname] #channel [message]')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} :/msg {dnickname} clone list')
except IndexError as ie:
self.Logs.error(f'Index Error: {ie}')
except Exception as err:
self.Logs.error(f'Index Error: {err}')

View File

@@ -44,11 +44,13 @@ class Defender():
nickname: str nickname: str
username: str username: str
hostname: str hostname: str
realname: str
umodes: str umodes: str
vhost: str vhost: str
ip: str ip: str
score: int score: int
isWebirc: bool isWebirc: bool
isWebsocket: bool
secret_code: str secret_code: str
connected_datetime: str connected_datetime: str
updated_datetime: str updated_datetime: str
@@ -109,19 +111,13 @@ class Defender():
self.timeout = self.Config.API_TIMEOUT self.timeout = self.Config.API_TIMEOUT
# Listes qui vont contenir les ip a scanner avec les différentes API
self.abuseipdb_UserModel: list[User.UserModel] = [] self.abuseipdb_UserModel: list[User.UserModel] = []
self.freeipapi_UserModel: list[User.UserModel] = [] self.freeipapi_UserModel: list[User.UserModel] = []
self.cloudfilt_UserModel: list[User.UserModel] = [] self.cloudfilt_UserModel: list[User.UserModel] = []
self.psutil_UserModel: list[User.UserModel] = [] self.psutil_UserModel: list[User.UserModel] = []
self.localscan_UserModel: list[User.UserModel] = [] self.localscan_UserModel: list[User.UserModel] = []
# Listes qui vont contenir les ip a scanner avec les différentes API
# self.freeipapi_remote_ip:list = []
# self.cloudfilt_remote_ip:list = []
# self.abuseipdb_remote_ip:list = []
# self.psutil_remote_ip:list = []
# self.localscan_remote_ip:list = []
# Variables qui indique que les threads sont en cours d'éxecutions # Variables qui indique que les threads sont en cours d'éxecutions
self.abuseipdb_isRunning:bool = True self.abuseipdb_isRunning:bool = True
self.freeipapi_isRunning:bool = True self.freeipapi_isRunning:bool = True
@@ -234,11 +230,11 @@ class Defender():
"""Cette methode sera executée a chaque désactivation ou """Cette methode sera executée a chaque désactivation ou
rechargement de module rechargement de module
""" """
self.abuseipdb_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec abuseipdb self.abuseipdb_UserModel: list[User.UserModel] = []
self.freeipapi_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec freeipapi self.freeipapi_UserModel: list[User.UserModel] = []
self.cloudfilt_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec cloudfilt self.cloudfilt_UserModel: list[User.UserModel] = []
self.psutil_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec psutil_scan self.psutil_UserModel: list[User.UserModel] = []
self.localscan_remote_ip:list = [] # Liste qui va contenir les adresses ip a scanner avec local_scan self.localscan_UserModel: list[User.UserModel] = []
self.abuseipdb_isRunning:bool = False self.abuseipdb_isRunning:bool = False
self.freeipapi_isRunning:bool = False self.freeipapi_isRunning:bool = False
@@ -617,13 +613,14 @@ class Defender():
"""local_scan """local_scan
Args: Args:
remote_ip (str): _description_ userModel (UserModel): _description_
""" """
User = userModel User = userModel
remote_ip = User.remote_ip remote_ip = User.remote_ip
username = User.username username = User.username
hostname = User.hostname hostname = User.hostname
nickname = User.nickname nickname = User.nickname
fullname = f'{nickname}!{username}@{hostname}'
if remote_ip in self.Config.WHITELISTED_IP: if remote_ip in self.Config.WHITELISTED_IP:
return None return None
@@ -637,14 +634,13 @@ class Defender():
connection = (remote_ip, self.Base.int_if_possible(port)) connection = (remote_ip, self.Base.int_if_possible(port))
newSocket.connect(connection) newSocket.connect(connection)
fullname = f'{nickname}!{username}@{hostname}'
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}PROXY_SCAN{self.Config.CONFIG_COLOR['noire']} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]") self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}PROXY_SCAN{self.Config.CONFIG_COLOR['noire']} ] {fullname} ({remote_ip}) : Port [{str(port)}] ouvert sur l'adresse ip [{remote_ip}]")
# print(f"=======> Le port {str(port)} est ouvert !!") # print(f"=======> Le port {str(port)} est ouvert !!")
self.Base.running_sockets.append(newSocket) self.Base.running_sockets.append(newSocket)
# print(newSocket) # print(newSocket)
newSocket.shutdown(socket.SHUT_RDWR) newSocket.shutdown(socket.SHUT_RDWR)
newSocket.close() newSocket.close()
except (socket.timeout, ConnectionRefusedError): except (socket.timeout, ConnectionRefusedError):
self.Logs.info(f"Le port {remote_ip}:{str(port)} est fermé") self.Logs.info(f"Le port {remote_ip}:{str(port)} est fermé")
except AttributeError as ae: except AttributeError as ae:
@@ -676,10 +672,10 @@ class Defender():
self.Logs.warning(f"thread_local_scan Error : {ve}") self.Logs.warning(f"thread_local_scan Error : {ve}")
def get_ports_connexion(self, userModel: User.UserModel) -> list[int]: def get_ports_connexion(self, userModel: User.UserModel) -> list[int]:
"""psutil_scan for Linux """psutil_scan for Linux (should be run on the same location as the unrealircd server)
Args: Args:
remote_ip (str): The remote ip address userModel (UserModel): The User Model Object
Returns: Returns:
list[int]: list of ports list[int]: list of ports
@@ -700,6 +696,9 @@ class Defender():
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]
self.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}") self.Logs.info(f"Connexion of {fullname} ({remote_ip}) using ports : {str(matching_ports)}")
if matching_ports:
self.Irc.send2socket(f":{self.Config.SERVICE_NICKNAME} PRIVMSG {self.Config.SERVICE_CHANLOG} :[ {self.Config.CONFIG_COLOR['rouge']}PSUTIL_SCAN{self.Config.CONFIG_COLOR['noire']} ] {fullname} ({remote_ip}) : is using ports {matching_ports}")
return matching_ports return matching_ports
except psutil.AccessDenied as ad: except psutil.AccessDenied as ad:
@@ -1067,9 +1066,9 @@ class Defender():
currentDateTime = self.Base.get_datetime() currentDateTime = self.Base.get_datetime()
self.reputation_insert( self.reputation_insert(
self.ReputationModel( self.ReputationModel(
uid=_User.uid, nickname=_User.nickname, username=_User.username, hostname=_User.hostname, uid=_User.uid, nickname=_User.nickname, username=_User.username, realname=_User.realname,
umodes=_User.umodes, vhost=_User.vhost, ip=_User.remote_ip, score=_User.score_connexion, hostname=_User.hostname, umodes=_User.umodes, vhost=_User.vhost, ip=_User.remote_ip, score=_User.score_connexion,
secret_code=self.Base.get_random(8), isWebirc=_User.isWebirc, connected_datetime=currentDateTime, secret_code=self.Base.get_random(8), isWebirc=_User.isWebirc, isWebsocket=_User.isWebsocket, connected_datetime=currentDateTime,
updated_datetime=currentDateTime updated_datetime=currentDateTime
) )
) )
@@ -1092,6 +1091,9 @@ class Defender():
get_reputation = self.reputation_get_Reputation(parsed_UID) get_reputation = self.reputation_get_Reputation(parsed_UID)
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +b ~security-group:unknown-users")
self.Irc.send2socket(f":{service_id} MODE {parsed_chan} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
if not get_reputation is None: if not get_reputation is None:
isWebirc = get_reputation.isWebirc isWebirc = get_reputation.isWebirc
@@ -1115,20 +1117,20 @@ class Defender():
if not self.Base.is_valid_ip(cmd[7]): if not self.Base.is_valid_ip(cmd[7]):
return None return None
if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # if self.ModConfig.local_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
self.localscan_remote_ip.append(cmd[7]) # self.localscan_remote_ip.append(cmd[7])
if self.ModConfig.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # if self.ModConfig.psutil_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
self.psutil_remote_ip.append(cmd[7]) # self.psutil_remote_ip.append(cmd[7])
if self.ModConfig.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # if self.ModConfig.abuseipdb_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
self.abuseipdb_remote_ip.append(cmd[7]) # self.abuseipdb_remote_ip.append(cmd[7])
if self.ModConfig.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # if self.ModConfig.freeipapi_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
self.freeipapi_remote_ip.append(cmd[7]) # self.freeipapi_remote_ip.append(cmd[7])
if self.ModConfig.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP: # if self.ModConfig.cloudfilt_scan == 1 and not cmd[7] in self.Config.WHITELISTED_IP:
self.cloudfilt_remote_ip.append(cmd[7]) # self.cloudfilt_remote_ip.append(cmd[7])
case 'NICK': case 'NICK':
# :0010BS24L NICK [NEWNICK] 1697917711 # :0010BS24L NICK [NEWNICK] 1697917711
@@ -1291,9 +1293,7 @@ class Defender():
for chan in self.Channel.UID_CHANNEL_DB: for chan in self.Channel.UID_CHANNEL_DB:
if chan.name != jail_chan: if chan.name != jail_chan:
self.Irc.send2socket(f":{service_id} MODE {chan.name} +b ~security-group:unknown-users") self.Irc.send2socket(f":{service_id} MODE {chan.name} +b ~security-group:unknown-users")
self.Irc.send2socket(f":{service_id} MODE {chan.name} +e ~security-group:webirc-users") self.Irc.send2socket(f":{service_id} MODE {chan.name} +eee ~security-group:webirc-users ~security-group:known-users ~security-group:websocket-users")
self.Irc.send2socket(f":{service_id} MODE {chan.name} +e ~security-group:known-users")
self.Irc.send2socket(f":{service_id} MODE {chan.name} +e ~security-group:websocket-users")
self.Base.db_query_channel('add', self.module_name, jail_chan) self.Base.db_query_channel('add', self.module_name, jail_chan)
@@ -1629,10 +1629,13 @@ class Defender():
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : UID : {UserObject.uid}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : UID : {UserObject.uid}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : NICKNAME : {UserObject.nickname}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : NICKNAME : {UserObject.nickname}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : USERNAME : {UserObject.username}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : USERNAME : {UserObject.username}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : REALNAME : {UserObject.realname}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : HOSTNAME : {UserObject.hostname}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : HOSTNAME : {UserObject.hostname}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : VHOST : {UserObject.vhost}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : VHOST : {UserObject.vhost}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : IP : {UserObject.remote_ip}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : IP : {UserObject.remote_ip}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : Country : {UserObject.geoip}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : WebIrc : {UserObject.isWebirc}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : WebIrc : {UserObject.isWebirc}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : WebWebsocket : {UserObject.isWebsocket}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : REPUTATION : {UserObject.score_connexion}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : REPUTATION : {UserObject.score_connexion}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : MODES : {UserObject.umodes}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : MODES : {UserObject.umodes}')
self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CONNECTION TIME : {UserObject.connexion_datetime}') self.Irc.send2socket(f':{dnickname} NOTICE {fromuser} : CONNECTION TIME : {UserObject.connexion_datetime}')

View File

@@ -1,3 +1,3 @@
{ {
"version": "5.2.0" "version": "5.2.3"
} }