示例#1
0
def identify_decoding_functions(vw):
    selected_functions = floss_main.select_functions(vw, None)
    selected_plugin_names = floss_main.select_plugins(None)
    selected_plugins = filter(lambda p: str(p) in selected_plugin_names,
                              floss_main.get_all_plugins())
    decoding_functions_candidates = im.identify_decoding_functions(
        vw, selected_plugins, selected_functions)
    return decoding_functions_candidates
示例#2
0
def identify_decoding_functions(vw):
    selected_functions = floss_main.select_functions(vw, None)
    selected_plugin_names = floss_main.select_plugins(None)
    selected_plugins = [
        p for p in floss_main.get_all_plugins()
        if str(p) in selected_plugin_names
    ]
    decoding_functions_candidates = im.identify_decoding_functions(
        vw, selected_plugins, selected_functions)
    return decoding_functions_candidates
示例#3
0
    def each(self, target):
        self.results = {
            'warnings': [],
            'static_strings': [],
            'decoded_strings': [],
            'stack_strings': []
        }

        try:
            data = open(target, "r").read(MAX_FILESIZE)
        except (IOError, OSError) as e:
            self.log('error', 'Cannot open file {}'.format(target))
            self.results = None
            return False

        # Load list of IOC's
        try:
            with open(self.interesting_strings_file) as f:
                self.interesting_strings = f.read().splitlines()
            self.log(
                'info', 'Loaded interesting strings from {}'.format(
                    self.interesting_strings_file))
        except:
            # No IOC file, create an empty list
            self.log('info', 'No file with interesting strings defined')
            self.interesting_strings = []

        # Load list of ignored strings
        try:
            with open(self.ignored_strings_file) as f:
                self.ignored_strings = f.read().splitlines()
            self.log(
                'info', 'Loaded ignored strings from {}'.format(
                    self.ignored_strings_file))
        except:
            # No IOC file, create an empty list
            self.log('info', 'No file with ignored strings defined')
            self.ignored_strings = []

        # Extract static strings
        static_strings = re.findall(
            "[\x1f-\x7e]{" + str(self.minimum_string_len) + ",}", data)
        for s in re.findall(
                "(?:[\x1f-\x7e][\x00]){" + str(self.minimum_string_len) + ",}",
                data):
            static_strings.append(s.decode("utf-16le"))

        if self.maximum_string_len != 0:
            for i, s in enumerate(static_strings):
                static_strings[i] = s[:self.maximum_string_len]

        if self.maximum_strings != 0 and len(
                static_strings) > self.maximum_strings:
            self.log(
                'warning', 'Maximum number of strings reached ({})'.format(
                    str(self.maximum_strings)))
            static_strings = static_strings[:self.maximum_strings]
            static_strings.append("[snip]")

        try:
            # Prepare Floss for extracting hidden & encoded strings
            vw = vivisect.VivWorkspace()
            vw.loadFromFile(target)
            vw.analyze()

            selected_functions = main.select_functions(vw, None)
            decoding_functions_candidates = id_man.identify_decoding_functions(
                vw, main.get_all_plugins(), selected_functions)
        except Exception as e:
            self.log('error', 'Cannot analyze file {}'.format(target))
            self.results = None
            return False

        # Decode & extract hidden & encoded strings
        try:
            decoded_strings = main.decode_strings(
                vw, decoding_functions_candidates, self.minimum_string_len)
            decoded_strs = main.filter_unique_decoded(decoded_strings)

            stack_strings = stackstrings.extract_stackstrings(
                vw, selected_functions, self.minimum_string_len)
            stack_strings = list(stack_strings)

            decoded_strings = [
                x for x in decoded_strs if not x in static_strings
            ]
        except Exception as e:
            self.log('error', 'Cannot extract strings from {}'.format(target))
            self.results = None
            return False

        # Populate results[] with found strings
        if len(decoded_strings) or len(stack_strings):
            self.log('info', 'Found stack or decoded strings')
            for k, s in enumerate(decoded_strings):
                buffer = main.sanitize_string_for_printing(s.s)
                skip = False
                for ignore in self.ignored_strings:
                    if str(buffer).find(ignore) >= 0:
                        skip = True
                        break
                if not skip:
                    self.results['decoded_strings'].append(buffer)
            self.search_ioc(self.results['decoded_strings'])

            for k, s in enumerate(stack_strings):
                skip = False
                for ignore in self.ignored_strings:
                    if str(s.s).find(ignore) >= 0:
                        skip = True
                        break
                if not skip:
                    self.results['stack_strings'].append(s.s)
            self.search_ioc(self.results['stack_strings'])

        # Populate results[] with static strings
        self.log('info', 'Found static strings')
        for s in static_strings:
            skip = False
            for ignore in self.ignored_strings:
                if str(s).find(ignore) >= 0:
                    skip = True
                    break
            if not skip:
                self.results['static_strings'].append(s)
        self.search_ioc(self.results['static_strings'])

        # Deduplicate warnings
        self.results['warnings'] = list(dict.fromkeys(
            self.results['warnings']))

        return True
