Ejemplo n.º 1
0
def get_agents_summary_os(agent_list=None):
    """Gets a list of available OS.

    :param agent_list: List of agents ID's.
    :return: WazuhResult.
    """
    result = AffectedItemsWazuhResult(
        none_msg='Could not get the operative system of the agents',
        all_msg='Showing the operative system of all specified agents',
        some_msg='Could not get the operative system of some agents')
    if len(agent_list) != 0:
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(),
                                        permitted_resources=agent_list)

        db_query = WazuhDBQueryAgents(select=['os.platform'],
                                      default_sort_field='os_platform',
                                      min_select_fields=set(),
                                      distinct=True,
                                      **rbac_filters)
        query_data = db_query.run()
        query_data['items'] = [
            row['os']['platform'] for row in query_data['items']
        ]
        result.affected_items = query_data['items']
        result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 2
0
def get_outdated_agents(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None,
                        q=None):
    """Gets the outdated agents.

    :param agent_list: List of agents ID's.
    :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 select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param q: Defines query to filter in DB.
    :return: AffectedItemsWazuhResult.
    """

    result = AffectedItemsWazuhResult(all_msg='All selected agents information was returned',
                                      some_msg='Some agents information was not returned',
                                      none_msg='No agent information was returned'
                                      )
    if agent_list:
        # Get manager version
        manager = Agent(id='000')
        manager.load_info_from_db()

        select = ['version', 'id', 'name'] if select is None else select
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list)

        db_query = WazuhDBQueryAgents(offset=offset, limit=limit, sort=sort, search=search, select=select,
                                      query=f"version!={manager.version}" + (';' + q if q else ''), **rbac_filters)
        data = db_query.run()
        result.affected_items = data['items']
        result.total_affected_items = data['totalItems']

    return result
Ejemplo n.º 3
0
def get_agents_summary_os(agent_list=None):
    """Get a list of available OS.

    Parameters
    ----------
    agent_list : list[str]
       List of agents ID's

    Returns
    -------
    WazuhResult
    """
    result = AffectedItemsWazuhResult(
        none_msg='Could not get the operative system of the agents',
        all_msg='Showing the operative system of all specified agents',
        some_msg='Could not get the operative system of some agents')
    if agent_list:
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(),
                                        permitted_resources=agent_list)

        # We don't consider agent 000 in order to get the summary
        db_query = WazuhDBQueryAgents(select=['os.platform'],
                                      default_sort_field='os_platform',
                                      min_select_fields=set(),
                                      distinct=True,
                                      query="id!=000",
                                      **rbac_filters)
        query_data = db_query.run()
        query_data['items'] = [
            row['os']['platform'] for row in query_data['items']
        ]
        result.affected_items = query_data['items']
        result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 4
0
def assign_agents_to_group(group_list=None, agent_list=None, replace=False, replace_list=None):
    """Assign a list of agents to a group.

    :param group_list: List of Group names.
    :param agent_list: List of Agent IDs.
    :param replace: Whether to append new group to current agent's group or replace it.
    :param replace_list: List of Group names that can be replaced.
    :return: AffectedItemsWazuhResult.
    """
    group_id = group_list[0]
    result = AffectedItemsWazuhResult(all_msg=f'All selected agents were assigned to {group_id}'
                                              f'{" and removed from the other groups" if replace else ""}',
                                      some_msg=f'Some agents were not assigned to {group_id}'
                                               f'{" and removed from the other groups" if replace else ""}',
                                      none_msg='No agents were assigned to {0}'.format(group_id)
                                      )
    # Check if the group exists
    if not Agent.group_exists(group_id):
        raise WazuhResourceNotFound(1710)
    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            if agent_id == "000":
                raise WazuhError(1703)
            Agent.add_group_to_agent(group_id, agent_id, force=True, replace=replace, replace_list=replace_list)
            result.affected_items.append(agent_id)
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)

    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort(key=int)

    return result
Ejemplo n.º 5
0
def get_agents_summary_status(agent_list=None):
    """Count the number of agents by status.

    Parameters
    ----------
    agent_list : list[str]
       List of agents ID's

    Returns
    -------
    WazuhResult
    """
    summary = {
        'active': 0,
        'disconnected': 0,
        'never_connected': 0,
        'pending': 0,
        'total': 0
    }
    if agent_list:
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(),
                                        permitted_resources=agent_list)

        # We don't consider agent 000 in order to get the summary
        db_query = WazuhDBQueryAgents(limit=None,
                                      select=['status'],
                                      query="id!=000",
                                      **rbac_filters)
        data = db_query.run()

        for agent in data['items']:
            summary[agent['status']] += 1
            summary['total'] += 1

    return WazuhResult({'data': summary})
