Esempio n. 1
0
async def get_nodes(filter_node=None,
                    offset=0,
                    limit=common.database_limit,
                    sort=None,
                    search=None,
                    select=None,
                    filters={},
                    q=''):
    # set default value to 'filter_type' parameter
    filter_type = filters['type'] if 'type' in filters else 'all'

    if q:
        # if exists q parameter, apply limit and offset after filtering by q
        arguments = {
            'filter_node': filter_node,
            'offset': 0,
            'limit': common.database_limit,
            'sort': sort,
            'search': search,
            'select': select,
            'filter_type': filter_type
        }
    else:
        arguments = {
            'filter_node': filter_node,
            'offset': offset,
            'limit': limit,
            'sort': sort,
            'search': search,
            'select': select,
            'filter_type': filter_type
        }

    result = json.loads(await local_client.execute(
        command=b'get_nodes',
        data=json.dumps(arguments).encode(),
        wait_for_complete=False))
    if 'error' in result and result['error'] > 0:
        raise Exception(result['message'])

    if q:
        result['items'] = filter_array_by_query(q, result['items'])
        # get totalItems after applying q filter
        result['totalItems'] = len(result['items'])
        # apply offset and limit filters
        result['items'] = result['items'][offset:offset + limit]

    return result
Esempio n. 2
0
    def get_decoders(offset=0,
                     limit=common.database_limit,
                     sort=None,
                     search=None,
                     filters={},
                     q=''):
        """
        Gets a list of available decoders.

        :param offset: First item to return.
        :param limit: Maximum number of items to return.
        :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
        :param search: Looks for items with the specified string.
        :param filters: Defines field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}.
            This filter is used for filtering by 'status', 'path', 'file', 'name' and 'parents'.
        :param q: Defines query to filter.

        :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)}
        """
        # set default values to parameters
        status = filters.get('status', None)
        path = filters.get('path', None)
        file_ = filters.get('file', None)
        name = filters.get('name', None)
        parents = filters.get('parents', None)

        status = Decoder.__check_status(status)
        all_decoders = []

        for decoder_file in Decoder.get_decoders_files(status=status,
                                                       limit=None)['items']:
            all_decoders.extend(
                Decoder.__load_decoders_from_file(decoder_file['file'],
                                                  decoder_file['path'],
                                                  decoder_file['status']))

        decoders = list(all_decoders)
        for d in all_decoders:
            if path and path != d.path:
                decoders.remove(d)
                continue
            if file_ and file_ != d.file:
                decoders.remove(d)
                continue
            if name and name != d.name:
                decoders.remove(d)
                continue
            if parents and 'parent' in d.details:
                decoders.remove(d)
                continue

        if search:
            decoders = search_array(decoders, search['value'],
                                    search['negation'])

        if q:
            # decoders contains a list of Decoder objects, it is necessary to cast it into dictionaries
            decoders = filter_array_by_query(
                q, [decoder.to_dict() for decoder in decoders])

        if sort:
            decoders = sort_array(decoders, sort['fields'], sort['order'],
                                  Decoder.SORT_FIELDS)
        else:
            decoders = sort_array(decoders, ['file', 'position'], 'asc')

        return {
            'items': cut_array(decoders, offset, limit),
            'totalItems': len(decoders)
        }
