Beispiel #1
0
def get_last_scan(agent_list):
    """Get the last rootcheck scan of the agent.

    Parameters
    ----------
    agent_list : list
        Agent ID to get the last scan date from.

    Returns
    -------
    result : AffectedItemsWazuhResult
        JSON containing the scan date.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Last rootcheck scan of the agent was returned',
        none_msg='No last scan information was returned')

    result.affected_items.append(last_scan(agent_list[0]))
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #2
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
Beispiel #3
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:
            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
Beispiel #4
0
def files(agent_list=None, offset=0, limit=common.database_limit, sort=None, search=None, select=None, filters=None,
          q='', summary=False, distinct=False):
    """Return a list of files from the database that match the filters

    :param agent_list: Agent ID.
    :param filters: Fields to filter by
    :param summary: Returns a summary grouping by filename.
    :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: ["field1","field2"].
    :param q: Query to filter by
    :param distinct: Look for distinct values
    :return: AffectedItemsWazuhResult.
    """
    if filters is None:
        filters = {}
    parameters = {"date": "date", "mtime": "mtime", "file": "file", "size": "size", "perm": "perm", "uname": "uname",
                  "gname": "gname", "md5": "md5", "sha1": "sha1", "sha256": "sha256", "inode": "inode", "gid": "gid",
                  "uid": "uid", "type": "type", "changes": "changes", "attributes": "attributes"}
    summary_parameters = {"date": "date", "mtime": "mtime", "file": "file"}
    result = AffectedItemsWazuhResult(all_msg='FIM findings of the agent were returned',
                                      none_msg='No FIM information was returned')

    if 'hash' in filters:
        q = f'(md5={filters["hash"]},sha1={filters["hash"]},sha256={filters["hash"]})' + ('' if not q else ';' + q)
        del filters['hash']

    db_query = WazuhDBQuerySyscheck(agent_id=agent_list[0], offset=offset, limit=limit, sort=sort, search=search,
                                    filters=filters, query=q, select=select, table='fim_entry', distinct=distinct,
                                    fields=summary_parameters if summary else parameters)

    db_query = db_query.run()

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

    return result
Beispiel #5
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
Beispiel #6
0
def totals(date):
    """Retrieve statistical information for the current or specified date.

    Parameters
    ----------
    date: date
        Date object with the date value of the stats.

    Returns
    -------
    AffectedItemsWazuhResult
        Array of dictionaries. Each dictionary represents an hour.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Statistical information for each node was successfully read',
        some_msg='Could not read statistical information for some nodes',
        none_msg='Could not read statistical information for any node')
    affected = totals_(date)
    result.affected_items = affected
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #7
0
def read_ossec_conf(section=None, field=None):
    """ Wrapper for get_ossec_conf

    :param section: Filters by section (i.e. rules).
    :param field: Filters by field in section (i.e. included).
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(
        all_msg=f"Configuration was successfully read"
        f"{' in specified node' if node_id != 'manager' else ''}",
        some_msg='Could not read configuration in some nodes',
        none_msg=f"Could not read configuration"
        f"{' in specified node' if node_id != 'manager' else ''}")

    try:
        result.affected_items.append(
            get_ossec_conf(section=section, field=field))
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #8
0
def get_config(component=None, config=None):
    """ Wrapper for get_active_configuration

    :param component: Selected component.
    :param config: Configuration to get, written on disk.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg=f"Active configuration read successfully"
                                              f"{' in specified node' if node_id != 'manager' else ''}",
                                      some_msg='Could not read active configuration in some nodes',
                                      none_msg=f"Could not read active configuration"
                                               f"{' in specified node' if node_id != 'manager' else ''}"
                                      )

    try:
        data = configuration.get_active_configuration(agent_id='000', component=component, configuration=config)
        len(data.keys()) > 0 and result.affected_items.append(data)
    except WazuhError as e:
        result.add_failed_item(id_=node_id, error=e)
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #9
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
Beispiel #10
0
def create_user(username: str = None,
                password: str = None,
                allow_run_as: bool = False):
    """Create a new user

    Parameters
    ----------
    username : str
        Name for the new user
    password : str
        Password for the new user
    allow_run_as : bool
        Enable authorization context login method for the new user

    Returns
    -------
    result : AffectedItemsWazuhResult
        Status message
    """
    if len(password) > 64 or len(password) < 8:
        raise WazuhError(5009)
    elif not _user_password.match(password):
        raise WazuhError(5007)

    result = AffectedItemsWazuhResult(none_msg='User could not be created',
                                      all_msg='User was successfully created')
    with AuthenticationManager() as auth:
        if auth.add_user(username, password, allow_run_as=allow_run_as):
            operation = auth.get_user(username)
            if operation:
                result.affected_items.append(operation)
                result.total_affected_items = 1
            else:
                result.add_failed_item(id_=username, error=WazuhError(5000))
        else:
            result.add_failed_item(id_=username, error=WazuhError(5000))

    return result