Ejemplo n.º 6
0
def remove_agents_from_group(agent_list=None, group_list=None):
    """Remove a list of agents assignment from a specified group.

    :param agent_list: List of agents ID's.
    :param group_list: List of Group names.
    :return: AffectedItemsWazuhResult.
    """
    group_id = group_list[0]
    result = AffectedItemsWazuhResult(
        all_msg=f'All selected agents were removed from group {group_id}',
        some_msg=f'Some agents were not removed from group {group_id}',
        none_msg=f'No agent was removed from group {group_id}')

    system_groups = get_groups()
    system_agents = get_agents_info()
    # Check if group exists
    if group_id not in system_groups:
        raise WazuhResourceNotFound(1710)

    for agent_id in agent_list:
        try:
            if agent_id == '000':
                raise WazuhError(1703)
            elif agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            Agent.unset_single_group_agent(agent_id=agent_id,
                                           group_id=group_id,
                                           force=True)
            result.affected_items.append(agent_id)
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)
    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort(key=int)

    return result
Ejemplo n.º 7
0
def delete_agents(agent_list=None, backup=False, purge=False, use_only_authd=False, filters=None, q=None):
    """Delete a list of agents.

    Parameters
    ----------
    agent_list : list
        List of agents ID's to be deleted.
    backup : bool
        Create backup before removing the agent.
    purge : bool
        Delete definitely from key store.
    use_only_authd : bool
        Force the use of authd when adding and removing agents.
    filters : dict
        Define required field filters. Format: {"field1":"value1", "field2":["value2","value3"]}
    q : str
        Define query to filter in DB.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Result with affected agents.
    """
    result = AffectedItemsWazuhResult(all_msg='All selected agents were deleted',
                                      some_msg='Some agents were not deleted',
                                      none_msg='No agents were deleted'
                                      )
    if agent_list:
        system_agents = get_agents_info()
        rbac_filters = get_rbac_filters(system_resources=system_agents, permitted_resources=agent_list,
                                        filters=filters)

        db_query = WazuhDBQueryAgents(limit=None, select=["id"], query=q, **rbac_filters)
        data = db_query.run()
        can_purge_agents = list(map(operator.itemgetter('id'), data['items']))
        for agent_id in agent_list:
            try:
                if agent_id == "000":
                    raise WazuhError(1703)
                elif agent_id not in system_agents:
                    raise WazuhResourceNotFound(1701)
                elif agent_id not in can_purge_agents:
                    raise WazuhError(
                        1731,
                        extra_message="some of the requirements are not met -> {}".format(
                            ', '.join(f"{key}: {value}" for key, value in filters.items() if key != 'rbac_ids') +
                            (f', q: {q}' if q else '')
                        )
                    )
                else:
                    my_agent = Agent(agent_id)
                    my_agent.load_info_from_db()
                    my_agent.remove(backup=backup, purge=purge, use_only_authd=use_only_authd)
                    result.affected_items.append(agent_id)
            except WazuhException as e:
                result.add_failed_item(id_=agent_id, error=e)
        result.total_affected_items = len(result.affected_items)
        result.affected_items.sort(key=int)

    return result