示例#4
0
def identify_decoding_functions(vw):
    selected_functions = floss_main.select_functions(vw, None)
    selected_plugin_names = floss_main.select_plugins(None)
    selected_plugins = filter(lambda p: str(p) in selected_plugin_names, floss_main.get_all_plugins())
    decoding_functions_candidates = im.identify_decoding_functions(vw, selected_plugins, selected_functions)
    return decoding_functions_candidates
示例#5
0
    def run(self):
        """Run Floss on analyzed file.
        @return: Floss results dict.
        """
        self.key = "strings"
        self.floss = self.options.get("floss")
        self.MIN_STRINGLEN = int(self.options.get("min_str_len"))
        self.MAX_STRINGLEN = self.options.get("max_str_len")
        self.MAX_STRINGCNT = self.options.get("max_str_cnt")
        self.MAX_FILESIZE = 16*1024*1024
        
        STRING_TYPES = [
            "decoded",
            "stack",
            "static"
        ]
        
        strings = {}

        if self.task["category"] == "file":
            if not os.path.exists(self.file_path):
                raise CuckooProcessingError(
                    "Sample file doesn't exist: \"%s\"" % self.file_path
                )

            try:
                f = File(self.file_path)
                filename = os.path.basename(self.task["target"])
                base_name = os.path.splitext(filename)[0]
                ext = filename.split(os.path.extsep)[-1].lower()
                data = open(self.file_path, "r").read(self.MAX_FILESIZE)
            except (IOError, OSError) as e:
                raise CuckooProcessingError("Error opening file %s" % e)
            
            # Extract static strings
            static_strings = re.findall("[\x1f-\x7e]{" + str(self.MIN_STRINGLEN) + ",}", data)
            for s in re.findall("(?:[\x1f-\x7e][\x00]){" + str(self.MIN_STRINGLEN) + ",}", data):
                static_strings.append(s.decode("utf-16le"))

            if self.MAX_STRINGLEN != 0:
                for i, s in enumerate(static_strings):
                    static_strings[i] = s[:self.MAX_STRINGLEN]

            if self.MAX_STRINGCNT != 0 and len(static_strings) > self.MAX_STRINGCNT:
                static_strings = static_strings[:self.MAX_STRINGCNT]
                static_strings.append("[snip]")

            package = self.task.get("package")

            if self.floss and (package == "exe" or ext == "exe" or "PE32" in f.get_type()):
                # Disable floss verbose logging
                main.set_logging_levels()
                
                try:
                    # Prepare Floss for extracting hidden & encoded strings
                    vw = vivisect.VivWorkspace()
                    vw.loadFromFile(self.file_path)
                    vw.analyze()

                    selected_functions = main.select_functions(vw, None)
                    decoding_functions_candidates = id_man.identify_decoding_functions(
                        vw, main.get_all_plugins(), selected_functions
                    )
                except Exception as e:
                    raise CuckooProcessingError("Error analyzing file with vivisect: %s" % e)

                try:
                    # Decode & extract hidden & encoded strings
                    decoded_strings = main.decode_strings(
                        vw, decoding_functions_candidates, self.MIN_STRINGLEN
                    )
                    decoded_strs = main.filter_unique_decoded(decoded_strings)

                    stack_strings = stackstrings.extract_stackstrings(
                        vw, selected_functions, self.MIN_STRINGLEN
                    )
                    stack_strings = list(stack_strings)

                    decoded_strings = [x for x in decoded_strs if not x in static_strings]
                except Exception as e:
                    raise CuckooProcessingError("Error extracting strings with floss: %s" % e)

                if len(decoded_strings) or len(stack_strings):
                    # Create annotated scripts
                    if self.options.get("idapro_str_sct"):
                        idapro_sct_name = base_name + ".idb"
                        strings["idapro_sct_name"] = idapro_sct_name

                        main.create_ida_script(
                            self.file_path, os.path.join(self.str_script_path, idapro_sct_name), 
                            decoded_strings, stack_strings
                        )

                    if self.options.get("radare_str_sct"):
                        radare_sct_name = base_name + ".r2"
                        strings["radare_sct_name"] = radare_sct_name

                        main.create_r2_script(
                            self.file_path, os.path.join(self.str_script_path, radare_sct_name), 
                            decoded_strings, stack_strings
                        )

                    if self.options.get("x64dbg_str_sct"):
                        x64dbg_sct_name = base_name + ".json"
                        strings["x64dbg_sct_name"] = x64dbg_sct_name

                        imagebase = vw.filemeta.values()[0]['imagebase']
                        main.create_x64dbg_database(
                            self.file_path, os.path.join(self.str_script_path, base_name + ".json"), 
                            imagebase, decoded_strings
                        )

                # convert Floss strings into regular, readable strings
                for idx, s in enumerate(decoded_strings):
                    decoded_strings[idx] = main.sanitize_string_for_printing(s.s)

                for idx, s in enumerate(stack_strings):
                    stack_strings[idx] = s.s

                results = [decoded_strings, stack_strings, static_strings]

                for idx, str_type in enumerate(STRING_TYPES):
                    strings[str_type] = results[idx]

            else:
                strings["static"] = static_strings

        return strings