Example #1
0
    def _generator(self):

        rules = yarascan.YaraScan.process_yara_options(dict(self.config))

        filter_func = pslist.PsList.create_pid_filter(
            self.config.get('pid', None))

        for task in pslist.PsList.list_processes(
                context=self.context,
                layer_name=self.config['primary'],
                symbol_table=self.config['nt_symbols'],
                filter_func=filter_func):
            layer_name = task.add_process_layer()
            layer = self.context.layers[layer_name]
            for offset, rule_name, name, value in layer.scan(
                    context=self.context,
                    scanner=yarascan.YaraScanner(rules=rules),
                    sections=self.get_vad_maps(task)):
                yield 0, (format_hints.Hex(offset), task.UniqueProcessId,
                          rule_name, name, value)
Example #2
0
    def _generator(self):
        if not has_yara:
            log.error("You must install yara")
            return

        config = dict()

        if self.config.get('yara_file', None) is not None:
            RULES = yara.compile(file=resources.ResourceAccessor().open(
                self.config['yara_file'], "rb"))
        else:
            # https://github.com/Yara-Rules/rules/blob/master/malware/MALW_Pony.yar
            SIGS = {
                'pony':
                '''

                    rule pony {
                        meta:
                            author = "Brian Wallace @botnet_hunter"
                            author_email = "*****@*****.**"
                            date = "2014-08-16"
                            description = "Identify Pony"
                        strings:
                            $ = "YUIPWDFILE0YUIPKDFILE0YUICRYPTED0YUI1.0"
                        condition:
                            all of them
                }
                '''
            }

            RULES = yara.compile(sources=SIGS)

        #filter_func = pslist.PsList.create_pid_filter([self.config.get('pid', None)])
        filter_func = pslist.PsList.create_pid_filter(
            [self.config.get('pid', None)])

        for task in pslist.PsList.list_processes(
                context=self.context,
                layer_name=self.config['primary'],
                symbol_table=self.config['nt_symbols'],
                filter_func=filter_func):
            try:
                proc_layer_name = task.add_process_layer()
            except exceptions.InvalidAddressException:
                continue

            proc_layer = self.context.layers[proc_layer_name]

            for offset, rule_name, name, value in proc_layer.scan(
                    context=self.context,
                    scanner=yarascan.YaraScanner(rules=RULES),
                    sections=vadyarascan.VadYaraScan.get_vad_maps(task)):
                log.debug("Got a Yara match!")

                vad, vad_start, vad_end = self.get_vad(task, offset)
                if vad is None:
                    log.debug("VAD not found")
                    return

                full_pe = io.BytesIO()
                chunk_size = 1024 * 1024 * 10
                #vadinfo.VadInfo.vad_dump(self.context, task, vad, full_pe)
                offset = vad_start
                while offset < vad_end:
                    to_read = min(chunk_size, vad_end - offset)
                    data = proc_layer.read(offset, to_read, pad=True)
                    if not data:
                        break
                    full_pe.write(data)
                    offset += to_read
                if not full_pe:
                    continue
                config = self.get_config(full_pe.getvalue())
                if not config:
                    log.debug("Config extraction failed")
                    continue

                yield (0, (format_hints.Hex(offset), task.UniqueProcessId,
                           str(config)))