Ejemplo n.º 8
0
def restart_agents(agent_list=None):
    """Restart a list of agents.

    :param agent_list: List of agents ID's.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg='Restart command was sent to all agents',
                                      some_msg='Restart command was not sent to some agents',
                                      none_msg='Restart command was not sent to any agent'
                                      )

    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            if agent_id == "000":
                raise WazuhError(1703)
            Agent(agent_id).restart()
            result.affected_items.append(agent_id)
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)

    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort(key=int)

    return result
Ejemplo n.º 9
0
def get_distinct_agents(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None,
                        fields=None, q=None):
    """ Gets all the different combinations that all system agents have for the selected fields. It also indicates the
    total number of agents that have each combination.

    :param agent_list: List of agents ID's.
    :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 select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]}
    :param q: Defines query to filter in DB.
    :param fields: Fields to group by
    :return: WazuhResult
    """

    result = AffectedItemsWazuhResult(all_msg='All selected agents information was returned',
                                      some_msg='Some agents information was not returned',
                                      none_msg='No agent information was returned'
                                      )

    if agent_list:
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(), permitted_resources=agent_list)

        db_query = WazuhDBQueryGroupByAgents(filter_fields=fields, offset=offset, limit=limit, sort=sort,
                                             search=search, select=select, query=q, min_select_fields=set(), count=True,
                                             get_data=True, **rbac_filters)

        data = db_query.run()
        result.affected_items.extend(data['items'])
        result.total_affected_items = data['totalItems']

    return result
Ejemplo n.º 10
0
def clear(agent_list=None):
    """Clear the rootcheck database for a list of agents.

    Parameters
    ----------
    agent_list : list
        List of agent ids.

    Returns
    -------
    result : AffectedItemsWazuhResult
        JSON containing the affected agents.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Rootcheck database was cleared on returned agents',
        some_msg='Rootcheck database was not cleared on some agents',
        none_msg="No rootcheck database was cleared")

    wdb_conn = WazuhDBConnection()
    for agent_id in agent_list:
        if agent_id not in get_agents_info():
            result.add_failed_item(id_=agent_id,
                                   error=WazuhResourceNotFound(1701))
        else:
            try:
                wdb_conn.execute(f"agent {agent_id} rootcheck delete",
                                 delete=True)
                result.affected_items.append(agent_id)
            except WazuhError as e:
                result.add_failed_item(id_=agent_id, error=e)

    result.affected_items.sort(key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 11
0
def reconnect_agents(agent_list: Union[list, str] = None) -> AffectedItemsWazuhResult:
    """Force reconnect a list of agents.

    Parameters
    ----------
    agent_list : Union[list, str]
        List of agent IDs. All possible values from 000 onwards. Default `*`

    Returns
    -------
    AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(all_msg='Force reconnect command was sent to all agents',
                                      some_msg='Force reconnect command was not sent to some agents',
                                      none_msg='Force reconnect command was not sent to any agent'
                                      )

    system_agents = get_agents_info()
    wq = WazuhQueue(common.ARQUEUE)
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            if agent_id == "000":
                raise WazuhError(1703)
            Agent(agent_id).reconnect(wq)
            result.affected_items.append(agent_id)
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)
    wq.close()

    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort(key=int)

    return result
Ejemplo n.º 12
0
def delete_agents(agent_list=None,
                  backup=False,
                  purge=False,
                  status="all",
                  older_than="7d",
                  use_only_authd=False):
    """Deletes a list of agents.

    :param agent_list: List of agents ID's.
    :param backup: Create backup before removing the agent.
    :param purge: Delete definitely from key store.
    :param older_than:  Filters out disconnected agents for longer than specified. Time in seconds | "[n_days]d" |
    "[n_hours]h" | "[n_minutes]m" | "[n_seconds]s". For never_connected agents, uses the register date.
    :param status: Filters by agent status: active, disconnected or never_connected. Multiples statuses separated
    by commas.
    :param use_only_authd: Force the use of authd when adding and removing agents.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected agents were deleted',
        some_msg='Some agents were not deleted',
        none_msg='No agents were deleted')
    if len(agent_list) != 0:
        db_query = WazuhDBQueryAgents(limit=None,
                                      select=["id"],
                                      filters={
                                          'older_than': older_than,
                                          'status': status,
                                          'id': agent_list
                                      })
        data = db_query.run()
        can_purge_agents = list(map(operator.itemgetter('id'), data['items']))
        system_agents = get_agents_info()
        for agent_id in agent_list:
            try:
                if agent_id == "000":
                    raise WazuhError(1703)
                elif agent_id not in system_agents:
                    raise WazuhResourceNotFound(1701)
                else:
                    my_agent = Agent(agent_id)
                    my_agent.load_info_from_db()
                    if agent_id not in can_purge_agents:
                        raise WazuhError(
                            1731,
                            extra_message=
                            "The agent has a status different to '{0}' or the specified time "
                            "frame 'older_than {1}' does not apply".format(
                                status, older_than))
                    my_agent.remove(backup=backup,
                                    purge=purge,
                                    use_only_authd=use_only_authd)
                    result.affected_items.append(agent_id)
            except WazuhException as e:
                result.add_failed_item(id_=agent_id, error=e)
        result.total_affected_items = len(result.affected_items)
        result.affected_items.sort(key=int)
        result['older_than'] = older_than

    return result
