def update_hids_agent_status(agent_id, sensor_id, agent_status): """ Update status of HIDS agent Raises: APICannotResolveSensorID APIInvalidHIDSAgentID APICannotUpdateHIDSAgent """ if sensor_id is None: api_log.error( "[update_hids_agent_status]: Sensor ID could not be empty") raise APICannotResolveSensorID(sensor_id) if agent_id is None: api_log.error( "[update_hids_agent_status]: Agent ID could not be empty") raise APIInvalidHIDSAgentID(agent_id) try: sensor_id_bin = get_bytes_from_uuid(sensor_id) status_integer = Hids_Agents.get_status_integer_from_string( agent_status) db.session.begin() db.session.query(Hids_Agents).filter( and_(Hids_Agents.agent_id == agent_id, Hids_Agents.sensor_id == sensor_id_bin)).update( {"agent_status": status_integer}) db.session.commit() except Exception as msg: db.session.rollback() api_log.error("[update_hids_agent_status]: %s" % str(msg)) raise APICannotUpdateHIDSAgent(agent_id, sensor_id)
def delete_orphan_hids_agents(agent_list, sensor_id): """ Delete orphan HIDS agents Args: agent_list(list): List of active HIDS agents sensor_id(str): Sensor ID Raises: APICannotResolveSensorID APICannotDeleteHIDSAgentList """ if sensor_id is None: api_log.error( "[delete_orphan_hids_agents]: Sensor ID could not be empty") raise APICannotResolveSensorID(sensor_id) try: if agent_list: q_agent_list = "'" + "','".join(agent_list) + "'" sensor_id_hex = get_hex_string_from_uuid(sensor_id) query = "DELETE FROM hids_agents WHERE sensor_id = UNHEX('{0}') " \ "AND agent_id NOT IN ({1})".format(sensor_id_hex, q_agent_list) db.sesion.begin() db.session.connection(mapper=Hids_Agents).execute(query) db.session.commit() except Exception as msg: db.session.rollback() api_log.error("[delete_orphan_hids_agents]: %s" % str(msg)) raise APICannotDeleteHIDSAgentList(agent_list, sensor_id)
def apimethod_run_nmap_scan(sensor_id, target, idm, scan_type, rdns, scan_timing, autodetect, scan_ports, output_file_prefix="", save_to_file=False, job_id=""): """Launches an MAP scan Args: sensor_id: The system IP where you want to get the [sensor]/interfaces from ossim_setup.conf target: IP address of the component where the NMAP will be executed idm: Convert results into idm events scan_type: Sets the NMAP scan type rdns: Tells Nmap to do reverse DNS resolution on the active IP addresses it finds scan_timing: Set the timing template autodetect: Aggressive scan options (enable OS detection) scan_ports: Only scan specified ports output_file_prefix: Prefix string to be added to the output filename save_to_file: Indicates whether you want to save the NMAP report to a file or not. job_id: Celery job ID. Returns: nmap_report: The NMAP report or the filename where the report has been saved. Raises: APINMAPScanCannotRun APICannotResolveSensorID APINMAPScanCannotRetrieveBaseFolder APINMAPScanCannotCreateLocalFolder """ (result, sensor_ip) = get_sensor_ip_from_sensor_id(sensor_id, local_loopback=False) if result is False: api_log.error( "[apimethod_run_nmap_scan] Cannot retrieve the sensor ip from the given sensor id <%s>" % sensor_id) raise APICannotResolveSensorID(sensor_id) success, nmap_report = ansible_run_nmap_scan(sensor_ip=sensor_ip, target=target, scan_type=scan_type, rdns=rdns, scan_timing=scan_timing, autodetect=autodetect, scan_ports=scan_ports, job_id=job_id) if not success: api_log.error('Failed to launch NMAP scan: %s' % nmap_report) raise APINMAPScanCannotRun(nmap_report) filename = None if save_to_file: base_path = get_nmap_directory(sensor_id) filename = "%s/nmap_report_%s.json" % (base_path, output_file_prefix) with open(filename, "w") as f: f.write(json.dumps(nmap_report)) if idm: conn = IDMConnection(sensor_id=sensor_id) if conn.connect(): conn.send_events_from_hosts(nmap_report) try: if filename is not None: os.remove(filename) except Exception: pass else: api_log.error("[apimethod_run_nmap_scan] Cannot connect with the IDM Service") try: apimethods_nmap_purge_scan_files(job_id) except Exception as exp: api_log.warning("[apimethod_run_nmap_scan] Cannot purge the scan files %s" % str(exp)) return nmap_report
def delete_hids_agent(agent_id, sensor_id): """ Delete a HIDS agent Args: agent_id(str): HIDS agent ID sensor_id(str): Sensor ID Raises: APICannotResolveSensorID APIInvalidHIDSAgentID APICannotDeleteHIDSAgent """ if sensor_id is None: api_log.error("[delete_hids_agent]: Sensor ID could not be empty") raise APICannotResolveSensorID(sensor_id) if agent_id is None: api_log.error("[delete_hids_agent]: Agent ID could not be empty") raise APIInvalidHIDSAgentID(agent_id) try: sensor_id_bin = get_bytes_from_uuid(sensor_id) db.session.begin() db.session.query(Hids_Agents).filter( and_(Hids_Agents.agent_id == agent_id, Hids_Agents.sensor_id == sensor_id_bin)).delete() db.session.commit() except Exception as msg: db.session.rollback() api_log.error("[delete_hids_agent] %s" % str(msg)) raise APICannotDeleteHIDSAgent(agent_id, sensor_id)
def update_asset_id(sensor_id, agent_id, asset_id): """ Update Asset ID related to agent Raises: APICannotResolveSensorID APIInvalidHIDSAgentID APICannotUpdateHIDSAgent APICannotResolveAssetID """ if sensor_id is None: api_log.error("[update_asset_id]: Sensor ID could not be empty") raise APICannotResolveSensorID(sensor_id) if agent_id is None: api_log.error("[update_asset_id]: Agent ID could not be empty") raise APIInvalidHIDSAgentID(agent_id) if asset_id is None: api_log.error("[update_asset_id]: Asset ID could not be empty") raise APICannotResolveAssetID(asset_id) try: sensor_id_bin = get_bytes_from_uuid(sensor_id) asset_id_bin = get_bytes_from_uuid(asset_id) db.session.query(Hids_Agents).filter( and_(Hids_Agents.agent_id == agent_id, Hids_Agents.sensor_id == sensor_id_bin)).update( {"host_id": asset_id_bin}) except Exception as msg: api_log.error("[update_asset_id]: %s" % str(msg)) raise APICannotUpdateHIDSAgent(agent_id, sensor_id)
def get_hids_agents_by_sensor(sensor_id): """ Get HIDS agents by sensor Args: sensor_id(str): Sensor ID Returns: Dictionary with HIDS agents of the sensor in the database Raises: APICannotResolveSensorID APICannotGetHIDSAgents """ hids_agents = {} if sensor_id is None: api_log.error( "[get_hids_agents_by_sensor]: Sensor ID could not be empty") raise APICannotResolveSensorID(sensor_id) try: sensor_id_hex = get_hex_string_from_uuid(sensor_id) query = "SELECT HEX(ha.sensor_id) AS sensor_id, ha.agent_id, ha.agent_name, ha.agent_ip, " \ "ha.agent_status, HEX(ha.host_id) AS host_id " \ "FROM hids_agents ha WHERE ha.sensor_id = UNHEX('{0}')".format(sensor_id_hex) ha_list = db.session.connection(mapper=Hids_Agents).execute(query) for hids_agent in ha_list: ha_id = hids_agent.agent_id ha_name = hids_agent.agent_name ha_ip = hids_agent.agent_ip ha_status = hids_agent.agent_status ha_host_id = hids_agent.host_id if hids_agent.host_id is not None else '' hids_agents[ha_id] = { 'id': ha_id, 'name': ha_name, 'ip_cidr': ha_ip, 'status': { 'id': ha_status, 'descr': Hids_Agents.get_status_string_from_integer(ha_status) }, 'host_id': ha_host_id } except Exception as msg: api_log.error("[get_hids_agents_by_sensor]: %s" % str(msg)) raise APICannotGetHIDSAgents(sensor_id) return hids_agents
def get_sensor_plugins(sensor_id, no_cache=False): """ Get the plugins of a sensor Raise: APICannotGetSensorPlugins """ success, sensor_ip = get_sensor_ip_from_sensor_id(sensor_id) if not success: raise APICannotResolveSensorID( sensor_id=sensor_id, log='[get_sensor_plugins] Error getting sensor ip: {0}'.format(str(sensor_ip))) plugins = ansible_get_sensor_plugins(system_ip=sensor_ip) return plugins
def add_hids_agent(agent_id, sensor_id, agent_name, agent_ip, agent_status, host_id=None): """ Add a new HIDS agent Raises: APICannotResolveSensorID APIInvalidHIDSAgentID APICannotAddHIDSAgent """ if sensor_id is None: api_log.error("[add_hids_agent]: Sensor ID could not be empty") raise APICannotResolveSensorID(sensor_id) if agent_id is None: api_log.error("[add_hids_agent]: Agent ID could not be empty") raise APIInvalidHIDSAgentID(agent_id) try: db.session.begin() sensor_id_bin = get_bytes_from_uuid(sensor_id) if host_id: hex_id_bin = get_bytes_from_uuid(host_id) else: hex_id_bin = None status_integer = Hids_Agents.get_status_integer_from_string( agent_status) hids_agent = Hids_Agents() hids_agent.agent_id = agent_id hids_agent.sensor_id = sensor_id_bin hids_agent.agent_name = agent_name hids_agent.agent_ip = agent_ip hids_agent.agent_status = status_integer hids_agent.host_id = hex_id_bin db.session.merge(hids_agent) db.session.commit() except Exception as msg: db.session.rollback() api_log.error("[add_hids_agent]: %s" % str(msg)) raise APICannotAddHIDSAgent(agent_id, sensor_id)
def apimethod_monitor_nmap_scan(sensor_id, task_id): """Monitors an NMAP scan Args: sensor_id: The sensor id where the NMAP is working. task_id: The celery task id that is launching the NMAP Raises APICannotResolveSensorID APINMAPScanCannotRetrieveScanProgress """ (result, sensor_ip) = get_sensor_ip_from_sensor_id(sensor_id, local_loopback=False) if result is False: api_log.error( "[apimethod_monitor_nmap_scan] Cannot retrieve the sensor ip from the given sensor id <%s>" % sensor_id) raise APICannotResolveSensorID(sensor_id) try: nhosts = ansible_nmap_get_scan_progress(sensor_ip=sensor_ip, task_id=task_id) except Exception as e: api_log.error("[apimethod_monitor_nmap_scan] Cannot retrieve scan progress {0}".format(str(e))) raise APINMAPScanCannotRetrieveScanProgress() return nhosts
def get_sensor_by_sensor_id(sensor_id): """Returns a Sensor object given a Sensor ID""" try: # Getting Sensor ID for local system if sensor_id.lower() == 'local': (success, system_id) = get_system_id_from_local() if not success: raise APICannotResolveLocalSystemID() (success, local_sensor_id) = get_sensor_id_from_system_id(system_id) if success and local_sensor_id: sensor_id = local_sensor_id if not is_valid_uuid(sensor_id): raise APICannotResolveSensorID(sensor_id) # Getting sensor information success = True sensor_id_bin = get_bytes_from_uuid(sensor_id.lower()) data = db.session.query(Sensor).filter( Sensor.id == sensor_id_bin).one() except NoResultFound: success = False data = "No sensor found with the given ID" except MultipleResultsFound: success = False data = "More than one sensor found with the given ID" except Exception as ex: db.session.rollback() success = False data = "Something wrong happen while retrieving the sensor {0}".format( ex) return success, data
def apimethods_stop_scan(task_id): """Stops the given scan id Raises: APICannotResolveSensorID APINMAPScanKeyNotFound APINMAPScanException """ # Stops the celery task. job = apimethod_get_nmap_scan_status(task_id) job["status"] = "Stopping" apimethod_nmapdb_update_task(task_id, job) (result, sensor_ip) = get_sensor_ip_from_sensor_id(job["sensor_id"], local_loopback=False) if not result: raise APICannotResolveSensorID(job["sensor_id"]) base_path = get_nmap_directory(job["sensor_id"]) success, result = ansible_nmap_stop(sensor_ip, task_id) if not success: raise APINMAPScanException(str(result)) job["status"] = "Finished" job["reason"] = "Stopped by the user" apimethod_nmapdb_update_task(task_id, job) success, result_file = ansible_get_partial_results(sensor_ip, task_id) if success: try: results = {} if os.path.isfile(result_file): with open(result_file, "r") as f: for line in f.readlines(): d = json.loads(line) results[d["host"]] = d["scan"] filename = "%s/nmap_report_%s.json" % (base_path, task_id) with open(filename, "w") as f: f.write(json.dumps(results)) except Exception as e: raise APINMAPScanException(str(e))
def ossec_win_deploy(sensor_id, asset_id, windows_ip, windows_username, windows_password, windows_domain, agent_id=None): """ Deploy HIDS agent on a Windows System Args: sensor_id(str): Sensor ID asset_id(str): Asset ID windows_ip(str) : Deployment IP (where we are going to deploy the HIDS Agent) windows_username(str) : Windows Username windows_password(str) : Windows Password windows_domain(str) : Windows Domain agent_id(str) : Agent ID Returns: True if HIDS agent was properly deployed Raises: APICannotResolveAssetID APICannotCreateHIDSAgent APICannotGetHIDSAgentByAsset APICannotResolveSensorID APICannotDeployHIDSAgent APIInvalidDeploymentIP APIInvalidWindowsUsername APIInvalidWindowsPassword APIInvalidAgentID """ # Setting default values agent_name = None sensor_ip = None sensor_name = None asset_name = None try: # Validate deployment parameters if not is_valid_uuid(asset_id): raise APICannotResolveAssetID(asset_id) if not is_valid_ipv4(windows_ip): raise APIInvalidDeploymentIP(windows_ip) if not is_valid_windows_user(windows_username): raise APIInvalidWindowsUsername(windows_username) if not is_valid_user_password(windows_password): raise APIInvalidWindowsPassword() if agent_id and not is_valid_ossec_agent_id(agent_id): raise APIInvalidAgentID(agent_id) # Getting Sensor Information (success, sensor) = get_sensor_by_sensor_id(sensor_id) if not success: raise APICannotResolveSensorID(sensor_id) sensor_id = get_uuid_string_from_bytes(sensor.id) sensor_id = sensor_id.replace('-', '').upper() sensor_ip = get_ip_str_from_bytes(sensor.ip) sensor_name = sensor.name # Getting agent related to assets hids_agents = get_hids_agents_by_asset(asset_id, sensor_id) # Getting asset info asset_name = get_name_by_host_id(asset_id) if len(hids_agents) == 0: # Creating agent if doesn't exists agent_name = asset_name (success, data) = apimethod_ossec_add_new_agent(sensor_id, agent_name, windows_ip, asset_id) if not success: raise APICannotCreateHIDSAgent(agent_name, sensor_id) else: agent_id = data else: # Getting agent information if agent_id: agent_key = sensor_id + '#' + agent_id else: agent_key = hids_agents.keys().pop(0) if agent_key in hids_agents: agent_name = hids_agents[agent_key].get('name') agent_id = hids_agents[agent_key].get('id') else: raise APICannotGetHIDSAgentByAsset(asset_id) # Deploy HIDS Agent ansible_result = ansible_ossec_win_deploy(sensor_ip, agent_name, windows_ip, windows_username, windows_domain, windows_password) if ansible_result[sensor_ip]['unreachable'] == 0 and ansible_result[ sensor_ip]['failures'] == 0: # No error, update agent status in database time.sleep(2) (success, data) = apimethod_ossec_get_agent_detail(sensor_id, agent_id) if success: agent_info = data[0].split(',') agent_status = agent_info[3] update_hids_agent_status(agent_id, sensor_id, agent_status) else: ans_last_error = "" if ansible_result[sensor_ip]['unreachable'] == 1: ans_last_error = "System is unreachable" elif 'msg' in ansible_result['alienvault']['lasterror'][ sensor_ip] and ansible_result['alienvault']['lasterror'][ sensor_ip]['msg'] != "": ans_last_error = ansible_result['alienvault']['lasterror'][ sensor_ip]['msg'] elif 'stderr' in ansible_result['alienvault']['lasterror'][ sensor_ip] and ansible_result['alienvault']['lasterror'][ sensor_ip]['stderr'] != "": ans_last_error = ansible_result['alienvault']['lasterror'][ sensor_ip]['stderr'] elif 'stdout' in ansible_result['alienvault']['lasterror'][ sensor_ip] and ansible_result['alienvault']['lasterror'][ sensor_ip]['stdout'] != "": ans_last_error = ansible_result['alienvault']['lasterror'][ sensor_ip]['stdout'] error_msg = 'HIDS Agent cannot be deployed. Reason: {0}'.format( ans_last_error) raise APICannotDeployHIDSAgent(error_msg) res = True message = 'HIDS agent successfully deployed' except APICannotDeployHIDSAgent as err: message = str(err) res = False except Exception as err: message = str(err) logger.error(message) res = False # Create message in Message Center mc_id = "00000000-0000-0000-0000-000000010033" if res is True else "00000000-0000-0000-0000-000000010031" additional_info = { "asset_id": asset_id, "sensor_id": sensor_id, "agent_id": agent_id, "asset_name": asset_name, "asset_ip": windows_ip, "sensor_ip": sensor_ip, "sensor_name": sensor_name, "agent_name": agent_name, "deploy_status": message } additional_info = json.dumps(additional_info) insert_current_status_message(mc_id, asset_id, "host", additional_info) return res, message
def set_sensor_plugins_enabled_by_asset(sensor_id, assets_info): """ Set the list of plugins enabled in a sensor by asset Params: sensor_id (UUID): sensor id assets_info (dict or json string): {"<asset_id>": ["<plugin_1>", "<plugin_2>", ...], ...} Return: the id of the agent restart job """ (success, sensor_ip) = get_sensor_ip_from_sensor_id(sensor_id) if not success: raise APICannotResolveSensorID( sensor_id=sensor_id, log="[set_sensor_plugins_enabled_by_asset] " "Error getting Sensor ip: %s".format(sensor_ip)) try: plugins = {} if isinstance(assets_info, basestring): assets_info = json.loads(assets_info) for asset_id, asset_plugins in assets_info.iteritems(): asset_id = str(uuid.UUID(asset_id)) asset_ips = get_asset_ip_from_id(asset_id=asset_id) if not asset_ips: api_log.error( "Cannot resolve ips for asset '{0}'".format(asset_id)) continue plugins[asset_id] = { 'device_ip': asset_ips[0], 'plugins': asset_plugins } except Exception as e: raise APIInvalidInputFormat( log="[set_sensor_plugins_enabled_by_asset] " "Invalid asset_info format: '{0}'".format(str(e))) try: (success, data) = set_sensor_detectors_from_yaml(sensor_ip, str(plugins)) except Exception as e: raise APICannotSetSensorPlugins( log="[set_sensor_plugins_enabled_by_asset] " "Cannot set asset plugins: '{0}'".format(str(e))) if not success: api_log.error("[set_sensor_plugins_enabled_by_asset] " "Cannot set asset plugins: '{0}'".format(str(data))) raise APICannotSetSensorPlugins( log="[set_sensor_plugins_enabled_by_asset] " "Cannot set asset plugins: '{0}'".format(str(data))) # Flush sensor plugin cache and Update host plugin info flush_cache("sensor_plugins") # Import here to avoid circular imports from celerymethods.tasks.monitor_tasks import ( monitor_update_host_plugins, monitor_enabled_plugins_limit) try: monitor_update_host_plugins.delay() except AlreadyQueued: api_log.info( "[set_sensor_plugins_enabled_by_asset] monitor update host plugins already queued" ) try: monitor_enabled_plugins_limit.delay() except AlreadyQueued: api_log.info( "[set_sensor_plugins_enabled_by_asset] monitor for enabled plugins already queued" ) # Restart the alienvault agent job = restart_alienvault_agent.delay(sensor_ip=sensor_ip) return job.id