def report(self, reportName, parentName): reportManager = ReportManager() reportManager.createPage(parentName, reportName)
class Software(Script): def __init__(self): Script.__init__(self, "Software") def start(self, args): try: self.root = args["root"].value() except IndexError: self.root = self.vfs.getnode('/') self.registryManager = ModuleProcessusManager().get("winreg") self.uninstalls = Uninstalls() self.MSIs = MSIs() self.ARPCaches = ARPCaches() self.autoRuns = AutoRuns() self.uninstalled() self.msi() self.arpcache() self.runs() self.report() def uninstalled(self): regKeys = self.registryManager.getKeys( { "HKLM\Software\Microsoft\Windows\Currentversion\Uninstall\*": ['*'] }, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: self.uninstalls.add(node, Uninstall(key)) regKeys = self.registryManager.getKeys( { "HKU\Software\Microsoft\Windows\Currentversion\Uninstall\*": ['*'] }, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: self.uninstalls.add(node, Uninstall(key)) regKeys = self.registryManager.getKeys( { "HKLM\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*": ['*'] }, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: self.uninstalls.add(node, Uninstall(key)) def msi(self): regKeys = self.registryManager.getKeys( { "HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\*\Products\*\InstallProperties": ['*'] }, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: values = key.values() if values: self.MSIs.add(node, MSI(key.values())) def arpcache(self): regKeys = self.registryManager.getKeys( { "HKLM\Software\Microsoft\Windows\CurrentVersion\App Management\ARPCache\*": ['*'] }, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: applicationName = key.name if applicationName[0] == '{': applicationName = self.uninstalls.find(applicationName) if applicationName: self.ARPCaches.add(node, ARPCache(applicationName)) def runs(self): self.runsPath("HKLM\Software\Microsoft\Windows\CurrentVersion\Run") self.runsPath("HKU\Software\Microsoft\Windows\CurrentVersion\Run") self.runsPath("HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce", True) self.runsPath( "HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnceEx", True) self.runsPath("HKU\Software\Microsoft\Windows\CurrentVersion\RunOnce", True) self.runsPath( "HKU\Software\Microsoft\Windows\CurrentVersion\RunOnceEx", True) def runsPath(self, path, once=False): regKeys = self.registryManager.getKeys({path: ['*']}, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: values = key.values() if values: for value in key.values(): self.autoRuns.add(node, AutoRun(value, once)) def report(self): self.reportManager = ReportManager() trSoftware = TranslateSoftware() page = self.reportManager.createPage( trSoftware.translate("Operating system") + " " + self.root.name().translate(None, "!@#$%^&'\/?"), trSoftware.translate("Software")) self.uninstalls.report(page) self.MSIs.report(page) self.ARPCaches.report(page) self.autoRuns.report(page) self.reportManager.addPage(page)
class ReportEditorTree(QTreeWidget): def __init__(self, parent): QTreeWidget.__init__(self) self.treeItemMenu = ReportTreeItemMenu(self) self.treeNewItemMenu = ReportTreeNewItemMenu(self) self.header().hide() self.connect(parent, SIGNAL("newCategory"), self.newCategory) self.connect(parent, SIGNAL("newPage"), self.newPage) self.connect(self, SIGNAL("itemClicked(QTreeWidgetItem*, int)"), self.clicked) self.thumbnailer = Thumbnailer() self.reportManager = ReportManager() self.__categoryItems = [] def categoryItem(self, categoryName): for item in self.__categoryItems: if item.category().name() == categoryName: return item item = ReportCategoryItem(self, categoryName) self.__categoryItems.append(item) return item def removeCategoryItem(self, categoryItem): try: self.__categoryItems.remove(categoryItem) except ValueError: pass def newPage(self, categoryName): categoryName = categoryName.decode( 'UTF-8' ) #Variant didn't support unicode object so must decode from str for categoryItem in self.__categoryItems: if categoryName == categoryItem.category().name(): categoryItem.refreshPage() def newCategory(self, categoryName): categoryName = categoryName.decode('UTF-8') categoryItem = self.categoryItem(categoryName) def export(self): extractDialog = ReportExportDialog() extractDialog.export(exportContent=False, askOptions=True, checkExportSize=True) def mousePressEvent(self, e): QTreeWidget.mousePressEvent(self, e) index = self.indexAt(e.pos()) if index.isValid(): item = self.itemAt(e.pos()) if e.button() == Qt.LeftButton: self.emit(SIGNAL("itemClicked"), item) elif e.button() == Qt.RightButton: self.treeItemMenu.popup(QCursor.pos()) else: if e.button() == Qt.RightButton: self.treeNewItemMenu.popup(QCursor.pos()) @pyqtSlot() def deleteDocument(self): item = self.currentItem() item.remove() item.takeChildren() parent = item.parent() if parent: parent.removeChild(item) else: self.removeCategoryItem(item) index = self.indexOfTopLevelItem(item) self.takeTopLevelItem(index) @pyqtSlot() def moveUpDocument(self): item = self.currentItem() item.moveUp() parent = item.parent() if not parent: parent = self.invisibleRootItem() index = parent.indexOfChild(item) if index != 0: parent.takeChild(index) parent.insertChild(index - 1, item) self.setCurrentItem(item) @pyqtSlot() def moveDownDocument(self): item = self.currentItem() item.moveDown() parent = item.parent() if not parent: parent = self.invisibleRootItem() index = parent.indexOfChild(item) if (index + 1) != parent.childCount(): parent.takeChild(index) parent.insertChild(index + 1, item) self.setCurrentItem(item) @pyqtSlot() def addNotes(self): noteName, ok = QInputDialog.getText(self, "New note", "Note name:", QLineEdit.Normal, "New note") if ok and noteName != "": item = self.currentItem() page = self.reportManager.createPage("Notes", unicode(noteName.toUtf8())) page.addText("Notes", "Enter your notes here ...") self.reportManager.addPage(page)
def report(self): reportManager = ReportManager() page = reportManager.createPage("Information", "Error output") data = str(self.toPlainText().toUtf8()).replace('\n', '<br>') page.addText("Output", data) reportManager.addPage(page)
def moveDown(self): ReportManager().moveCategoryAfter(self.__category)
def remove(self): ReportManager().removeCategory(self.__category)
def moveUp(self): ReportManager().moveCategoryBefore(self.__category)
class Devices(Script): def __init__(self): Script.__init__(self, "Devices") def start(self, args): try: self.root = args["root"].value() except IndexError: self.root = self.vfs.getnode("/") self.process() self.report() def process(self, root=None): self.registryManager = ModuleProcessusManager().get("winreg") if root != None: self.root = root self.devices = DevicesReg() self.mountedDevices = MountedDevices() self.volumes = Volumes() self.currentControlSet() self.enums('USBSTOR') self.enums('USBPRINT') self.enums('USB') self.enums('IDE') self.storage() self.mounted() self.mountPoints() self.correlate() def currentControlSet(self): currents = [] regKeys = self.registryManager.getKeys( {'HKLM\SYSTEM\Select': ['current']}, self.root) #last known good ? regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: for value in key.values(): self.devices.addCurrent(node, value.data()) return currents def enums(self, enumName): regKeys = self.registryManager.getKeys( { 'HKLM\SYSTEM\ControlSet*\Enum\\' + enumName + '\*\*': ['Class', 'DeviceDesc', 'FriendlyName', 'ParentIdPrefix'] }, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: self.devices.addDevice( node, Device(enumName, key.name, key.values())) def mounted(self): regKeys = self.registryManager.getKeys( {'HKLM\SYSTEM\MountedDevices': { "values": "*" }}, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: for value in key.values(): self.mountedDevices.add( node, MountedDevice(value.name, value.data().decode('utf-16'))) def storage(self): regKeys = self.registryManager.getKeys( {'HKLM\SYSTEM\ControlSet*\Enum\STORAGE\Volume\*': { "values": "*" }}, self.root) regSplit = regKeys.split() for node, keys in regSplit.iteritems(): for key in keys: self.volumes.add(node, Volume(key.name, key.values())) #for volume in self.volumes: #print volume def correlate(self): for nodeID, devices in self.devices.devices().iteritems(): for device in devices: parentIdPrefix = device.parentIdPrefix() if parentIdPrefix: mountedDevices = self.mountedDevices.findParentIdPrefix( nodeID, parentIdPrefix) if mountedDevices: for mountedDevice in mountedDevices: if mountedDevice.isMountPoint(): device.addMountPoint(mountedDevice.name()) else: users = self.searchUsersVolume( mountedDevice.volume()) device.addUsers(users) def mountPoints(self): self.__mountPointsKeys = self.registryManager.getKeys( { 'HKU\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2\*': { "values": "*" } }, self.root).split() def searchUsersVolume(self, volume): users = [] for node, keys in self.__mountPointsKeys.iteritems(): for key in keys: if volume == key.name: parent = key.parent().get_parent() for value in parent.values: if value.name == 'Logon User Name': user = value.fetch_raw_data().decode('utf-16') if not user in users: users.append((user, MS64DateTime(key.mtime))) return users def report(self): translator = DeviceTranslator() self.reportManager = ReportManager() tables = self.devices.tables() categoryName = translator.translate( "Operating system") + " " + self.root.name().translate( None, "!@#$%^&'\/?") page = self.reportManager.createPage(categoryName, translator.translate("Devices")) for (name, props, table) in tables: page.addTable(name, props, table) self.volumes.report(page) self.reportManager.addPage(page)
class Account(object): class Info(object): def __init__(self): self.__users = [] self.__groups = [] self.__accountDB = [] def addUser(self, user): self.__users.append(user) def users(self): return self.__users def addGroup(self, group): self.__groups.append(group) def groups(self): return self.__groups def addDB(self, accountDB): self.__accountDB.append(accountDB) def accountDB(self): return self.__accountDB def __init__(self): self.__accountInfo = {} def addUser(self, node, user): try: self.__accountInfo[node.uid()].addUser(user) except KeyError: self.__accountInfo[node.uid()] = Account.Info() self.__accountInfo[node.uid()].addUser(user) def addGroup(self, node, group): try: self.__accountInfo[node.uid()].addGroup(group) except KeyError: self.__accountInfo[node.uid()] = Account.Info() self.__accountInfo[node.uid()].addGroup(group) def addDB(self, node, accountDB): try: self.__accountInfo[node.uid()].addDB(accountDB) except KeyError: self.__accountInfo[node.uid()] = Account.Info() self.__accountInfo[node.uid()].addDB(accountDB) def report(self, root): self.reportManager = ReportManager() self.translator = AccountTranslator() for nodeID in self.__accountInfo.iterkeys(): node = VFS.Get().getNodeById(nodeID) info = self.__accountInfo[nodeID] categoryName = self.translator.translate( "Operating system") + " " + root.name().translate( None, "!@#$%^&'\/?") page = self.reportManager.createPage( categoryName, self.translator.translate("Users") + " (" + node.name() + ')') tableHeader = ["userName", "RID", "lastLoginDate", "logins"] headerTranslation = [] translationMap = {} translationMap.update(UserV.Translate().details()) translationMap.update(UserF.Translate().details()) for name in tableHeader: headerTranslation.append(translationMap[name]) userTable = page.addDetailTable( self.translator.translate("Accounts"), headerTranslation) for user in info.users(): tempTable = [] for attr, description in user.details().iteritems(): try: value = getattr(user, attr)() if value: tempTable.append((description, value)) except AttributeError: pass detailTable = TableFragment( self.translator.translate("Details"), [ self.translator.translate('Key'), self.translator.translate('Value') ], tempTable) userTable.addRow((user.userName(), user.RID(), user.lastLoginDate(), user.logins()), detailTable) groupTable = [] gtr = GroupC.Translate() headerTranslation = [] for m in ["name", "ID", "members"]: headerTranslation.append(gtr.translate(m)) for group in info.groups(): groupTable.append((group.name(), group.ID(), group.members())) page.addTable(gtr.translate("groups"), headerTranslation, groupTable) self.reportManager.addPage(page)
class SkypeContainers(object): ContainersType = [ 'Accounts', 'Contacts', 'Transfers', 'Messages', 'Chats', 'ChatMembers', 'Calls', 'CallMembers', 'SMSes', 'Voicemails' ] def __init__(self, node): self.translator = SkypeTranslator() self.__node = node self.__reportName = 'Skype' self.__containers = {} for each in self.ContainersType: self.__containers[each] = [] def add(self, records): for record in records: try: self.__containers[record.SkypeType + 's'].append(record) except TypeError as e: pass def findChatByName(self, chatname): for chat in self.__containers['Chats']: if chatname == chat.name(): return chat return None def findChatMemberByChatName(self, chatname): members = set() for chatMember in self.__containers['ChatMembers']: if chatname == chatMember.chatname(): members.add(chatMember.identity()) return list(members) def correlate(self): self.__chats = {} for message in self.__containers['Messages']: try: self.__chats[message.chatname()].append(message) except KeyError: self.__chats[message.chatname()] = [message] for chatname, messages in self.__chats.iteritems(): self.__chats[chatname] = sorted(messages, key=id) def report(self, name): self.__reportName += " (" + name + ")" self.__reportName = self.__reportName.translate(None, "!@#$%^&'\/?").encode( 'UTF-8', 'replace') self.reportManager = ReportManager() for containerName, container in self.__containers.iteritems(): if len(container): if containerName == 'Contacts': self.reportContacts(container) elif containerName == 'Transfers': self.reportTransfers(container) elif containerName == 'Accounts': self.reportAccount(container) elif containerName == 'SMSes': self.reportSMS(container) elif containerName == 'Voicemails': self.reportVoicemails(container) if len(self.__containers['Chats']): self.reportChats() #self.reportChatsRecovery() if len(self.__containers['Calls']): self.reportCalls() def reportChats(self): page = self.reportManager.createPage( self.__reportName, self.translator.translate("Chats")) headersDescription = self.translator.translate([ "ChatFriendlyName", "ChatMembers", "Messages", "FirstMessage", "LastMessage", "Type" ]) reportTable = page.addDetailTable(self.translator.translate("Chats"), headersDescription) if len(self.__chats): for chatname, messages in self.__chats.iteritems(): chat = self.findChatByName(chatname) if chat: chatMember = self.findChatMemberByChatName(chatname) if len(chatMember): headers = [ chat.friendlyname(), chatMember, len(messages), chat.timestamp(), chat.last_change(), chat._type() ] else: headers = [ chat.friendlyname(), chat.activemembers(), len(messages), chat.timestamp(), chat.last_change(), chat._type() ] convChat = self.createChatFragment(chat, messages) reportTable.addRow(headers, convChat) self.reportManager.addPage(page) def findChild(self, node, name): children = node.children() for child in children: if child.name().lower() == name.lower(): return child return None def reportChatsRecovery(self): for chat in self.__containers['Chats']: datnode = None try: datname = chat.dbpath() datpath = chat.dbpath()[:2] except: continue chatsync = self.findChild(self.__node.parent(), 'chatsync') if chatsync: dbpath = self.findChild(chatsync, datpath) if dbpath: datnode = self.findChild(dbpath, datname) if not datnode: continue try: chatSync = ChatSync(datnode) #for message in chatSync.messages(): #print message except: print "Can't parse ChatSync" def createChatFragment(self, chat, messages): messagesTable = [] for message in messages: messagesTable.append( [message.time(), message._from(), message.message()]) chats = [{ self.translator.translate("date"): chat.timestamp(), self.translator.translate("messages"): messagesTable }] chatname = chat.friendlyname().replace('"', '') return ChatFragment(chatname, chats) def findUniqCallMembers(self, callMembers): cms = [] for member in callMembers: flag = 1 for m in cms: if m.identity() == member.identity(): flag = 0 continue if flag: cms.append(member) return cms def findCallMemberByName(self, callName): cms = [] for callMember in self.__containers['CallMembers']: if callMember.call_name() == callName: cms.append(callMember) cms = self.findUniqCallMembers(cms) return cms def reportCalls(self): page = self.reportManager.createPage( self.__reportName, self.translator.translate("Calls")) headersDescription = self.translator.translate( ["Members", "begin_timestamp", "is_incoming"]) reportTable = page.addDetailTable(self.translator.translate("Calls"), headersDescription) details = [] for call in self.__containers['Calls']: callMembers = self.findCallMemberByName(call.name()) memberName = [] if callMembers: for member in callMembers: memberName.append(member.dispname()) headerTable = [ memberName, call.begin_timestamp(), call.is_incoming() ] detailsTable = None if callMembers: tempTable = [] for member in callMembers: tempTable.append( (member.identity(), member.dispname(), member.start_timestamp(), member.call_duration()), ) detailsHeaders = self.translator.translate([ "identity", "dispname", "start_timestamp", "call_duration" ]) detailsTable = TableFragment( self.translator.translate("Details"), detailsHeaders, tempTable) reportTable.addRow(headerTable, detailsTable) self.reportManager.addPage(page) def reportSMS(self, container): page = self.reportManager.createPage( self.__reportName, self.translator.translate("SMS(s)")) table = [] for sms in container: row = (sms.target_numbers(), sms.timestamp(), sms.body()) if row != (None, None, None): table.append(row) if len(table): page.addTable( self.translator.translate('SMS'), self.translator.translate( ['target_numbers', 'timestamp', 'body']), table) self.reportManager.addPage(page) def reportAccount(self, container): page = self.reportManager.createPage( self.__reportName, self.translator.translate("Account")) for account in container: table = [ (self.translator.translate('fullname'), account.fullname()), (self.translator.translate('skypename'), account.skypename()), (self.translator.translate('mood'), account.mood()), (self.translator.translate('emails'), account.emails()), (self.translator.translate('profileTimestamp'), account.profileTimestamp()), (self.translator.translate('country'), account.country()), (self.translator.translate('languages'), account.languages()), (self.translator.translate('balance'), account.balance()) ] accountName = account.emails() if accountName == None: accountName = self.translator.translate('Unknown') page.addTable(accountName, self.translator.translate(['Description', 'Value']), table) self.reportManager.addPage(page) def reportVoicemails(self, container): pageName = self.translator.translate("VoiceMails") headers = ['partner_dispname', 'timestamp', 'duration'] headersDescription = self.translator.translate(headers) details = ['partner_handle', 'size', 'path'] detailsTranslation = self.translator.translate(details) self.reportDetailsTable(pageName, container, headers, headersDescription, details, detailsTranslation, None) def reportContacts(self, container): pageName = self.translator.translate('Contacts') headers = 'displayname', 'phone', 'country', 'languages' headersDescription = self.translator.translate(headers) details = [ 'displayname', 'skypename', 'fullname', 'birthday', 'gender', 'country', 'languages', 'province', 'city', 'pstnnumber', 'phone_home', 'phone_office', 'emails', 'profile_timestamp', 'about', 'timezone', 'rich_mood_text', 'last_used_network_time' ] detailsTranslation = self.translator.translate(details) self.reportDetailsTable(pageName, container, headers, headersDescription, details, detailsTranslation, ( 'skypename', 'avatar_image', )) def reportTransfers(self, container): pageName = self.translator.translate('Transfers') headers = 'partner_dispname', 'type', 'filename', 'filesize' headersDescription = self.translator.translate(headers) details = [ 'partner_handle', 'starttime', 'endtime', 'transferduration', 'status', 'filepath', 'bytestransferred', 'extprop_localfilename', ] detailsTranslation = self.translator.translate(details) self.reportDetailsTable(pageName, container, headers, headersDescription, details, detailsTranslation) def reportDetailsTable(self, pageName, container, headers, headersDescription, details, detailsTranslation, thumb=None): page = self.reportManager.createPage(self.__reportName, pageName) reportTable = page.addDetailTable(pageName, headersDescription) for record in container: headersTable = () flag = None for header in headers: res = getattr(record, header)() if res != None: flag = 1 headersTable += (res, ) if not flag: continue tempTable = [] for idx in range(len(details)): try: res = getattr(record, details[idx])() if res: tempTable.append(( detailsTranslation[idx], res, )) except: pass thumbData = None if thumb: thumbData = () for f in thumb: try: res = getattr(record, f)() if res: thumbData += (res, ) except Exception as e: pass if len(thumbData) != len(thumb): thumbData = None detailsTable = TableFragment( self.translator.translate("Details"), self.translator.translate(['Description', "Value"]), tempTable) reportTable.addRow(headersTable, detailsTable, thumbData) self.reportManager.addPage(page)
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)