Ejemplo n.º 13
0
def clear(agent_list=None):
    """Clear the syscheck database for a list of agents.

    :param agent_list: List of agent ids
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg='Syscheck database was cleared on returned agents',
                                      some_msg='Syscheck database was not cleared on some agents',
                                      none_msg="No syscheck database was cleared")
    wdb_conn = WazuhDBConnection()
    for agent in agent_list:
        if agent not in get_agents_info():
            result.add_failed_item(id_=agent, error=WazuhResourceNotFound(1701))
        else:
            try:
                wdb_conn.execute("agent {} sql delete from fim_entry".format(agent), delete=True)
                # Update key fields which contains keys to value 000
                wdb_conn.execute("agent {} sql update metadata set value = '000' "
                                 "where key like 'fim_db%'".format(agent), update=True)
                wdb_conn.execute("agent {} sql update metadata set value = '000' "
                                 "where key = 'syscheck-db-completed'".format(agent), update=True)
                result.affected_items.append(agent)
            except WazuhError as e:
                result.add_failed_item(id_=agent, error=e)

    result.affected_items.sort(key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 14
0
def get_agents_summary_status(agent_list=None):
    """Counts the number of agents by status.

    :param agent_list: List of agents ID's.
    :return: WazuhResult.
    """
    summary = {
        'active': 0,
        'disconnected': 0,
        'never_connected': 0,
        'pending': 0,
        'total': 0
    }
    if len(agent_list) != 0:
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(),
                                        permitted_resources=agent_list)

        db_query = WazuhDBQueryAgents(limit=None,
                                      select=['status'],
                                      **rbac_filters)
        data = db_query.run()

        for agent in data['items']:
            summary[agent['status']] += 1
            summary['total'] += 1

    return WazuhResult({'data': summary})
Ejemplo n.º 15
0
def get_agents_component_stats_json(agent_list=None, component=None):
    """Get statistics of an agent's component.

    Parameters
    ----------
    agent_list: list, optional
        List of agents ID's, by default None.
    component: str, optional
        Name of the component to get stats from, by default None.

    Returns
    -------
    AffectedItemsWazuhResult
        Component stats.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Statistical information for each agent was successfully read',
        some_msg='Could not read statistical information for some agents',
        none_msg='Could not read statistical information for any agent')
    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            result.affected_items.append(
                Agent(agent_id).get_stats(component=component))
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 16
0
def run(agent_list: Union[list, None] = None) -> AffectedItemsWazuhResult:
    """Run a rootcheck scan in the specified agents.

    Parameters
    ----------
    agent_list : Union[list, None]
         List of the agents IDs to run the scan for.

    Returns
    -------
    result : AffectedItemsWazuhResult
        JSON containing the affected agents.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Rootcheck scan was restarted on returned agents',
        some_msg='Rootcheck scan was not restarted on some agents',
        none_msg='No rootcheck scan was restarted')

    system_agents = get_agents_info()
    rbac_filters = get_rbac_filters(system_resources=system_agents,
                                    permitted_resources=agent_list)
    agent_list = set(agent_list)
    not_found_agents = agent_list - system_agents

    # Add non existent agents to failed_items
    [
        result.add_failed_item(id_=agent, error=WazuhResourceNotFound(1701))
        for agent in not_found_agents
    ]

    # Add non eligible agents to failed_items
    non_eligible_agents = WazuhDBQueryAgents(limit=None,
                                             select=["id", "status"],
                                             query=f'status!=active',
                                             **rbac_filters).run()['items']
    [
        result.add_failed_item(
            id_=agent['id'],
            error=WazuhError(1601,
                             extra_message=f'Status - {agent["status"]}'))
        for agent in non_eligible_agents
    ]

    wq = WazuhQueue(common.ARQUEUE)
    eligible_agents = agent_list - not_found_agents - {
        d['id']
        for d in non_eligible_agents
    }
    for agent_id in eligible_agents:
        try:
            wq.send_msg_to_agent(WazuhQueue.HC_SK_RESTART, agent_id)
            result.affected_items.append(agent_id)
        except WazuhError as e:
            result.add_failed_item(id_=agent_id, error=e)
    wq.close()
    result.affected_items.sort(key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 17
0
def _expand_resource(resource):
    """This function expand a specified resource depending of its type.
    
    Parameters
    ----------
    resource : str
        Resource to be expanded

    Returns
    -------
    str
        Result of the resource expansion.
    """
    name, attribute, value = resource.split(':')
    resource_type = ':'.join([name, attribute])

    # This is the special case, expand_group can receive * or the name of the group. That's why it' s always called
    if resource_type == 'agent:group':
        return expand_group(value)

    # We need to transform the wildcard * to the resource of the system
    if value == '*':
        if resource_type == 'agent:id':
            return get_agents_info()
        elif resource_type == 'group:id':
            return get_groups()
        elif resource_type == 'role:id':
            with RolesManager() as rm:
                roles = rm.get_roles()
            return {str(role_id.id) for role_id in roles}
        elif resource_type == 'policy:id':
            with PoliciesManager() as pm:
                policies = pm.get_policies()
            return {str(policy_id.id) for policy_id in policies}
        elif resource_type == 'user:id':
            users_system = set()
            with AuthenticationManager() as auth:
                users = auth.get_users()
            for user in users:
                users_system.add(str(user['user_id']))
            return users_system
        elif resource_type == 'rule:id':
            with RulesManager() as rum:
                rules = rum.get_rules()
            return {str(rule_id.id) for rule_id in rules}
        elif resource_type == 'rule:file':
            return expand_rules()
        elif resource_type == 'decoder:file':
            return expand_decoders()
        elif resource_type == 'list:file':
            return expand_lists()
        elif resource_type == 'node:id':
            return set(cluster_nodes.get())
        elif resource_type == '*:*':  # Resourceless
            return {'*'}
        return set()
    # We return the value casted to set
    else:
        return {value}
Ejemplo n.º 18
0
def get_distinct_agents(agent_list: list = None,
                        offset: int = 0,
                        limit: int = common.database_limit,
                        sort: str = None,
                        search: str = None,
                        fields: str = None,
                        q: str = None) -> AffectedItemsWazuhResult:
    """Get all the different combinations that all system agents have for the selected fields. It also indicates the
    total number of agents that have each combination.

    Parameters
    ----------
    agent_list : list
        List of agents ID's.
    fields : str
        List of fields to group by.
    offset : int
        First item to return.
    limit : int
        Maximum number of items to return.
    sort : str
        Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
    search : str
        Looks for items with the specified string. Format: {"fields": ["field1","field2"]}.
    q : str
        Query to filter results by. For example q="status=active"

    Returns
    -------
    AffectedItemsWazuhResult
    """

    result = AffectedItemsWazuhResult(
        all_msg='All selected agents information was returned',
        some_msg='Some agents information was not returned',
        none_msg='No agent information was returned')

    if agent_list:
        rbac_filters = get_rbac_filters(system_resources=get_agents_info(),
                                        permitted_resources=agent_list)

        db_query = WazuhDBQueryGroupByAgents(filter_fields=fields,
                                             select=fields,
                                             offset=offset,
                                             limit=limit,
                                             sort=sort,
                                             search=search,
                                             query=q,
                                             min_select_fields=set(),
                                             count=True,
                                             get_data=True,
                                             **rbac_filters)

        data = db_query.run()
        result.affected_items.extend(data['items'])
        result.total_affected_items = data['totalItems']

    return result
Ejemplo n.º 19
0
def get_ciscat_results(agent_list=None, offset=0, limit=common.database_limit, select=None, search=None, sort=None,
                       filters=None, nested=True, array=True, q=''):
    """ Get CIS-CAT results for a list of agents

    :param agent_list: list of Agent ID to get scan results from. Currently, only first item will be considered
    :param offset: First element to return in the collection
    :param limit: Maximum number of elements to return
    :param select: Select which fields to return
    :param search: Looks for items with the specified string. Begins with '-' for a complementary search
    :param sort: Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}
    :param filters: Fields to filter by
    :param nested: Nested fields
    :param array: Array
    :param q: Defines query to filter in DB.
    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='All CISCAT results were returned',
        some_msg='Some CISCAT results were not returned',
        none_msg='No CISCAT results were returned',
        sort_fields=['agent_id'] if sort is None else sort['fields'],
        sort_casting=['str'],
        sort_ascending=[sort['order'] == 'asc' for _ in sort['fields']] if sort is not None else ['True']
    )

    valid_select_fields = {'scan.id': 'scan_id', 'scan.time': 'scan_time', 'benchmark': 'benchmark',
                           'profile': 'profile', 'pass': '******', 'fail': 'fail', 'error': 'error',
                           'notchecked': 'notchecked', 'unknown': 'unknown', 'score': 'score'}
    table = 'ciscat_results'

    system_agents = get_agents_info()
    for agent in agent_list:
        try:
            if agent not in system_agents:
                raise WazuhResourceNotFound(1701)
            db_query = WazuhDBQuerySyscollector(agent_id=agent, offset=offset, limit=limit, select=select,
                                                search=search,
                                                sort=sort, filters=filters, fields=valid_select_fields, table=table,
                                                array=array, nested=nested, query=q)
            data = db_query.run()

            if len(data['items']) > 0:
                for item in data['items']:
                    item['agent_id'] = agent
                    result.affected_items.append(item)
                result.total_affected_items += data['totalItems']
        except WazuhResourceNotFound as e:
            result.add_failed_item(id_=agent, error=e)

    result.affected_items = merge(*[[res] for res in result.affected_items],
                                  criteria=result.sort_fields,
                                  ascending=result.sort_ascending,
                                  types=result.sort_casting)

    return result
