2020-10-17 12:22:22 -04:00
|
|
|
import pydle
|
2020-10-25 16:05:46 -04:00
|
|
|
import asyncio
|
|
|
|
from asyncio import new_event_loop, gather, get_event_loop, sleep
|
2020-10-17 12:22:22 -04:00
|
|
|
import random
|
|
|
|
import string
|
2020-10-25 16:05:46 -04:00
|
|
|
import time
|
2020-10-17 12:22:22 -04:00
|
|
|
|
2020-10-18 19:16:32 -04:00
|
|
|
CNC_HOST='dark.deflax.net'
|
|
|
|
CNC_CHANNEL='#izba'
|
2020-10-17 12:22:22 -04:00
|
|
|
ADMIN_NICKNAMES = [ 'afx' ]
|
2020-10-18 19:16:32 -04:00
|
|
|
MOTD='] Forest CnC ready!'
|
2020-10-17 12:22:22 -04:00
|
|
|
|
|
|
|
def get_random_string(length):
|
|
|
|
letters = string.ascii_lowercase
|
|
|
|
result_str = ''.join(random.choice(letters) for i in range(length))
|
|
|
|
return result_str
|
|
|
|
|
2020-10-26 10:06:25 -04:00
|
|
|
class ForestBot(pydle.Client):
|
|
|
|
verbose = True
|
|
|
|
|
2020-10-17 12:22:22 -04:00
|
|
|
async def on_connect(self):
|
|
|
|
await super().on_connect()
|
2020-10-18 19:16:32 -04:00
|
|
|
await self.join(CNC_CHANNEL)
|
2020-10-26 10:06:25 -04:00
|
|
|
#await self.message(CNC_CHANNEL, MOTD)
|
|
|
|
await self.dumplog(CNC_CHANNEL)
|
|
|
|
|
|
|
|
async def dumplog(self, target):
|
|
|
|
sleep_time = 1
|
|
|
|
while True:
|
|
|
|
msg = self.queue.get()
|
|
|
|
if self.verbose:
|
|
|
|
await asyncio.sleep(sleep_time)
|
|
|
|
await self.message(target, msg)
|
|
|
|
else:
|
|
|
|
print(msg)
|
|
|
|
|
2020-10-17 12:22:22 -04:00
|
|
|
async def is_admin(self, nickname):
|
|
|
|
"""
|
|
|
|
Check whether or not a user has administrative rights for this bot.
|
|
|
|
This is a blocking function: use a coroutine to call it.
|
|
|
|
See pydle's documentation on blocking functionality for details.
|
|
|
|
"""
|
|
|
|
admin = False
|
|
|
|
# Check the WHOIS info to see if the source has identified with NickServ.
|
|
|
|
# This is a blocking operation, so use yield.
|
|
|
|
if nickname in ADMIN_NICKNAMES:
|
|
|
|
info = await self.whois(nickname)
|
2020-10-18 19:16:32 -04:00
|
|
|
print('] Detected privileged request from {}'.format(info))
|
2020-10-17 12:22:22 -04:00
|
|
|
admin = info['identified']
|
|
|
|
return admin
|
|
|
|
|
|
|
|
async def on_message(self, target, source, message):
|
|
|
|
await super().on_message(target, source, message)
|
2020-10-18 13:53:02 -04:00
|
|
|
|
2020-10-18 19:16:32 -04:00
|
|
|
# Print help
|
|
|
|
if message.startswith('help {}'.format(self.nickname)):
|
|
|
|
await self.message(target, '] cnc usage:')
|
|
|
|
await self.message(target, '] help - displays help')
|
|
|
|
await self.message(target, '] id - cnc user info')
|
2020-10-26 10:06:25 -04:00
|
|
|
await self.message(target, '] log on - dump cnc log')
|
|
|
|
await self.message(target, '] log off - stop cnc log dump')
|
2020-10-18 19:16:32 -04:00
|
|
|
|
|
|
|
# Show user info
|
|
|
|
if message.startswith('id {}'.format(self.nickname)):
|
2020-10-17 12:22:22 -04:00
|
|
|
admin = await self.is_admin(source)
|
|
|
|
if admin:
|
2020-10-18 19:16:32 -04:00
|
|
|
await self.message(target, '] You are an administrator. :)'.format(source))
|
2020-10-17 12:22:22 -04:00
|
|
|
else:
|
2020-10-18 19:16:32 -04:00
|
|
|
await self.message(target, '] You are NOT an administrator. :('.format(source))
|
2020-10-25 16:05:46 -04:00
|
|
|
|
2020-10-26 10:06:25 -04:00
|
|
|
if message.startswith('log on {}'.format(self.nickname)):
|
2020-10-25 16:05:46 -04:00
|
|
|
admin = await self.is_admin(source)
|
|
|
|
if admin:
|
2020-10-26 10:06:25 -04:00
|
|
|
self.verbose = True
|
2020-10-25 21:48:06 -04:00
|
|
|
else:
|
|
|
|
await self.message(target, '] You are NOT an administrator. :('.format(source))
|
2020-10-26 10:06:25 -04:00
|
|
|
|
|
|
|
if message.startswith('log off {}'.format(self.nickname)):
|
|
|
|
admin = await self.is_admin(source)
|
|
|
|
if admin:
|
|
|
|
self.verbose = False
|
|
|
|
else:
|
|
|
|
await self.message(target, '] You are NOT an administrator. :('.format(source))
|
|
|
|
|
2020-10-25 16:05:46 -04:00
|
|
|
def run(self, *args, **kwargs):
|
|
|
|
self.queue = kwargs['extqueue']
|
2020-10-25 21:48:06 -04:00
|
|
|
|
|
|
|
loop = self.eventloop
|
|
|
|
#loop.run_until_complete(self.connect(*args, **kwargs))
|
|
|
|
loop.run_until_complete(self.connect(*args))
|
2020-10-25 16:05:46 -04:00
|
|
|
try:
|
2020-10-25 21:48:06 -04:00
|
|
|
loop.run_forever()
|
2020-10-25 16:05:46 -04:00
|
|
|
finally:
|
2020-10-25 21:48:06 -04:00
|
|
|
loop.stop()
|
2020-10-25 16:05:46 -04:00
|
|
|
|
|
|
|
def CnCApp(queue):
|
|
|
|
botnick = 'cnc_' + get_random_string(8)
|
|
|
|
botnick_fallback = [botnick + '_re']
|
|
|
|
cnc = ForestBot(botnick, botnick_fallback, botnick, botnick, None)
|
|
|
|
cnc.run(CNC_HOST, tls=False, tls_verify=False, extqueue=queue)
|
2020-10-18 13:53:02 -04:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
CnCApp()
|