Пример #1
0
def get_random_tags() -> dict:
    desired_tag_types = [
        'attribution.actor', 'network.static.ip', 'network.dynamic.ip',
        'network.static.domain', 'network.dynamic.domain',
        'network.static.uri', 'network.dynamic.uri', 'av.virus_name',
        'attribution.implant', 'file.rule.yara', 'file.behavior',
        'attribution.exploit', 'technique.packer', 'technique.obfuscation'
    ]
    out = {}
    flat_fields = Tagging.flat_fields()
    tag_list = random.choices(list(flat_fields.keys()), k=random.randint(0, 2))
    tag_list.extend(random.choices(desired_tag_types, k=random.randint(1, 2)))
    for key in tag_list:
        parts = key.split(".")
        d = out
        for part in parts[:-1]:
            if part not in d:
                d[part] = dict()
            d = d[part]

        if parts[-1] not in d:
            d[parts[-1]] = []

        for _ in range(random.randint(1, 2)):
            d[parts[-1]].append(
                random_data_for_field(flat_fields[key],
                                      key.split(".")[-1]))

    return out
Пример #2
0
    def __init__(self, data, log=None):
        valid_tags = set(Tagging.flat_fields().keys())

        self.match = data.get('match', {})
        self.regex = data.get('regex', {})
        self.log = log

        # Validate matches and regex
        for section, item in {
                'match': self.match,
                'regex': self.regex
        }.items():
            if not isinstance(item, dict):
                raise InvalidWhitelist(
                    f"Section {section} should be of type: DICT")

            for k, v in item.items():
                if not isinstance(v, list):
                    raise InvalidWhitelist(
                        f"Values in the {section} section should all be of type: LIST"
                    )

                if k not in valid_tags:
                    raise InvalidWhitelist(
                        f"Key ({k}) in the {section} section is not a valid tag."
                    )

                if section == 'regex':
                    self.regex[k] = [re.compile(x) for x in v]
Пример #3
0
def get_systems_constants(**_):
    """
    Return the current system configuration constants which includes:
        * Priorities
        * File types
        * Service tag types
        * Service tag contexts

    Variables: 
    None
    
    Arguments: 
    None
    
    Data Block:
    None
    
    Result example:
    {
        "priorities": {},
        "file_types": [],
        "tag_types": [],
        "tag_contexts": []
    }
    """
    accepts_map = {}
    rejects_map = {}
    default_list = []

    for srv in STORAGE.list_all_services(as_obj=False):
        name = srv.get('name', None)
        if name:
            accept = srv.get('accepts', DEFAULT_SERVICE_ACCEPTS)
            reject = srv.get('rejects', DEFAULT_SERVICE_REJECTS)
            if accept == DEFAULT_SERVICE_ACCEPTS and reject == DEFAULT_SERVICE_REJECTS:
                default_list.append(name)
            else:
                accepts_map[name] = re.compile(accept)
                rejects_map[name] = re.compile(reject)

    out = {
        "max_priority":
        constants.MAX_PRIORITY,
        "priorities":
        constants.PRIORITIES,
        "file_types": [[
            t,
            sorted([
                x for x in accepts_map.keys() if re.match(accepts_map[x], t)
                and not re.match(rejects_map[x], t)
            ])
        ] for t in sorted(constants.RECOGNIZED_TYPES.keys())],
        "tag_types":
        sorted(list(Tagging.flat_fields().keys()))
    }
    out['file_types'].insert(0, ["*", default_list])

    return make_api_response(out)
Пример #4
0
 def start(self):
     yara_externals = {
         f'al_{x.replace(".", "_")}': ""
         for x in Tagging.flat_fields().keys()
     }
     yara_externals.update({"al_file_rule_yara": ""})
     file_parsers, tag_parsers = cli.compile(yara_externals)
     self.log.info(f"loaded {file_parsers}")
     cli.validate_parser_config()
     self.file_parsers = file_parsers
     self.tag_parsers = tag_parsers
Пример #5
0
def put_tag_safelist(**_):
    """
    Save a new version of the tag_safelist file

    Variables:
    None

    Arguments:
    None

    Data Block:
    <new tag_safelist.yml file>

    Result example:
    {"success": true}
    """
    tag_safelist_yml = request.json

    try:
        yml_data = yaml.safe_load(tag_safelist_yml)
        for key in yml_data.keys():
            if key not in ['match', 'regex']:
                raise Exception('Invalid key found.')

            fields = Tagging.flat_fields()
            for tag_type in ['match', 'regex']:
                for key, value in yml_data[tag_type].items():
                    if key not in fields:
                        raise Exception(f'{key} is not a valid tag type')

                    if not isinstance(value, list):
                        raise Exception(
                            f'Value for {key} should be a list of strings')
    except Exception as e:
        return make_api_response(
            None, f"Invalid tag_safelist.yml file submitted: {str(e)}", 400)

    with forge.get_cachestore('system', config=config,
                              datastore=STORAGE) as cache:
        cache.save('tag_safelist_yml',
                   tag_safelist_yml.encode('utf-8'),
                   ttl=ADMIN_FILE_TTL,
                   force=True)

    return make_api_response({'success': True})
 def __init__(self, config=None):
     externals = list(Tagging.flat_fields().keys())
     super().__init__(config, name="TagCheck", externals=externals)