Example #3
0
    def _generator(self):
        layer = self.context.layers[self.config['primary']]

        # Yara Rule to scan for MFT Header Signatures
        rules = yarascan.YaraScan.process_yara_options(
            {'yara_rules': '/FILE0|FILE\*|BAAD/'})

        # Read in the Symbol File
        symbol_table = intermed.IntermediateSymbolTable.create(
            context=self.context,
            config_path=self.config_path,
            sub_path="windows",
            filename="mft",
            class_types={
                'FILE_NAME_ENTRY': mft.MFTFileName,
                'MFT_ENTRY': mft.MFTEntry
            })

        # get each of the individual Field Sets
        mft_object = symbol_table + constants.BANG + "MFT_ENTRY"
        attribute_object = symbol_table + constants.BANG + "ATTRIBUTE"
        header_object = symbol_table + constants.BANG + "ATTR_HEADER"
        si_object = symbol_table + constants.BANG + "STANDARD_INFORMATION_ENTRY"
        fn_object = symbol_table + constants.BANG + "FILE_NAME_ENTRY"

        # Scan the layer for Raw MFT records and parse the fields
        for offset, _rule_name, _name, _value in layer.scan(
                context=self.context,
                scanner=yarascan.YaraScanner(rules=rules)):
            try:
                mft_record = self.context.object(mft_object,
                                                 offset=offset,
                                                 layer_name=layer.name)
                # We will update this on each pass in the next loop and use it as the new offset.
                attr_base_offset = mft_record.FirstAttrOffset

                attr_header = self.context.object(header_object,
                                                  offset=offset +
                                                  attr_base_offset,
                                                  layer_name=layer.name)

                # There is no field that has a count of Attributes
                # Keep Attempting to read attributes until we get an invalid attr_header.AttrType

                while attr_header.AttrType.is_valid_choice:
                    vollog.debug(f"Attr Type: {attr_header.AttrType.lookup()}")

                    # Offset past the headers to the attribute data
                    attr_data_offset = offset + attr_base_offset + self.context.symbol_space.get_type(
                        attribute_object).relative_child_offset("Attr_Data")

                    # MFT Flags determine the file type or dir
                    # If we don't have a valid enum, coerce to hex so we can keep the record
                    try:
                        mft_flag = mft_record.Flags.lookup()
                    except ValueError:
                        mft_flag = hex(mft_record.Flags)

                    # Standard Information Attribute
                    if attr_header.AttrType.lookup() == 'STANDARD_INFORMATION':
                        attr_data = self.context.object(
                            si_object,
                            offset=attr_data_offset,
                            layer_name=layer.name)

                        yield 0, (
                            format_hints.Hex(attr_data_offset),
                            mft_record.get_signature(),
                            mft_record.RecordNumber,
                            mft_record.LinkCount,
                            mft_flag,
                            renderers.NotApplicableValue(),
                            attr_header.AttrType.lookup(),
                            conversion.wintime_to_datetime(
                                attr_data.CreationTime),
                            conversion.wintime_to_datetime(
                                attr_data.ModifiedTime),
                            conversion.wintime_to_datetime(
                                attr_data.UpdatedTime),
                            conversion.wintime_to_datetime(
                                attr_data.AccessedTime),
                            renderers.NotApplicableValue(),
                        )

                    # File Name Attribute
                    if attr_header.AttrType.lookup() == 'FILE_NAME':
                        attr_data = self.context.object(
                            fn_object,
                            offset=attr_data_offset,
                            layer_name=layer.name)
                        file_name = attr_data.get_full_name()

                        # If we don't have a valid enum, coerce to hex so we can keep the record
                        try:
                            permissions = attr_data.Flags.lookup()
                        except ValueError:
                            permissions = hex(attr_data.Flags)

                        yield 1, (format_hints.Hex(attr_data_offset),
                                  mft_record.get_signature(),
                                  mft_record.RecordNumber,
                                  mft_record.LinkCount, mft_flag, permissions,
                                  attr_header.AttrType.lookup(),
                                  conversion.wintime_to_datetime(
                                      attr_data.CreationTime),
                                  conversion.wintime_to_datetime(
                                      attr_data.ModifiedTime),
                                  conversion.wintime_to_datetime(
                                      attr_data.UpdatedTime),
                                  conversion.wintime_to_datetime(
                                      attr_data.AccessedTime), file_name)

                    # If there's no advancement the loop will never end, so break it now
                    if attr_header.Length == 0:
                        break

                    # Update the base offset to point to the next attribute
                    attr_base_offset += attr_header.Length
                    # Get the next attribute
                    attr_header = self.context.object(header_object,
                                                      offset=offset +
                                                      attr_base_offset,
                                                      layer_name=layer.name)

            except exceptions.PagedInvalidAddressException:
                pass