예제 #1
0
    def eval_list(self, value_file, ioc_list):

        if self.__bypass:
            return evltResult.UNDEF

        # private attribute for child class
        rc = self.getRemoteCommand()
        wd = self.getWD()

        result = {}

        ioc_list = self.filter_ioc_list(ioc_list)

        if len(ioc_list) == 0:
            return result

        file_name, file_content = self.file_from_ioc_list(ioc_list)
        self.log('Loading file %s' % file_name, logging.DEBUG)

        with open(value_file, 'w') as f:
            f.write(file_content)

        if self.__confidential:
            raise NotImplementedError
            # Local SQLITE3 instance
            # TODO: do it
            # sqlite3loc = os.path.join(LOCAL_ANALYSIS_DIR, 'sqlite3.exe')
            # dbloc = os.path.join(self.dirname, self.__dbName)
            # localcommand = 'type "%s" | "%s" "%s"' % (value_file, sqlite3loc, dbloc)
            # res = os.popen(localcommand).read().replace('\r', '').replace('\n', '')
        else:
            rc.dropFile(value_file, file_name, True, False)
            file_identifier = '%s.%s' % (threadname,
                                         ioc_list[0].document.lower())

            results_filename = '%s.tar.gz' % (file_identifier)

            # self.log('Running the sql file %s' % file_name, logging.DEBUG)
            rc.execCommand('type %s | sqlite3 %s' % (file_name, self.__dbName),
                           wd)

            # self.log('Compressing results from %s' % file_identifier, logging.DEBUG)
            rc.execCommand('getresults.bat %s' % (file_identifier), wd)

            # self.log('Downloading results from %s' % results_filename, logging.DEBUG)
            # TODO: find a clean way to get the localanalysis directory
            extract_dir = os.path.join(
                os.path.dirname(os.path.dirname(os.path.realpath(__file__))),
                'resources', 'localanalysis')
            rc.getFile(results_filename,
                       os.path.join(extract_dir, results_filename))

            rc.deleteFile(results_filename)

            self.log(
                'Extracting results from %s' %
                os.path.join(extract_dir, results_filename), logging.DEBUG)
            tarname = os.path.join(extract_dir, results_filename)
            tar = tarfile.open(tarname, 'r:gz')
            # 'r|gz' might be used for better perf & stream-mode reading ?

            self.log('Found %s' % tar.getnames(), logging.DEBUG)

            for member in tar.getmembers():
                f = tar.extractfile(member)

                tmp_data = f.read()
                tmp_id = member.name.split('.')[2]
                tmp_db_ioc_id = member.name.split('.')[3]

                ret = evltResult.TRUE
                res_data = None

                if tmp_data == '':
                    ret = evltResult.UNDEF
                elif tmp_data == '0\n' or tmp_data == '\x01\n':
                    ret = evltResult.FALSE
                elif tmp_data[:1] == '\x01':
                    res_data = [
                        e.decode(sys.stdout.encoding)
                        for e in tmp_data.splitlines()[1:]
                    ]

                result[tmp_id] = {
                    'res': evltResult._str(ret),
                    'iocid': tmp_db_ioc_id,
                    'data': res_data
                }

            tar.close()

            if not self.__keepFiles:
                os.remove(tarname)

        return result
예제 #2
0
    def eval(self, valueFile, iocList=None):
        if iocList is not None:
            return self.eval_list(valueFile, iocList)
        if self.getIOC() is None:
            return AttributeError

        if self.__bypass:
            return evltResult.UNDEF

        # private attribute for child class
        ioc = self.getIOC()
        rc = self.getRemoteCommand()
        wd = self.getWD()

        select = ioc.select.replace('%s/' % ioc.document, '')

        self.log('IOC : %s' % (ioc), logging.DEBUG)

        # Hey, I don't know how to search for that
        if (ioc.search.lower() not in self.__evalList)\
                or (ioc.condition not in conditionList.keys()):
            self.log(
                '%s/%s is not in evaluation list' %
                (ioc.search, ioc.condition), logging.WARNING)
            return (evltResult.UNDEF, None)

        if select and select.lower() not in self.__evalList:
            self.log(
                'Could not select %s (not in evaluation list)' % (ioc.select),
                logging.WARNING)
            select = ''

        category = ioc.search.replace('%s/' % ioc.document, '')
        conditionTerm = conditionList[ioc.condition]

        # Escape '\' not using REGEX
        condition = conditionTerm % self.escapeValue(
            ioc.value
        ) if ioc.condition != 'regex' else conditionTerm % ioc.value

        # Craft query
        # > selecting count by default, otherwise selecting the user defined element
        # SELECT COUNT *  FROM <table> WHERE <index> LIKE <value> (default example)
        # SELECT FilePath FROM <table> WHERE <index> LIKE <value> (user defined example)
        querySelect = 'COUNT(*)' if not select else ('`%s`' % select)
        queryStart = 'SELECT %s FROM %s WHERE ' % (querySelect,
                                                   self.__tableName)
        queryVariable = '`%(index)s` %(clause)s' % {
            'index': category,
            'clause': (condition)
        }
        queryEnd = ';' if not select else ' UNION SELECT CHAR(1);'
        query = queryStart + queryVariable + queryEnd

        # Load PCRE for REGEX support
        loadext = 'SELECT load_extension("pcre.so");\n'

        queryContent = query

        res = ''
        retryCount = 15

        # Sometimes, queries may return "" (empty result)
        # Happens randomly, so just retry until it does not happen anymore
        while res == '' and retryCount > 0:
            self.log('query=%s' % query, logging.DEBUG)

            f = open(valueFile, 'w')
            f.write(loadext)
            f.write(queryContent)
            f.close()

            if self.__confidential:
                # Local SQLITE3 instance
                sqlite3loc = os.path.join(LOCAL_ANALYSIS_DIR, 'sqlite3.exe')
                dbloc = os.path.join(self.dirname, self.__dbName)
                localcommand = 'type "%s" | "%s" "%s"' % (valueFile,
                                                          sqlite3loc, dbloc)
                res = os.popen(localcommand).read().replace('\r', '').replace(
                    '\n', '')
            else:
                rc.dropFile(valueFile, 'query.sql', True, False)
                res = rc.execCommand(
                    'type query.sql | sqlite3 %s' % self.__dbName, wd)
                rc.deleteFile('query.sql')

            self.log('query returned "%s"' % res, logging.DEBUG)

            retryCount -= 1

        ret = evltResult.TRUE
        if res == '':
            ret = evltResult.UNDEF
        elif res == '0' or res == '\x01':
            ret = evltResult.FALSE

        resData = res.splitlines()[1:] if select else None

        return (evltResult._str(ret), resData)