PicusNG
Picus - The Complete Security Control Validation NG Platform.
Network Security · PicusNGAutomation
Details
| ID | PicusNG |
|---|---|
| Provider | Picus Security |
| Category | Network Security |
| From Version | 6.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
This integration was integrated and tested with Picus NG
Configure PicusNG in Cortex

| Parameter | Required |
|---|---|
| Picus Manager URL | True |
| Trust any certificate (not secure) | False |
| Use system proxy settings | False |
| Picus Refresh Token | True |

Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
picus-get-access-token
OAuth2 protocol is used to authorize Refresh/Access tokens. To obtain the API, you should generate a refresh token and then request an access token using this command.
Base Command
picus-get-access-token
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
picus-get-agent-list
This command returns the simulation agent list with agent name, id, status, agent type and platform information as in Picus platform > Agents.
Base Command
picus-get-agent-list
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
picus-get-agent-detail
This command returns agent name, status, agent type, platform and also mitigation devices and attack modules using the agent ID.
Base Command
picus-get-agent-detail
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Agent id. | Required |
Context Output
There is no context output for this command.
picus-create-simulation
This command creates and runs a simulation as requested; scheduled or instant.
You can create a simulation by giving your simulation a name and adding the template ID, agent ID.
Base Command
picus-create-simulation
Input
| Argument Name | Description | Required |
|---|---|---|
| agent_id | ID of the agent. | Required |
| description | Description of the simulation. Default is this simulation created with cortex app. | Optional |
| name | Name of the simulation. | Required |
| schedule_now | Schedule now state. Possible values are: True, False. | Required |
| template_id | Id of the template. | Required |
Context Output
There is no context output for this command.
picus-get-template-list
This command returns template list that contains template name, id, description, content type, category as in Picus Platform> Threat Templates.
Base Command
picus-get-template-list
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Pagination value. | Optional |
| limit | Pagination value. | Optional |
Context Output
There is no context output for this command.
picus-get-integration-agent-list
This command returns the agent name, id, status, agent installation information and the token expiration information.
Base Command
picus-get-integration-agent-list
Input
There are no input arguments for this command.
Context Output
There is no context output for this command.
picus-get-simulation-list
This command returns the list of you latest simulation result overview as in Picus Platform > Simulations tab. Latest simulation run results are included.
Base Command
picus-get-simulation-list
Input
| Argument Name | Description | Required |
|---|---|---|
| offset | Pagination value. | Optional |
| limit | Pagination value. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Picus.simulationlist.simulation_id | Number | ID of the simulation |
picus-simulate-now
This command runs the existing simulation using the Simulation ID.
Base Command
picus-simulate-now
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Simulation ID. | Required |
Context Output
There is no context output for this command.
picus-get-simulation-detail
This command returns the information about a specific simulation.
Base Command
picus-get-simulation-detail
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Simulation ID. | Required |
Context Output
There is no context output for this command.
picus-get-latest-simulation-result
This command returns detailed information about simulation results including Prevention and Detection result details for the latest simulation run.
Base Command
picus-get-latest-simulation-result
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Simulation ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Picus.latestSimulationResult.simulation_run_id | String | Simulation Run ID |
| Picus.latestSimulationResult.simulation_id | String | Simulation ID |
| Picus.latestSimulationResult.status | String | Simulation Status |
picus-get-simulation-result
This command returns detailed information about simulation results including Prevention and Detection result details for a specific simulation run with run id.
Base Command
picus-get-simulation-result
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Simulation ID. | Required |
| run_id | Simulation Run ID. | Required |
Context Output
There is no context output for this command.
picus-get-simulation-threats
This command returns simulation result based on threats. Threat result includes threat id and name, prevention result and action count.
Base Command
picus-get-simulation-threats
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Simulation ID. | Required |
| run_id | Simulation Run ID. | Required |
| limit | Pagination value. | Optional |
| offset | Pagination value. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Picus.SimulationThreats | String | Threat list of simulation |
picus-get-simulation-actions
This command returns simulation result based on action list using threat ID, simulation ID and simulation run ID.
Base Command
picus-get-simulation-actions
Input
| Argument Name | Description | Required |
|---|---|---|
| id | Simulation ID. | Required |
| run_id | Simulation Run ID. | Required |
| threat_ids | Threat ID list (“111,222,333,…”) or single threat ID can be given. | Required |
| limit | Pagination value. | Optional |
| offset | Pagination value. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Picus.SimulationActions | String | Action Results(ID and result combination) |
picus-get-mitigation-devices
This command returns mitigation device information as obtained under Picus platform > Mitigation > Vendor Based Mitigations. Vendor based mitigation devices can be fetched using this command.
Base Command
picus-get-mitigation-devices
Input
| Argument Name | Description | Required |
|---|---|---|
| ids | Simulation ID list (“111,222,333,…”) or single simulation ID can be given. | Optional |
Context Output
There is no context output for this command.
picus-get-signature-list
This command returns action based signature suggestions.
Base Command
picus-get-signature-list
Input
| Argument Name | Description | Required |
|---|---|---|
| device_id | Mitigation Device ID. | Required |
| action_ids | Action ID list (“111,222,333,…”) or single action ID can be given. | Required |
Context Output
There is no context output for this command.
picus-set-paramPB
Set parameter on playbook. (This command is only used on playbook)
Base Command
picus-set-paramPB
Input
| Argument Name | Description | Required |
|---|---|---|
| agent_id | Simulation Agent ID. | Required |
| device_id | Device ID . | Optional |
| simulation_id | Simulation ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Picus.param.agent_id | String | Agent ID |
| Picus.param.device_id | String | Device ID |
| Picus.param.simulation_id | String | Simulation ID |
picus-filter-insecure-attacks
Filter insecure attacks on playbook. (This command is only used on playbook)
Base Command
picus-filter-insecure-attacks
Input
| Argument Name | Description | Required |
|---|---|---|
| threatinfo | Threat id and result combine. Used for playbook. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| Picus.filterinsecure | String | Insecure Attack List |
Configuration parameters
picus_server— Picus Manager URL (required)insecure— Trust any certificate (not secure)proxy— Use system proxy settingspicus_apikey— Picus Refresh Token (required)
Commands (16)
-
picus-create-simulationThis command creates and runs a simulation as requested; scheduled or instant. You can create a simulation by giving your simulation a name and adding the template ID, agent ID.
-
picus-filter-insecure-attacksFilter insecure attacks on playbook. (This command is only used on playbook).
-
picus-get-agent-detailThis command returns agent name, status, agent type, platform and also mitigation devices and attack modules using the agent ID.
-
picus-get-agent-listThis command returns the simulation agent list with agent name, id, status, agent type and platform information as in Picus platform > Agents.
-
picus-get-integration-agent-listThis command returns the agent name, id, status, agent installation information and the token expiration information.
-
picus-get-latest-simulation-resultThis command returns detailed information about simulation results including Prevention and Detection result details for the latest simulation run.
-
picus-get-mitigation-devicesThis command returns mitigation device information as obtained under Picus platform > Mitigation > Vendor Based Mitigations. Vendor based mitigation devices can be fetched using this command.
-
picus-get-signature-listThis command returns action based signature suggestions.
-
picus-get-simulation-actionsThis command returns simulation result based on action list using threat ID, simulation ID and simulation run ID.
-
picus-get-simulation-detailThis command returns the information about a specific simulation.
-
picus-get-simulation-listThis command returns the list of you latest simulation result overview as in Picus Platform > Simulations tab. Latest simulation run results are included.
-
picus-get-simulation-resultThis command returns detailed information about simulation results including Prevention and Detection result details for a specific simulation run with run id.
-
picus-get-simulation-threatsThis command returns simulation result based on threats. Threat result includes threat id and name, prevention result and action count.
-
picus-get-template-listThis command returns template list that contains template name, id, description, content type, category as in Picus Platform> Threat Templates.
-
picus-set-paramPBSet parameter on playbook. (This command is only used on playbook).
-
picus-simulate-nowThis command runs the existing simulation using the Simulation ID.
import demistomock as demisto from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa import urllib3 from typing import Any # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # ISO8601 format with UTC, default in XSOAR """ CLIENT CLASS """ class Client(BaseClient): def __init__(self, api_key: str, base_url: str, proxy: bool, verify: bool): super().__init__(base_url=base_url, proxy=proxy, verify=verify) self.api_key = api_key if self.api_key: self._headers = {"Content-Type": "application/json"} self.access_token = self.get_access_token() picus_headers = {"Content-Type": "application/json", "Authorization": ""} picus_headers["Authorization"] = "Bearer " + self.access_token self._headers = picus_headers def get_access_token(self): picus_token_data = {"refresh_token": ""} picus_token_data["refresh_token"] = str(self.api_key) picus_auth_endpoint = "/v1/auth/token" picus_auth_response = self.http_request(method="POST", json_data=picus_token_data, url_suffix=picus_auth_endpoint) picus_accessToken = picus_auth_response["token"] return picus_accessToken def http_request( self, method: str, url_suffix: str, params: Optional[dict] = None, json_data: Optional[dict] = None, additional_headers: Optional[dict] = None, timeout: Optional[int] = None, data: Optional[dict] = None, ): headers = {**additional_headers, **self._headers} if additional_headers else self._headers return self._http_request( method=method, url_suffix=url_suffix, params=params, json_data=json_data, data=data, headers=headers, timeout=timeout, ok_codes=(200,), ) def get_agent_list(self): return self.http_request(method="GET", url_suffix="/v1/agents") def get_agent_detail(self, agent_id: str): return self.http_request(method="GET", url_suffix="/v1/agents/" + agent_id) def get_integration_agent_list(self): return self.http_request(method="GET", url_suffix="/v1/integrations/agents") def get_template_list(self, query_parameters: str): return self.http_request(method="GET", url_suffix="/v1/templates" + query_parameters) def create_simulation(self, picus_post_data_simulation: dict): return self.http_request(method="POST", url_suffix="/v1/simulations", json_data=picus_post_data_simulation) def get_simulation_list(self, query_parameters: str): return self.http_request(method="GET", url_suffix="/v1/simulations" + query_parameters) def simulate_now(self, simulation_id: str): return self.http_request(method="POST", url_suffix="/v1/simulations/" + simulation_id + "/simulate-now") def get_simulation_detail(self, simulation_id: str): return self.http_request(method="GET", url_suffix="/v1/simulations/" + simulation_id) def get_latest_simulation_result(self, simulation_id: str): return self.http_request(method="GET", url_suffix="/v1/simulations/" + simulation_id + "/run/latest") def get_simulation_result(self, simulation_id: str, run_id: str): return self.http_request(method="GET", url_suffix="/v1/simulations/" + simulation_id + "/run/" + run_id) def get_simulation_threats(self, query_parameters: str, simulation_id: str, run_id: str): return self.http_request( method="GET", url_suffix="/v1/simulations/" + simulation_id + "/run/" + run_id + "/threats" + query_parameters ) def get_simulation_actions(self, query_parameters: str, simulation_id: str, run_id: str, threat_id: str): return self.http_request( method="GET", url_suffix="/v1/simulations/" + simulation_id + "/run/" + run_id + "/threats/" + threat_id + "/actions" + query_parameters, ) def get_mitigation_devices(self, query_parameters: str): return self.http_request(method="GET", url_suffix="/v2/mitigation/devices" + query_parameters) def get_signature_list(self, query_parameters: str, device_id: str): return self.http_request( method="GET", url_suffix="/v1/mitigation/devices/" + device_id + "/signatures" + query_parameters ) """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: """Tests API connectivity and authentication' Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Raises exceptions if something goes wrong. :type client: ``Client`` :param Client: client to use :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ message: str = "" picus_accessToken: str = "" try: client.get_access_token() message = "ok" except Exception as e: if ( "Forbidden" in str(e) or "Authorization" in str(e) or "NewConnectionError" in str(e) or "Unauthorized" in str(e) or picus_accessToken is None ): message = "Authorization Error: make sure API Key or Picus URL is correctly set" else: raise e return message def get_agent_list_command(client: Client) -> CommandResults: picus_endpoint_response = client.get_agent_list() picus_agents = picus_endpoint_response["agents"] for agent in picus_agents: agent["created_at"] = str(datetime.fromtimestamp(agent["created_at"] / 1000)) table_name = "Picus Agent List" table_headers = ["id", "name", "status", "type", "version", "created_at", "platform_name", "platform_architecture"] md_table = tableToMarkdown( table_name, picus_agents, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_agents, outputs_prefix="Picus.agentlist") def get_agent_detail_command(client: Client) -> CommandResults: agent_id = demisto.args().get("id") tmp_attack_modules: dict = {} picus_endpoint_response = client.get_agent_detail(agent_id) picus_agent_detail = picus_endpoint_response picus_agent_attack_modules = picus_endpoint_response["attack_modules"] picus_agent_detail.pop("attack_modules") for modules in picus_agent_attack_modules: tmp_attack_modules[modules["name"]] = modules["enabled"] picus_agent_detail.update(tmp_attack_modules) table_name = "Picus Agent Details" table_headers = [ "id", "name", "status", "File Download", "Endpoint Scenario", "Web Application", "Email", "Data Exfiltration", ] md_table = tableToMarkdown( table_name, picus_agent_detail, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) results = CommandResults(readable_output=md_table, outputs=picus_agent_detail, outputs_prefix="Picus.agentdetail") return results def get_integration_agent_list_command(client: Client) -> CommandResults: picus_endpoint_response = client.get_integration_agent_list() picus_integration_agents = picus_endpoint_response["integration_agents"] for agent in picus_integration_agents: agent["created_at"] = str(datetime.fromtimestamp(agent["created_at"] / 1000)) agent["updated_at"] = str(datetime.fromtimestamp(agent["updated_at"] / 1000)) table_name = "Picus Integration Agent List" table_headers = ["id", "name", "status", "created_at", "updated_at", "installed", "token_expired"] md_table = tableToMarkdown( table_name, picus_integration_agents, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_integration_agents, outputs_prefix="Picus.integrationagentlist") def get_template_list_command(client: Client) -> CommandResults: query_parameters: str = "" offset = demisto.args().get("offset") limit = demisto.args().get("limit") if offset is not None and limit is None: raise DemistoException("limit should be set.") elif offset is None and limit is not None: raise DemistoException("offset should be set.") if offset is not None and limit is not None: query_parameters = "?" + "limit=" + limit + "&" + "offset=" + offset picus_endpoint_response = client.get_template_list(query_parameters) picus_templates = picus_endpoint_response["templates"] table_name = "Picus Template List" table_headers = ["id", "name", "description", "threat_count", "category_name", "content_type", "agent_types"] md_table = tableToMarkdown( table_name, picus_templates, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_templates, outputs_prefix="Picus.templatelist") def create_simulation_command(client: Client) -> CommandResults: picus_simulation_creation_results: dict = {} agent_id = int(demisto.args().get("agent_id")) simulation_description = demisto.args().get("description") simulation_name = demisto.args().get("name") schedule_now = bool(demisto.args().get("schedule_now")) template_id = int(demisto.args().get("template_id")) picus_post_data_simulation = { "agent_id": agent_id, "description": simulation_description, "name": simulation_name, "schedule_now": schedule_now, "template_id": template_id, } picus_endpoint_response = client.create_simulation(picus_post_data_simulation) picus_endpoint_response_all = picus_endpoint_response picus_created_simulation = picus_endpoint_response["simulation"] picus_simulation_run_info = picus_endpoint_response["run_info"] picus_simulation_creation_results["simulation_id"] = picus_created_simulation["id"] picus_simulation_creation_results["name"] = picus_created_simulation["name"] picus_simulation_creation_results["description"] = picus_created_simulation["description"] picus_simulation_creation_results["run_immediately"] = picus_endpoint_response_all["run_immediately"] picus_simulation_creation_results["simulation_status"] = picus_simulation_run_info["status"] table_name = "Picus Simulation Create Status" table_headers = ["simulation_id", "name", "description", "run_immediately", "simulation_status"] md_table = tableToMarkdown( table_name, picus_simulation_creation_results, headers=table_headers, removeNull=True, headerTransform=string_to_table_header, ) return CommandResults( readable_output=md_table, outputs=picus_simulation_creation_results, outputs_prefix="Picus.createsimulation" ) def get_simulation_list_command(client: Client) -> CommandResults: query_parameters: str = "" offset = demisto.args().get("offset") limit = demisto.args().get("limit") if offset is not None and limit is None: raise DemistoException("limit should be set.") elif offset is None and limit is not None: raise DemistoException("offset sohuld be set.") if offset is not None and limit is not None: query_parameters = "?" + "limit=" + limit + "&" + "offset=" + offset picus_endpoint_response = client.get_simulation_list(query_parameters) picus_simulations = picus_endpoint_response["simulations"] table_name = "Picus Simulation List" table_headers = [ "simulation_id", "simulation_name", "status", "has_detection_analysis", "has_last_run_detection_analysis", "last_detection_security_score", "last_prevention_security_score", "agent", ] md_table = tableToMarkdown( table_name, picus_simulations, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_simulations, outputs_prefix="Picus.simulationlist") def simulate_now_command(client: Client) -> CommandResults: simulation_id = demisto.args().get("id") picus_endpoint_response = client.simulate_now(simulation_id) picus_simulateNow = picus_endpoint_response["run_info"] table_name = "Picus Simulate Now Status" table_headers = ["browser", "id", "status"] md_table = tableToMarkdown( table_name, picus_simulateNow, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_simulateNow, outputs_prefix="Picus.simulatenow") def get_simulation_detail_command(client: Client) -> CommandResults: simulation_id = demisto.args().get("id") picus_endpoint_response = client.get_simulation_detail(simulation_id) picus_simulationDetail = picus_endpoint_response["simulation_run"] for sRun in picus_simulationDetail: sRun["started_at"] = str(datetime.fromtimestamp(sRun["started_at"] / 1000)) sRun["completed_at"] = str(datetime.fromtimestamp(sRun["completed_at"] / 1000)) table_name = "Picus Simulation Detail" table_headers = ["id", "started_at", "completed_at", "status"] md_table = tableToMarkdown( table_name, picus_simulationDetail, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_simulationDetail, outputs_prefix="Picus.simulationDetail") def get_latest_simulation_result_command(client: Client) -> CommandResults: simulation_id = demisto.args().get("id") picus_latestSimulation = client.get_latest_simulation_result(simulation_id) if picus_latestSimulation["status"] == "COMPLETED": picus_latestSimulation["started_at"] = str(datetime.fromtimestamp(picus_latestSimulation["started_at"] / 1000)) picus_latestSimulation["completed_at"] = str(datetime.fromtimestamp(picus_latestSimulation["completed_at"] / 1000)) picus_latestSimulation["prevention_security_score"] = picus_latestSimulation["results"]["prevention"]["security_score"] picus_latestSimulation["prevention_total_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "total_count" ] picus_latestSimulation["prevention_blocked_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "blocked_count" ] picus_latestSimulation["prevention_not_blocked_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "not_blocked_count" ] picus_latestSimulation["prevention_not_tested_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "not_tested_count" ] picus_latestSimulation["prevention_total_attacker_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["total_count"] picus_latestSimulation["prevention_achieved_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["achived_count"] picus_latestSimulation["prevention_unachieved_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["unachived_count"] picus_latestSimulation["prevention_not_tested_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["not_tested_count"] picus_latestSimulation["has_detection_analysis"] = picus_latestSimulation["results"]["has_detection_analysis"] else: picus_latestSimulation["started_at"] = str(datetime.fromtimestamp(picus_latestSimulation["started_at"] / 1000)) table_name = "Picus Latest Simulation Result" table_headers = [ "started_at", "completed_at", "simulation_id", "simulation_run_id", "template_id", "status", "prevention_security_score", "prevention_total_threat", "prevention_blocked_threat", "prevention_not_blocked_threat", "prevention_not_tested_threat", "prevention_total_attacker_objectives", "prevention_achieved_objectives", "prevention_unachieved_objectives", "prevention_not_tested_objectives", "has_detection_analysis", ] md_table = tableToMarkdown( table_name, picus_latestSimulation, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_latestSimulation, outputs_prefix="Picus.latestSimulationResult") def get_simulation_result_command(client: Client) -> CommandResults: simulation_id = demisto.args().get("id") run_id = demisto.args().get("run_id") picus_latestSimulation = client.get_simulation_result(simulation_id, run_id) picus_latestSimulation["started_at"] = str(datetime.fromtimestamp(picus_latestSimulation["started_at"] / 1000)) picus_latestSimulation["completed_at"] = str(datetime.fromtimestamp(picus_latestSimulation["completed_at"] / 1000)) picus_latestSimulation["prevention_security_score"] = picus_latestSimulation["results"]["prevention"]["security_score"] picus_latestSimulation["prevention_total_threat"] = picus_latestSimulation["results"]["prevention"]["threat"]["total_count"] picus_latestSimulation["prevention_blocked_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "blocked_count" ] picus_latestSimulation["prevention_not_blocked_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "not_blocked_count" ] picus_latestSimulation["prevention_not_tested_threat"] = picus_latestSimulation["results"]["prevention"]["threat"][ "not_tested_count" ] picus_latestSimulation["prevention_total_attacker_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["total_count"] picus_latestSimulation["prevention_achieved_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["achived_count"] picus_latestSimulation["prevention_unachieved_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["unachived_count"] picus_latestSimulation["prevention_not_tested_objectives"] = picus_latestSimulation["results"]["prevention"][ "attacker_objectives" ]["not_tested_count"] picus_latestSimulation["has_detection_analysis"] = picus_latestSimulation["results"]["has_detection_analysis"] table_name = "Picus Simulation Result" table_headers = [ "started_at", "completed_at", "simulation_id", "simulation_run_id", "template_id", "status", "prevention_security_score", "prevention_total_threat", "prevention_blocked_threat", "prevention_not_blocked_threat", "prevention_not_tested_threat", "prevention_total_attacker_objectives", "prevention_achieved_objectives", "prevention_unachieved_objectives", "prevention_not_tested_objectives", "has_detection_analysis", ] md_table = tableToMarkdown( table_name, picus_latestSimulation, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_latestSimulation, outputs_prefix="Picus.SimulationResult") def get_simulation_threats_command(client: Client) -> CommandResults: query_parameters: str = "" simulation_id = str(demisto.args().get("id")) run_id = str(demisto.args().get("run_id")) picus_threat_list = "" offset = demisto.args().get("offset") limit = demisto.args().get("limit") if offset is not None and limit is None: raise DemistoException("limit should be set.") elif offset is None and limit is not None: raise DemistoException("offset sohuld be set.") if offset is not None and limit is not None: query_parameters = "?" + "limit=" + limit + "&" + "offset=" + offset picus_endpoint_response = client.get_simulation_threats(query_parameters, simulation_id, run_id) picus_simulationThreats = picus_endpoint_response["threats"] for threat in picus_simulationThreats: action_count = 0 threat_objectives = threat["objectives"] for objective in threat_objectives: action_count += len(objective["actions"]) threat["action_count"] = action_count picus_threat_list += str(threat["threat_id"]) + "," if len(picus_threat_list) != 0: picus_threat_list = picus_threat_list[:-1] table_name = "Picus Simulation Threats" table_headers = ["threat_id", "threat_name", "severity", "prevention", "action_count"] md_table = tableToMarkdown( table_name, picus_simulationThreats, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_threat_list, outputs_prefix="Picus.SimulationThreats") def get_simulation_actions_command(client: Client) -> CommandResults: query_parameters: str = "" simulation_id = demisto.args().get("id") run_id = demisto.args().get("run_id") threat_ids = demisto.args().get("threat_ids") threat_ids = list(threat_ids.split(",")) picus_action_raw_results = "" picus_action_results: dict[str, Any] = {"results": []} offset = demisto.args().get("offset") limit = demisto.args().get("limit") if offset is not None and limit is None: raise DemistoException("limit should be set.") elif offset is None and limit is not None: raise DemistoException("offset sohuld be set.") for threat_id in threat_ids: if offset is not None and limit is not None: query_parameters = "?" + "limit=" + limit + "&" + "offset=" + offset picus_endpoint_response = client.get_simulation_actions(query_parameters, simulation_id, run_id, threat_id) picus_simulationActions = picus_endpoint_response["actions"] for action in picus_simulationActions: picus_action_raw_results += str(action["action_id"]) + "=" + str(action["prevention"]) + "," for action in picus_simulationActions: picus_action_results["results"].append(action) if len(picus_action_raw_results) != 0: picus_action_raw_results = picus_action_raw_results[:-1] picus_action_results = picus_action_results["results"] table_name = "Picus Simulation Actions" table_headers = ["action_id", "display_id", "action_name", "affected_os", "attack_module", "category", "prevention"] md_table = tableToMarkdown( table_name, picus_action_results, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_action_raw_results, outputs_prefix="Picus.SimulationActions") def get_mitigation_devices_command(client: Client) -> CommandResults: query_parameters: str = "" simulation_ids = demisto.args().get("ids") if simulation_ids is not None: query_parameters = "?" + "simulation_ids=" + simulation_ids picus_mitigationDevices = client.get_mitigation_devices(query_parameters) table_name = "Picus Mitigation Devices" table_headers = ["id", "device_name", "score", "total_action_count", "blocked_action_count", "not_blocked_action_count"] md_table = tableToMarkdown( table_name, picus_mitigationDevices, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults(readable_output=md_table, outputs=picus_mitigationDevices, outputs_prefix="Picus.MitigationDevices") def get_signature_list_command(client: Client) -> CommandResults: device_id = demisto.args().get("device_id") action_ids = demisto.args().get("action_ids") picus_signature_raw_results: dict[str, Any] = {"results": []} picus_signature_all_results: dict[str, Any] = {"results": []} action_ids = action_ids.split(",") for action in action_ids: query_parameters = "?" + "action_ids=" + action picus_mitigationSignatures = client.get_signature_list(query_parameters, device_id) for mitigation in picus_mitigationSignatures: mitigation["action_id"] = action picus_signature_raw_results["results"].append(picus_mitigationSignatures) picus_signature_raw_results = picus_signature_raw_results["results"] for raw_results_list in picus_signature_raw_results: for raw_results in raw_results_list: picus_signature_all_results["results"].append(raw_results) picus_signature_all_results = picus_signature_all_results["results"] table_name = "Picus Mitigation Signature List" table_headers = [ "action_id", "signature_id", "name", "signature_category", "signature_version", "product_platform", "product_version", "vendor_severity", ] md_table = tableToMarkdown( table_name, picus_signature_all_results, headers=table_headers, removeNull=True, headerTransform=string_to_table_header ) return CommandResults( readable_output=md_table, outputs=picus_signature_all_results, outputs_prefix="Picus.MitigationSignatures" ) def setParamPB(): agent_id = demisto.args().get("agent_id") device_id = demisto.args().get("device_id") simulation_id = demisto.args().get("simulation_id") param_data = {"agent_id": agent_id, "device_id": device_id, "simulation_id": simulation_id} return CommandResults(outputs=param_data, outputs_prefix="Picus.param") def filterInsecureAttacks(): threatinfo = demisto.args().get("threatinfo") threat_ids = "" threatinfo = list(threatinfo.split(",")) threatinfo = [th_info for th_info in threatinfo if "unblocked" in th_info] for th_info in threatinfo: threat_id = th_info.split("=")[0] threat_ids += str(threat_id) + "," if len(threat_ids) != 0: threat_ids = threat_ids[:-1] return CommandResults(readable_output=threat_ids, outputs=threat_ids, outputs_prefix="Picus.filterinsecure") """ MAIN FUNCTION """ def main() -> None: params = demisto.params() command = demisto.command() picus_apikey = params.get("picus_apikey") picus_server = params.get("picus_server") picus_server = picus_server[:-1] if picus_server.endswith("/") else picus_server verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) demisto.debug(f"Command being called is {demisto.command()}") try: client = Client(api_key=picus_apikey, base_url=picus_server, verify=verify_certificate, proxy=proxy) if command == "test-module": # This is the call made when pressing the integration Test button. return_results(test_module(client)) elif command == "picus-get-agent-list": return_results(get_agent_list_command(client)) elif command == "picus-get-agent-detail": return_results(get_agent_detail_command(client)) elif command == "picus-create-simulation": return_results(create_simulation_command(client)) elif command == "picus-get-template-list": return_results(get_template_list_command(client)) elif command == "picus-get-integration-agent-list": return_results(get_integration_agent_list_command(client)) elif command == "picus-get-simulation-list": return_results(get_simulation_list_command(client)) elif command == "picus-simulate-now": return_results(simulate_now_command(client)) elif command == "picus-get-simulation-detail": return_results(get_simulation_detail_command(client)) elif command == "picus-get-latest-simulation-result": return_results(get_latest_simulation_result_command(client)) elif command == "picus-get-simulation-result": return_results(get_simulation_result_command(client)) elif command == "picus-get-simulation-threats": return_results(get_simulation_threats_command(client)) elif command == "picus-get-simulation-actions": return_results(get_simulation_actions_command(client)) elif command == "picus-get-mitigation-devices": return_results(get_mitigation_devices_command(client)) elif demisto.command() == "picus-get-signature-list": return_results(get_signature_list_command(client)) elif command == "picus-set-paramPB": return_results(setParamPB()) elif command == "picus-filter-insecure-attacks": return_results(filterInsecureAttacks()) # Log exceptions and return errors except Exception as e: return_error(f"Failed to execute {demisto.command()} command.\nError:\n{str(e)}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()