Beispiel #11
0
def delete_groups(group_list=None):
    """Delete a list of groups and remove it from every agent assignments.

    :param group_list: List of Group names.
    :return: AffectedItemsWazuhResult.
    """
    result = AffectedItemsWazuhResult(all_msg='All selected groups were deleted',
                                      some_msg='Some groups were not deleted',
                                      none_msg='No group was deleted')

    affected_agents = set()
    system_groups = get_groups()
    for group_id in group_list:
        try:
            # Check if group exists
            if group_id not in system_groups:
                raise WazuhResourceNotFound(1710)
            if group_id == 'default':
                raise WazuhError(1712)
            agent_list = list(map(operator.itemgetter('id'),
                                  WazuhDBQueryMultigroups(group_id=group_id, limit=None).run()['items']))
            try:
                affected_agents_result = remove_agents_from_group(agent_list=agent_list, group_list=[group_id])
                if affected_agents_result.total_failed_items != 0:
                    raise WazuhError(4015)
            except WazuhError:
                raise WazuhError(4015)
            Agent.delete_single_group(group_id)
            result.affected_items.append(group_id)
            affected_agents.update(affected_agents_result.affected_items)
        except WazuhException as e:
            result.add_failed_item(id_=group_id, error=e)

    result['affected_agents'] = sorted(affected_agents, key=int)
    result.affected_items.sort()
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #12
0
def run(agent_list=None):
    """Run rootcheck scan.

    Parameters
    ----------
    agent_list : list
         Run rootcheck in a list of agents.

    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')
    for agent_id in agent_list:
        try:
            agent_info = Agent(agent_id).get_basic_information()
            agent_status = agent_info.get('status', 'N/A')
            if agent_status.lower() != 'active':
                result.add_failed_item(
                    id_=agent_id,
                    error=WazuhError(
                        1601,
                        extra_message='Status - {}'.format(agent_status)))
            else:
                oq = OssecQueue(common.ARQUEUE)
                oq.send_msg_to_agent(OssecQueue.HC_SK_RESTART, agent_id)
                result.affected_items.append(agent_id)
                oq.close()
        except WazuhError as e:
            result.add_failed_item(id_=agent_id, error=e)
    result.affected_items = sorted(result.affected_items, key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #13
0
def run(agent_list=None):
    """Run a syscheck scan in the specified agents.

    Parameters
    ----------
    agent_list : str
        List of the agents IDs to run the scan for.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Confirmation/Error message.
    """
    result = AffectedItemsWazuhResult(
        all_msg='Syscheck scan was restarted on returned agents',
        some_msg='Syscheck scan was not restarted on some agents',
        none_msg='No syscheck scan was restarted')
    for agent_id in agent_list:
        try:
            agent_info = Agent(agent_id).get_basic_information()
            agent_status = agent_info.get('status', 'N/A')
            if agent_status.lower() != 'active':
                result.add_failed_item(
                    id_=agent_id,
                    error=WazuhError(
                        1601,
                        extra_message='Status - {}'.format(agent_status)))
            else:
                wq = WazuhQueue(common.ARQUEUE)
                wq.send_msg_to_agent(WazuhQueue.HC_SK_RESTART, agent_id)
                result.affected_items.append(agent_id)
                wq.close()
        except WazuhError as e:
            result.add_failed_item(id_=agent_id, error=e)
    result.affected_items = sorted(result.affected_items, key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #14
0
def hourly():
    """
    Returns the hourly averages.
    :return: Dictionary: averages and interactions.
    """

    averages = []
    interactions = 0

    # What's the 24 for?
    for i in range(25):
        try:
            hfile = open(common.stats_path + '/hourly-average/' + str(i))
            data = hfile.read()

            if i == 24:
                interactions = int(data)
            else:
                averages.append(int(data))

            hfile.close()
        except IOError:
            if i < 24:
                averages.append(0)

    result = AffectedItemsWazuhResult(
        all_msg=
        'Statistical information per hour for each node was successfully read',
        some_msg=
        'Could not read statistical information per hour for some nodes',
        none_msg='Could not read statistical information per hour for any node'
    )
    result.affected_items.append({
        'averages': averages,
        'interactions': interactions
    })
    result.total_affected_items = len(result.affected_items)
    return result
Beispiel #15
0
def ossec_log(level=None, tag=None, offset=0, limit=common.database_limit, sort_by=None,
              sort_ascending=True, search_text=None, complementary_search=False, search_in_fields=None, q=''):
    """Gets logs from ossec.log.

    :param level: Filters by log level: all, error or info.
    :param tag: Filters by log category/tag (i.e. wazuh-remoted).
    :param offset: First item to return.
    :param limit: Maximum number of items to return.
    :param sort_by: Fields to sort the items by
    :param sort_ascending: Sort in ascending (true) or descending (false) order
    :param search_text: Text to search
    :param complementary_search: Find items without the text to search
    :param search_in_fields: Fields to search in
    :param q: Defines query to filter.
    :return: AffectedItemsWazuhResult
    """
    result = AffectedItemsWazuhResult(all_msg=f"Logs were successfully read"
                                              f"{' in specified node' if node_id != 'manager' else ''}",
                                      some_msg='Could not read logs in some nodes',
                                      none_msg=f"Could not read logs"
                                               f"{' in specified node' if node_id != 'manager' else ''}"
                                      )
    logs = get_ossec_logs()

    query = []
    level and query.append(f'level={level}')
    tag and query.append(f'tag={tag}')
    q and query.append(q)
    query = ';'.join(query)

    data = process_array(logs, search_text=search_text, search_in_fields=search_in_fields,
                         complementary_search=complementary_search, sort_by=sort_by,
                         sort_ascending=sort_ascending, offset=offset, limit=limit, q=query)
    result.affected_items.extend(data['items'])
    result.total_affected_items = data['totalItems']

    return result
Beispiel #16
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
Beispiel #17
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
Beispiel #18
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:
        db_query = WazuhDBQueryAgents(select=['os.platform'],
                                      filters={'id': agent_list},
                                      default_sort_field='os_platform',
                                      min_select_fields=set(),
                                      distinct=True)
        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
Beispiel #19
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
Beispiel #20
0
def create_user(username: str = None, password: str = None):
    """Create a new user

    :param username: Name for the new user
    :param password: Password for the new user
    :return: Status message
    """
    if not _user_password.match(password):
        raise WazuhError(5007)

    result = AffectedItemsWazuhResult(none_msg='User could not be created',
                                      all_msg='User created correctly')
    with AuthenticationManager() as auth:
        if auth.add_user(username, password):
            operation = auth.get_user(username)
            if operation:
                result.affected_items.append(operation)
                result.total_affected_items = 1
            else:
                result.add_failed_item(id_=username, error=WazuhError(5000))
        else:
            result.add_failed_item(id_=username, error=WazuhError(5000))

    return result
Beispiel #21
0
def clear(agent_list: list = None):
    """Clear the syscheck database of the specified agents.

    Parameters
    ----------
    agent_list : str
        Agent ID.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Confirmation/Error message.
    """
    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")

    system_agents = get_agents_info()
    not_found_agents = set(agent_list) - system_agents
    list(
        map(
            lambda ag: result.add_failed_item(
                id_=ag, error=WazuhResourceNotFound(1701)), not_found_agents))

    wdb_conn = None
    rbac_filters = get_rbac_filters(system_resources=system_agents,
                                    permitted_resources=agent_list)
    db_query = WazuhDBQueryAgents(select=["id", "version"], **rbac_filters)
    data = db_query.run()

    for item in data['items']:
        agent_id = item['id']
        agent_version = item.get(
            'version',
            None)  # If the value was NULL in the DB the key might not exist
        if agent_version is not None:
            if WazuhVersion(agent_version) < WazuhVersion('v3.12.0'):
                try:
                    if wdb_conn is None:
                        wdb_conn = WazuhDBConnection()
                    syscheck_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)
            else:
                result.add_failed_item(
                    id_=agent_id,
                    error=WazuhError(
                        1760,
                        extra_message="Agent version should be < v3.12.0."))
        else:
            result.add_failed_item(id_=agent_id, error=WazuhError(1015))

    if wdb_conn is not None:
        wdb_conn.close()
    result.affected_items.sort(key=int)
    result.total_affected_items = len(result.affected_items)

    return result
Beispiel #22
0
def get_group_files(group_list=None,
                    offset=0,
                    limit=None,
                    search_text=None,
                    search_in_fields=None,
                    complementary_search=False,
                    sort_by=None,
                    sort_ascending=True,
                    hash_algorithm='md5'):
    """Gets the group files.

    :param group_list: List of Group names.
    :param offset: First item to return.
    :param limit: Maximum number of items to return.
    :param sort_by: Fields to sort the items by.
    :param sort_ascending: Sort in ascending (true) or descending (false) order.
    :param search_text: Text to search.
    :param complementary_search: Find items without the text to search.
    :param search_in_fields: Fields to search in.
    :param hash_algorithm: hash algorithm used to get mergedsum and configsum.
    :return: WazuhResult.
    """
    # We access unique group_id from list, this may change if and when we decide to add option to get files for
    # a list of groups
    group_id = group_list[0]
    group_path = common.shared_path
    result = AffectedItemsWazuhResult(
        all_msg='All selected groups files were returned',
        some_msg='Some groups files were not returned',
        none_msg='No groups files were returned')
    if group_id:
        if not Agent.group_exists(group_id):
            result.add_failed_item(id_=group_id,
                                   error=WazuhResourceNotFound(1710))
            return result
        group_path = path.join(common.shared_path, group_id)

    if not path.exists(group_path):
        result.add_failed_item(id_=group_path, error=WazuhError(1006))
        return result

    try:
        data = []
        for entry in listdir(group_path):
            item = dict()
            item['filename'] = entry
            item['hash'] = get_hash(path.join(group_path, entry),
                                    hash_algorithm)
            data.append(item)

        # ar.conf
        ar_path = path.join(common.shared_path, 'ar.conf')
        data.append({
            'filename': "ar.conf",
            'hash': get_hash(ar_path, hash_algorithm)
        })
        data = process_array(data,
                             search_text=search_text,
                             search_in_fields=search_in_fields,
                             complementary_search=complementary_search,
                             sort_by=sort_by,
                             sort_ascending=sort_ascending,
                             offset=offset,
                             limit=limit)
        result.affected_items = data['items']
        result.total_affected_items = data['totalItems']
    except WazuhError as e:
        result.add_failed_item(id_=group_path, error=e)
        raise e
    except Exception as e:
        raise WazuhInternalError(1727, extra_message=str(e))

    return result
Beispiel #23
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 = set(map(operator.itemgetter('id'), data['items']))
        agent_list = set(agent_list)

        try:
            agent_list.remove('000')
            result.add_failed_item('000', WazuhError(1703))
        except KeyError:
            pass

        # Add not existing agents to failed_items
        not_found_agents = agent_list - system_agents
        list(
            map(
                lambda ag: result.add_failed_item(
                    id_=ag, error=WazuhResourceNotFound(1701)),
                not_found_agents))

        # Add non eligible agents to failed_items
        non_eligible_agents = agent_list - not_found_agents - can_purge_agents
        list(
            map(
                lambda ag: result.add_failed_item(
                    id_=ag,
                    error=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 '')))), non_eligible_agents))

        for agent_id in agent_list.intersection(system_agents).intersection(
                can_purge_agents):
            try:
                my_agent = Agent(agent_id)
                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)

        # Clear temporary cache
        clear_temporary_caches()

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

    return result
Beispiel #24
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
Beispiel #25
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

    Parameters
    ----------
    agent_list : list
        Agent ids to get 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 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
Beispiel #26
0
def get_rootcheck_agent(agent_list=None,
                        offset=0,
                        limit=common.database_limit,
                        sort=None,
                        search=None,
                        select=None,
                        filters=None,
                        q='',
                        distinct=None):
    """Return a list of events from the rootcheck database.

    Parameters
    ----------
    agent_list : list
        Agent ID to get the rootcheck events from.
    offset : int
        First element to return in the collection.
    limit : int
        Maximum number of elements to return.
    sort : str
        Sort the collection by a field or fields (separated by comma). Use +/- at the beginning to list in
        ascending or descending order.
    search : str
        Look for elements with the specified string.
    select : str
        Select which fields to return (separated by comma).
    q : str
        Query to filter results by.
    distinct : bool
        Look for distinct values.
    filters : dict
        Fields to filter by.

    Returns
    -------
    result : AffectedItemsWazuhResult
        JSON containing the rootcheck events.
    """
    if filters is None:
        filters = {}
    result = AffectedItemsWazuhResult(
        all_msg='All selected rootcheck information was returned',
        some_msg='Some rootcheck information was not returned',
        none_msg='No rootcheck information was returned')

    db_query = WazuhDBQueryRootcheck(agent_id=agent_list[0],
                                     offset=offset,
                                     limit=limit,
                                     sort=sort,
                                     search=search,
                                     select=select,
                                     count=True,
                                     get_data=True,
                                     query=q,
                                     filters=filters,
                                     distinct=distinct)
    data = db_query.run()
    result.affected_items.extend(data['items'])
    result.total_affected_items = data['totalItems']

    return result
Beispiel #27
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

    :param policy_id: policy id to get the checks from
    :param agent_list: agent id to get the 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/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:
        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()))

            db_query = WazuhDBQuerySCA(agent_id=agent_list[0],
                                       offset=offset,
                                       limit=limit,
                                       sort=sort,
                                       search=search,
                                       select=full_select,
                                       count=True,
                                       get_data=True,
                                       query=f"policy_id={policy_id}" if q
                                       == "" else f"policy_id={policy_id};{q}",
                                       filters=filters,
                                       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)))
                        ]

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

    return result
Beispiel #28
0
def totals(date):
    """
    Returns the totals file.
    :param date: date object with the date value of the stats
    :return: Array of dictionaries. Each dictionary represents an hour.
    """

    stat_filename = ""
    try:
        stat_filename = os.path.join(
            common.stats_path, "totals", str(date.year),
            MONTHS[date.month - 1], f"ossec-totals-{date.strftime('%d')}.log")
        stats = open(stat_filename, 'r')
    except IOError:
        raise WazuhError(1308, extra_message=stat_filename)

    result = AffectedItemsWazuhResult(
        all_msg='Statistical information for each node was successfully read',
        some_msg='Could not read statistical information for some nodes',
        none_msg='Could not read statistical information for any node')
    alerts = []

    for line in stats:
        data = line.split('-')

        if len(data) == 4:
            sigid = int(data[1])
            level = int(data[2])
            times = int(data[3])

            alert = {'sigid': sigid, 'level': level, 'times': times}
            alerts.append(alert)
        else:
            data = line.split('--')

            if len(data) != 5:
                if len(data) in (0, 1):
                    continue
                else:
                    result.add_failed_item(
                        id_=node_id if cluster_enabled else 'manager',
                        error=WazuhInternalError(1309))
                    return result

            hour = int(data[0])
            total_alerts = int(data[1])
            events = int(data[2])
            syscheck = int(data[3])
            firewall = int(data[4])

            result.affected_items.append({
                'hour': hour,
                'alerts': alerts,
                'totalAlerts': total_alerts,
                'events': events,
                'syscheck': syscheck,
                'firewall': firewall
            })
            alerts = []

    result.total_affected_items = len(result.affected_items)
    return result
Beispiel #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
Beispiel #30
0
def files(agent_list=None,
          offset=0,
          limit=common.database_limit,
          sort=None,
          search=None,
          select=None,
          filters=None,
          q='',
          nested=True,
          summary=False,
          distinct=False):
    """Return a list of files from the syscheck database of the specified agents.

    Parameters
    ----------
    agent_list : str
        Agent ID.
    filters : dict
        Fields to filter by.
    summary : bool
        Returns a summary grouping by filename.
    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.
    select : list[str]
        Select fields to return. Format: ["field1","field2"].
    q : str
        Query to filter by.
    nested : bool
        Specify whether there are nested fields or not.
    distinct : bool
        Look for distinct values.

    Returns
    -------
    result : AffectedItemsWazuhResult
        Confirmation/Error message.
    """
    if filters is None:
        filters = {}
    parameters = {
        "date": "date",
        "arch": "arch",
        "value.type": "value_type",
        "value.name": "value_name",
        "mtime": "mtime",
        "file": "file",
        "size": "size",
        "perm": "perm",
        "uname": "uname",
        "gname": "gname",
        "md5": "md5",
        "sha1": "sha1",
        "sha256": "sha256",
        "inode": "inode",
        "gid": "gid",
        "uid": "uid",
        "type": "type",
        "changes": "changes",
        "attributes": "attributes"
    }
    summary_parameters = {"date": "date", "mtime": "mtime", "file": "file"}
    result = AffectedItemsWazuhResult(
        all_msg='FIM findings of the agent were returned',
        none_msg='No FIM information was returned')

    if 'hash' in filters:
        q = f'(md5={filters["hash"]},sha1={filters["hash"]},sha256={filters["hash"]})' + (
            '' if not q else ';' + q)
        del filters['hash']

    with WazuhDBQuerySyscheck(
            agent_id=agent_list[0],
            offset=offset,
            limit=limit,
            sort=sort,
            search=search,
            filters=filters,
            nested=nested,
            query=q,
            select=select,
            table='fim_entry',
            distinct=distinct,
            fields=summary_parameters if summary else parameters,
            min_select_fields={'file'}) as db_query:
        db_query = db_query.run()

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

    return result