Ejemplo n.º 20
0
def get_agents(agent_list=None,
               offset=0,
               limit=common.database_limit,
               sort=None,
               search=None,
               select=None,
               filters=None,
               q=None):
    """Gets a list of available agents with basic attributes.

    :param agent_list: List of agents ID's.
    :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 select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]}
    :param filters: Defines required field filters. Format: {"field1":"value1", "field2":["value2","value3"]}
    :param q: Defines query to filter in DB.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected agents information was returned',
        some_msg='Some agents information was not returned',
        none_msg='No agent information was returned')
    if agent_list:
        if filters is None:
            filters = dict()

        system_agents = get_agents_info()

        for agent_id in agent_list:
            if agent_id not in system_agents:
                result.add_failed_item(id_=agent_id,
                                       error=WazuhResourceNotFound(1701))

        rbac_filters = get_rbac_filters(system_resources=system_agents,
                                        permitted_resources=agent_list,
                                        filters=filters)

        db_query = WazuhDBQueryAgents(offset=offset,
                                      limit=limit,
                                      sort=sort,
                                      search=search,
                                      select=select,
                                      query=q,
                                      **rbac_filters)
        data = db_query.run()
        result.affected_items.extend(data['items'])
        result.total_affected_items = data['totalItems']

    return result
Ejemplo n.º 21
0
def get_item_agent(agent_list, offset=0, limit=common.database_limit, select=None, search=None, sort=None, filters=None,
                   q='', array=True, nested=True, element_type='os'):
    """ Get syscollector information about a list of agents.

    :param agent_list: List of agents ID's.
    :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 select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param search: Looks for items with the specified string. Format: {"fields": ["field1","field2"]}
    :param q: Defines query to filter in DB.
    :param filters: Fields to filter by
    :param nested: Nested fields
    :param array: Array
    :param element_type: Type of element to get syscollector information from
    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        none_msg='No syscollector information was returned',
        some_msg='Some syscollector information was not returned',
        all_msg='All specified syscollector information was returned',
        sort_fields=['agent_id'] if sort is None else sort['fields'],
        sort_casting=['str'],
        sort_ascending=[sort['order'] == 'asc' for _ in sort['fields']] if sort is not None else ['True']
    )

    for agent in agent_list:
        try:
            if agent not in get_agents_info():
                raise WazuhResourceNotFound(1701)
            table, valid_select_fields = get_valid_fields(Type(element_type), agent_id=agent)
            db_query = WazuhDBQuerySyscollector(agent_id=agent, offset=offset, limit=limit, select=select,
                                                search=search,
                                                sort=sort, filters=filters, fields=valid_select_fields, table=table,
                                                array=array, nested=nested, query=q)
            data = db_query.run()
            for item in data['items']:
                item['agent_id'] = agent
                result.affected_items.append(item)
            result.total_affected_items += data['totalItems']
        except WazuhResourceNotFound as e:
            result.add_failed_item(id_=agent, error=e)

    result.affected_items = merge(*[[res] for res in result.affected_items],
                                  criteria=result.sort_fields,
                                  ascending=result.sort_ascending,
                                  types=result.sort_casting)

    return result
