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()
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' )
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)
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
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()
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()
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)