class ReportExportDialog(QDialog, EventHandler): def __init__(self): QDialog.__init__(self, None) EventHandler.__init__(self) self.reportManager = ReportManager() self.reportManager.connection(self) self.setModal(True) self.detail = False self.items = ReportExportProgressItems() self.__optionsDialog = None self.elements = ReportExportProgress( self.tr("of elements"), ReportPageFragment.EventWriteElements, ReportPageFragment.EventWriteElementStart, ReportPageFragment.EventWriteElementFinish) self.fragments = ReportExportProgress( self.tr("of fragments"), ReportPage.EventExportFragments, ReportPageFragment.EventWriteStart, ReportPageFragment.EventWriteFinish, self.elements) self.pages = ReportExportProgress(self.tr("of pages"), ReportManager.EventExportPages, ReportPage.EventExportStart, ReportPage.EventExportFinish, self.fragments) self.category = ReportExportProgress( self.tr("of category"), ReportManager.EventExportCategories, ReportManager.EventExportCategoryStart, ReportManager.EventExportCategoryFinish, self.pages) self.progresses = [ self.category, self.pages, self.fragments, self.elements ] self.detailButton = QPushButton("<<< " + self.tr("Show details")) self.connect(self.detailButton, SIGNAL("clicked()"), self.showDetail) self.cancelButton = QPushButton("&" + self.tr("Cancel")) self.connect(self.cancelButton, SIGNAL("clicked()"), self.cancel) self.hboxLayout = QVBoxLayout(self) self.hboxLayout.addWidget(self.items.label) self.hboxLayout.addWidget(self.items.bar) for progress in self.progresses: self.hboxLayout.addWidget(progress.label) progress.label.hide() self.hboxLayout.addWidget(progress.bar) progress.bar.hide() self.hboxLayout.addWidget(self.detailButton) self.hboxLayout.addWidget(self.cancelButton) self.setLayout(self.hboxLayout) def showDetail(self): self.detail = not self.detail if self.detail: self.detailButton.setText(">>> " + self.tr("Hide details")) for progress in self.progresses: progress.bar.show() progress.label.show() else: self.detailButton.setText("<<< " + self.tr("Show details")) for progress in self.progresses: progress.bar.hide() progress.label.hide() if self.sizeHint().width() > self.size().width(): self.resize(self.sizeHint().width(), self.sizeHint().height()) else: self.resize(self.size().width(), self.sizeHint().height()) def Event(self, event): self.items.event(event) for progress in self.progresses: progress.event(event) def checkExportFreeSpace(self, exportContent): exportPath = self.reportManager.exportPath() if os.name == "nt": exportPath = exportPath[:exportPath.rfind("\\")] else: exportPath = exportPath[:exportPath.rfind("/")] freeSpace = Extract.freeSpace(exportPath) exportSize = self.reportManager.exportSize(exportContent) if freeSpace < exportSize: msg = self.tr("Not enough free space to extract files.") + '\n' msg += str(freeSpace) + self.tr(" bytes of free space for ") + str( exportSize) + self.tr(" bytes of data to extract.") + '\n' msg += self.tr("Choose an other directory ?") return QMessageBox.warning( self, self.tr("Export"), msg, QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) return QMessageBox.No def optionsDialog(self, exportContent=False): if self.__optionsDialog: return self.__optionsDialog else: self.__optionsDialog = ReportExportOptionsDialog(exportContent) return self.__optionsDialog def export(self, exportContent=True, askOptions=False, checkExportSize=True, displayInformations=True): if askOptions: self.optionsDialog(exportContent).exec_() exportContent = self.optionsDialog().exportContent() if checkExportSize: choice = self.checkExportFreeSpace(exportContent) if choice == QMessageBox.No: return self.__export(exportContent, displayInformations) elif choice == QMessageBox.Yes: self.export(exportContent, askOptions=True, checkExportSize=True, displayInformations=True) else: return self.__export(exportContent, displayInformations) def __export(self, exportContent, displayInformations=True): self.show() try: self.reportManager.export(exportContent) status = True self.accept() except Exception as e: print 'Error : Export failed ', e self.reject() status = False self.reject() if displayInformations: ReportExportInformations(self, status).exec_() return status def cancel(self): self.reportManager.exportCancel() QDialog.reject(self) def __del__(self): self.reportManager.deconnection(self)
class ReportUI(UI): def __init__(self, arguments): UI.__init__(self, arguments) self.taskManager = TaskManager() self.reportManager = ReportManager() self.registryManager = ModuleProcessusManager().get("winreg") self.evtxManager = ModuleProcessusManager().get("evtx") self.sqliteManager = ModuleProcessusManager().get('SqliteDB') self.root = vfs().getnode("/") def configureProcessing(self): self.taskManager.addPostProcessingModules(PROCESSING_MODULES) self.taskManager.addPostProcessingAnalyses(PROCESSING_ANALYSES) self.taskManager.addAnalyseDependencies() def launchProcessing(self): proc = self.taskManager.add("local", {"path": self.dumpPath}, "console") proc.event.wait() self.taskManager.join() def launch(self): self.startTime = time.time() self.dumpPath = sys.argv[1] self.reportPath = sys.argv[2] #PROCESSING self.configureProcessing() self.launchProcessing() self.searchTaggedNode() self.addProcessingTime() self.reportManager.setExportPath(self.reportPath) self.reportManager.export(exportContent=True) #SHOW EXECUTION TIME def addProcessingTime(self): totalTime = time.time() - self.startTime if totalTime > 60: totalTime = str(totalTime / 60) + " minutes" else: totalTime = str(totalTime) + " secondes" page = self.reportManager.createPage("MyAnalysis", "Stats") page.addText("Processing time ", totalTime) self.reportManager.addPage(page) def searchTaggedNode(self): f = Filter("") f.compile('tags in ["malware", "suspicious"]') f.process(self.root) malwareNodes = f.matchedNodes() if len(malwareNodes ) != 0: #if get some results we add it to the report page = self.reportManager.createPage("MyAnalysis", "Files") page.addNodeList("Malware", malwareNodes) self.reportManager.addPage(page) def searchRegistryKeys(self): regKeys = self.registryManager.getKeys( {'HKLM\Software\Microsoft\Windows NT\CurrentVersion': ['*']}, root) table = [] for key in regKeys: for value in key.values(): data = value.data() if type(data) != bytearray: table.append(( value.name, data, key.hive.absolute(), )) registryPage = iself.reportManager.createPage("MyAnalysis", "Registry") registryPage.addTable("Current version", ["name", "value", "hive path"], table) self.reportManager.addPage(registryPage) def searchSQL(self): cookiePage = reportManager.createPage("MyAnalysis", "Cookies") for db, node in sqliteManager.databases.iteritems(): sqltables = db.execute("SELECT * FROM cookies").fetchall() table = [] for row in sqltables: table.append((row[1], )) if len(table): cookiePage.addTable(node.absolute(), ["site"], table) reportManager.addPage(cookiePage) def searchEVTX(self): events = self.evtxManager.getXmlById({"id": [4624]}, "/") table = [] for event in events: try: etime = event.findall(".//TimeCreated")[0].attrib["SystemTime"] user = event.findall( ".//Data[@Name='SubjectUserName']")[0].text domain = event.findall( ".//Data[@Name='SubjectDomainName']")[0].text table.append(( etime, user, domain, )) except: pass #NODES COUNT AND STATS (type of files etc ?) #save to reload ? :) eventPage = self.reportManager.createPage("MyAnalysis", "Event") eventPage.addTable("Login", ["time", "user", "domain"], table) self.reportManager.addPage(eventPage)