Ejemplo n.º 22
0
def run_command(agent_list: list = None,
                command: str = '',
                arguments: list = None,
                custom: bool = False,
                alert: dict = None) -> AffectedItemsWazuhResult:
    """Run AR command in a specific agent.

    Parameters
    ----------
    agent_list : list
        Agents list that will run the AR command.
    command : str
        Command running in the agents. If this value starts with !, then it refers to a script name instead of a
        command name.
    custom : bool
        Whether the specified command is a custom command or not.
    arguments : list
        Command arguments.
    alert : dict
        Alert information depending on the AR executed.

    Returns
    -------
    AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='AR command was sent to all agents',
        some_msg='AR command was not sent to some agents',
        none_msg='AR command was not sent to any agent')
    if agent_list:
        wq = WazuhQueue(common.ARQUEUE)
        system_agents = get_agents_info()
        for agent_id in agent_list:
            try:
                if agent_id not in system_agents:
                    raise WazuhResourceNotFound(1701)
                if agent_id == "000":
                    raise WazuhError(1703)
                active_response.send_ar_message(agent_id, wq, command,
                                                arguments, custom, alert)
                result.affected_items.append(agent_id)
                result.total_affected_items += 1
            except WazuhException as e:
                result.add_failed_item(id_=agent_id, error=e)
        result.affected_items.sort(key=int)
        wq.close()

    return result
Ejemplo n.º 23
0
def get_sca_list(agent_list=None,
                 q="",
                 offset=0,
                 limit=common.database_limit,
                 sort=None,
                 search=None,
                 select=None,
                 filters=None):
    """ Get a list of policies analyzed in the configuration assessment for a given agent

    :param agent_list: agent id to get policies from
    :param q: Defines query to filter in DB.
    :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. Format: {"fields": ["field1","field2"]}
    :param select: Select fields to return. Format: {"fields":["field1","field2"]}.
    :param filters: Define field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}
    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected sca information was returned',
        some_msg='Some sca information was not returned',
        none_msg='No sca information was returned')

    if len(agent_list) != 0:
        if agent_list[0] in get_agents_info():
            select = list(
                fields_translation_sca.keys()) if select is None else select

            db_query = WazuhDBQuerySCA(agent_id=agent_list[0],
                                       offset=offset,
                                       limit=limit,
                                       sort=sort,
                                       search=search,
                                       select=select,
                                       count=True,
                                       get_data=True,
                                       query=q,
                                       filters=filters)
            data = db_query.run()
            result.affected_items.extend(data['items'])
            result.total_affected_items = data['totalItems']
        else:
            result.add_failed_item(id_=agent_list[0],
                                   error=WazuhResourceNotFound(1701))

    return result