Esempio n. 3
0
def ossec_log(months=3,
              offset=0,
              limit=common.database_limit,
              sort=None,
              search=None,
              filters={},
              q=''):
    """
    Gets logs from ossec.log.

    :param months: Returns logs of the last n months. By default is 3 months.
    :param offset: First item to return.
    :param limit: Maximum number of items to return.
    :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
    :param search: Looks for items with the specified string.
    :param filters: Defines field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}.
            This filter is used for filtering by 'type_log' (all, error or info) or 'category' (i.e. ossec-remoted).
    :param q: Defines query to filter.
    :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)}
    """
    # set default values to 'type_log' and 'category' parameters
    type_log = filters.get('type_log', 'all')
    category = filters.get('category', 'all')

    logs = []

    first_date = previous_month(months)
    statfs_error = "ERROR: statfs('******') produced error: No such file or directory"

    for line in tail(common.ossec_log, 2000):
        log_fields = __get_ossec_log_fields(line)
        if log_fields:
            log_date, log_category, level, description = log_fields

            if log_date < first_date:
                continue

            if category != 'all':
                if log_category:
                    if log_category != category:
                        continue
                else:
                    continue

            # We transform local time (ossec.log) to UTC maintaining time integrity and log format
            log_line = {
                'timestamp':
                log_date.astimezone(
                    timezone.utc).strftime('%Y-%m-%d %H:%M:%S'),
                'tag':
                log_category,
                'level':
                level,
                'description':
                description
            }
            if type_log == 'all':
                logs.append(log_line)
            elif type_log.lower() == level.lower():
                if "ERROR: statfs(" in line:
                    if statfs_error in logs:
                        continue
                    else:
                        logs.append(statfs_error)
                else:
                    logs.append(log_line)
            else:
                continue
        else:
            if logs and line and log_category == logs[-1][
                    'tag'] and level == logs[-1]['level']:
                logs[-1]['description'] += "\n" + line

    if search:
        logs = search_array(logs, search['value'], search['negation'])

    if q:
        logs = filter_array_by_query(q, logs)

    if sort:
        if sort['fields']:
            logs = sort_array(logs,
                              order=sort['order'],
                              sort_by=sort['fields'])
        else:
            logs = sort_array(logs, order=sort['order'], sort_by=['timestamp'])
    else:
        logs = sort_array(logs, order='desc', sort_by=['timestamp'])

    return {'items': cut_array(logs, offset, limit), 'totalItems': len(logs)}
Esempio n. 4
0
    def get_rules(offset=0,
                  limit=common.database_limit,
                  sort=None,
                  search=None,
                  filters={},
                  q=''):
        """
        Gets a list of rules.

        :param offset: First item to return.
        :param limit: Maximum number of items to return.
        :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
        :param search: Looks for items with the specified string.
        :param filters: Defines field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}.
            This filter is used for filtering by 'status', 'group', 'pci', 'gpg13', 'gdpr', 'hipaa', 'nist-800-53',
            'file', 'path', 'id' and 'level'.
        :param q: Defines query to filter.

        :return: Dictionary: {'items': array of items, 'totalItems': Number of items (without applying the limit)}
        """
        # set default values to parameters
        status = filters.get('status', None)
        group = filters.get('group', None)
        pci = filters.get('pci', None)
        gpg13 = filters.get('gpg13', None)
        gdpr = filters.get('gdpr', None)
        hipaa = filters.get('hipaa', None)
        nist_800_53 = filters.get('nist-800-53', None)
        path = filters.get('path', None)
        file_ = filters.get('file', None)
        id_ = filters.get('id', None)
        level = filters.get('level', None)

        all_rules = []

        if level:
            levels = level.split('-')
            if len(levels) < 0 or len(levels) > 2:
                raise WazuhException(1203)

        for rule_file in Rule.get_rules_files(status=status,
                                              limit=None)['items']:
            all_rules.extend(
                Rule.__load_rules_from_file(rule_file['file'],
                                            rule_file['path'],
                                            rule_file['status']))

        rules = list(all_rules)
        for r in all_rules:
            if group and group not in r.groups:
                rules.remove(r)
                continue
            elif pci and pci not in r.pci:
                rules.remove(r)
                continue
            elif gpg13 and gpg13 not in r.gpg13:
                rules.remove(r)
                continue
            elif gdpr and gdpr not in r.gdpr:
                rules.remove(r)
                continue
            elif hipaa and hipaa not in r.hipaa:
                rules.remove(r)
                continue
            elif nist_800_53 and nist_800_53 not in r.nist_800_53:
                rules.remove(r)
                continue
            elif path and path != r.path:
                rules.remove(r)
                continue
            elif file_ and file_ != r.file:
                rules.remove(r)
                continue
            elif id_ and int(id_) != r.id:
                rules.remove(r)
                continue
            elif level:
                if len(levels) == 1:
                    if int(levels[0]) != r.level:
                        rules.remove(r)
                        continue
                elif not (int(levels[0]) <= r.level <= int(levels[1])):
                    rules.remove(r)
                    continue

        if search:
            rules = search_array(rules, search['value'], search['negation'])

        if q:
            # rules contains a list of Rule objects, it is necessary to cast it into dictionaries
            rules = filter_array_by_query(q,
                                          [rule.to_dict() for rule in rules])

        if sort:
            rules = sort_array(rules, sort['fields'], sort['order'],
                               Rule.SORT_FIELDS)
        else:
            rules = sort_array(rules, ['id'], 'asc')

        return {
            'items': cut_array(rules, offset, limit),
            'totalItems': len(rules)
        }