Пример #7
0
def get_systems_constants(**_):
    """
    Return the current system configuration constants which includes:
        * Priorities
        * File types
        * Service tag types
        * Service tag contexts

    Variables:
    None

    Arguments:
    None

    Data Block:
    None

    Result example:
    {
        "priorities": {},
        "file_types": [],
        "tag_types": [],
        "tag_contexts": []
    }
    """
    accepts_map = {}
    rejects_map = {}
    default_list = []

    recognized_types = set(IDENTIFY.trusted_mimes.values())
    recognized_types = recognized_types.union(
        set([x['al_type'] for x in IDENTIFY.magic_patterns]))

    with open(IDENTIFY.magic_file.split(":")[0]) as fh:
        for values in magic_custom.findall(fh.read()):
            recognized_types.add(values)

    with open(IDENTIFY.yara_file) as fh:
        for values in yara_custom.findall(fh.read()):
            recognized_types.add(values)

    for srv in STORAGE.list_all_services(as_obj=False):
        name = srv.get('name', None)
        if name:
            accept = srv.get('accepts', DEFAULT_SERVICE_ACCEPTS)
            reject = srv.get('rejects', DEFAULT_SERVICE_REJECTS)
            if accept == DEFAULT_SERVICE_ACCEPTS and reject == DEFAULT_SERVICE_REJECTS:
                default_list.append(name)
            else:
                accepts_map[name] = re.compile(accept)
                rejects_map[name] = re.compile(reject)

    out = {
        "max_priority":
        constants.MAX_PRIORITY,
        "priorities":
        constants.PRIORITIES,
        "file_types": [[
            t,
            sorted([
                x for x in accepts_map.keys() if re.match(accepts_map[x], t)
                and not re.match(rejects_map[x], t)
            ])
        ] for t in sorted(list(recognized_types))],
        "tag_types":
        sorted(list(Tagging.flat_fields().keys()))
    }
    out['file_types'].insert(0, ["*", default_list])

    return make_api_response(out)
def test_update_single_alert(config, datastore):
    persistent_redis = get_client(
        host=config.core.redis.persistent.host,
        port=config.core.redis.persistent.port,
        private=False,
    )
    alerter = Alerter()
    # Swap our alerter onto a private queue so our test doesn't get intercepted
    alerter.alert_queue = alert_queue = NamedQueue(uuid.uuid4().hex,
                                                   persistent_redis)

    # Get a random submission
    submission = random.choice(all_submissions)
    all_submissions.remove(submission)

    # Generate a task for the submission
    ingest_msg = random_model_obj(IngestTask)
    ingest_msg.submission.sid = submission.sid
    ingest_msg.submission.metadata = submission.metadata
    ingest_msg.submission.params = submission.params
    ingest_msg.submission.files = submission.files

    alert_queue.push(ingest_msg.as_primitives())
    alert_type = alerter.run_once()
    assert alert_type == 'create'
    datastore.alert.commit()

    original_alert = datastore.alert.get(
        datastore.alert.search(f"sid:{submission.sid}", fl="id",
                               as_obj=False)['items'][0]['id'])
    assert original_alert is not None

    # Generate a children task
    child_submission = Submission(submission.as_primitives())
    child_submission.sid = get_random_id()
    child_submission.params.psid = submission.sid

    # Alter the result of one of the services
    r = None
    while r is None:
        r = datastore.result.get(random.choice(child_submission.results))

    for s in r.result.sections:
        old_tags = s.tags.as_primitives(strip_null=True)
        s.tags = Tagging(recursive_extend(old_tags, get_random_tags()))

    datastore.result.save(r.build_key(), r)
    datastore.result.commit()

    datastore.submission.save(child_submission.sid, child_submission)
    datastore.submission.commit()

    child_ingest_msg = random_model_obj(IngestTask)
    child_ingest_msg.submission.sid = child_submission.sid
    child_ingest_msg.submission.metadata = child_submission.metadata
    child_ingest_msg.submission.params = child_submission.params
    child_ingest_msg.submission.files = child_submission.files
    child_ingest_msg.submission.time = ingest_msg.submission.time

    alert_queue.push(child_ingest_msg.as_primitives())
    alert_type = alerter.run_once()
    assert alert_type == 'update'
    datastore.alert.commit()

    updated_alert = datastore.alert.get(
        datastore.alert.search(f"sid:{child_submission.sid}",
                               fl="id",
                               as_obj=False)['items'][0]['id'])
    assert updated_alert is not None

    assert updated_alert != original_alert
Пример #9
0
from assemblyline.odm.models.tagging import Tagging

from yara_.yara_updater import *

UPDATE_CONFIGURATION_PATH = os.environ.get(
    'UPDATE_CONFIGURATION_PATH', "/tmp/tagcheck_updater_config.yaml")
UPDATE_OUTPUT_PATH = os.environ.get('UPDATE_OUTPUT_PATH',
                                    "/tmp/tagcheck_updater_output")
UPDATE_DIR = os.path.join(tempfile.gettempdir(), 'tagcheck_updates')

YARA_EXTERNALS = {
    f'al_{x.replace(".", "_")}': ''
    for x in list(Tagging.flat_fields().keys())
}

if __name__ == '__main__':
    al_log.init_logging('updater.tagcheck')
    logger = logging.getLogger('assemblyline.updater.tagcheck')
    yara_update("tagcheck", UPDATE_CONFIGURATION_PATH, UPDATE_OUTPUT_PATH,
                UPDATE_DIR, YARA_EXTERNALS, logger)