Ejemplo n.º 1
0
def send_restart_command(agent_id: str = '',
                         agent_version: str = '',
                         wq: WazuhQueue = None) -> str:
    """Send restart command to an agent.

    Parameters
    ----------
    agent_id : str
        ID specifying the agent where the restart command will be sent to
    agent_version : str
        Agent version to compare with the required version. The format is vX.Y.Z.
    wq : WazuhQueue
        WazuhQueue used for the active response messages.

    Returns
    -------
    str
        Message generated by Wazuh.
    """
    # If the Wazuh agent version is newer or equal to the AR legacy version,
    # the message sent will have JSON format
    if WazuhVersion(agent_version) >= WazuhVersion(common.AR_LEGACY_VERSION):
        ret_msg = wq.send_msg_to_agent(WazuhQueue.RESTART_AGENTS_JSON,
                                       agent_id)
    else:
        ret_msg = wq.send_msg_to_agent(WazuhQueue.RESTART_AGENTS, agent_id)

    return ret_msg
Ejemplo n.º 2
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.º 3
0
def send_ar_message(agent_id: str = '',
                    wq: WazuhQueue = None,
                    command: str = '',
                    arguments: list = None,
                    custom: bool = False,
                    alert: dict = None) -> None:
    """Send the active response message to the agent.

    Parameters
    ----------
    agent_id : str
        ID specifying the agent where the msg_queue will be sent to.
    wq : WazuhQueue
        WazuhQueue used for the active response messages.
    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.

    Raises
    ------
    WazuhError(1651)
        If the agent with ID agent_id is not active.
    """
    # Agent basic information
    agent_info = Agent(agent_id).get_basic_information()

    # Check if agent is active
    if agent_info['status'].lower() != 'active':
        raise WazuhError(1651,
                         extra_message='{0}'.format(agent_info['status']))

    # Once we know the agent is active, store version
    agent_version = agent_info['version']

    # Check if AR is enabled
    agent_conf = Agent(agent_id).getconfig('com', 'active-response',
                                           agent_version)
    if agent_conf['active-response']['disabled'] == 'yes':
        raise WazuhError(1750)

    # Create classic msg or JSON msg depending on the agent version
    if WazuhVersion(agent_version) >= WazuhVersion(common.AR_LEGACY_VERSION):
        msg_queue = create_json_message(command=command,
                                        arguments=arguments,
                                        alert=alert)
    else:
        msg_queue = create_message(command=command,
                                   arguments=arguments,
                                   custom=custom)

    wq.send_msg_to_agent(msg=msg_queue,
                         agent_id=agent_id,
                         msg_type=WazuhQueue.AR_TYPE)
Ejemplo n.º 4
0
def test_WazuhQueue_close(mock_close, mock_conn):
    """Tests WazuhQueue.close function works"""

    queue = WazuhQueue('test_path')

    queue.close()

    mock_conn.assert_called_once_with('test_path')
    mock_close.assert_called_once_with()
Ejemplo n.º 5
0
def test_WazuhQueue_protected_send_ko(mock_send, mock_conn):
    """Tests WazuhQueue._send function exceptions works"""

    queue = WazuhQueue('test_path')

    with pytest.raises(WazuhException, match=".* 1011 .*"):
        queue._send('msg')

    mock_conn.assert_called_with('test_path')
Ejemplo n.º 6
0
def test_WazuhQueue_send_msg_to_agent(mock_send, mock_conn, msg, agent_id,
                                      msg_type):
    """Tests WazuhQueue.send_msg_to_agent function works"""

    queue = WazuhQueue('test_path')

    response = queue.send_msg_to_agent(msg, agent_id, msg_type)

    assert isinstance(response, str)
    mock_conn.assert_called_once_with('test_path')
Ejemplo n.º 7
0
def test_WazuhQueue_send_msg_to_agent_ko(mock_send, mock_conn, msg, agent_id,
                                         msg_type, expected_exception):
    """Tests WazuhQueue.send_msg_to_agent function exception works"""

    queue = WazuhQueue('test_path')

    with pytest.raises(WazuhException, match=f'.* {expected_exception} .*'):
        queue.send_msg_to_agent(msg, agent_id, msg_type)

    mock_conn.assert_called_once_with('test_path')
