def test_request(get_configuration, configure_environment, remove_shared_files,
                 restart_remoted, command_request, expected_answer):
    """
    Writes (config/state) requests in $DIR/queue/ossec/request and check if remoted forwards it to the agent,
    collects the response, and writes it in the socket or returns an error message if the queried
    agent is disconnected.
    """
    cfg = get_configuration['metadata']
    protocols = cfg['PROTOCOL'].split(',')

    agents = [
        ag.Agent(manager_address, "aes", os="debian8", version="4.2.0")
        for _ in range(len(protocols))
    ]
    for agent, protocol in zip(agents, protocols):
        if "disconnected" not in command_request:
            sender, injector = ag.connect(agent, manager_address, protocol)

        msg_request = f'{agent.id} {command_request}'

        response = send_request(msg_request)

        assert expected_answer in response, "Remoted unexpected answer"

        if "disconnected" not in command_request:
            injector.stop_receive()
Example #2
0
def test_agent_remote_configuration(agent_name, get_configuration,
                                    configure_environment, remove_shared_files,
                                    restart_remoted, create_agent_group):
    """Check if the agents correctly send their version, receive the shared configuration, and finally,
        the start-up message is received and processed by the manager.

    Raises:
        AssertionError: if `wazuh-db` returns a wrong agent version, agents do not receive shared configuration or
        startup message after agent restart is not received.
    """

    protocols = get_configuration['metadata']['protocol']

    for protocol in protocols.split(","):
        agent = ag.Agent(**agent_info[agent_name])

        # Sleep to avoid ConnectionRefusedError
        sleep(1)

        sender = ag.Sender(agent_info[agent_name]['manager_address'],
                           protocol=protocol)

        check_push_shared_config(agent, sender)

        wazuh_db_agent_version = agent.get_agent_version()
        assert wazuh_db_agent_version == fr"Wazuh {agent_info[agent_name]['version']}"

        wazuh_log_monitor = FileMonitor(LOG_FILE_PATH)
        log_callback = remote.callback_start_up(agent.name)
        wazuh_log_monitor.start(
            timeout=10,
            callback=log_callback,
            error_message='The start up message has not been found in the logs'
        )
Example #3
0
def test_push_shared_config(get_configuration, configure_environment, remove_shared_files,
                            restart_remoted, create_agent_group):
    """Checks that manager push shared configuration to agents when required.

    Checks if Wazuh Manager sends new shared files from group shared folder when the merged.mg checksum received from
    agent is different than the stored one, for example, when the group configuration changes.
    """

    protocols = get_configuration['metadata']['protocol']

    for protocol in protocols.split(","):
        agent = ag.Agent(**agent_info)
        # Sleep to avoid ConnectionRefusedError
        sleep(1)
        sender = ag.Sender(agent_info['manager_address'], protocol=protocol)
        check_push_shared_config(agent, sender)
Example #4
0
def send_agent_event(wazuh_log_monitor,
                     message=EXAMPLE_MESSAGE_EVENT,
                     protocol=TCP,
                     manager_address='127.0.0.1',
                     manager_port=1514,
                     agent_os='debian7',
                     agent_version='4.2.0',
                     disable_all_modules=True):
    """Allow to create a new simulated agent and send a message to the manager.

    Args:
        wazuh_log_monitor (FileMonitor): FileMonitor object to monitor the Wazuh log.
        message (str): Raw event to send to the manager.
        protocol (str): it can be UDP or TCP.
        manager_address (str): Manager IP address.
        manager_port (str): Port used by remoted in the manager.
        agent_os (str): Agent operating system. The OS must belong to the agent simulator's list of allowed agents.
        agent_version (str): Agent version.
        disable_all_modules (boolean): True to disable all agent modules, False otherwise.

    Returns:
        tuple(Agent, Sender): agent and sender objects.
    """
    # Create an agent with agent simulator
    agent = ag.Agent(manager_address=manager_address,
                     os=agent_os,
                     version=agent_version,
                     disable_all_modules=disable_all_modules)

    # Wait until remoted has loaded the new agent key
    wait_to_remoted_key_update(wazuh_log_monitor)

    # Build the event message and send it to the manager as an agent event
    event = agent.create_event(message)

    # Send the event to the manager
    sender = ag.Sender(manager_address=manager_address,
                       manager_port=manager_port,
                       protocol=protocol)
    sender.send_event(event)

    return agent, sender
