def update_project_display(self): _translate = QtCore.QCoreApplication.translate __sortingEnabled = self.project_info.isSortingEnabled() self.project_data = ProjectController.get_project_info() self.project_info.setSortingEnabled(False) self.project_info.clear() self.project_info.addItem( QListWidgetItem("Project Name: {0}".format( self.project_data['project_name']))) self.project_info.addItem( QListWidgetItem("Project Directory: {0}".format( self.project_data['project_directory']))) self.project_info.addItem( QListWidgetItem("ECELd Data Directory: {0}".format( self.project_data['eceld_root']))) self.project_info.addItem( QListWidgetItem("Project Timeframe: {0}".format( self.project_data['time_frame']))) item = QListWidgetItem() item.setFlags(Qt.NoItemFlags) item.setText(_translate("Widget", " ")) self.project_info.addItem(item) self.project_info.addItem(QListWidgetItem("Salient Artifacts")) for artifact in ProjectController.get_salient_artifacts_json(): self.project_info.addItem(QListWidgetItem(str(artifact))) self.project_info.setSortingEnabled(__sortingEnabled)
def open_directory(self): directory = str( QtWidgets.QFileDialog.getExistingDirectory( QtWidgets.QFileDialog(), "Select Directory", directory=os.path.realpath(os.getcwd()))) full_directory = Path(directory) PATH = full_directory / 'project_config.json' # Check if user clicks on cancel if (len(directory) <= 0): return # Check if project_config exists in chosen directory elif (os.path.isfile(PATH) and os.access(PATH, os.R_OK)): print("File exists and is readable") ProjectController.load_project(directory) if (ProjectController.is_project_loaded): QMessageBox.information( self.centralwidget, "Success", "Project has been loaded successfully.") self.update_tabs() else: print("Either the file is missing or not readable") QMessageBox.critical( self.centralwidget, "Project Failure", "Project could not be loaded. Check that directory contains appropriate files" )
def update_tables(self): self.listrelationships.clear() if ProjectController.is_project_loaded(): self.populate_trees() if ProjectController.get_dependencies_file() != "": try: self.load_dependencies() except: pass
def load_script(self): script_file = QFileDialog.getOpenFileName(self, 'Open file')[0] if script_file: script_file_path = script_file else: self.invalid_path_alert_message() return False ProjectController.set_dependencies_file(script_file_path) ProjectController.save_project() self.load_dependencies()
def save_script(self): new_file_path, filter_type = QFileDialog.getSaveFileName( self, "Save this script as...", "", ".json") if new_file_path: script_file_path = new_file_path else: self.invalid_path_alert_message() return False ProjectController.set_dependencies_file(script_file_path + '.json') ProjectController.save_project() self.create_dependencies_json(script_file_path + '.json')
def open_artifacts(self): if ProjectController.is_project_loaded(): self.artifacts_window.populate_table() self.artifacts_window.show() else: QMessageBox.critical(self, "Project Error", "No project is currently loaded.")
def load_dependencies(self): with open(ProjectController.get_dependencies_file()) as f: data = json.load(f) for node in data: tempQtreewidgetitem = QTreeWidgetItem(self.listdependencies) tempQtreewidgetitem.setFlags(Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) tempQtreewidgetitem.setText(4, node['Content']) tempQtreewidgetitem.setText(3, node['Attributes']) tempQtreewidgetitem.setText(2, node['Time']) tempQtreewidgetitem.setText(1, node['Subtype']) tempQtreewidgetitem.setText(0, node['Type']) for child in node['Children']: childItem = QTreeWidgetItem(tempQtreewidgetitem) childItem.setFlags(Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) childItem.setText(4, child['Content']) childItem.setText(3, child['Attributes']) childItem.setText(2, child['Time']) childItem.setText(1, child['Subtype']) childItem.setText(0, child['Type'])
def openProject(self): project_file = QFileDialog.getOpenFileName(self, 'Open file') try: if project_file[0]: ProjectController.load_project(project_file[0]) self.project_info = ProjectInfoWidget(previous_window = self) self.project_info.show() self.hide() else: raise FileNotFoundError("No file selected") except FileNotFoundError as err: self.popup = PopupWidget(previous_window = self) self.popup.retranslateUi(popup_title = "File Error", popup_text = "File error: {0}".format(err)) self.popup.show() except TypeError as err: self.popup = PopupWidget(previous_window = self) self.popup.retranslateUi(popup_title = "File Error", popup_text = "File error: {0}".format(err)) self.popup.show()
def calc_delta_time(self, node=None, index=None): #If arguments are not correct. Return default value of 1 sec. if node is None or index is None: return datetime.time(0, 0, 1) else: deltaTime = datetime.time(0, 0, 1) #Select previous relationship to calculate time difference. prevIndex = self.listrelationships.indexAbove(index) prevItem = self.listrelationships.itemAbove(node) if prevItem is not None: try: prevTime = ProjectController.parse_timestamp( prevItem.text(1)).time() except: #Return default if formatting is incorrect. return deltaTime else: #Return default if no previous item is found return deltaTime try: #Extract time from current relationship node. deltaTime = ProjectController.parse_timestamp( node.text(1)).time() except: #Return default if time format is not valid. return deltaTime if prevTime < deltaTime: #Return difference betweem current and previous node. delatDateTime = datetime.datetime.combine( datetime.datetime.today(), deltaTime) - datetime.datetime.combine( datetime.datetime.today(), prevTime) date = datetime.datetime.strptime( "1900-01-01T00:00:00.000", "%Y-%m-%dT%H:%M:%S.%f") + delatDateTime deltaTime = date.time() else: return datetime.time(0, 0, 1) return deltaTime
def CausationExtractor(self): check_datafolder = os.path.isdir(self.import_field.text()) check_rootfolder = os.path.isdir(self.root_field.text()) if not (check_rootfolder): self.errorRootMsg() elif not (check_datafolder): self.errorDataMsg() else: # Checks for valid time frame format try: check_time_frame_format = datetime.datetime.strptime( self.timeframe_field.text(), '%H:%M:%S') except: self.errorTimeFrame() return ProjectController.create_project(self.import_field.text(), self.root_field.text(), "Test", self.timeframe_field.text()) self.CEWidget = CausationExtractorWidget(previous_window=self) self.CEWidget.show() self.previous_window.update_tabs() self.hide()
def add_node(self, _type=None, time=None, content=None, parent=None, isSalientArtifact=False): if (parent is not None): tempQtreewidgetitem = QTreeWidgetItem(parent) tempQtreewidgetitem.setFlags(Qt.ItemIsSelectable | Qt.ItemIsDragEnabled | Qt.ItemIsDropEnabled | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) if isSalientArtifact: tempQtreewidgetitem.setForeground( 0, QtGui.QBrush( QtGui.QColor(ProjectController.get_artifact_color()))) tempQtreewidgetitem.setText(2, content) tempQtreewidgetitem.setText(1, time) tempQtreewidgetitem.setText(0, _type) return tempQtreewidgetitem
def populate_branch(self, children=None, parent=None): artifactList = ProjectController.get_salient_artifacts_json() keypressArtifacts = [ i['artifact'] for i in artifactList if 'keypresses' in i['type'] ] clicksArtifacts = [ i['artifact'] for i in artifactList if 'clicks' in i['type'] ] auditArtifacts = [ i['artifact'] for i in artifactList if 'auditd' in i['type'] ] timedArtifacts = [ i['artifact'] for i in artifactList if 'timed' in i['type'] ] trafficArtifacts = [ i['artifact'] for i in artifactList if 'traffic' in i['type'] ] trafficThroughputArtifacts = [ i['artifact'] for i in artifactList if 'trafficThroughput' in i['type'] ] for child in children: salientArtifactFlag = False eventType = "" content = "" if "keypresses_id" in child.keys(): eventType = "keypresses_id" if "content" in child.keys(): if any(s in child['content'] for s in keypressArtifacts): salientArtifactFlag = True if "clicks_id" in child.keys(): eventType = "clicks_id" if "content" in child.keys(): if any(s in child['content'] for s in clicksArtifacts): salientArtifactFlag = True if "auditd_id" in child.keys(): eventType = "audit_id" if "content" in child.keys(): if any(s in child['content'] for s in auditArtifacts): salientArtifactFlag = True if "timed_id" in child.keys(): eventType = "timed_id" if "content" in child.keys(): if any(s in child['content'] for s in timedArtifacts): salientArtifactFlag = True #Traffic events hold no 'content' field, so they need to use alternative fields for content. if "traffic_all_id" in child.keys(): eventType = "traffic_all_id" content = child['title'].__str__() if "title" in child.keys(): if any(s in child['title'] for s in trafficArtifacts): salientArtifactFlag = True if "traffic_xy_id" in child.keys(): content = child['y'].__str__() eventType = "traffic_xy_id" if "y" in child.keys(): if any(s in child['y'] for s in trafficThroughputArtifacts): salientArtifactFlag = True if "suricata_id" in child.keys(): eventType = "suricata_id" if "content" in child.keys(): content = child['content'] newNode = self.listrelationships.add_node( eventType, child['start'], content, parent, isSalientArtifact=salientArtifactFlag)
def UI(self): self.gridLayout = QGridLayout(self) self.gridLayout.setObjectName(u"gridLayout") self.setLayout(self.gridLayout) self.setWindowIcon(QtGui.QIcon("A.png")) # A icons #Set up default values for search bars self.search_relationship_query = "" self.search_dependencies_query = "" #Search results index used to cycle through the results. self.search_dependencies_index = 0 self.search_relationships_index = 0 #Top label self.label = QLabel('Builder', self) self.label.setObjectName(u"label") self.label.setFont(QFont('MS Shell Dlg 2', 12)) self.gridLayout.addWidget(self.label, 0, 0) #Layout for left search bar. self.horizontalTopLeftLayoutWidget = QWidget(self) self.horizontalTopLeftLayoutWidget.setObjectName( u"horizontalTopLeftLayoutWidget") self.horizontalTopLeftLayout = QHBoxLayout( self.horizontalTopLeftLayoutWidget) self.horizontalTopLeftLayout.setObjectName(u"horizontalTopLayout") self.gridLayout.addWidget(self.horizontalTopLeftLayoutWidget, 1, 0) #Create left search bar self.search_relationships_lineedit = QLineEdit(self) self.search_relationships_lineedit.textChanged.connect( self.relationshipQueryChanged) self.horizontalTopLeftLayout.addWidget( self.search_relationships_lineedit, 0) self.relationship_search_button = QPushButton('Search', self) self.horizontalTopLeftLayout.addWidget(self.relationship_search_button, 1) self.relationship_search_button.clicked.connect( self.search_relationships) self.relationship_search_button.setEnabled(False) #Layout for right searchbar self.horizontalTopRightLayoutWidget = QWidget(self) self.horizontalTopRightLayoutWidget.setObjectName( u"horizontalTopRightLayoutWidget") self.horizontalTopRightLayout = QHBoxLayout( self.horizontalTopRightLayoutWidget) self.horizontalTopRightLayout.setObjectName( u"horizontalTopRightLayout") self.gridLayout.addWidget(self.horizontalTopRightLayoutWidget, 1, 3) #Create right search bar self.search_dependency_lineedit = QLineEdit(self) self.search_dependency_lineedit.textChanged.connect( self.dependencyQueryChanged) self.horizontalTopRightLayout.addWidget( self.search_dependency_lineedit, 0) self.dependency_search_button = QPushButton('Search', self) self.dependency_search_button.clicked.connect(self.search_dependency) self.horizontalTopRightLayout.addWidget(self.dependency_search_button, 1) self.dependency_search_button.setEnabled(False) #Create relationships tree holder self.listrelationships = ABSRelationshipTreeWidget() self.gridLayout.addWidget(self.listrelationships, 2, 0) #Vertical layout to hold center buttons. self.verticalCenterLayoutWidget = QWidget(self) self.verticalCenterLayoutWidget.setObjectName(u"verticalLayoutWidget") self.verticalCenterLayout = QVBoxLayout( self.verticalCenterLayoutWidget) self.verticalCenterLayout.setObjectName(u"verticalLayout") self.gridLayout.addWidget(self.verticalCenterLayoutWidget, 2, 1) #Center layout buttons. self.move_node_button = QPushButton('Move Node', self) self.verticalCenterLayout.addWidget(self.move_node_button) self.move_node_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.move_node_button.clicked.connect(self.move_node) self.move_node_button.setEnabled(False) self.move_branch_button = QPushButton('Move Branch', self) self.verticalCenterLayout.addWidget(self.move_branch_button) self.move_branch_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.move_branch_button.clicked.connect(self.move_branch) self.move_branch_button.setEnabled(False) self.move_tree_button = QPushButton('Move Tree', self) self.verticalCenterLayout.addWidget(self.move_tree_button) self.move_tree_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.move_tree_button.clicked.connect(self.copy_all_relationships) self.move_tree_button.setEnabled(False) self.properties_button = QPushButton('Node Properties', self) self.verticalCenterLayout.addWidget(self.properties_button) self.properties_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.properties_button.clicked.connect(self.openProperties) self.properties_button.setEnabled(False) self.new_node_button = QPushButton('New Node >', self) self.verticalCenterLayout.addWidget(self.new_node_button) self.new_node_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.new_node_button.clicked.connect(self.new_dependency_node) self.new_node_button.setEnabled(False) self.clearDependenciesButton = QPushButton('Clear Dependencies >', self) self.verticalCenterLayout.addWidget(self.clearDependenciesButton) self.clearDependenciesButton.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.clearDependenciesButton.clicked.connect(self.clear_dependencies) self.clearDependenciesButton.setEnabled(False) #Align center buttons to the center of the layout. self.verticalCenterLayout.setAlignment(Qt.AlignCenter) #Create tree to hold dependency information. self.listdependencies = ABSDependencyTreeWidget() self.gridLayout.addWidget(self.listdependencies, 2, 2, 1, 2) self.edit_artifacts_button = QPushButton('Edit Salient Artifacts', self) self.gridLayout.addWidget(self.edit_artifacts_button, 3, 0) self.edit_artifacts_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.edit_artifacts_button.clicked.connect(self.open_artifacts) self.edit_artifacts_button.setEnabled(False) # Generate script button self.generate_script_button = QPushButton('Generate Script', self) self.gridLayout.addWidget(self.generate_script_button, 3, 1) self.generate_script_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.generate_script_button.clicked.connect(self.generate_script) self.generate_script_button.setEnabled(False) # Load Dependencies Button self.load_button = QPushButton('Load Dependencies', self) self.gridLayout.addWidget(self.load_button, 3, 2) self.load_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.load_button.setStyleSheet("background-color: lightblue") self.load_button.clicked.connect(self.load_script) self.load_button.setEnabled(False) # Save Button self.save_button = QPushButton('Save Dependencies', self) self.gridLayout.addWidget(self.save_button, 3, 3) self.save_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.save_button.setStyleSheet("background-color: lightblue") self.save_button.clicked.connect(self.save_script) self.save_button.setEnabled(False) # Loads events when project is loaded if ProjectController.is_project_loaded(): self.populate_trees() self.save_button.setEnabled(True) self.edit_artifacts_button.setEnabled(True) self.relationship_search_button.setEnabled(True) self.dependency_search_button.setEnabled(True) self.move_tree_button.setEnabled(True) self.properties_button.setEnabled(True) self.generate_script_button.setEnabled(True) self.new_node_button.setEnabled(True) self.move_node_button.setEnabled(True) self.load_button.setEnabled(True) self.move_branch_button.setEnabled(True) self.clearDependenciesButton.setEnabled(True) if ProjectController.get_dependencies_file() != "": try: self.load_dependencies() except: pass
def populate_trees(self): eventGroups = ProjectController.load_event_list() artifactList = ProjectController.get_salient_artifacts_json() keypressArtifacts = [ i['artifact'] for i in artifactList if 'keypresses' in i['type'] ] clicksArtifacts = [ i['artifact'] for i in artifactList if 'clicks' in i['type'] ] auditArtifacts = [ i['artifact'] for i in artifactList if 'auditd' in i['type'] ] timedArtifacts = [ i['artifact'] for i in artifactList if 'timed' in i['type'] ] trafficArtifacts = [ i['artifact'] for i in artifactList if 'traffic' in i['type'] ] trafficThroughputArtifacts = [ i['artifact'] for i in artifactList if 'trafficThroughput' in i['type'] ] for group in eventGroups: if len(group) < 1: continue parent = group[0] eventType = "" content = "" salientArtifactFlag = False if "keypresses_id" in parent.keys(): eventType = "keypresses_id" if "content" in parent.keys(): if any(s in parent['content'] for s in keypressArtifacts): salientArtifactFlag = True if "clicks_id" in parent.keys(): eventType = "clicks_id" if "content" in parent.keys(): if any(s in parent['content'] for s in clicksArtifacts): salientArtifactFlag = True if "auditd_id" in parent.keys(): eventType = "audit_id" if "content" in parent.keys(): if any(s in parent['content'] for s in auditArtifacts): salientArtifactFlag = True if "timed_id" in parent.keys(): eventType = "timed_id" if "content" in parent.keys(): if any(s in parent['content'] for s in timedArtifacts): salientArtifactFlag = True #Traffic events hold no 'content' field, so they need to use alternative fields for content. if "traffic_all_id" in parent.keys(): eventType = "traffic_all_id" content = parent['title'] if "title" in parent.keys(): if any(s in parent['title'] for s in trafficArtifacts): salientArtifactFlag = True if "traffic_xy_id" in parent.keys(): content = parent['y'] eventType = "traffic_xy_id" if "y" in parent.keys(): if any(s in parent['y'] for s in trafficThroughputArtifacts): salientArtifactFlag = True if "suricata_id" in parent.keys(): eventType = "suricata_id" if "content" in parent.keys(): content = parent['content'] newNode = self.listrelationships.add_node( eventType, parent['start'], content, self.listrelationships, isSalientArtifact=salientArtifactFlag) #Recursively populate the relationship child nodes. Relationship tree is limited to 1 level. self.populate_branch(group[1:], newNode)
def __init__(self, previous_window=None): super().__init__() self.project_data = ProjectController.get_project_info() self.previous_window = previous_window self.UI() self.show()