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 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()
def test_os_exec(set_debug_mode, get_configuration, configure_environment, restart_service, configure_agents): """Check if Active Response message is sent in correct format depending on agent version""" metadata = get_configuration.get('metadata') protocol = metadata['protocol'] extra_args = metadata['extra_args'] timeout = metadata['timeout'] all_agents = metadata['all_agents'] sender = ag.Sender(SERVER_ADDRESS, protocol=protocol) log_monitor = FileMonitor(LOG_FILE_PATH) injectors = [] # Agents for agent in agents: injector = ag.Injector(sender, agent) injectors.append(injector) injector.run() if protocol == "tcp": sender = ag.Sender(manager_address=SERVER_ADDRESS, protocol=protocol) agents_id = [agent.id for agent in agents] # Give time for registration key to be available and send a few heartbeats time.sleep(30) for agent in agents: if all_agents == 'yes': message = f"1:({SERVER_NAME}) {LOG_LOCATION}:{LOG_MESSAGE}" ids = agents_id else: message = f"1:[{agent.id}] ({agent.name}) {LOG_LOCATION}:{LOG_MESSAGE}" ids = agent.id validate_ar_message(message, ids, log_monitor, agent, extra_args, timeout, all_agents) for injector in injectors: injector.stop_receive()
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 check_active_agents(num_agents=1, manager_address='127.0.0.1', agent_version='4.2.0', agent_os='debian7', manager_port=1514, protocol=TCP): """Check if the status of the agents is active after sending start-up and keep-alive events. This can be done for n agents using any protocol. Args: num_agents (int): Number of agents to create and check their status. manager_address (str): Manager IP address. agent_version (str): Agent wazuh version. agent_os (str): Agent operating system. manager_port (int): Manager remote communication port. protocol (str): It can be TCP, UDP or TCP_UDP (both). Raises: AttributeError: If the agent status is not active. """ def send_initialization_events(agent, sender): """Send the start-up and keep-alive events""" try: sender.send_event(agent.startup_msg) # Wait 1 second between start-up message and keep_alive sleep(1) sender.send_event(agent.keep_alive_event) # Wait 1 seconds to ensure that the message has ben sent before closing the socket. sleep(1) finally: sender.socket.close() wazuh_log_monitor = FileMonitor(LOG_FILE_PATH) # Create num_agents (parameter) agents agents = ag.create_agents(agents_number=num_agents, manager_address=manager_address, disable_all_modules=True, agents_version=[agent_version] * num_agents, agents_os=[agent_os] * num_agents) send_event_threads = [] # Wait until remoted has loaded the new agent key rd.wait_to_remoted_key_update(wazuh_log_monitor) # Create sender threads. One for each agent for idx, agent in enumerate(agents): if protocol == TCP_UDP: # Round robin to select the protocol protocol = TCP if idx % 2 == 0 else UDP sender = ag.Sender(manager_address, manager_port, protocol) send_event_threads.append( ThreadExecutor(send_initialization_events, { 'agent': agent, 'sender': sender })) # Run sender threads for thread in send_event_threads: thread.start() # Wait until sender threads finish for thread in send_event_threads: thread.join() # Check agent active status for earch agent for agent in agents: agent.wait_status_active()
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 send_event(event, protocol, manager_port, agent): """Send an event to the manager""" sender = ag.Sender(agent_info['manager_address'], protocol=protocol, manager_port=manager_port) injector = ag.Injector(sender=sender, agent=agent) injector.sender.send_event(event) return injector
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)