Example #5
0
def check_manager_ack(protocol):
    """Allow to check if the manager sends the ACK message after receiving the start-up message from agent.

    Args:
        protocol (str): It can be UDP or TCP.

    Raises:
        TimeoutError: If agent does not receive the manager ACK message in the expected time.
    """

    # Create agent and sender object with default parameters
    agent = ag.Agent(**agent_info)

    # Sleep to avoid ConnectionRefusedError
    sleep(1)

    sender = ag.Sender(agent_info['manager_address'], protocol=protocol)

    # Activate receives_messages modules in simulated agent.
    agent.set_module_status('receive_messages', 'enabled')

    # Run injector with only receive messages module enabled
    injector = ag.Injector(sender, agent)
    try:
        injector.run()

        # Wait until remoted has loaded the new agent key
        rd.wait_to_remoted_key_update(wazuh_log_monitor)

        # Send the start-up message
        sender.send_event(agent.startup_msg)

        # Check ACK manager message
        rd.check_agent_received_message(agent.rcv_msg_queue, '#!-agent ack')
    finally:
        injector.stop_receive()
Example #6
0
def validate_agent_manager_protocol_communication(protocol=TCP,
                                                  manager_port=1514):
    """Check the communication between the agent-manager using different protocols.

    Args:
        protocol (str): It can be only TCP or UDP.
        manager_port (int): Manager remote communication port.

    Raises:
        ConnectionRefusedError: If communication could not be established with the socket.
        TimeoutError: If the event could not be found in the socket queue.
    """
    def send_event(event, protocol, manager_port):
        """Send an event to the manager"""
        print(f"Sending {protocol}")
        sender = ag.Sender(agent_info['manager_address'],
                           protocol=protocol,
                           manager_port=manager_port)

        try:
            sender.send_event(event)
        finally:
            sender.socket.close()

    # Create agent and sender
    agent = ag.Agent(manager_address=agent_info['manager_address'],
                     os=agent_info['os'],
                     version=agent_info['version'])

    # Wait until remoted has loaded the new agent key
    rd.wait_to_remoted_key_update(wazuh_log_monitor)

    # Generate a custom event
    search_pattern = f"test message from agent {agent.id}"
    agent_custom_message = f"1:/test.log:Feb 23 17:18:20 manager sshd[40657]: {search_pattern}"
    event = agent.create_event(agent_custom_message)

    send_event_thread = ThreadExecutor(send_event, {
        'event': event,
        'protocol': protocol,
        'manager_port': manager_port
    })

    # If protocol is TCP, then just send the message as the attempt to establish the connection will fail.
    if protocol == TCP:
        send_event_thread.start()
        send_event_thread.join()
    else:  # If protocol is UDP, then monitor the  socket queue to verify that the event has not been received.
        socket_monitor_thread = ThreadExecutor(rd.check_queue_socket_event, {
            'raw_events': search_pattern,
            'timeout': 20
        })
        socket_monitor_thread.start()

        # Wait 3 seconds until socket monitor is fully initialized
        sleep(3)

        send_event_thread.start()
        send_event_thread.join()

        # Wait until socket monitor thread finishes
        socket_monitor_thread.join()