Ejemplo n.º 24
0
def get_agents_sync_group(agent_list=None):
    """Get agents configuration sync status.

    :param agent_list: List of agents ID's.
    :return AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Sync info was returned for all selected agents',
        some_msg='Sync info was not returned for some selected agents',
        none_msg='No sync info was returned',
    )

    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id == "000":
                raise WazuhError(1703)
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            else:
                # Check if agent exists and it is active
                agent_info = Agent(agent_id).get_basic_information()
                # Check if it has a multigroup
                if len(agent_info['group']) > 1:
                    multi_group = ','.join(agent_info['group'])
                    multi_group = hashlib.sha256(
                        multi_group.encode()).hexdigest()[:8]
                    group_merged_path = path.join(common.multi_groups_path,
                                                  multi_group, "merged.mg")
                else:
                    group_merged_path = path.join(common.shared_path,
                                                  agent_info['group'][0],
                                                  "merged.mg")
                result.affected_items.append({
                    'id':
                    agent_id,
                    'synced':
                    md5(group_merged_path) == agent_info['mergedSum']
                })
        except (IOError, KeyError):
            # The file couldn't be opened and therefore the group has not been synced
            result.affected_items.append({'id': agent_id, 'synced': False})
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)

    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 25
0
def remove_agent_from_group(group_list=None, agent_list=None):
    """Removes an agent assignment from a specified group.

    :param group_list: List of Group names.
    :param agent_list: List of Agent IDs.
    :return: Confirmation message.
    """
    group_id = group_list[0]
    agent_id = agent_list[0]

    # Check if agent and group exist and it is not 000
    if agent_id not in get_agents_info():
        raise WazuhResourceNotFound(1701)
    if agent_id == '000':
        raise WazuhError(1703)
    if group_id not in get_groups():
        raise WazuhResourceNotFound(1710)

    return WazuhResult({'message': Agent.unset_single_group_agent(agent_id=agent_id, group_id=group_id, force=True)})
Ejemplo n.º 26
0
def remove_agent_from_groups(agent_list=None, group_list=None):
    """Removes an agent assigment from a list of groups.

    :param agent_list: List of agents ID's.
    :param group_list: List of Group names.
    :return: AffectedItemsWazuhResult.
    """
    agent_id = agent_list[0]
    result = AffectedItemsWazuhResult(
        all_msg='Specified agent was removed from returned groups',
        some_msg='Specified agent was not removed from some groups',
        none_msg='Specified agent was not removed from any group')

    # Check if agent exists and it is not 000
    if agent_id == '000':
        raise WazuhError(1703)
    if agent_id not in get_agents_info():
        raise WazuhResourceNotFound(1701)

    # We move default group to last position in case it is contained in group_list. When an agent is removed from all
    # groups it is reverted to 'default'. We try default last to avoid removing it and then adding again.
    try:
        group_list.append(group_list.pop(group_list.index('default')))
    except ValueError:
        pass

    system_groups = get_groups()
    for group_id in group_list:
        try:
            if group_id not in system_groups:
                raise WazuhResourceNotFound(1710)
            Agent.unset_single_group_agent(agent_id=agent_id,
                                           group_id=group_id,
                                           force=True)
            result.affected_items.append(group_id)
        except WazuhException as e:
            result.add_failed_item(id_=group_id, error=e)
    result.total_affected_items = len(result.affected_items)
    result.affected_items.sort()

    return result
Ejemplo n.º 27
0
def get_agents_keys(agent_list=None):
    """Get the key of existing agents.

    :param agent_list: List of agents ID's.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg='Obtained keys for all selected agents',
                                      some_msg='Some agent keys were not obtained',
                                      none_msg='No agent keys were obtained'
                                      )
    system_agents = get_agents_info()
    for agent_id in agent_list:
        try:
            if agent_id not in system_agents:
                raise WazuhResourceNotFound(1701)
            result.affected_items.append({'id': agent_id, 'key': Agent(agent_id).get_key()})
        except WazuhException as e:
            result.add_failed_item(id_=agent_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 28
0
def clear(agent_list=None):
    """Clear the rootcheck database for a list of agents.

    Parameters
    ----------
    agent_list : list
        List of agent ids.

    Returns
    -------
    result : AffectedItemsWazuhResult
        JSON containing the affected agents.
    """
    result = AffectedItemsWazuhResult(all_msg='Rootcheck database was cleared on returned agents',
                                      some_msg='Rootcheck database was not cleared on some agents',
                                      none_msg="No rootcheck database was cleared")

    wdb_conn = WazuhDBConnection()
    system_agents = get_agents_info()
    agent_list = set(agent_list)
    not_found_agents = agent_list - system_agents
    # Add non existent agents to failed_items
    [result.add_failed_item(id_=agent_id, error=WazuhResourceNotFound(1701)) for agent_id in not_found_agents]

    eligible_agents = agent_list - not_found_agents
    for agent_id in eligible_agents:
        try:
            rootcheck_delete_agent(agent_id, wdb_conn)
            result.affected_items.append(agent_id)
        except WazuhError as e:
            result.add_failed_item(id_=agent_id, error=e)

    result.affected_items.sort(key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Ejemplo n.º 29
0
def get_sca_checks(policy_id=None,
                   agent_list=None,
                   q="",
                   offset=0,
                   limit=common.database_limit,
                   sort=None,
                   search=None,
                   select=None,
                   filters=None):
    """ Get a list of checks analyzed for a policy

    Parameters
    ----------
    policy_id : str
        Policy id to get the checks from.
    agent_list : list
        Agent id to get the policies from
    q : str
        Defines query to filter in DB.
    offset : int
        First item to return.
    limit : int
        Maximum number of items to return.
    sort : str
        Sorts the items. Format: {"fields":["field1","field2"],"order":"asc|desc"}.
    search : str
        Looks for items with the specified string. Format: {"fields": ["field1","field2"]}
    select : str
        Select fields to return. Format: {"fields":["field1","field2"]}.
    filters : str
        Define field filters required by the user. Format: {"field1":"value1", "field2":["value2","value3"]}

    Returns
    -------
    AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='All selected sca/policy information was returned',
        some_msg='Some sca/policy information was not returned',
        none_msg='No sca/policy information was returned')
    if len(agent_list) != 0:
        sca_checks = list()
        if agent_list[0] in get_agents_info():
            fields_translation = {
                **fields_translation_sca_check,
                **fields_translation_sca_check_compliance,
                **fields_translation_sca_check_rule
            }

            full_select = (
                list(fields_translation_sca_check.keys()) +
                list(fields_translation_sca_check_compliance.keys()) +
                list(fields_translation_sca_check_rule.keys()))

            # Workaround for too long sca_checks results until the chunk algorithm is implemented (1/2)
            db_query = WazuhDBQuerySCA(agent_id=agent_list[0],
                                       offset=0,
                                       limit=None,
                                       sort=None,
                                       filters=filters,
                                       search=None,
                                       select=full_select,
                                       count=True,
                                       get_data=True,
                                       query=f"policy_id={policy_id}",
                                       default_query=default_query_sca_check,
                                       default_sort_field='policy_id',
                                       fields=fields_translation,
                                       count_field='id')
            result_dict = db_query.run()

            if 'items' in result_dict:
                checks = result_dict['items']
            else:
                raise WazuhInternalError(2007)

            groups = groupby(checks, key=itemgetter('id'))
            select_fields = full_select if select is None else select
            select_fields = set([
                field if field != 'compliance' else 'compliance'
                for field in select_fields
                if field in fields_translation_sca_check
            ])
            # Rearrange check and compliance fields

            for _, group in groups:
                group_list = list(group)
                check_dict = {
                    k: v
                    for k, v in group_list[0].items() if k in select_fields
                }

                for extra_field, field_translations in [
                    ('compliance', fields_translation_sca_check_compliance),
                    ('rules', fields_translation_sca_check_rule)
                ]:
                    if (select is None or extra_field in select) \
                            and set(field_translations.keys()) & group_list[0].keys():
                        check_dict[extra_field] = [
                            dict(zip(field_translations.values(), x))
                            for x in set((
                                map(itemgetter(
                                    *field_translations.keys()), group_list)))
                        ]

                sca_checks.append(check_dict)
        else:
            result.add_failed_item(id_=agent_list[0],
                                   error=WazuhResourceNotFound(1701))
            result.total_affected_items = 0

        # Workaround for too long sca_checks results until the chunk algorithm is implemented (2/2)
        data = process_array(
            sca_checks,
            search_text=search['value'] if search else None,
            complementary_search=search['negation'] if search else False,
            sort_by=sort['fields'] if sort else ['policy_id'],
            sort_ascending=False if sort and sort['order'] == 'desc' else True,
            offset=offset,
            limit=limit,
            q=q)

        result.affected_items = data['items']
        result.total_affected_items = data['totalItems']

    return result
Ejemplo n.º 30
0
def restart_agents(agent_list: list = None) -> AffectedItemsWazuhResult:
    """Restart a list of agents.

    Parameters
    ----------
    agent_list : list
        List of agents IDs.

    Raises
    ------
    WazuhError(1703)
        If the agent to be restarted is 000.
    WazuhError(1701)
        If the agent to be restarted is not in the system.
     WazuhError(1707)
            If the agent to be restarted is not active.

    Returns
    -------
    AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(
        all_msg='Restart command was sent to all agents',
        some_msg='Restart command was not sent to some agents',
        none_msg='Restart command was not sent to any agent')

    agent_list = set(agent_list)

    # Add agent with ID 000 to failed_items
    try:
        agent_list.remove('000')
        result.add_failed_item('000', WazuhError(1703))
    except KeyError:
        pass

    if agent_list:
        system_agents = get_agents_info()
        rbac_filters = get_rbac_filters(system_resources=system_agents,
                                        permitted_resources=list(agent_list))
        agents_with_data = WazuhDBQueryAgents(
            limit=None, select=["id", "status",
                                "version"], **rbac_filters).run()['items']

        # Add non existent agents to failed_items
        not_found_agents = agent_list - system_agents
        [
            result.add_failed_item(id_=agent,
                                   error=WazuhResourceNotFound(1701))
            for agent in not_found_agents
        ]

        # Add non active agents to failed_items
        non_active_agents = [
            agent for agent in agents_with_data if agent['status'] != 'active'
        ]
        [
            result.add_failed_item(id_=agent['id'],
                                   error=WazuhError(
                                       1707,
                                       extra_message=f'{agent["status"]}'))
            for agent in non_active_agents
        ]

        eligible_agents = [agent for agent in agents_with_data if agent not in non_active_agents] if non_active_agents \
            else agents_with_data
        wq = WazuhQueue(common.ARQUEUE)
        for agent in eligible_agents:
            try:
                send_restart_command(agent['id'], agent['version'], wq)
                result.affected_items.append(agent['id'])
            except WazuhException as e:
                result.add_failed_item(id_=agent['id'], error=e)
        wq.close()

        result.total_affected_items = len(result.affected_items)
        result.affected_items.sort(key=int)

    return result