def __init__(self, _base, _vtapi, _password=Vault.DefaultArchivePassword, _saveFileNoDetection=False, _allowMultipleSamples=False, _logger=None): """Initializes the engine, including the logger, vault and other class variables. Creates a default logger if none provided. The constructor also creates the data sources required to identify malware. Finally it will create a Vault object with the given base parameter. Args: _base: The directory in which the filesystem of the vault will be created. _vtapi: The public API key used to make requests to VirusTotal. _password: Password to use on archive creation. _saveFileNoDetection: Specified whether analyzed files undetected by no AV software should be saved in the archive. _logger: Logger object to output information about program execution. If none provided, it will use sys.stdout by default. Returns: None. Raises: None. """ #************************************************************************** # Creates a new logger object. #************************************************************************** if _logger == None: self.logger = Logger(sys.stdout) else: self.logger = _logger #************************************************************************** # Initializes an empty dictionary of data sources, # adds the VirusTotal data source object to it. #************************************************************************** self.data_sources = {} self.data_sources[DS_VIRUS_TOTAL] = VirusTotalSource( _vtapi, _logger=self.logger) #************************************************************************** # Initializes a new vault object with the # given base directory. #************************************************************************** self.vxvault = Vault(_base, _logger=self.logger, _multipleSamplesAllowed=_allowMultipleSamples) self.saveUndetectedFiles = _saveFileNoDetection self.active_hunters = [] self.hunt_is_on = False
def __init__(self, directory): import pyre.filesystem rep = pyre.filesystem.root(directory) Vault.__init__(self, rep) return
def _tablebtnSave(self): self.filename = self.saveFileDialog() + '.txt' self.password = self.tbox_pass.text() self.myVault = Vault(self.password, self.filename) dataReady = self.convertData_2_bytes() self.myVault.encrypt(dataReady) os.chmod(self.filename, S_IREAD)
def _getPass(self, thepass): print('New pass:'******'' for i, account in enumerate(tempList): dataReady += f',{account.service},{account.ID},{account.PASS}' dataReady = str.encode(dataReady[1:]) print(dataReady) del self._myVault self._myVault = Vault(thepass, self._filename) self._myVault.encrypt(dataReady) print("Password was changed successfully")
def deserialize(vault_dict): """ Deserializes dict to vault :param vault_dict: dictionary from database :return: Vault """ new_vault = Vault() vault_x = vault_dict[Constants.JSON_VAULT_X] vault_y = vault_dict[Constants.JSON_VAULT_Y] for i, _ in enumerate(vault_x): new_vault.add_vault_element(VaultElement(vault_x[i], vault_y[i])) return new_vault
def assignData2Table(self): del self._myVault self._myVault = Vault(self._password, self._filename) # create the vault a, check, checkPass = self._myVault.extractAccount() if checkPass == False: #print("Plase enter diff password") self.lbl_errorMsg.setText( "<font color='red'>Please try a diff password</font>") else: #print(len(self._myVault)) if check == True: #Enbale some btn if the file is open successfully self.lbl_errorMsg.setText('') self.tablebtnAdd.setDisabled(False) self.tablebtnSave.setDisabled(False) self.tablebtnDelete.setDisabled(False) self.tablebtnChangePassword.setDisabled(False) self.btn_unclock.setDisabled(True) for idx, item in enumerate(self._myVault.listAccount): #print(idx) self.table.insertRow(self.table.rowCount()) newRowidx = self.table.rowCount() - 1 checkBox, iViewPass = self.widgetInsideTable() self.table.setItem(newRowidx, 0, QTableWidgetItem(item.service)) self.table.setItem(newRowidx, 1, QTableWidgetItem(item.ID)) self.table.setCellWidget(newRowidx, 2, QLineEdit(item.PASS)) self.table.setItem(newRowidx, 3, iViewPass) self.table.setItem(newRowidx, 4, checkBox) self.countTable.append(True) self.countCheckbox.append(False) self.table.cellWidget(newRowidx, 2).setEchoMode(2) #print(self.table.item(1,3).sizeHint().height()) else: #print("Print a message box : error the invalid file") del self._myVault self._myVault = '' self.lbl_errorMsg.setText( "<font color='red'>the file which is invaild, is not the format of password vault app</font>" ) self.table.resizeColumnsToContents()
def __init__(self, _base, _vtapi, _password=Vault.DefaultArchivePassword, _saveFileNoDetection=False, _allowMultipleSamples=False, _logger=None): """Initializes the engine, including the logger, vault and other class variables. Creates a default logger if none provided. The constructor also creates the data sources required to identify malware. Finally it will create a Vault object with the given base parameter. Args: _base: The directory in which the filesystem of the vault will be created. _vtapi: The public API key used to make requests to VirusTotal. _password: Password to use on archive creation. _saveFileNoDetection: Specified whether analyzed files undetected by no AV software should be saved in the archive. _logger: Logger object to output information about program execution. If none provided, it will use sys.stdout by default. Returns: None. Raises: None. """ #************************************************************************** # Creates a new logger object. #************************************************************************** if _logger == None: self.logger = Logger(sys.stdout) else: self.logger = _logger #************************************************************************** # Initializes an empty dictionary of data sources, # adds the VirusTotal data source object to it. #************************************************************************** self.data_sources = {} self.data_sources[DS_VIRUS_TOTAL] = VirusTotalSource( _vtapi, _logger=self.logger) #************************************************************************** # Initializes a new vault object with the # given base directory. #************************************************************************** self.vxvault = Vault(_base, _logger=self.logger, _multipleSamplesAllowed = _allowMultipleSamples) self.saveUndetectedFiles = _saveFileNoDetection self.active_hunters = [] self.hunt_is_on = False
def __init__(self, branch_name, cardinality, siblings_vault, attr_vault=None): self._Name = branch_name + "/%d" % (cardinality, ) self._Cardinality = cardinality self._DataVault = siblings_vault self._AttrVault = attr_vault or Vault(siblings_vault.SizeArray)
def __init__( self, rginfo, column_to_branch, raw_stroll, tagged_event_ids, ): self.RGInfo = rginfo #self.RGID = rginfo.RGID self.NEvents = rginfo.NEvents #print "Frame: created for rgid=%d, nevents=%d" % (rginfo.RGID, rginfo.NEvents) self.AttrVault = Vault() self.VarAttrVaults = {} self.BranchVaults = {} # name -> branch vault for cn, (bn, sc) in column_to_branch.items(): if bn: prefix = bn + '.' assert cn.startswith(prefix) aname = cn[len(prefix):] if sc != bn + ".@size": raise NotImplementedError( "Variable length branch attributes not implemented yet" ) size = raw_stroll[bn + ".@size"] #print "Frame: Size array for branch %s: %s" % (bn, size) v = self.BranchVaults.get(bn) if v is None: v = Vault(size) self.BranchVaults[bn] = v try: v.addStripe(aname, raw_stroll[cn]) except: info = traceback.format_exc() message = "Exception in VaultaddStripe: \n%s\nRGInfo: %s\nAttribute name: %s, column name: %s" % ( info, rginfo, aname, cn) raise RuntimeError(message) else: #print "Frame: size column for %s: %s" % (cn, sc) if sc: #print "Frame: var attr %s size array:%s" % (cn, raw_stroll[sc]) v = Vault(raw_stroll[sc]) # attributes with variable size self.VarAttrVaults[cn] = v else: v = self.AttrVault v.addStripe(cn, raw_stroll[cn])
def dashboard(self): from Vault import Vault auth_code = self.request.get("code") user = User().get(code=auth_code)[0] vault_entries = Vault().get(email=user.email) a = [] for vault_entry in vault_entries: a.append(Vault.get_json_object(vault_entry)) template_variables = { "first_name": user.first_name.lower().title(), "send_req_url": "/".join(self.request.url.split('/')[:-2]) + "/vault/generate?code=" + auth_code + "&file_name=myfile.pdf&[email protected]", "vault_entries": a } page = utils.template("User-dashboard.html") self.response.out.write(template.render(page, template_variables))
class PasswordVault_newAccount(QWidget): _dirIcon = os.getcwd() + '/Icon/' _dirBackup = os.getcwd() + '/Backup/' def __init__(self): super(PasswordVault_newAccount, self).__init__() self.myVault = '' self.filename = '' # a fill directory self.password = '' self.viewpass = False self.countViewpassword = [] self.countCheckbox = [] self.countCheckboxAll = False self.table = QTableWidget() self.vlayout = QVBoxLayout() self.move(550, 400) self.setWindowTitle("New account for password vault") self.drawTable() self.events() self.show() def events(self): # Table events self.tablebtnAdd.clicked.connect(self._tablebtnAdd) self.tablebtnDelete.clicked.connect(self._tablebtnDelete) self.tablebtnSave.clicked.connect(self._tablebtnSave) self.table.cellClicked.connect(self._cellCLicked) self.btn_viewpass.clicked.connect(self._viewPass) self.tablebtnSave.installEventFilter(self) self.tbox_pass.installEventFilter(self) #self.tablebtnChangePassword.clicked.connect(self._tableChangepass) #self.table.itemSelectionChanged.connect(self._tableEditTable) def drawTable(self): #check=True height = self.frameGeometry().height() width = self.table.frameGeometry().width() fontBold = QFont() fontBold.setBold(True) self.tablebtnSave = QPushButton("Save") self.tablebtnDelete = QPushButton('-') self.tablebtnAdd = QPushButton('+') sizeHint_height = self.tablebtnAdd.sizeHint().height() self.size = sizeHint_height print(self.size) self.lbl_pass = QLabel("Password:"******"ID")) self.table.setItem(0, 2, QTableWidgetItem('Password')) self.table.setItem(0, 3, QTableWidgetItem('')) self.table.setItem(0, 4, QTableWidgetItem('')) for i in range(0, 5): #print(i) self.table.item(0, i).setFont(fontBold) self.table.item(0, i).setFlags(Qt.ItemIsEnabled) # import data to the table #==== UPDATA the PasswordVault Layout self.table.resizeColumnsToContents() self.vlayout.addWidget(self.table) self.vlayout.addLayout(hboxTable) self.setLayout(self.vlayout) #rint(width,height) #self.table.setFocusPolicy(Qt.NoFocus) self._tablebtnAdd() self.resize(width - (width * 0.2), height - (height * 0.3)) def widgetInsideTable(self): # ===== Button view pass inside table ===== # viewPassbtn=QPushButton() # viewPassbtn.setFixedHeight(self.size_of_btn) # viewPassbtn.setFixedWidth(self.size_of_btn) # viewPassbtn.setIcon(QIcon(self._dirIcon+'icons8-eye-1.png')) # ====== CheckBox ====== checkBox = QTableWidgetItem() checkBox.setIcon(QIcon(self._dirIcon + 'icons8-checkbox-0.png')) checkBox.setFlags(Qt.ItemIsEnabled) ItemViewPass = QTableWidgetItem() ItemViewPass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) ItemViewPass.setFlags(Qt.ItemIsEnabled) self.table.setIconSize(QSize(self.size, self.size)) return checkBox, ItemViewPass def eventFilter(self, ob, event): #print(event.type()) if ob is self.tablebtnSave and event.type() == 129: #print (ob, event.type()) if self.tbox_pass.text() == '': self.tbox_pass.setText("Enter your pass word") self.tbox_pass.setStyleSheet("color: red") self.tbox_pass.setEchoMode(0) self.viewpass = True self.btn_viewpass.setIcon( QIcon(self._dirIcon + 'icons8-eye-0.png')) self.tablebtnSave.setDisabled(True) elif ob is self.tbox_pass and event.type() == 2: self.tbox_pass.setText('') self.tbox_pass.setEchoMode(2) self.viewpass = False self.btn_viewpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) self.tablebtnSave.setDisabled(False) self.tbox_pass.setStyleSheet("color: black") return False def saveFileDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, a = QFileDialog.getSaveFileName( self, "QFileDialog.getSaveFileName()", "", "Text Files (*.txt)", options=options) #print(a) if fileName: return fileName def convertData_2_bytes(self): # this function is user before encrypt data noRow = self.table.rowCount() data = '' for i in range(1, noRow): #print(len(self._listAccount)) Service = self.table.item(i, 0).text() ID = self.table.item(i, 1).text() PASS = self.table.cellWidget(i, 2).text() data += f',{Service},{ID},{PASS}' data = str.encode(data[1:]) return data @pyqtSlot() def _viewPass(self): self.viewpass = not self.viewpass if self.viewpass == True: self.tbox_pass.setEchoMode(0) self.btn_viewpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-0.png')) #print ("echo 0") else: self.tbox_pass.setEchoMode(2) self.btn_viewpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) def _tablebtnAdd( self ): # when a new row added a new account created coreponding to the row nomber #print(self.table.rowCount()) checkBox, iViewPass = self.widgetInsideTable() self.table.insertRow(self.table.rowCount()) newRowidx = self.table.rowCount() - 1 # setup new row self.table.setItem(newRowidx, 0, QTableWidgetItem(' new service')) self.table.setItem(newRowidx, 1, QTableWidgetItem(' new ID ')) self.table.setCellWidget(newRowidx, 2, QLineEdit('type pass')) self.table.setItem(newRowidx, 3, iViewPass) self.table.setItem(newRowidx, 4, checkBox) #self.table.item(newRowidx,3).setIcon(QIcon(self._dirIcon+'icons8-eye-0.png')) self.table.cellWidget(newRowidx, 2).setEchoMode(2) self.countViewpassword.append(True) self.countCheckbox.append(False) self.table.resizeColumnsToContents() def _tablebtnDelete(self): #print(self.countCheckbox) #print(len(self.countCheckbox)) idx = 0 out = True while idx < len(self.countCheckbox): checkBox = self.countCheckbox[idx] if checkBox == True: self.table.removeRow(idx + 1) self.countCheckbox.remove(self.countCheckbox[idx]) idx = -1 idx += 1 #.statusBar.showMessage(f'A row at {self.currentRow-2} was delete') #print(self.countCheckbox) def _tablebtnSave(self): self.filename = self.saveFileDialog() + '.txt' self.password = self.tbox_pass.text() self.myVault = Vault(self.password, self.filename) dataReady = self.convertData_2_bytes() self.myVault.encrypt(dataReady) os.chmod(self.filename, S_IREAD) def _cellCLicked(self, row, column): ## cellClicked for view password if column == 3 and row > 0: self.countViewpassword[row - 1] = not self.countViewpassword[row - 1] if self.countViewpassword[row - 1] == False: self.table.cellWidget(row, 2).setEchoMode(0) self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-eye-0.png')) else: self.table.cellWidget(row, 2).setEchoMode(2) self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-eye-1.png')) ## cellClicked for cehckbox elif column == 4 and row > 0: #print (self.countCheckbox[row-1]) self.countCheckbox[row - 1] = not self.countCheckbox[row - 1] # print('clicked',row, column,self.countCheckbox[row-1]) if self.countCheckbox[row - 1] == True: self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-1.png')) else: self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-0.png')) #print(self.countCheckbox) elif row == 0 and column == 4: self.countCheckboxAll = not self.countCheckboxAll for i in range(1, self.table.rowCount()): if self.countCheckboxAll == True: self.countCheckbox[i - 1] = True self.table.item(i, 4).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-1.png')) else: self.countCheckbox[i - 1] = False self.table.item(i, 4).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-0.png')) self.table.resizeColumnsToContents() # if __name__ == "__main__": # app = QApplication(sys.argv) # w=PasswordVault_newAccount() # try: # sys.exit(app.exec_()) # except: # pass
def generate_vault(xyt_input_path, minutiae_points_amount, chaff_points_amount, poly_degree, secret, crc_length, gf_exp, log_dict, echo=False): # extract minutiae from template nbis_minutiae_extractor = MinutiaeExtractor() minutiae_list = nbis_minutiae_extractor.extract_minutiae_from_xyt(xyt_input_path) if len(minutiae_list) < minutiae_points_amount: if echo: print('Not enough minutiae in template to proceed for generation of vault...') log_dict['too_few_minutiae_gallery'] = True return None vault = Vault() m2b = MinutiaConverter() # Cut low quality minutiae and convert all minutiae to uint and add to vault genuine_minutiae_list = [] for candidate in minutiae_list: if len(genuine_minutiae_list) == minutiae_points_amount: break too_close = False for minutia in genuine_minutiae_list: if candidate.distance_to(minutia) <= POINTS_DISTANCE: too_close = True break if not too_close: genuine_minutiae_list.append(candidate) for minutia in genuine_minutiae_list: vault.add_minutia_rep(m2b.get_uint_from_minutia(minutia)) # create chaff points and add to vault chaff_points_list = ChaffPointsGenerator.generate_chaff_points_randomly(chaff_points_amount, genuine_minutiae_list, vault.get_smallest_original_minutia(), m2b) for chaff_point in chaff_points_list: vault.add_chaff_point_rep(m2b.get_uint_from_minutia(chaff_point)) # generate secret polynomial secret_poly_generator = PolynomialGenerator(secret, poly_degree, crc_length, gf_exp) if echo: print('Coefficients of secret polynomial: {}'.format(secret_poly_generator.coefficients)) # evaluate polynomial at all vault minutiae points (not at chaff points) vault.evaluate_polynomial_on_minutiae(secret_poly_generator, echo=echo) # generate random evaluation for chaff points vault.evaluate_random_on_chaff_points(secret_poly_generator, gf_exp) # finalize vault (delete information on vault creation except vault_final_elements_pairs) vault.finalize_vault() return vault
class Engine(object): #****************************************************************************** # Class Static Variables # DefaultDataSource = DS_VIRUS_TOTAL # # URL to use for testing Interner connectivity. UrlTestInternet = "https://www.google.com/" # #****************************************************************************** def __init__(self, _base, _vtapi, _password=Vault.DefaultArchivePassword, _saveFileNoDetection=False, _allowMultipleSamples=False, _logger=None): """Initializes the engine, including the logger, vault and other class variables. Creates a default logger if none provided. The constructor also creates the data sources required to identify malware. Finally it will create a Vault object with the given base parameter. Args: _base: The directory in which the filesystem of the vault will be created. _vtapi: The public API key used to make requests to VirusTotal. _password: Password to use on archive creation. _saveFileNoDetection: Specified whether analyzed files undetected by no AV software should be saved in the archive. _logger: Logger object to output information about program execution. If none provided, it will use sys.stdout by default. Returns: None. Raises: None. """ #************************************************************************** # Creates a new logger object. #************************************************************************** if _logger == None: self.logger = Logger(sys.stdout) else: self.logger = _logger #************************************************************************** # Initializes an empty dictionary of data sources, # adds the VirusTotal data source object to it. #************************************************************************** self.data_sources = {} self.data_sources[DS_VIRUS_TOTAL] = VirusTotalSource( _vtapi, _logger=self.logger) #************************************************************************** # Initializes a new vault object with the # given base directory. #************************************************************************** self.vxvault = Vault(_base, _logger=self.logger, _multipleSamplesAllowed=_allowMultipleSamples) self.saveUndetectedFiles = _saveFileNoDetection self.active_hunters = [] self.hunt_is_on = False def __str__(self): return "<Engine>" def __repr__(self): return "<VxVault Engine {:s}>".format(__version__) def is_windows(self): """Verifies if the current underlying operating system is Windows-based. This function verifies if the current underlying operating system is Windows-based. Args: None. Returns: True if the program is running on a Windows platform, False otherwise. Raises: None. """ return ("win" in platform.system().lower()) def set_archiver(self, _archiver): """Sets the Archiver object to be used by the vault. This function will sets the Archiver to be used by the Vault to archive and compress malware into the filesystem. Args: Archiver object. Returns: None. Raises: None. """ if (_archiver): self.vxvault.set_archiver(_archiver) else: raise FileNotFoundException(_program) def get_archiver(self): """Returns the Archiver object currently used by the vault. This function will return the Archiver object currently used by the Vault to archive and compress malware into the filesystem. Args: None. Returns: Archiver object. Raises: None. """ return self.archiver def create_vault(self): """Creates a new file system. This function will create the file system at the base specified at the creation of the engine. it will also initialize the vault. Args: None. Returns: None Raises: Exception if there was an error while creating the file system. """ self.vxvault.create_vault() def vault_is_created(self): """Verifies if the vault has been created at the base directory. This function will confirm if the vault has been created on the file system. Args: None. Returns: True if the vault has been created in the configured base directory provided at the creation of the engine. Returns False otherwise. Raises: None. """ return self.vxvault.is_created() def get_vault(self): """ Returns the vault object used by the engine. Args: None. Returns: Vault object associated with the engine. Raises: None. """ return self.vxvault def can_connect_internet(self): """Verifies if a connection to the Internet is available. this function verifies if a connection to the Internet is available by attempting to connect to the website specified in Engine.UrlTestInternet. Args: None. Returns: True if the function was able to successfully connect to the specified website. Raises: Exception if an error occured while connecting to the site. """ self.logger.print_debug("Attempting to connect to '{:s}'.".format( self.UrlTestInternet)) request = urllib2.Request(self.UrlTestInternet) try: response = urllib2.urlopen(request) html = response.read() self.logger.print_debug(INFO_CONNECTED_INTERNET) return True except Exception as e: self.logger.print_debug(ERR_FAILED_CONNECT_NET.format(e.message)) return False def add_http_file_virus(self, _url): """ Downloads a file at the specified URL into the pit directory of the vault and analyzes it prior to storing it in the vault. This function will download a file specified by a HTTP/HTTPS URL and save it to the "pit" directory. It will then proceed into retrieving scan information for the downloaded file and archive it into the vault. TODO: [X] Test this function. Args: _url: The URL of the file to download. Must start with HTTP. Returns: None. Raises: InvalidUrlException: If the provided URL is invalid. NullOrEmptyArgumentException: if the URL or destination path is empty or null. FileDownloadException: If the function failed to create the local file. """ if (_url and len(_url.strip()) > 0): url = _url.strip() #****************************************************************** # Verifies if the URL provided is valid #****************************************************************** if (url[0:4].lower() == "http"): #****************************************************************** # Build the destination path of the file. #****************************************************************** dst_path = self.vxvault.get_pit() dst_file = url.split("/")[-1].strip() dst_file = self.replace_chars_in_string( dst_file, UNALLOWED_CHARS_FILES, DEFAULT_REPLACE_CHAR) dst = os.path.join(dst_path, dst_file) if (os.path.exists(dst)): raise FileExistsException(dst) self.download_file(url, dst) #****************************************************************** # Analyze the file downloaded after making sure it exists. #****************************************************************** if (os.path.exists(dst)): self.add_single_file_virus(dst) else: raise FileDownloadException() else: raise InvalidUrlException(url) else: raise NullOrEmptyArgumentException() def add_files_from_urls(self, _files): """ """ if (_files and len(_files) > 0): hunter = LocalHunter(_engine=self, _files=_files, _extensions=Hunter.HuntedExtensions, _logger=self.logger) urls = hunter.get_urls_from_files(_files) if (len(urls) > 0): for url in urls: self.add_http_file_virus(url) else: raise NoUrlFoundException() else: raise NullOrEmptyArgumentException() def replace_chars_in_string(self, _string, _chars, _replace): """ Replaces characters in the given string by a user-defined string. This functions will replace each instance of the characters specified in the _chars string found inthe _string argument with the characters specified in the _replace argument. Args: _string: String containing chars to be replaced _chars: String or array of characters to replaced. _replace: String or character used as replacement. Returns: None. Raises: None. """ new_string = _string for char in _chars: if char in _string: new_string = new_string.replace(char, _replace) return new_string def download_file(self, _url, _dst): """ Downloads a file at the specified URL into the local filesystem. This function will download a file specified by a HTTP/HTTPS URL and save it to the specified destination. Args: _url: The URL of the file to download. Must start with HTTP. _dst: Absolute path of the destination on the local file system. Returns: None. Raises: InvalidUrlException: If the provided URL is invalid. NullOrEmptyArgumentException: if the URL or destination path is empty or null. FileDownloadException: If the function failed to create the local file. """ url = urllib.unquote(_url.strip()) if (url and len(url) > 0): #****************************************************************** # Verifies if the URL provided is HTTP # Todo: # [ ] Better URL validation function. #****************************************************************** if (url[0:4].lower() == "http"): self.logger.print_info(MSG_INFO_DOWNLOADING.format(_dst, url)) try: urllib.urlretrieve(url, _dst) except Exception as e: raise FileDownloadException("{:s}: {:s}".format( _dst, e.message)) else: raise InvalidUrlException(url) else: raise NullOrEmptyArgumentException() def add_single_file_virus(self, _file): """ Adds a single file from the local system to the vault. This function will add a single file to the vault. It will analyze the file and attempt to identify it as a malware. Once completed, it will archive the file in a 7zip archive and move it into the vault based on the class and target OS. This function will remove the original file from the source. Args: _file: The file to archive into the vault. Returns: None. Raises: Exception if provided file argument is null or empty. Will raise exception if the file cannot be found, or cannot connect to the Internet. Will also raise an exception if Analysis fails or archiving fails. """ #********************************************************************** # Verifies if the provided argument is valid. #********************************************************************** if (_file and len(_file) > 0): #****************************************************************** # Checks if the file exists. #****************************************************************** if (os.path.exists(_file)): #************************************************************** # Confirm if the file is not already stored in the vault #************************************************************** is_stored = self.file_is_archived(_file) if (is_stored): raise ArchiveExistsException(_file) #************************************************************** # Attempts to extract malware identification of # the given file. #************************************************************** datasrc = self.data_sources[DS_VIRUS_TOTAL] analyzer = Analyzer(_vxdata=datasrc, _vault=self.vxvault, _logger=self.logger) vx = analyzer.analyze_file(_file) if (vx): if (vx.is_detected() or (vx.is_undetected and self.saveUndetectedFiles)): #****************************************************** # Archives the file into the fault. #****************************************************** self.vxvault.archive_file(vx) else: self.logger.print_warning( WARN_IGNORE_FILE.format(vx.get_file())) else: raise FileNotFoundException(_file) else: raise NullOrEmptyArgumentException() def add_single_dir_virus(self, _dir): """ Add a malware containing multiple files contained in a single directory. This function accepts a directory containing files of the same malware, bundles it into an archive and move it to the vault. Args: _dir: The directory containing the files of the malware. Returns: None. Raises: Exception if provided argument is null. Other exceptions on error retrieving data from the internet, directory not found, moving file to the vault or creating a new entry in the database. """ #********************************************************************** # Verifies if the provided argument is valid. #********************************************************************** if (_dir and len(_dir) > 0): #****************************************************************** # Checks if the file exists. #****************************************************************** if (os.path.isdir(_dir)): #************************************************************** # Check if the directory contains files #************************************************************** nb_files = len(os.listdir(_dir)) if (nb_files == 0): raise Exception( "Directory '{:s}' contains no file.".format(_dir)) #************************************************************** # Attempts to extract malware identification of # the given file. #************************************************************** datasrc = self.data_sources[DS_VIRUS_TOTAL] analyzer = Analyzer(_vxdata=datasrc, _vault=self.vxvault, _logger=self.logger) vx = analyzer.analyze_dir(_dir) if (vx): #********************************************************** # Archives the file into the fault. #********************************************************** self.vxvault.archive_file(vx) else: raise FileNotFoundException(_dir) else: raise NullOrEmptyArgumentException() def add_multiple_virii_from_dir(self, _dir): """ Adds all files in the specified directory and subdirectories as individual malware. This function lists all files and subdirectories in the user-provided directory and adds each individual file to the vault as a individual malware. Subdirectories are considered as a single malware. All files in the subdirectory are considered part of the same malware. Args: _dir: The directory containing the malware Returns: None Raises: Exception on failure to find the directory, or if directory is empty. Exception if fail to analyze, store file into the vault or record the file into the database. """ #********************************************************************** # Verifies if the provided argument is valid. #********************************************************************** if (_dir and len(_dir) > 0): #****************************************************************** # Checks if the file exists. #****************************************************************** if (os.path.isdir(_dir)): #************************************************************** # Check if the directory contains files #************************************************************** nb_files = len(os.listdir(_dir)) if (nb_files == 0): raise Exception( "Directory '{:s}' contains no file.".format(_dir)) datasrc = self.data_sources[DS_VIRUS_TOTAL] analyzer = Analyzer(_vxdata=datasrc, _vault=self.vxvault, _logger=self.logger) for root, dirs, files in os.walk(_dir): for name in files: vx_file = os.path.join(root, name) #****************************************************** # Confirm if the file is not already stored in the # vault #****************************************************** is_stored = self.file_is_archived(vx_file) if (is_stored): raise Exception( ERR_FILE_ALREADY_EXISTS.format(_file)) self.logger.print_debug( "Adding file '{:s}'...".format(vx_file)) vx = analyzer.analyze_file(vx_file) if (vx): #****************************************************** # Archives the file into the fault. #****************************************************** self.vxvault.archive_file(vx) #********************************************************** # Verifies if we are allowed to make a new request to # the data source. #********************************************************** next_run = datasrc.get_next_allowed_request() self.logger.print_debug( MSG_INFO_NEXT_RUN.format(next_run)) while (datetime.now() < next_run): time.sleep(3) for dir in dirs: vx_dir = os.path.join(root, dir) #************************************************************** # Check if the directory contains files #************************************************************** nb_files = len(os.listdir(vx_dir)) if (nb_files == 0): raise Exception( "Directory '{:s}' contains no file.".format( vx_dir)) vx = analyzer.analyze_dir(vx_dir) if (vx): #********************************************************** # Archives the file into the fault. #********************************************************** self.vxvault.archive_file(vx) #********************************************************** # Verifies if we are allowed to make a new request to # the data source. #********************************************************** next_run = datasrc.get_next_allowed_request() self.logger.print_debug( MSG_INFO_NEXT_RUN.format(next_run)) while (datetime.now() < next_run): time.sleep(3) else: raise FileNotFoundException(_dir) else: raise NullOrEmptyArgumentException() def start_malware_hunt(self): """ Starts the hunting threads. This function will create threads for each type of hunter available and start it. Each thread will then start downloading and analyzing files found on their individual sources. Malc0de: The malc0de hunter looks for new malware links on the malc0de website. Local: The local hunter will look for files in the ./pit/urls directory located in the vault. It will look within each file for URLs to files with extensions listed in Hunter.HuntedExtensions. Args: None. Returns: None. Raises: Multiple exceptions if downloading, archiving or recording fails. """ hunt_malcode = MalcodeHunter(_engine=self, _logger=self.logger) hunt_mdl = MdlHunter(_engine=self, _logger=self.logger) hunt_local = LocalHunter( _engine=self, _files=[self.vxvault.file_system.get_urls_dump()], _extensions=Hunter.HuntedExtensions, _logger=self.logger) self.active_hunters.append(hunt_malcode) self.active_hunters.append(hunt_mdl) self.active_hunters.append(hunt_local) for hunter in self.active_hunters: hunter.start() #self.stop_malware_hunt() def stop_malware_hunt(self): """ Stops the hunting threads. Args: None. Returns: None. Raises: None. """ for hunter in self.active_hunters: hunter.stop_hunting() hunter.join() def file_is_archived(self, _file): """ Verifies if the given file is already stored in one of the archive in the vault. This function is a shortcut to VaultDatabase.file_exists. Args: _file: Absolute path of the file to verify. Returns: True if the SHA1 hash of the given file is found in the Files table of the database. False otherwise. Raises: Exception if null or empty arguments. Raise exception if given file is not found. """ return self.vxvault.file_is_archived(_file) def shutdown(self): """Clean up function for the engine. This function will manage program termination. Args: None Returns: None. Raises: None. """ self.logger.print_warning(WARN_ENGINE_SHUTDOWN) self.stop_malware_hunt()
def unlock_vault_geom(vault: Vault, probe_minutiae, poly_degree, gf_exp, crc_length, secret_length, log_dict, echo=False): """ Given vault, find candidate minutiae according to probe minutiae (list of Minutia) using geometric hashing. Afterwards, run interpolation on candidate minutiae geom_table needs to exist in vault :returns True if match found in polynomial after interpolation, else False """ def exit_false(): """ :returns False for vault not unlocked """ log_dict['amount_geom_table'] = len(vault_geom_table) log_dict['evaluated_subsets'] = -1 log_dict['minutiae_candidates'] = 0 log_dict['time_geom'] = time.time() - t_geom log_dict['geom_gallery_basis'] = None log_dict['geom_probe_basis'] = None vault.vault_original_minutiae_rep.clear() vault.vault_function_points_rep.clear() vault.vault_chaff_points_rep.clear() return False def get_geom_table_basis_threshold(probe_minutiae_gh): """ Removes basis in geom_table of vault that correspond to no probe_minutiae orientation :param probe_minutiae_gh: list of probe minutiae as MinutiaNBIS_GH :return: changes vault.geom_table, no return value """ geom_table = vault.geom_table.copy() for element_enroll in geom_table.copy(): in_threshold = False for m in probe_minutiae_gh: if abs(element_enroll.basis.theta - m.theta) <= Constants.BASIS_THETA_THRESHOLD: # not removing element from geom_table in_threshold = True break # remove element from geom_table if there was no match if not in_threshold: geom_table.remove(element_enroll) return geom_table assert vault.geom_table log_dict['thresholds'] = '({}/[{}/{}/{}/{}]/{})'.format( Constants.POINTS_DISTANCE, Constants.X_THRESHOLD, Constants.Y_THRESHOLD, Constants.THETA_THRESHOLD, Constants.TOTAL_THRESHOLD, Constants.BASIS_THETA_THRESHOLD) # start time geometric hashing t_geom = time.time() # create polynomial extractor poly_extractor = PolynomialExtractor(gf_exp) # convert probe minutia to GH form, iterate through probe_minutiae, taking random probe minutia as basis probe_minutiae_GH = GHTransformer.convert_list_to_MinutiaNBIS_GH(probe_minutiae) random.shuffle(probe_minutiae_GH) # remove all basis in geom_table that are not within threshold of probe_minutiae orientation vault_geom_table = get_geom_table_basis_threshold(probe_minutiae_GH) for cnt_basis, basis in enumerate(probe_minutiae_GH): # take random basis and try matching element_verification = GHTransformer.generate_verification_table_element(basis, probe_minutiae_GH.copy()) for cnt_enroll, element_enrollment in enumerate(vault_geom_table): # check if basis in element_enrollment has similar orientation to current basis in probe if not (abs(element_verification.basis.theta - element_enrollment.basis.theta) <= Constants.BASIS_THETA_THRESHOLD): continue # clear lists in vault to be populated in decoding for each element in geom_table vault.vault_original_minutiae_rep.clear() vault.vault_function_points_rep.clear() vault.vault_chaff_points_rep.clear() assert len(element_enrollment.transformed_minutiae_list) == len(vault.vault_final_elements_pairs) # cnt_m_enr is representing the same indices also in vault_final_element_pairs match = 0 candidates_verification = [] candidates_enrollment = [] candidate_minutiae_verification = element_verification.transformed_minutiae_list.copy() for cnt_m_enr, minutia_enrollment in enumerate(element_enrollment.transformed_minutiae_list): if not candidate_minutiae_verification: break for minutia_verification in candidate_minutiae_verification: if fuzzy_compare(minutia_enrollment, minutia_verification): log_dict['geom_single_match'] += 1 # Only add element if not already in list if not vault.vault_final_elements_pairs[ cnt_m_enr].x_rep in vault.vault_original_minutiae_rep: match += 1 # add representation (uint) to candidate minutiae # first element corresponding to x value of vault tuple vault.add_minutia_rep(vault.vault_final_elements_pairs[cnt_m_enr].x_rep) # second element corresponding to y value of vault tuple vault.add_function_point_rep(vault.vault_final_elements_pairs[cnt_m_enr].y_rep) # candidate minutiae for logging purposes candidates_verification.append(minutia_verification) candidates_enrollment.append(minutia_enrollment) assert match == len(vault.vault_original_minutiae_rep) else: # add to chaff points (but not relevant as minutia can not be matched in different basis) chaff_candidate = vault.vault_final_elements_pairs[cnt_m_enr].x_rep if chaff_candidate not in vault.vault_chaff_points_rep: vault.add_chaff_point_rep(chaff_candidate) log_dict['geom_iteration'] += 1 if match >= Constants.MATCH_THRESHOLD: assert match == len(vault.vault_original_minutiae_rep) assert len(candidates_verification) == len(candidates_enrollment) assert len(vault.vault_original_minutiae_rep) == len(vault.vault_function_points_rep) assert len(vault.vault_function_points_rep) == len(candidates_enrollment) # log iterations in geometric hashing, minutiae candidates. tries to interpolate and basis log_dict['amount_geom_table'] += cnt_enroll log_dict['minutiae_candidates'] = len(vault.vault_original_minutiae_rep) log_dict['geom_match_tries'] += 1 log_dict['geom_gallery_basis'] = element_enrollment.basis log_dict['geom_probe_basis'] = element_verification.basis # time geometric hashing log_dict['time_geom'] = time.time() - t_geom # polynomial interpolation on candidate set function points and test CRC in extracted polynomials t_interpol = time.time() success = poly_extractor.interpolate_and_check_crc(vault, poly_degree, crc_length, secret_length, log_dict, echo=echo) log_dict['time_interpolation'] += time.time() - t_interpol if success: # log candidate minutiae if Constants.LOG_CANDIDATE_MINUTIAE: log_candidates_minutia(Constants.LOG_CANDIDATES_PATH_PREFIX, Constants.LOG_CANDIDATES_PATH_SUFFIX, candidates_verification, candidates_enrollment, element_verification.basis, element_enrollment.basis, vault, number=log_dict['exp_number']) return True # break if max threshold is reached if log_dict['geom_iteration'] > Constants.MAX_ITERATION_THRESHOLD: print("Max iteration threshold reached!") return exit_false() # unfortunately, no sets found return exit_false()
class Engine(object): #****************************************************************************** # Class Static Variables # DefaultDataSource = DS_VIRUS_TOTAL # # URL to use for testing Interner connectivity. UrlTestInternet = "https://www.google.com/" # #****************************************************************************** def __init__(self, _base, _vtapi, _password=Vault.DefaultArchivePassword, _saveFileNoDetection=False, _allowMultipleSamples=False, _logger=None): """Initializes the engine, including the logger, vault and other class variables. Creates a default logger if none provided. The constructor also creates the data sources required to identify malware. Finally it will create a Vault object with the given base parameter. Args: _base: The directory in which the filesystem of the vault will be created. _vtapi: The public API key used to make requests to VirusTotal. _password: Password to use on archive creation. _saveFileNoDetection: Specified whether analyzed files undetected by no AV software should be saved in the archive. _logger: Logger object to output information about program execution. If none provided, it will use sys.stdout by default. Returns: None. Raises: None. """ #************************************************************************** # Creates a new logger object. #************************************************************************** if _logger == None: self.logger = Logger(sys.stdout) else: self.logger = _logger #************************************************************************** # Initializes an empty dictionary of data sources, # adds the VirusTotal data source object to it. #************************************************************************** self.data_sources = {} self.data_sources[DS_VIRUS_TOTAL] = VirusTotalSource( _vtapi, _logger=self.logger) #************************************************************************** # Initializes a new vault object with the # given base directory. #************************************************************************** self.vxvault = Vault(_base, _logger=self.logger, _multipleSamplesAllowed = _allowMultipleSamples) self.saveUndetectedFiles = _saveFileNoDetection self.active_hunters = [] self.hunt_is_on = False def __str__(self): return "<Engine>" def __repr__(self): return "<VxVault Engine {:s}>".format(__version__) def is_windows(self): """Verifies if the current underlying operating system is Windows-based. This function verifies if the current underlying operating system is Windows-based. Args: None. Returns: True if the program is running on a Windows platform, False otherwise. Raises: None. """ return ("win" in platform.system().lower()) def set_archiver(self, _archiver): """Sets the Archiver object to be used by the vault. This function will sets the Archiver to be used by the Vault to archive and compress malware into the filesystem. Args: Archiver object. Returns: None. Raises: None. """ if (_archiver): self.vxvault.set_archiver(_archiver) else: raise FileNotFoundException(_program) def get_archiver(self): """Returns the Archiver object currently used by the vault. This function will return the Archiver object currently used by the Vault to archive and compress malware into the filesystem. Args: None. Returns: Archiver object. Raises: None. """ return self.archiver def create_vault(self): """Creates a new file system. This function will create the file system at the base specified at the creation of the engine. it will also initialize the vault. Args: None. Returns: None Raises: Exception if there was an error while creating the file system. """ self.vxvault.create_vault() def vault_is_created(self): """Verifies if the vault has been created at the base directory. This function will confirm if the vault has been created on the file system. Args: None. Returns: True if the vault has been created in the configured base directory provided at the creation of the engine. Returns False otherwise. Raises: None. """ return self.vxvault.is_created() def get_vault(self): """ Returns the vault object used by the engine. Args: None. Returns: Vault object associated with the engine. Raises: None. """ return self.vxvault def can_connect_internet(self): """Verifies if a connection to the Internet is available. this function verifies if a connection to the Internet is available by attempting to connect to the website specified in Engine.UrlTestInternet. Args: None. Returns: True if the function was able to successfully connect to the specified website. Raises: Exception if an error occured while connecting to the site. """ self.logger.print_debug("Attempting to connect to '{:s}'.".format(self.UrlTestInternet)) request = urllib2.Request(self.UrlTestInternet) try: response = urllib2.urlopen(request) html = response.read() self.logger.print_debug(INFO_CONNECTED_INTERNET) return True except Exception as e: self.logger.print_debug(ERR_FAILED_CONNECT_NET.format(e.message)) return False; def add_http_file_virus(self, _url): """ Downloads a file at the specified URL into the pit directory of the vault and analyzes it prior to storing it in the vault. This function will download a file specified by a HTTP/HTTPS URL and save it to the "pit" directory. It will then proceed into retrieving scan information for the downloaded file and archive it into the vault. TODO: [X] Test this function. Args: _url: The URL of the file to download. Must start with HTTP. Returns: None. Raises: InvalidUrlException: If the provided URL is invalid. NullOrEmptyArgumentException: if the URL or destination path is empty or null. FileDownloadException: If the function failed to create the local file. """ if (_url and len(_url.strip()) > 0): url = _url.strip() #****************************************************************** # Verifies if the URL provided is valid #****************************************************************** if (url[0:4].lower() == "http"): #****************************************************************** # Build the destination path of the file. #****************************************************************** dst_path = self.vxvault.get_pit() dst_file = url.split("/")[-1].strip() dst_file = self.replace_chars_in_string(dst_file, UNALLOWED_CHARS_FILES, DEFAULT_REPLACE_CHAR) dst = os.path.join(dst_path, dst_file) if (os.path.exists(dst)): raise FileExistsException(dst) self.download_file(url, dst) #****************************************************************** # Analyze the file downloaded after making sure it exists. #****************************************************************** if (os.path.exists(dst)): self.add_single_file_virus(dst) else: raise FileDownloadException() else: raise InvalidUrlException(url) else: raise NullOrEmptyArgumentException() def add_files_from_urls(self, _files): """ """ if (_files and len(_files) > 0): hunter = LocalHunter( _engine = self, _files = _files, _extensions = Hunter.HuntedExtensions, _logger = self.logger) urls = hunter.get_urls_from_files(_files) if (len(urls) > 0): for url in urls: self.add_http_file_virus(url) else: raise NoUrlFoundException() else: raise NullOrEmptyArgumentException() def replace_chars_in_string(self, _string, _chars, _replace): """ Replaces characters in the given string by a user-defined string. This functions will replace each instance of the characters specified in the _chars string found inthe _string argument with the characters specified in the _replace argument. Args: _string: String containing chars to be replaced _chars: String or array of characters to replaced. _replace: String or character used as replacement. Returns: None. Raises: None. """ new_string = _string for char in _chars: if char in _string: new_string = new_string.replace(char, _replace) return new_string def download_file(self, _url, _dst): """ Downloads a file at the specified URL into the local filesystem. This function will download a file specified by a HTTP/HTTPS URL and save it to the specified destination. Args: _url: The URL of the file to download. Must start with HTTP. _dst: Absolute path of the destination on the local file system. Returns: None. Raises: InvalidUrlException: If the provided URL is invalid. NullOrEmptyArgumentException: if the URL or destination path is empty or null. FileDownloadException: If the function failed to create the local file. """ url = urllib.unquote(_url.strip()) if (url and len(url) > 0): #****************************************************************** # Verifies if the URL provided is HTTP # Todo: # [ ] Better URL validation function. #****************************************************************** if (url[0:4].lower() == "http"): self.logger.print_info(MSG_INFO_DOWNLOADING.format(_dst, url)) try: urllib.urlretrieve (url, _dst) except Exception as e: raise FileDownloadException("{:s}: {:s}".format(_dst, e.message)) else: raise InvalidUrlException(url) else: raise NullOrEmptyArgumentException() def add_single_file_virus(self, _file): """ Adds a single file from the local system to the vault. This function will add a single file to the vault. It will analyze the file and attempt to identify it as a malware. Once completed, it will archive the file in a 7zip archive and move it into the vault based on the class and target OS. This function will remove the original file from the source. Args: _file: The file to archive into the vault. Returns: None. Raises: Exception if provided file argument is null or empty. Will raise exception if the file cannot be found, or cannot connect to the Internet. Will also raise an exception if Analysis fails or archiving fails. """ #********************************************************************** # Verifies if the provided argument is valid. #********************************************************************** if (_file and len(_file) > 0): #****************************************************************** # Checks if the file exists. #****************************************************************** if (os.path.exists(_file)): #************************************************************** # Confirm if the file is not already stored in the vault #************************************************************** is_stored = self.file_is_archived(_file) if (is_stored): raise ArchiveExistsException(_file) #************************************************************** # Attempts to extract malware identification of # the given file. #************************************************************** datasrc = self.data_sources[DS_VIRUS_TOTAL] analyzer = Analyzer( _vxdata = datasrc, _vault = self.vxvault, _logger = self.logger) vx = analyzer.analyze_file(_file) if (vx): if (vx.is_detected() or (vx.is_undetected and self.saveUndetectedFiles)): #****************************************************** # Archives the file into the fault. #****************************************************** self.vxvault.archive_file(vx) else: self.logger.print_warning(WARN_IGNORE_FILE.format(vx.get_file())) else: raise FileNotFoundException(_file) else: raise NullOrEmptyArgumentException() def add_single_dir_virus(self, _dir): """ Add a malware containing multiple files contained in a single directory. This function accepts a directory containing files of the same malware, bundles it into an archive and move it to the vault. Args: _dir: The directory containing the files of the malware. Returns: None. Raises: Exception if provided argument is null. Other exceptions on error retrieving data from the internet, directory not found, moving file to the vault or creating a new entry in the database. """ #********************************************************************** # Verifies if the provided argument is valid. #********************************************************************** if (_dir and len(_dir) > 0): #****************************************************************** # Checks if the file exists. #****************************************************************** if (os.path.isdir(_dir)): #************************************************************** # Check if the directory contains files #************************************************************** nb_files = len(os.listdir(_dir)) if (nb_files == 0): raise Exception("Directory '{:s}' contains no file.".format(_dir)) #************************************************************** # Attempts to extract malware identification of # the given file. #************************************************************** datasrc = self.data_sources[DS_VIRUS_TOTAL] analyzer = Analyzer( _vxdata = datasrc, _vault = self.vxvault, _logger = self.logger) vx = analyzer.analyze_dir(_dir) if (vx): #********************************************************** # Archives the file into the fault. #********************************************************** self.vxvault.archive_file(vx) else: raise FileNotFoundException(_dir) else: raise NullOrEmptyArgumentException() def add_multiple_virii_from_dir(self, _dir): """ Adds all files in the specified directory and subdirectories as individual malware. This function lists all files and subdirectories in the user-provided directory and adds each individual file to the vault as a individual malware. Subdirectories are considered as a single malware. All files in the subdirectory are considered part of the same malware. Args: _dir: The directory containing the malware Returns: None Raises: Exception on failure to find the directory, or if directory is empty. Exception if fail to analyze, store file into the vault or record the file into the database. """ #********************************************************************** # Verifies if the provided argument is valid. #********************************************************************** if (_dir and len(_dir) > 0): #****************************************************************** # Checks if the file exists. #****************************************************************** if (os.path.isdir(_dir)): #************************************************************** # Check if the directory contains files #************************************************************** nb_files = len(os.listdir(_dir)) if (nb_files == 0): raise Exception("Directory '{:s}' contains no file.".format(_dir)) datasrc = self.data_sources[DS_VIRUS_TOTAL] analyzer = Analyzer( _vxdata = datasrc, _vault = self.vxvault, _logger = self.logger) for root, dirs, files in os.walk(_dir): for name in files: vx_file = os.path.join(root, name) #****************************************************** # Confirm if the file is not already stored in the # vault #****************************************************** is_stored = self.file_is_archived(vx_file) if (is_stored): raise Exception(ERR_FILE_ALREADY_EXISTS.format(_file)) self.logger.print_debug("Adding file '{:s}'...".format(vx_file)) vx = analyzer.analyze_file(vx_file) if (vx): #****************************************************** # Archives the file into the fault. #****************************************************** self.vxvault.archive_file(vx) #********************************************************** # Verifies if we are allowed to make a new request to # the data source. #********************************************************** next_run = datasrc.get_next_allowed_request() self.logger.print_debug(MSG_INFO_NEXT_RUN.format(next_run)) while (datetime.now() < next_run): time.sleep(3) for dir in dirs: vx_dir = os.path.join(root, dir) #************************************************************** # Check if the directory contains files #************************************************************** nb_files = len(os.listdir(vx_dir)) if (nb_files == 0): raise Exception("Directory '{:s}' contains no file.".format(vx_dir)) vx = analyzer.analyze_dir(vx_dir) if (vx): #********************************************************** # Archives the file into the fault. #********************************************************** self.vxvault.archive_file(vx) #********************************************************** # Verifies if we are allowed to make a new request to # the data source. #********************************************************** next_run = datasrc.get_next_allowed_request() self.logger.print_debug(MSG_INFO_NEXT_RUN.format(next_run)) while (datetime.now() < next_run): time.sleep(3) else: raise FileNotFoundException(_dir) else: raise NullOrEmptyArgumentException() def start_malware_hunt(self): """ Starts the hunting threads. This function will create threads for each type of hunter available and start it. Each thread will then start downloading and analyzing files found on their individual sources. Malc0de: The malc0de hunter looks for new malware links on the malc0de website. Local: The local hunter will look for files in the ./pit/urls directory located in the vault. It will look within each file for URLs to files with extensions listed in Hunter.HuntedExtensions. Args: None. Returns: None. Raises: Multiple exceptions if downloading, archiving or recording fails. """ hunt_malcode = MalcodeHunter( _engine=self, _logger=self.logger) hunt_mdl = MdlHunter( _engine=self, _logger=self.logger) hunt_local = LocalHunter( _engine = self, _files = [self.vxvault.file_system.get_urls_dump()], _extensions = Hunter.HuntedExtensions, _logger = self.logger) self.active_hunters.append(hunt_malcode) self.active_hunters.append(hunt_mdl) self.active_hunters.append(hunt_local) for hunter in self.active_hunters: hunter.start() #self.stop_malware_hunt() def stop_malware_hunt(self): """ Stops the hunting threads. Args: None. Returns: None. Raises: None. """ for hunter in self.active_hunters: hunter.stop_hunting() hunter.join() def file_is_archived(self, _file): """ Verifies if the given file is already stored in one of the archive in the vault. This function is a shortcut to VaultDatabase.file_exists. Args: _file: Absolute path of the file to verify. Returns: True if the SHA1 hash of the given file is found in the Files table of the database. False otherwise. Raises: Exception if null or empty arguments. Raise exception if given file is not found. """ return self.vxvault.file_is_archived(_file) def shutdown(self): """Clean up function for the engine. This function will manage program termination. Args: None Returns: None. Raises: None. """ self.logger.print_warning(WARN_ENGINE_SHUTDOWN) self.stop_malware_hunt()
class PasswordVault(QWidget): #_listAccount=[] count = True _newFileCount = True _filename = '' # this is a full path of the file _password = '' _dirIcon = os.getcwd() + '/Icon/' _dirBackup = os.getcwd() + '/Backup/' countTable = [] countCheckbox = [] countCheckboxAll = False def __init__(self, x, y, title=""): super(PasswordVault, self).__init__() self.x = x self.y = y self._myVault = '' self.changePass = ChangePassword() self.changePass.getPass.connect(self._getPass) # self.height=height # self.width=width self.saveflag = True self.title = title #self.move(self.x,self.y) self.setWindowTitle(self.title) self.vlayout = QVBoxLayout() self.draw() self.drawTable() self.events() self.show() #self.setGeometry(self.x,self.y,self.width,self.height) #self.statusBar().showMessage('Message in statusbar.') # This function is stored all the events of the app def events(self): #click events self.btn_unclock.clicked.connect(self._btnUnClockCick) self.btn_brownse.clicked.connect(self._btnBrowse) self.btn_showpass.clicked.connect(self._btnShowpass) self.btn_brownse.installEventFilter(self) #self.table.clicked.connect(self._tableClickpass) self.table.cellClicked.connect(self._cellCLicked) self.table.cellChanged.connect(self._cellChanged) # Table events self.tablebtnAdd.clicked.connect(self._tablebtnAdd) self.tablebtnDelete.clicked.connect(self._tablebtnDelete) self.tablebtnSave.clicked.connect(self._tablebtnSave) self.tablebtnChangePassword.clicked.connect(self._tableChangepass) #self.table.itemSelectionChanged.connect(self._tableEditTable) # Draw the inition GUI for the app def draw(self): font_lbl_errorMsg = QFont() font_lbl_errorMsg.setItalic(True) font_lbl_errorMsg.setUnderline(True) # Table self.table = QTableWidget() #self.table.setEditTriggers(QAbstractItemView.NoEditTriggers); self.table.setFocusPolicy(Qt.NoFocus) self.table.setSelectionMode(QAbstractItemView.NoSelection) # ============= LABEL =============== self.lbl_filename = QLabel("Filename:") self.lbl_password = QLabel("Password:"******"") self.lbl_errorMsg.setFont(font_lbl_errorMsg) #self.lbl_errorMsg.setText("<font color='blue'>Create new file</font>") #self.lbl_errorMsg.setOpenExternalLinks(True) #self.lbl_errorMsg.installEventFilter(self) # ============= BUTTON ===================== self.btn_brownse = QPushButton() self.btn_brownse.setIcon( QIcon(self._dirIcon + 'icons8-browse-page-filled-50.png')) sizeHint_height = self.btn_brownse.sizeHint().height() self.size = sizeHint_height # this is a hint size is used for the table #print(sizeHint_height) self.btn_brownse.setIconSize(QSize(sizeHint_height, sizeHint_height)) #self.btn_brownse.setFixedWidth(sizeHint_height) #self.btn_brownse.setFixedHeight(self.size_of_btn) self.btn_showpass = QPushButton() self.btn_showpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) self.btn_showpass.setIconSize(QSize(sizeHint_height, sizeHint_height)) self.btn_unclock = QPushButton("Unclock") self.btn_unclock.setDisabled(True) #radio button # self.rbtn_textfile=QRadioButton("Text file") # self.rbtn_image=QRadioButton("Image file") # text box self.tbox_filename = QLineEdit("--- Select your file ---") self.tbox_password = QLineEdit() self.tbox_filename.setReadOnly(True) self.tbox_password.setEchoMode(2) hbox1 = QHBoxLayout() hbox1.addWidget(self.lbl_filename) hbox1.addWidget(self.tbox_filename) hbox1.addWidget(self.btn_brownse) #hbox1.addWidget(self.btn_hint) hbox2 = QHBoxLayout() hbox2.addWidget(self.lbl_password) hbox2.addWidget(self.tbox_password) hbox2.addWidget(self.btn_showpass) hbox2.addWidget(self.btn_unclock) hbox3 = QHBoxLayout() hbox3.addWidget(self.lbl_errorMsg) self.vlayout.addLayout(hbox1) self.vlayout.addLayout(hbox2) self.vlayout.addLayout(hbox3) #self.resize(580,120) self.setLayout(self.vlayout) # Create a data table def drawTable(self): #check=True height = self.frameGeometry().height() width = self.table.frameGeometry().width() fontBold = QFont() fontBold.setBold(True) #=== Button of the table ===== self.tablebtnSave = QPushButton("Save") self.tablebtnChangePassword = QPushButton("Change vault's password") self.tablebtnDelete = QPushButton('-') self.tablebtnAdd = QPushButton('+') ## SET size for btn sizeHint_height = self.tablebtnAdd.sizeHint().height() self.tablebtnDelete.setFixedWidth(sizeHint_height) #self.tablebtnDelete.setFixedHeight(self.size_of_btn) self.tablebtnAdd.setFixedWidth(sizeHint_height) #self.tablebtnAdd.setFixedHeight(self.size_of_btn) ## EVNET of the table self.tablebtnAdd.setDisabled(True) self.tablebtnSave.setDisabled(True) self.tablebtnDelete.setDisabled(True) self.tablebtnChangePassword.setDisabled(True) hboxTable = QHBoxLayout() hboxTable.addWidget(self.tablebtnChangePassword) hboxTable.addSpacing((width / height) * 120) hboxTable.addWidget(self.tablebtnSave) #hboxTable.addSpacing((width/height)*20) hboxTable.addWidget(self.tablebtnDelete) hboxTable.addWidget(self.tablebtnAdd) # Data handle of the table #print(self.tbox_filename.text()) #sefl._noAccount=int(self.tbox_filename.text()) self.table.setRowCount(1) self.table.setColumnCount(5) self.table.setItem(0, 0, QTableWidgetItem('Service')) self.table.setItem(0, 1, QTableWidgetItem("ID")) self.table.setItem(0, 2, QTableWidgetItem('Password')) self.table.setItem(0, 3, QTableWidgetItem('')) self.table.setItem(0, 4, QTableWidgetItem('')) for i in range(0, 5): #print(i) self.table.item(0, i).setFont(fontBold) self.table.item(0, i).setFlags(Qt.ItemIsEnabled) # import data to the table #==== UPDATA the PasswordVault Layout self.table.resizeColumnsToContents() self.vlayout.addWidget(self.table) self.vlayout.addLayout(hboxTable) self.setLayout(self.vlayout) print(width, height) #self.table.setFocusPolicy(Qt.NoFocus) self.resize(width, height) # Generate Item and Widget inside table cell def widgetInsideTable(self): # ===== Button view pass inside table ===== # viewPassbtn=QPushButton() # viewPassbtn.setFixedHeight(self.size_of_btn) # viewPassbtn.setFixedWidth(self.size_of_btn) # viewPassbtn.setIcon(QIcon(self._dirIcon+'icons8-eye-1.png')) # ====== CheckBox ====== checkBox = QTableWidgetItem() checkBox.setIcon(QIcon(self._dirIcon + 'icons8-checkbox-0.png')) checkBox.setFlags(Qt.ItemIsEnabled) # Item view pass ItemViewPass = QTableWidgetItem() ItemViewPass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) ItemViewPass.setFlags(Qt.ItemIsEnabled) self.table.setIconSize(QSize(self.size, self.size)) # ====== Line Edit / Textbox ====== return checkBox, ItemViewPass # pop-up a browse for choosing a file def openFileNameDialog(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self, "QFileDialog.getOpenFileName()", "", "Text Files (*.txt)", options=options) if fileName: self.resetData() return fileName # Converting all the data on the created table into a desire format def convertData_2_bytes(self): # this function is user before encrypt data noRow = self.table.rowCount() data = '' for i in range(1, noRow): #print(len(self._listAccount)) Service = self.table.item(i, 0).text() ID = self.table.item(i, 1).text() PASS = self.table.cellWidget(i, 2).text() data += f',{Service},{ID},{PASS}' data = str.encode(data[1:]) return data # A message from saving a file def popup_save_table(self): choice = QMessageBox.question( self, 'Double check!', "Your original file will be move to a backup folder\n Your edited data will be save at the same location with the same name", QMessageBox.Close) if choice == QMessageBox.Close: #self._filename[sefl._filename.rfind('/')+1:] backupname = self._filename[self._filename.rfind(')') + 1:] backupdir = self._dirBackup + '(BackupE)' + backupname copyfile(self._filename, backupdir) sys.exit() else: pass #confirm closing a working file def popup_exitingfile(self): op = QMessageBox.question( self, 'Warning', "Do you want to save this file", (QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)) if op == QMessageBox.Save: self._tablebtnSave() return True elif op == QMessageBox.Discard: return True else: return False # Getting the data from encrypted file then upload to the table base on the design format def assignData2Table(self): del self._myVault self._myVault = Vault(self._password, self._filename) # create the vault a, check, checkPass = self._myVault.extractAccount() if checkPass == False: #print("Plase enter diff password") self.lbl_errorMsg.setText( "<font color='red'>Please try a diff password</font>") else: #print(len(self._myVault)) if check == True: #Enbale some btn if the file is open successfully self.lbl_errorMsg.setText('') self.tablebtnAdd.setDisabled(False) self.tablebtnSave.setDisabled(False) self.tablebtnDelete.setDisabled(False) self.tablebtnChangePassword.setDisabled(False) self.btn_unclock.setDisabled(True) for idx, item in enumerate(self._myVault.listAccount): #print(idx) self.table.insertRow(self.table.rowCount()) newRowidx = self.table.rowCount() - 1 checkBox, iViewPass = self.widgetInsideTable() self.table.setItem(newRowidx, 0, QTableWidgetItem(item.service)) self.table.setItem(newRowidx, 1, QTableWidgetItem(item.ID)) self.table.setCellWidget(newRowidx, 2, QLineEdit(item.PASS)) self.table.setItem(newRowidx, 3, iViewPass) self.table.setItem(newRowidx, 4, checkBox) self.countTable.append(True) self.countCheckbox.append(False) self.table.cellWidget(newRowidx, 2).setEchoMode(2) #print(self.table.item(1,3).sizeHint().height()) else: #print("Print a message box : error the invalid file") del self._myVault self._myVault = '' self.lbl_errorMsg.setText( "<font color='red'>the file which is invaild, is not the format of password vault app</font>" ) self.table.resizeColumnsToContents() # Reset all data and delete the table / ready for another open file or create new file def resetData(self): PasswordVault._filename = '' # this is a full path of the file PasswordVault._password = '' del PasswordVault.countTable del PasswordVault.countCheckbox del self._myVault PasswordVault.countTable = [] PasswordVault.countCheckbox = [] self._myVault = '' for i in range(self.table.rowCount() - 1, 0, -1): self.table.removeRow(i) #self.setLayout(self.vlayout) #self.draw() #self.show() # overite Event def eventFilter(self, ob, event): if ob is self.btn_brownse and event.type() == 129: for i in range(0, self.table.rowCount() - 1): #print(self._myVault.listAccount[i].PASS,self.table.cellWidget(i+1,2).text()) if self._myVault.listAccount[i].PASS != self.table.cellWidget( i + 1, 2).text(): self.saveflag = False return False # this is the overwrite event of the lbl_errorMsg and can be for other widget # def eventFilter(self,ob,event): # #print(type(ob)) # if ob is self.lbl_errorMsg and event.type()==2: # #print(event.type()) # PasswordVault._newFileCount = not PasswordVault._newFileCount # #print(PasswordVault._new) # if PasswordVault._newFileCount==False: #new account # self.tbox_filename.setReadOnly(False) # self.btn_unclock.setDisabled(False) # self.btn_brownse.setDisabled(True) # self.btn_unclock.setText('Create') # self.tbox_filename.setText("--- Enter your file name ---") # self.lbl_errorMsg.setText("<font color='blue'>Already have a file</font>") # else: # self.tbox_filename.setReadOnly(True) # self.btn_unclock.setDisabled(True) # self.btn_brownse.setDisabled(False) # self.btn_unclock.setText('Unclock') # self.tbox_filename.setText("--- Select your file ---") # self.lbl_errorMsg.setText("<font color='blue'>Create new file</font>") # return False # else : # return False # ======== events ========= @pyqtSlot() # Event Browse btn def _btnBrowse(self): #self.resetData() #print(self._myVault) op = True if not self.saveflag: # currently openning a file op = self.popup_exitingfile() if op == True: self._filename = self.openFileNameDialog() if self._filename: self.tbox_password.setText('') self.tbox_filename.setText(self._filename) self.btn_unclock.setDisabled(False) #self.saveflag=False else: pass # event of Unclock btn or Create new file btn def _btnUnClockCick(self): self._password = self.tbox_password.text() #print(PasswordVault._newFileCount) if self._password: self.assignData2Table() self.saveflag = True else: self.lbl_errorMsg.setText( "<font color='red'>password is empty</font>") #print("Pop up a error message: password is empty") #these for testing # self._filename="/home/nhat/Documents/GUI/Project_1_encryption/TestFolder/(encrpted)AccountTest.txt" # self._password='******' #self.show() def _btnShowpass(self): self.count = not self.count if self.count == False: self.tbox_password.setEchoMode(0) self.btn_showpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-0.png')) #print ("echo 0") else: self.tbox_password.setEchoMode(2) self.btn_showpass.setIcon(QIcon(self._dirIcon + 'icons8-eye-1.png')) def _cellCLicked(self, row, column): ## cellClicked for view password if column == 3 and row > 0: self.countTable[row - 1] = not self.countTable[row - 1] if self.countTable[row - 1] == False: self.table.cellWidget(row, 2).setEchoMode(0) self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-eye-0.png')) else: self.table.cellWidget(row, 2).setEchoMode(2) self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-eye-1.png')) ## cellClicked for cehckbox elif column == 4 and row > 0: #print (self.countCheckbox[row-1]) self.countCheckbox[row - 1] = not self.countCheckbox[row - 1] # print('clicked',row, column,self.countCheckbox[row-1]) if self.countCheckbox[row - 1] == True: self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-1.png')) else: self.table.item(row, column).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-0.png')) #print(self.countCheckbox) elif row == 0 and column == 4: self.countCheckboxAll = not self.countCheckboxAll for i in range(1, self.table.rowCount()): if self.countCheckboxAll == True: self.countCheckbox[i - 1] = True self.table.item(i, 4).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-1.png')) else: self.countCheckbox[i - 1] = False self.table.item(i, 4).setIcon( QIcon(self._dirIcon + 'icons8-checkbox-0.png')) self.table.resizeColumnsToContents() def _cellChanged(self, row, column): if row > 0 and column is not 3 and column is not 4: # print ("cell changed") self.saveflag = False def _tablebtnAdd( self ): # when a new row added a new account created coreponding to the row nomber #print(self.table.rowCount()) checkBox, iViewPass = self.widgetInsideTable() self.table.insertRow(self.table.rowCount()) newRowidx = self.table.rowCount() - 1 # setup new row self.table.setItem(newRowidx, 0, QTableWidgetItem(' new service')) self.table.setItem(newRowidx, 1, QTableWidgetItem(' new ID ')) self.table.setCellWidget(newRowidx, 2, QLineEdit('type pass')) self.table.setItem(newRowidx, 3, iViewPass) self.table.setItem(newRowidx, 4, checkBox) #self.table.item(newRowidx,3).setIcon(QIcon(self._dirIcon+'icons8-eye-0.png')) self.table.cellWidget(newRowidx, 2).setEchoMode(2) self.countTable.append(True) self.countCheckbox.append(False) self.table.resizeColumnsToContents() self.saveflag = False def _tablebtnDelete(self): #print(self.countCheckbox) #print(len(self.countCheckbox)) self.saveflag = False idx = 0 out = True while idx < len(self.countCheckbox): checkBox = self.countCheckbox[idx] if checkBox == True: self.table.removeRow(idx + 1) self.countCheckbox.remove(self.countCheckbox[idx]) idx = -1 idx += 1 #.statusBar.showMessage(f'A row at {self.currentRow-2} was delete') #print(self.countCheckbox) def _tablebtnSave(self): dataReady = self.convertData_2_bytes() #print(dataReady) self._myVault.encrypt(dataReady) print("Saved") self.saveflag = True #self.resetData() # print("reset adtributes") # for i in reversed(range(self.vlayout.count())): # self.vlayout.removeItem(self.vlayout.takeAt(i)) # self.drawTable() #print(self.countCheckbox) #self.save_PasVault() def _tableChangepass(self): self.changePass.currentPassword = self._password self.changePass.show() def _getPass(self, thepass): print('New pass:'******'' for i, account in enumerate(tempList): dataReady += f',{account.service},{account.ID},{account.PASS}' dataReady = str.encode(dataReady[1:]) print(dataReady) del self._myVault self._myVault = Vault(thepass, self._filename) self._myVault.encrypt(dataReady) print("Password was changed successfully")