def test_active_response_ar_sending(get_configuration, configure_environment,
                                    restart_remoted):
    """Test if `wazuh-remoted` sends active response commands to the agent.

    Check if execd sends active response command to the remoted module in the manager. Then, it ensures that the agent receives 
    the active command message from the manager.

    Raises:
        AssertionError: if `wazuh-remoted` does not send the active response command to the agent.
    """
    protocol_array = (get_configuration['metadata']['protocol']).split(',')
    manager_port = get_configuration['metadata']['port']

    for protocol in protocol_array:
        # rcv_msg_limit of 1000 is necessary for UDP test
        agent = ag.Agent(manager_address,
                         'aes',
                         os='debian8',
                         version='4.2.0',
                         disable_all_modules=True,
                         rcv_msg_limit=1000)
        agent.set_module_status('receive_messages', 'enabled')
        agent.set_module_status('keepalive', 'enabled')

        # Time necessary until socket creation
        time.sleep(1)

        sender = ag.Sender(manager_address,
                           protocol=protocol,
                           manager_port=manager_port)

        injector = ag.Injector(sender, agent)

        try:
            injector.run()
            agent.wait_status_active()

            active_response_message = f"(local_source) [] NRN {agent.id} {remote.ACTIVE_RESPONSE_EXAMPLE_COMMAND}"

            send_active_response_message(active_response_message)

            log_callback = remote.callback_active_response_received(
                active_response_message)
            wazuh_log_monitor.start(
                timeout=10,
                callback=log_callback,
                error_message=
                'The expected event has not been found in ossec.log')

            log_callback = remote.callback_active_response_sent(
                active_response_message)

            wazuh_log_monitor.start(
                timeout=10,
                callback=log_callback,
                error_message=
                'The expected event has not been found in ossec.log')

            remote.check_agent_received_message(
                agent.rcv_msg_queue,
                f"#!-execd {remote.ACTIVE_RESPONSE_EXAMPLE_COMMAND}",
                escape=True)
        finally:
            injector.stop_receive()
Example #8
0
def run_agents(agents_number=1,
               manager_address='localhost',
               protocol=TCP,
               agent_version='v4.0.0',
               agent_os='debian8',
               eps=1000,
               run_duration=20,
               active_modules=[],
               modules_eps=None,
               fixed_message_size=None,
               registration_address=None,
               labels=None):
    """Run a batch of agents connected to a manager with the same parameters.

    Args:
        agents_number (int): Number of agents to run.
        manager_address (str): Manager address (hostname or IP).
        protocol (str): Communication protocol.
        agent_version (str): Agents version p.e: v4.0.0
        agent_os (str): Agents os, some examples: debian8, ubuntu18.04, mojave...
        eps (int): Total events per second sent by each agent to the manager.
        run_duration (int): Agent life time.
        active_modules (list): list with active modules names.
        modules_eps (list): list with eps for each active modules.
        fixed_message_size (int): size in bytes for the message.
        registration_address (str): Manager IP address where the agent will be registered.
        labels (dict): Wazuh agent labels in dict format.
    """

    logger = logging.getLogger(f"P{os.getpid()}")
    logger.info(f"Starting {agents_number} agents.")

    active_agents, injectors = [], []

    for _ in range(agents_number):
        agent = ag.Agent(manager_address,
                         "aes",
                         os=agent_os,
                         version=agent_version,
                         fim_eps=eps,
                         fixed_message_size=fixed_message_size,
                         syscollector_frequency=0,
                         sca_frequency=0,
                         registration_address=registration_address,
                         retry_enrollment=True,
                         labels=labels)
        available_modules = agent.modules.keys()

        for module in active_modules:
            if module not in available_modules:
                raise ValueError(
                    f"Selected module: '{module}' doesn't exist on agent simulator!"
                )

        for module in available_modules:
            if module in active_modules:
                index = list(active_modules).index(module)
                agent.modules[module]['status'] = 'enabled'
                if module in ['keepalive', 'receive_messages']:
                    continue
                if modules_eps is not None and 'eps' in agent.modules[module]:
                    agent.modules[module]['eps'] = modules_eps[index]
                else:
                    agent.modules[module]['eps'] = eps
            else:
                agent.modules[module]['status'] = 'disabled'
                agent.modules[module]['eps'] = 0

        logger.info(agent.modules)

        active_agents.append(agent)
        sender = ag.Sender(manager_address, protocol=protocol)
        injectors.append(ag.Injector(sender, agent))

    sleep(30)

    try:
        start(injectors)
        sleep(run_duration)
    finally:
        stop(injectors)