Ejemplo n.º 8
0
def test_WazuhQueue_protected_connect(mock_set, mock_conn):
    """Tests WazuhQueue._connect function works"""

    WazuhQueue('test_path')

    with patch('wazuh.core.wazuh_queue.socket.socket.getsockopt',
               return_value=1):
        WazuhQueue('test_path')

    mock_conn.assert_called_with('test_path')
    mock_set.assert_called_once_with(1, 7, 6400)
Ejemplo n.º 9
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.º 10
0
    def reconnect(self, wq: WazuhQueue) -> str:
        """Force reconnect to the manager.

        Parameters
        ----------
        wq : WazuhQueue
            WazuhQueue used for the active response message.

        Raises
        ------
        WazuhError(1750)
            If the agent has active response disabled.
        WazuhError(1757)
            If the agent to be reconnected is not active.

        Returns
        -------
        str
            Message generated by Wazuh.
        """
        # Check if agent is active
        self.get_basic_information()
        if self.status.lower() != 'active':
            raise WazuhError(1757)

        # Send force reconnect message to the WazuhQueue
        ret_msg = wq.send_msg_to_agent(WazuhQueue.HC_FORCE_RECONNECT, self.id)

        return ret_msg
Ejemplo n.º 11
0
def test_WazuhQueue_send_msg_to_agent(mock_send, mock_conn, msg, agent_id,
                                      msg_type):
    """Test WazuhQueue.send_msg_to_agent function.

    Parameters
    ----------
    msg : str
        Message sent to the agent.
    agent_id : str
        String indicating the agent ID.
    msg_type : str
        String indicating the message type.
    """

    queue = WazuhQueue('test_path')

    response = queue.send_msg_to_agent(msg, agent_id, msg_type)

    assert isinstance(response, str)
    mock_conn.assert_called_once_with('test_path')
Ejemplo n.º 12
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.º 13
0
def test_WazuhQueue_send_msg_to_agent_ko(mock_send, mock_conn, msg, agent_id,
                                         msg_type, expected_exception):
    """Test WazuhQueue.send_msg_to_agent function exceptions.

    Parameters
    ----------
    msg : str
        Message sent to the agent.
    agent_id : str
        String indicating the agent ID.
    msg_type : str
        String indicating the message type.
    expected_exception : int
        Expected Wazuh exception.
    """

    queue = WazuhQueue('test_path')

    with pytest.raises(WazuhException, match=f'.* {expected_exception} .*'):
        queue.send_msg_to_agent(msg, agent_id, msg_type)

    mock_conn.assert_called_once_with('test_path')
Ejemplo n.º 14
0
def test_WazuhQueue_protected_send(mock_conn, send_response, error):
    """Tests WazuhQueue._send function works"""

    queue = WazuhQueue('test_path')

    with patch('socket.socket.send', return_value=send_response):
        if error:
            with pytest.raises(WazuhException, match=".* 1011 .*"):
                queue._send('msg')
        else:
            queue._send('msg')

    mock_conn.assert_called_with('test_path')
Ejemplo n.º 15
0
def test_WazuhQueue_protected_send(mock_conn, send_response, error):
    """Test WazuhQueue._send function.

    Parameters
    ----------
    send_response : int
        Returned value of the socket send mocked function.
    error : bool
        Indicates whether a WazuhException will be raised or not.
    """

    queue = WazuhQueue('test_path')

    with patch('socket.socket.send', return_value=send_response):
        if error:
            with pytest.raises(WazuhException, match=".* 1011 .*"):
                queue._send('msg')
        else:
            queue._send('msg')

    mock_conn.assert_called_with('test_path')
Ejemplo n.º 16
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
Ejemplo n.º 17
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
Ejemplo n.º 18
0
def test_WazuhQueue__init__(mock_conn):
    """Tests WazuhQueue.__init__ function works"""

    WazuhQueue('test_path')

    mock_conn.assert_called_once_with()
Ejemplo n.º 19
0
def test_WazuhQueue_protected_connect_ko(mock_conn):
    """Tests WazuhQueue._connect function exceptions works"""

    with pytest.raises(WazuhException, match=".* 1010 .*"):
        WazuhQueue('test_path')