RiskSense
RiskSense is a cloud-based platform that provides vulnerability management and prioritization to measure and control cybersecurity risk.
Vulnerability Management · RiskSense
Details
| ID | RiskSense |
|---|---|
| Provider | Ivanti |
| Category | Vulnerability Management |
| From Version | 5.0.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM EDR Cortex Cloud Cloud Runtime Security |
README
Overview
RiskSense is a cloud-based platform that provides vulnerability management and prioritization to measure and control cybersecurity risk.
Use Cases
The SOAR market is still an emerging market and is often used as an umbrella term that covers security operations, security incident response and threat intelligence. Many vendors, even market leaders like Splunk, are adding features and functionality to their existing solutions in the fight for market leadership. One major commonality between new SOAR vendors and vendors trying to make their existing solution fit into this market definition is the need to be able to ingest security centric data including threat intelligence to address the biggest use-case for SOAR i.e. security operations.
Gartner claims that organizations need to have a continuous adaptive risk and trust assessment (CARTA) strategy to make their investments in SOAR technology pay off. CARTA’s value is that it is continuous, and one element helps and informs other elements, allowing for continuous improvement in your organization’s ability to improve both security posture and digital resilience.
Configure RiskSense on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for RiskSense.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- URL
- API Key
- Client Name
- HTTP Request Timeout (Specify the time interval in seconds. All the RiskSense API calls would timeout if the response is not returned within the configured time interval).
- Trust any certificate (not secure)
- Use system proxy settings
- Click Test to validate the URLs, token, and connection.
Commands
You can execute these commands from the Cortex XSOAR 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.
- risksense-get-hosts
- risksense-get-host-detail
- risksense-get-unique-cves
- risksense-get-unique-open-findings
- risksense-get-host-findings
- risksense-get-apps
- risksense-get-host-finding-detail
- risksense-get-app-detail
1. risksense-get-hosts
Gets details of the supplied host. The host details can be searched based on input parameters like fieldname (Host Name, IP Address, Criticality, etc), operator (EXACT, IN, LIKE, BETWEEN), page, size, sort by and sort direction.
Base Command
risksense-get-hosts
Input
| Argument Name | Description | Required |
|---|---|---|
| fieldname | The RiskSense host attribute by which to filter the results. Can be ‘Host Name’, ‘IP Address’, or ‘Criticality’. Apart from the available choices, you can provide the attributes supported by RiskSense API. Refer to the API /host/filter API to get the list of supported attributes. The uid of filter attributes must be provided here, for example, assessment_labels, asset_tags, cvss3BaseI, etc. If specified, ‘value’ argument is mandatory. | Optional |
| operator | The match operator should be applied for filtering the hosts based on ‘fieldname’ and ‘value’. Can be ‘EXACT’ - filter records exactly matching the criteria; ‘IN’ - filter records matching any one of the comma-separated values; ‘LIKE’ - filter records with the value matching the specified pattern. All the records fieldname value contains the string provided in value; ‘BETWEEN’ - filter the records with fieldname value falling in the numerical/date range provided. This argument also accepts other operator values supported by the RiskSense API. Refer to the API documentation for the list of supported operators. | Optional |
| exclude | The exclude flag that determines whether the returned records matches filter criteria or not. The default set is false. If set to True, host not matching the specified values are fetched. | Optional |
| value | The value of the host property mentioned in ‘fieldname’ to be considered for filter criteria. | Optional |
| page | The index of the page. The index is a numeric value starting with 0. | Optional |
| size | The maximum number of records to fetch in one page. | Optional |
| sort_by | The fieldname by which to sort the returned records. | Optional |
| sort_direction | The sorting direction to apply to returned records. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Host.Hostname | String | The hostname of the host. |
| Host.ID | String | The unique ID within the tool retrieving the host. |
| Host.IP | String | The IP address of the host. |
| Host.OS | String | The operating system of the host. |
| RiskSense.Host.ID | Number | The unique identifier of the host. |
| RiskSense.Host.ClientID | Number | The client id of the host. |
| RiskSense.Host.GroupID | Number | The ID of the group belonging to the host. |
| RiskSense.Host.GroupName | String | The name of the group belonging to the host. |
| RiskSense.Host.Group.ID | Number | The ID of the group belonging to the host. |
| RiskSense.Host.Group.Name | String | The name of the group belonging to the host. |
| RiskSense.Host.Rs3 | Number | The asset security score calculated by the RiskSense platform (includes vulnerability risk on related web applications). |
| RiskSense.Host.Xrs3 | String | The asset security score calculated by the RiskSense platform (includes vulnerability risk on related web applications). |
| RiskSense.Host.Criticality | Number | The asset importance using a scale of 1 (lowest importance) to 5 (highest importance). |
| RiskSense.Host.Tag.ID | Number | The ID of the tag. |
| RiskSense.Host.Tag.Name | String | The name of the tag. |
| RiskSense.Host.Tag.Category | String | The category of the tag. |
| RiskSense.Host.Tag.Description | String | The description of the tag. |
| RiskSense.Host.Tag.Created | String | The time when the tag was created. |
| RiskSense.Host.Tag.Updated | String | The time when the tag was last updated. |
| RiskSense.Host.Tag.Color | String | The color code of the tag. |
| RiskSense.Host.NetworkID | Number | The Network ID of the host. |
| RiskSense.Host.NetworkName | String | The name of the network used by the host. |
| RiskSense.Host.NetworkType | String | The type of the network used by the host. |
| RiskSense.Host.DiscoveredOn | String | The time when the host was discovered. |
| RiskSense.Host.LastFoundOn | String | The time when the host was last found. |
| RiskSense.Host.LastScanTime | String | The last time when the host was last scanned. |
| RiskSense.Host.HostName | String | The hostname of the host. |
| RiskSense.Host.IpAddress | String | The IP address of the host. |
| RiskSense.Host.PortNumbers | String | The list of ports that are currently bound. |
| RiskSense.Host.OS.Name | String | The operating system of the host. |
| RiskSense.Host.OS.Family | String | The family of the operating system of the host. |
| RiskSense.Host.OS.Class | String | The class of the operating system of the host. |
| RiskSense.Host.OS.Vendor | String | The vendor information of the operating system of the host. |
| RiskSense.Host.CMDB.Order | Number | The CMDB order number of the host. |
| RiskSense.Host.CMDB.Key | String | The CMDB key identifier of the host. |
| RiskSense.Host.CMDB.Value | String | The CMDB value identifier of the host. |
| RiskSense.Host.CMDB.Label | String | The CMDB label identifier of the host. |
| RiskSense.Host.Services | String | The name of the services which are used by the host. |
| RiskSense.Host.Note.UserID | String | The User ID of the user who added a note for the host. |
| RiskSense.Host.Note.UserName | String | The username of the user who added a note for the host. |
| RiskSense.Host.Note.Note | String | The notes that are added by the user for the host. |
| RiskSense.Host.Note.Date | String | The time when the note was added by the user for the host. |
| RiskSense.Host.Source.Name | String | The name of the source associated with the host. |
| RiskSense.Host.Source.UuID | String | The unique ID of the source associated with the host. |
| RiskSense.Host.Source.ScannerType | String | The type of scanner that discovered the host. |
| RiskSense.Host.Ticket.TicketNumber | String | The number of the ticket associated with the host. |
| RiskSense.Host.Ticket.TicketStatus | String | The status of the ticket associated with the host. |
| RiskSense.Host.Ticket.DeepLink | String | The deeplink associated with the ticket associated with the host. |
| RiskSense.Host.Ticket.Type | String | The type of the ticket associated with the host. |
| RiskSense.Host.Ticket.ConnectorName | String | The connector name of the ticket associated with the host. |
| RiskSense.Host.Ticket.DetailedStatus | String | The detailed status of the ticket associated with the host. |
| RiskSense.Host.LastVulnTrendingOn | String | The time when the last vulnerability was trending on the host. |
| RiskSense.Host.LastThreatTrendingOn | String | The time when the last threat was trending on the host. |
| RiskSense.Host.OldestOpenFindingWithThreatDiscoveredOn | String | The timestamp when the oldest open finding with the threat was discovered. |
| RiskSense.Host.Xrs3date | String | The time when the xrs3 is calculated by RiskSense platform. |
| RiskSense.Host.DiscoveredByRS | String | The flag that determines whether the host is discovered by the RiskSense platform or not. |
| RiskSense.Host.Href | String | The deeplink pointing to the host details on RiskSense. |
| RiskSense.Host.Total | Number | The number of total open findings of the host. |
| RiskSense.Host.Critical | Number | The number of open findings of the host with critical severity. |
| RiskSense.Host.High | Number | The number of open findings of the host with high severity. |
| RiskSense.Host.Medium | Number | The number of open findings of the host with medium severity. |
| RiskSense.Host.Low | Number | The number of open findings of the host with low severity. |
| RiskSense.Host.Info | Number | The number of open findings of the host with info severity. |
| Ticket.ID | String | The ID of the ticket associated with the host. |
| Ticket.State | String | The state of the ticket associated with the host. |
Command Example
!risksense-get-hosts fieldname="Criticality" value="5" page="0" size="2" sort_by="Total Findings" sort_direction="Descending"
Context Example
{
"RiskSense.Host": [
{
"OldestOpenFindingWithThreatDiscoveredOn": "2017-09-14",
"HostName": "iz0.y2.gov",
"Group": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Note": [],
"Source": [
{
"ScannerType": null,
"Name": "QUALYS",
"UuID": "QUALYS_SCANNER"
}
],
"Critical": 48,
"Low": 34,
"IpAddress": "45.19.214.161",
"Xrs3": null,
"Medium": 209,
"Criticality": 5,
"LastVulnTrendingOn": "2020-03-15",
"ClientID": 747,
"GroupID": 7990,
"Xrs3date": null,
"DiscoveredByRS": false,
"Tag": [
{
"Category": "PEOPLE",
"Updated": "2019-04-24T21:39:59",
"Name": "Linux_Team_2",
"Created": "2019-04-24T21:39:59",
"Color": "#78a19b",
"ID": 215554,
"Description": ""
},
{
"Category": "LOCATION",
"Updated": "2019-04-24T21:37:06",
"Name": "Data_Center_2",
"Created": "2019-04-24T21:37:06",
"Color": "#dd8361",
"ID": 215552,
"Description": ""
}
],
"Services": "ssh, telnet, ftp",
"Ticket": [],
"NetworkID": 78038,
"Info": 0,
"DiscoveredOn": "2007-06-14",
"PortNumbers": "22, 21, 23",
"LastScanTime": "2007-06-14T21:14:04",
"GroupName": "Default Group",
"ID": 3570259,
"CMDB": [
{
"Value": "",
"Order": 1,
"Key": "busines_criticality",
"Label": "Asset Criticality"
},
{
"Value": "",
"Order": 2,
"Key": "os",
"Label": "Operating System"
},
{
"Value": "",
"Order": 3,
"Key": "manufacturer",
"Label": "Manufactured By"
},
{
"Value": "",
"Order": 4,
"Key": "model_id",
"Label": "Model"
},
{
"Value": "",
"Order": 5,
"Key": "location",
"Label": "Location"
},
{
"Value": "",
"Order": 6,
"Key": "managed_by",
"Label": "Managed By"
},
{
"Value": "",
"Order": 7,
"Key": "owned_by",
"Label": "Owned By"
},
{
"Value": "",
"Order": 8,
"Key": "supported_by",
"Label": "Supported By"
},
{
"Value": "",
"Order": 9,
"Key": "support_group",
"Label": "Support Group"
},
{
"Value": "",
"Order": 10,
"Key": "sys_updated_on",
"Label": "Last Scanned"
},
{
"Value": "",
"Order": 11,
"Key": "asset_tag",
"Label": "Asset tags"
},
{
"Value": "",
"Order": 12,
"Key": "mac_address",
"Label": "Mac Address"
},
{
"Value": "",
"Order": 16,
"Key": "sys_id",
"Label": "Unique Id"
},
{
"Value": "",
"Order": 18,
"Key": "cf_1",
"Label": "Mike Name 1"
},
{
"Value": "",
"Order": 19,
"Key": "cf_2",
"Label": "Custom Field 2"
},
{
"Value": "",
"Order": 20,
"Key": "cf_3",
"Label": "Custom Field 3"
},
{
"Value": "",
"Order": 21,
"Key": "cf_4",
"Label": "Custom Field 4"
},
{
"Value": "",
"Order": 22,
"Key": "cf_5",
"Label": "Custom Field 5"
},
{
"Value": "",
"Order": 23,
"Key": "cf_6",
"Label": "Custom Field 6"
},
{
"Value": "",
"Order": 24,
"Key": "cf_7",
"Label": "Custom Field 7"
},
{
"Value": "",
"Order": 25,
"Key": "cf_8",
"Label": "Custom Field 8"
},
{
"Value": "",
"Order": 26,
"Key": "cf_9",
"Label": "Custom Field 9"
},
{
"Value": "",
"Order": 29,
"Key": "cf_10",
"Label": "Custom Field 10"
},
{
"Value": "",
"Order": 13,
"Key": "Asset Compliance",
"Label": "Asset Compliance"
}
],
"LastThreatTrendingOn": "2020-03-15",
"OS": {
"Vendor": "Red Hat",
"Class": "Not Reported",
"Family": "Linux",
"Name": "Red Hat Enterprise Linux Server 6.1"
},
"High": 127,
"Href": "http://platform.risksense.com/api/v1/client/747/host/search?page=0&size=2&sort=findingsDistribution.total,desc",
"LastFoundOn": "2019-04-23",
"NetworkType": "IP",
"Total": 418,
"NetworkName": "IP Network",
"Rs3": 513
},
{
"OldestOpenFindingWithThreatDiscoveredOn": "2015-02-10",
"HostName": "ftpserver",
"Group": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Note": [],
"Source": [
{
"ScannerType": null,
"Name": "QUALYS",
"UuID": "QUALYS_SCANNER"
}
],
"Critical": 23,
"Low": 49,
"IpAddress": "34.17.197.127",
"Xrs3": null,
"Medium": 141,
"Criticality": 5,
"LastVulnTrendingOn": "2020-02-23",
"ClientID": 747,
"GroupID": 7990,
"Xrs3date": null,
"DiscoveredByRS": false,
"Tag": [
{
"Category": "PEOPLE",
"Updated": "2019-04-24T21:39:59",
"Name": "Linux_Team_2",
"Created": "2019-04-24T21:39:59",
"Color": "#78a19b",
"ID": 215554,
"Description": ""
},
{
"Category": "LOCATION",
"Updated": "2019-04-24T21:37:06",
"Name": "Data_Center_2",
"Created": "2019-04-24T21:37:06",
"Color": "#dd8361",
"ID": 215552,
"Description": ""
}
],
"Services": "ssh, ftps, unknown, ftp, unknown, unknown, unknown",
"Ticket": [],
"NetworkID": 78038,
"Info": 0,
"DiscoveredOn": "2006-12-06",
"PortNumbers": "990, 80, 55443, 22, 65443, 443",
"LastScanTime": "2006-12-06T17:08:05",
"GroupName": "Default Group",
"ID": 3571622,
"CMDB": [
{
"Value": "",
"Order": 1,
"Key": "busines_criticality",
"Label": "Asset Criticality"
},
{
"Value": "",
"Order": 2,
"Key": "os",
"Label": "Operating System"
},
{
"Value": "",
"Order": 3,
"Key": "manufacturer",
"Label": "Manufactured By"
},
{
"Value": "",
"Order": 4,
"Key": "model_id",
"Label": "Model"
},
{
"Value": "",
"Order": 5,
"Key": "location",
"Label": "Location"
},
{
"Value": "",
"Order": 6,
"Key": "managed_by",
"Label": "Managed By"
},
{
"Value": "",
"Order": 7,
"Key": "owned_by",
"Label": "Owned By"
},
{
"Value": "",
"Order": 8,
"Key": "supported_by",
"Label": "Supported By"
},
{
"Value": "",
"Order": 9,
"Key": "support_group",
"Label": "Support Group"
},
{
"Value": "",
"Order": 10,
"Key": "sys_updated_on",
"Label": "Last Scanned"
},
{
"Value": "",
"Order": 11,
"Key": "asset_tag",
"Label": "Asset tags"
},
{
"Value": "",
"Order": 12,
"Key": "mac_address",
"Label": "Mac Address"
},
{
"Value": "",
"Order": 16,
"Key": "sys_id",
"Label": "Unique Id"
},
{
"Value": "",
"Order": 18,
"Key": "cf_1",
"Label": "Mike Name 1"
},
{
"Value": "",
"Order": 19,
"Key": "cf_2",
"Label": "Custom Field 2"
},
{
"Value": "",
"Order": 20,
"Key": "cf_3",
"Label": "Custom Field 3"
},
{
"Value": "",
"Order": 21,
"Key": "cf_4",
"Label": "Custom Field 4"
},
{
"Value": "",
"Order": 22,
"Key": "cf_5",
"Label": "Custom Field 5"
},
{
"Value": "",
"Order": 23,
"Key": "cf_6",
"Label": "Custom Field 6"
},
{
"Value": "",
"Order": 24,
"Key": "cf_7",
"Label": "Custom Field 7"
},
{
"Value": "",
"Order": 25,
"Key": "cf_8",
"Label": "Custom Field 8"
},
{
"Value": "",
"Order": 26,
"Key": "cf_9",
"Label": "Custom Field 9"
},
{
"Value": "",
"Order": 29,
"Key": "cf_10",
"Label": "Custom Field 10"
},
{
"Value": "",
"Order": 13,
"Key": "Asset Compliance",
"Label": "Asset Compliance"
}
],
"LastThreatTrendingOn": "2020-02-23",
"OS": {
"Vendor": "Red Hat",
"Class": "Not Reported",
"Family": "Linux",
"Name": "Red Hat Enterprise Linux Server 5.4"
},
"High": 78,
"Href": "http://platform.risksense.com/api/v1/client/747/host/search?page=0&size=2&sort=findingsDistribution.total,desc",
"LastFoundOn": "2019-04-23",
"NetworkType": "IP",
"Total": 291,
"NetworkName": "IP Network",
"Rs3": 528
}
],
"Host": [
{
"IP": "45.19.214.161",
"Hostname": "iz0.y2.gov",
"OS": "Red Hat Enterprise Linux Server 6.1",
"ID": 3570259
},
{
"IP": "34.17.197.127",
"Hostname": "ftpserver",
"OS": "Red Hat Enterprise Linux Server 5.4",
"ID": 3571622
}
]
}
Human Readable Output
Total hosts found: 1969 Page: 0/984 Client: The Demo Client
RiskSense host(s) details
| RS3 | Host Name | Total Findings | Critical Findings | High Findings | Medium Findings | Low Findings | Info Findings | ID | OS | Tags | Notes | Criticality | IP Address | Network | Group |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 513 | iz0.y2.gov | 418 | 48 | 127 | 209 | 34 | 0 | 3570259 | Red Hat Enterprise Linux Server 6.1 | 2 | 0 | 5 | 45.19.214.161 | IP Network | 1 |
| 528 | ftpserver | 291 | 23 | 78 | 141 | 49 | 0 | 3571622 | Red Hat Enterprise Linux Server 5.4 | 2 | 0 | 5 | 34.17.197.127 | IP Network | 1 |
2. risksense-get-host-detail
Gets in-depth details of a single host. This command accepts either hostname or host ID as an argument.
Base Command
risksense-get-host-detail
Input
| Argument Name | Description | Required |
|---|---|---|
| host_id | The unique host ID of the host. The host ID is either known by RiskSense users or it can be searched in context output (RiskSense.Host.ID) or in the human-readable output of ‘risksense-get-hosts’ command. | Optional |
| host | The hostname of the host. The hostname is either known by RiskSense users or it can be searched in context output (RiskSense.Host.HostName) or in the human-readable output of ‘risksense-get-hosts’ command. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| Host.Hostname | String | The hostname of the host. |
| Host.ID | String | The unique ID within the tool retrieving the host. |
| Host.IP | String | The IP address of the host. |
| Host.OS | String | The operating system of the host. |
| RiskSense.Host.ID | Number | The unique identifier of the host. |
| RiskSense.Host.ClientID | Number | The client ID of the host. |
| RiskSense.Host.GroupID | Number | The ID of the group belonging to the host. |
| RiskSense.Host.GroupName | String | The name of the group belonging to the host. |
| RiskSense.Host.Group.ID | Number | The ID of the group belonging to the host. |
| RiskSense.Host.Group.Name | String | The name of the group belonging to the host. |
| RiskSense.Host.Rs3 | Number | The asset security score calculated by the RiskSense platform (includes vulnerability risk on related web applications). |
| RiskSense.Host.Xrs3 | String | The asset security score calculated by RiskSense platform. |
| RiskSense.Host.Criticality | Number | The asset importance using a scale of 1 (lowest importance) to 5 (highest importance). |
| RiskSense.Host.Tag.ID | Number | The ID of the tag. |
| RiskSense.Host.Tag.Name | String | The name of the tag. |
| RiskSense.Host.Tag.Category | String | The category of the tag. |
| RiskSense.Host.Tag.Description | String | The description of the tag. |
| RiskSense.Host.Tag.Created | String | The time when the tag was created. |
| RiskSense.Host.Tag.Updated | String | The time when the tag was last updated. |
| RiskSense.Host.Tag.Color | String | The color code of the tag. |
| RiskSense.Host.NetworkID | Number | The network ID of the host. |
| RiskSense.Host.NetworkName | String | The name of the network used by the host. |
| RiskSense.Host.NetworkType | String | The type of the network used by the host. |
| RiskSense.Host.DiscoveredOn | String | The time when the host was discovered. |
| RiskSense.Host.LastFoundOn | String | The time when the host was last found. |
| RiskSense.Host.LastScanTime | String | The last time when the host was last scanned. |
| RiskSense.Host.HostName | String | The hostname of the host. |
| RiskSense.Host.IpAddress | String | The IP address of the host. |
| RiskSense.Host.PortNumbers | String | The list of ports that are currently bound. |
| RiskSense.Host.OS.Name | String | The operating system of the host. |
| RiskSense.Host.OS.Family | String | The family of the operating system of the host. |
| RiskSense.Host.OS.Class | String | The class of the operating system of the host. |
| RiskSense.Host.OS.Vendor | String | The vendor information of the operating system of the host. |
| RiskSense.Host.CMDB.Order | Number | The CMDB order number of the host. |
| RiskSense.Host.CMDB.Key | String | The CMDB key identifier of the host. |
| RiskSense.Host.CMDB.Value | String | The CMDB value identifier of the host. |
| RiskSense.Host.CMDB.Label | String | The CMDB label identifier of the host. |
| RiskSense.Host.Services | String | The name of the services which are used by the host. |
| RiskSense.Host.Note.UserID | String | The User ID of the user who added a note for the host. |
| RiskSense.Host.Note.UserName | String | The username of the user who added a note for the host. |
| RiskSense.Host.Note.Note | String | The notes that are added by the user for the host. |
| RiskSense.Host.Note.Date | String | The time when the note was added by the user for the host. |
| RiskSense.Host.Source.Name | String | The name of the source associated with the host. |
| RiskSense.Host.Source.UuID | String | The unique ID of the source associated with the host. |
| RiskSense.Host.Source.ScannerType | String | The type of scanner that discovered the host. |
| RiskSense.Host.Ticket.TicketNumber | String | The number of the ticket associated with the host. |
| RiskSense.Host.Ticket.TicketStatus | String | The status of the ticket associated with the host. |
| RiskSense.Host.Ticket.DeepLink | String | The deeplink of the ticket associated with the host. |
| RiskSense.Host.Ticket.Type | String | The type of the ticket associated with the host. |
| RiskSense.Host.Ticket.ConnectorName | String | The connector name of the ticket associated with the host. |
| RiskSense.Host.Ticket.DetailedStatus | String | The detailed status of the ticket associated with the host. |
| RiskSense.Host.LastVulnTrendingOn | String | The time when the last vulnerability was trending on the host. |
| RiskSense.Host.LastThreatTrendingOn | String | The time when the last threat was trending on the host. |
| RiskSense.Host.OldestOpenFindingWithThreatDiscoveredOn | String | The timestamp when the oldest open finding with the threat was discovered. |
| RiskSense.Host.Xrs3date | String | The time when the xrs3 is calculated by RiskSense platform. |
| RiskSense.Host.DiscoveredByRS | String | The flag that determines whether the host is discovered by the RiskSense platform or not. |
| RiskSense.Host.Href | String | The deeplink pointing to the host details on RiskSense. |
| RiskSense.Host.Total | Number | The number of total open findings of the host. |
| RiskSense.Host.Critical | Number | The number of open findings of the host with critical severity. |
| RiskSense.Host.High | Number | The number of open findings of the host with high severity. |
| RiskSense.Host.Medium | Number | The number of open findings of the host with medium severity. |
| RiskSense.Host.Low | Number | The number of open findings of the host with low severity. |
| RiskSense.Host.Info | Number | The number of open findings of the host with info severity. |
| Ticket.ID | String | The ID of the ticket associated with the host. |
| Ticket.State | String | The state of the ticket associated with the host. |
Command Example
!risksense-get-host-detail host=united-78c957c5
Context Example
{
"Host": [
{
"Hostname": "united-78c957c5",
"ID": 3571259,
"IP": "53.132.37.52",
"OS": "Windows 2008/7"
}
],
"RiskSense.Host": [
{
"CMDB": [
{
"Key": "busines_criticality",
"Label": "Asset Criticality",
"Order": 1,
"Value": ""
},
{
"Key": "os",
"Label": "Operating System",
"Order": 2,
"Value": ""
},
{
"Key": "manufacturer",
"Label": "Manufactured By",
"Order": 3,
"Value": ""
},
{
"Key": "model_id",
"Label": "Model",
"Order": 4,
"Value": ""
},
{
"Key": "location",
"Label": "Location",
"Order": 5,
"Value": ""
},
{
"Key": "managed_by",
"Label": "Managed By",
"Order": 6,
"Value": ""
},
{
"Key": "owned_by",
"Label": "Owned By",
"Order": 7,
"Value": ""
},
{
"Key": "supported_by",
"Label": "Supported By",
"Order": 8,
"Value": ""
},
{
"Key": "support_group",
"Label": "Support Group",
"Order": 9,
"Value": ""
},
{
"Key": "sys_updated_on",
"Label": "Last Scanned",
"Order": 10,
"Value": ""
},
{
"Key": "asset_tag",
"Label": "Asset tags",
"Order": 11,
"Value": ""
},
{
"Key": "mac_address",
"Label": "Mac Address",
"Order": 12,
"Value": ""
},
{
"Key": "sys_id",
"Label": "Unique Id",
"Order": 16,
"Value": ""
},
{
"Key": "cf_1",
"Label": "Mike Name 1",
"Order": 18,
"Value": ""
},
{
"Key": "cf_2",
"Label": "Custom Field 2",
"Order": 19,
"Value": ""
},
{
"Key": "cf_3",
"Label": "Custom Field 3",
"Order": 20,
"Value": ""
},
{
"Key": "cf_4",
"Label": "Custom Field 4",
"Order": 21,
"Value": ""
},
{
"Key": "cf_5",
"Label": "Custom Field 5",
"Order": 22,
"Value": ""
},
{
"Key": "cf_6",
"Label": "Custom Field 6",
"Order": 23,
"Value": ""
},
{
"Key": "cf_7",
"Label": "Custom Field 7",
"Order": 24,
"Value": ""
},
{
"Key": "cf_8",
"Label": "Custom Field 8",
"Order": 25,
"Value": ""
},
{
"Key": "cf_9",
"Label": "Custom Field 9",
"Order": 26,
"Value": ""
},
{
"Key": "cf_10",
"Label": "Custom Field 10",
"Order": 29,
"Value": ""
},
{
"Key": "Asset Compliance",
"Label": "Asset Compliance",
"Order": 13,
"Value": ""
}
],
"ClientID": 747,
"Critical": 2,
"Criticality": 3,
"DiscoveredByRS": false,
"DiscoveredOn": "2007-01-23",
"Group": [
{
"ID": 7990,
"Name": "Default Group"
},
{
"ID": 8002,
"Name": "BU2_Other_Devices"
}
],
"GroupID": 7990,
"GroupName": "Default Group",
"High": 0,
"HostName": "united-78c957c5",
"Href": "http://platform.risksense.com/api/v1/client/747/host/search?page=0&size=20&sort=id,asc",
"ID": 3571259,
"Info": 0,
"IpAddress": "53.132.37.52",
"LastFoundOn": "2019-11-01",
"LastScanTime": "2007-01-23T16:46:50",
"LastThreatTrendingOn": null,
"LastVulnTrendingOn": null,
"Low": 0,
"Medium": 0,
"NetworkID": 78038,
"NetworkName": "IP Network",
"NetworkType": "IP",
"Note": [
{
"Date": "2019-12-30T11:35:41",
"Note": "Testing note\n",
"UserID": 5969,
"UserName": "Ravindra Sojitra"
},
{
"Date": "2019-12-30T11:38:25",
"Note": "This is second note for testing",
"UserID": 5969,
"UserName": "Ravindra Sojitra"
}
],
"OS": {
"Class": "Not Reported",
"Family": "Windows",
"Name": "Windows 2008/7",
"Vendor": "Microsoft"
},
"OldestOpenFindingWithThreatDiscoveredOn": "2014-09-24",
"PortNumbers": "135, 1025, 1494, 80, 139, 3389, 5353, 445",
"Rs3": 409,
"Services": "msrpc-epmap, blackjack, microsoft-ds, ica, ms-wbt-server, www, netbios-ssn, VxWorks",
"Source": [
{
"Name": "QUALYS",
"ScannerType": null,
"UuID": "QUALYS_SCANNER"
}
],
"Tag": [
{
"Category": "LOCATION",
"Color": "#dd8361",
"Created": "2019-04-24T21:37:06",
"Description": "",
"ID": 215552,
"Name": "Data_Center_2",
"Updated": "2019-04-24T21:37:06"
},
{
"Category": "PEOPLE",
"Color": "#78a19b",
"Created": "2019-04-24T21:42:34",
"Description": "",
"ID": 215557,
"Name": "Windows_Server_Team_1",
"Updated": "2019-04-24T21:42:34"
},
{
"Category": "CUSTOM",
"Color": "#648d9f",
"Created": "2019-10-29T20:22:25",
"Description": "",
"ID": 229865,
"Name": "Dev_Servers",
"Updated": "2019-10-29T20:22:25"
},
{
"Category": "SCANNER",
"Color": "#648d9f",
"Created": "2019-12-30T11:27:57",
"Description": "",
"ID": 232940,
"Name": "Test Ticket for host",
"Updated": "2019-12-30T11:28:00"
}
],
"Ticket": [
{
"ConnectorName": "Test JIRA ",
"DeepLink": "https://risksense.atlassian.net/browse/JINT-525",
"DetailedStatus": "",
"TicketNumber": "JINT-525",
"TicketStatus": "To Do",
"Type": "JIRA"
}
],
"Total": 2,
"Xrs3": null,
"Xrs3date": null
}
],
"Ticket": [
{
"ID": "JINT-525",
"State": "To Do"
}
]
}
Human Readable Output
Client: The Demo Client
Group Details
Name: Default Group
Most Recently Identified Service(s)
msrpc-epmap, blackjack, microsoft-ds, ica, ms-wbt-server, www, netbios-ssn, VxWorks
Sources
Scanner(s): QUALYS
Host Details
| Name | IP | RS3 | Discovered On | Last Found On |
|---|---|---|---|---|
| united-78c957c5 | 53.132.37.52 | 351 | 2007-01-23 | 2007-01-23 |
Findings Distribution
| Total | Critical | High | Medium | Low | Info |
|---|---|---|---|---|---|
| 2 | 2 | 0 | 0 | 0 | 0 |
Operating System
| Name | Vendor | Class | Family |
|---|---|---|---|
| Windows 2008/7 | Microsoft | Not Reported | Windows |
Tag(s) (4)
| Name | Category | Description | Created | Updated |
|---|---|---|---|---|
| Data_Center_2 | LOCATION | 2019-04-24T21:37:06 | 2019-04-24T21:37:06 | |
| Windows_Server_Team_1 | PEOPLE | 2019-04-24T21:42:34 | 2019-04-24T21:42:34 | |
| Dev_Servers | CUSTOM | 2019-10-29T20:22:25 | 2019-10-29T20:22:25 | |
| Test Ticket for host | SCANNER | 2019-12-30T11:27:57 | 2019-12-30T11:28:00 |
Ticket(s) (1)
| Ticket Number | Ticket Status | Deep Link | Type | Connector Name |
|---|---|---|---|---|
| JINT-525 | To Do | https://risksense.atlassian.net/browse/JINT-525 | JIRA | Test JIRA |
3. risksense-get-unique-cves
Looks up vulnerability details for the supplied host finding with its base score.
Base Command
risksense-get-unique-cves
Input
| Argument Name | Description | Required |
|---|---|---|
| hostFindingId | The unique host finding ID. The host finding ID is either known by RiskSense users or it can be found in the human-readable output or context data(RiskSense.HostFinding.ID) after executing ‘risksense-get-host-findings’ command. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.UniqueVulnerabilities.Cve | String | Common Vulnerabilities and Exposures name. |
| RiskSense.UniqueVulnerabilities.HostFindingID | String | The unique ID of the host finding. |
| RiskSense.UniqueVulnerabilities.BaseScore | Unknown | The base score represents the severity of the risk (informational, low, medium, high, or critical). |
| RiskSense.UniqueVulnerabilities.ThreatCount | Number | Total number of threats found. |
| RiskSense.UniqueVulnerabilities.AttackVector | String | The attack vectors are a path by which attackers can gain access to the network. |
| RiskSense.UniqueVulnerabilities.AccessComplexity | String | The access complexity describes conditions that are beyond the attacker’s control that must exist in order to exploit the vulnerability. |
| RiskSense.UniqueVulnerabilities.Authentication | String | The authentication value represents attackers authorization to get network access. |
| RiskSense.UniqueVulnerabilities.ConfidentialityImpact | String | The confidentiality impact measures the potential impact on confidentiality of a successfully exploited misuse vulnerability. |
| RiskSense.UniqueVulnerabilities.Integrity | String | The Integrity refers to the trust level and veracity of the information. |
| RiskSense.UniqueVulnerabilities.AvailabilityImpact | String | The availability refers to accessibility of network resources. |
| RiskSense.UniqueVulnerabilities.Trending | Boolean | Trending is defined by RiskSense as vulnerabilities that are being actively abused by attackers in the wild based on activity in hacker forums, Twitter feeds, and analysis of 3rd party threat intelligence sources. |
| RiskSense.UniqueVulnerabilities.VulnLastTrendingOn | String | The last trending date of vulnerability. |
| CVE.ID | String | Common Vulnerabilities and Exposures ID. |
| CVE.Description | String | Description about CVE. |
| CVE.CVSS | String | The CVSS represents the severity of the risk (informational, low, medium, high, critical). |
Command Example
!risksense-get-unique-cves hostFindingId=115469504
Context Example
{
'RiskSense.UniqueVulnerabilities': [
{
'HostFindingID': '115469504',
'Cve': 'CVE-2007-0882',
'BaseScore': 10.0,
'ThreatCount': 5,
'AttackVector': 'Network',
'AccessComplexity': 'Low',
'Authentication': 'None',
'ConfidentialityImpact': 'Complete',
'Integrity': 'Complete',
'AvailabilityImpact': 'Complete',
'Trending': False,
'VulnLastTrendingOn': None
}
],
'CVE': [
{
'ID': 'CVE-2007-0882',
'CVSS': 10.0,
'Description': 'Argument injection vulnerability in the telnet daemon (in.telnetd) in Solaris 10 and 11 (SunOS 5.10 and 5.11) misinterprets certain client "-f" sequences as valid requests for the login program to skip authentication, which allows remote attackers to log into certain accounts, as demonstrated by the bin account.'
}
]
}
Human Readable Output
Client: The Demo Client
Vulnerabilities found
| Name | V2/Score | Attack Vector | Attack Complexity | Authentication | Confidentiality Impact | Integrity Impact | Availability Impact | Summary |
|---|---|---|---|---|---|---|---|---|
| CVE-2007-0882 | 10.0 | Network | Low | None | Complete | Complete | Complete | Argument injection vulnerability in the telnet daemon (in.telnetd) in Solaris 10 and 11 (SunOS 5.10 and 5.11) misinterprets certain client “-f” sequences as valid requests for the login program to skip authentication, which allows remote attackers to log into certain accounts, as demonstrated by the bin account. |
4. risksense-get-unique-open-findings
Finds unique open host findings.The open findings can be searched based on input parameters like fieldname (Severity, Title, Source etc), operator (EXACT, IN, LIKE, BETWEEN), page and size.
Base Command
risksense-get-unique-open-findings
Input
| Argument Name | Description | Required |
|---|---|---|
| fieldname | The RiskSense host finding attribute that should be considered for filtering the results. The available choices are ‘Title’, ‘Severity’, and ‘Source’. Apart from the available choices, one can provide the attributes supported by RiskSense API. Refer to the API /uniqueHostFinding/filter API to get the list of supported attributes. The uid of filter attributes must be provided here. e.g. assessment_labels, asset_tags, cvss3BaseI, etc. If specified, ‘value’ argument is mandatory. | Optional |
| operator | The match operator should be applied for filtering the hosts based on ‘fieldname’ and ‘value’. Available options are ‘EXACT’ - filter records exactly matching the criteria; ‘IN’ - filter records matching any one of the comma-separated values; ‘LIKE’ - filter records with the value matching the specified pattern. All the records fieldname value contains the string provided in value; ‘BETWEEN’ - filter the records with fieldname value falling in the numerical/date range provided. This argument also accepts other operator values supported by the RiskSense API. Refer to the API documentation for the list of supported operators. | Optional |
| value | The value of the unique open finding property mentioned in ‘fieldname’ to be considered for filter criteria. | Optional |
| exclude | The exclude flag that determines whether the returned records matches filter criteria or not. By default set to False. | Optional |
| page | The index of the page. The index is a numeric value and starting with 0. | Optional |
| size | The maximum number of records to fetch in one page. | Optional |
| sort_by | The fieldname that should be considered for sorting the returned records. | Optional |
| sort_direction | The sorting direction to apply to returned records. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.UniqueHostFinding.Title | String | The title of the unique host finding. |
| RiskSense.UniqueHostFinding.Severity | Number | Similar to risk rating, the severity of a vulnerability conveys the potential threat. |
| RiskSense.UniqueHostFinding.HostCount | Number | The total number of hosts found in unique host finding. |
| RiskSense.UniqueHostFinding.Source | String | The name of the source associated with the unique host finding. |
| RiskSense.UniqueHostFinding.SourceID | String | The unique ID of the source. |
| RiskSense.UniqueHostFinding.Href | String | Reference API link of the unique host finding search. |
Command Example
!risksense-get-unique-open-findings fieldname=Source value=QUALYS sort_by=Severity sort_direction="Descending" size="3"
Context Example
{
"RiskSense.UniqueHostFinding": [
{
"Severity": 10,
"Title": "Solaris 10 and Solaris 11 (SolarisExpress) Remote Access Telnet Daemon Flaw",
"SourceID": "QUALYS38574",
"HostCount": 22,
"Source": "QUALYS",
"Href": "http://platform.risksense.com/api/v1/client/747/uniqueHostFinding/search?page=0&size=3&sort=severity,desc"
},
{
"Severity": 10,
"Title": "FreeBSD Telnetd Code Execution Vulnerability (FreeBSD-SA-11:08)",
"SourceID": "QUALYS119834",
"HostCount": 17,
"Source": "QUALYS",
"Href": "http://platform.risksense.com/api/v1/client/747/uniqueHostFinding/search?page=0&size=3&sort=severity,desc"
},
{
"Severity": 10,
"Title": "Microsoft SMB Server Remote Code Execution Vulnerability (MS17-010) and Shadow Brokers",
"SourceID": "QUALYS91345",
"HostCount": 140,
"Source": "QUALYS",
"Href": "http://platform.risksense.com/api/v1/client/747/uniqueHostFinding/search?page=0&size=3&sort=severity,desc"
}
]
}
Human Readable Output
Total unique open findings: 3949 Page: 0/1316 Client: The Demo Client
Unique open finding(s) details
| Title | Severity | Asset Count | Source | Source ID |
|---|---|---|---|---|
| Solaris 10 and Solaris 11 (SolarisExpress) Remote Access Telnet Daemon Flaw | 10.0 | 22 | QUALYS | QUALYS38574 |
| FreeBSD Telnetd Code Execution Vulnerability (FreeBSD-SA-11:08) | 10.0 | 17 | QUALYS | QUALYS119834 |
| Microsoft SMB Server Remote Code Execution Vulnerability (MS17-010) and Shadow Brokers | 10.0 | 140 | QUALYS | QUALYS91345 |
5. risksense-get-host-findings
A detailed host finding view with the severity level. Displays vulnerability information like CVE, Threats associated with current findings and origin of findings.
Base Command
risksense-get-host-findings
Input
| Argument Name | Description | Required |
|---|---|---|
| fieldname | The RiskSense host finding attribute that should be considered for filtering the results. The available choices are ‘Title’, ‘IP Address’, or ‘Host Name’. In addition to the available choices, you can provide the attributes supported by RiskSense API. Refer to the API /hostFinding/filter API to get the list of supported attributes. The uid of filter attributes must be provided here. e.g. assessment_labels, asset_tags, cvss3BaseI, etc. If specified, ‘value’ argument is mandatory. | Optional |
| operator | The match operator should be applied for filtering the hosts based on ‘fieldname’ and ‘value’. Available options are ‘EXACT’ (filter records exactly matching the criteria), ‘IN’ (filter records matching any one of the comma-separated values), or ‘LIKE’ (filter records with the value matching the specified pattern). All the records fieldname value contains the string provided in value; ‘BETWEEN’ - filter the records with fieldname value falling in the numerical/date range provided. This argument also accepts other operator values supported by the RiskSense API. Refer to the API documentation for the list of supported operators. | Optional |
| exclude | The exclude flag that determines whether the returned records matches filter criteria or not. By default set to False. | Optional |
| value | The value of the ‘fieldname’ to be considered for filter criteria. | Optional |
| page | The index of the page. The index is numeric value starting with 0. | Optional |
| size | The maximum number of records to fetch in one page. | Optional |
| sort_by | The fieldname that should be considered for sorting the returned records. | Optional |
| sort_direction | The sorting direction to apply to returned records. | Optional |
| status | The status of the host findings to be considered for returned records. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.HostFinding.ID | String | The unique ID of the host finding. |
| RiskSense.HostFinding.Source | String | Host discovered by the scanner. |
| RiskSense.HostFinding.SourceID | String | Scanner ID of discovered scanner. |
| RiskSense.HostFinding.Title | String | The title of the host finding. |
| RiskSense.HostFinding.Port | Number | The port number of the host finding. |
| RiskSense.HostFinding.GroupCount | Number | The total number of groups for host finding. |
| RiskSense.HostFinding.Group.ID | Number | The unique ID of the group associated with the host finding. |
| RiskSense.HostFinding.Group.Name | String | The name of the group associated with the host finding. |
| RiskSense.HostFinding.HostID | Number | The unique ID of the host associated with the host finding. |
| RiskSense.HostFinding.HostName | String | The hostname of the host associated with the host finding. |
| RiskSense.HostFinding.HostIpAddress | String | The IP address of the host associated with the host finding. |
| RiskSense.HostFinding.Host.Criticality | Number | The criticality of the host associated with the host finding. |
| RiskSense.HostFinding.Host.External | boolean | Whether the identify of the host is external or internal. |
| RiskSense.HostFinding.Host.Port.ID | Number | The unique ID of the host(s) port associated with the host finding. |
| RiskSense.HostFinding.Host.Port.Number | Number | The port number of the host associated with the host finding. |
| RiskSense.HostFinding.Host.Rs3 | Number | The Asset Security Score calculated by the RiskSense platform (includes vulnerability risk on related web applications). |
| RiskSense.HostFinding.Network.ID | Number | The network ID of the host finding. |
| RiskSense.HostFinding.Network.Name | String | The name of the network used by the host finding. |
| RiskSense.HostFinding.Network.Type | String | The type of the network used by the host finding. |
| RiskSense.HostFinding.Assessment.ID | Number | The assessment ID of the host finding. |
| RiskSense.HostFinding.Assessment.Name | String | The name of the assessment associated with the host finding. |
| RiskSense.HostFinding.Assessment.Date | String | The time when the assessment is created. |
| RiskSense.HostFinding.Vulnerability.Cve | String | The name of the Common Vulnerabilities and Exposures associated with the host finding. |
| RiskSense.HostFinding.Vulnerability.BaseScore | Number | CVE Score. |
| RiskSense.HostFinding.Vulnerability.ThreatCount | Number | The total number of threats associated with the host finding. |
| RiskSense.HostFinding.Vulnerability.AttackVector | String | Vector information in which the host was attacked. |
| RiskSense.HostFinding.Vulnerability.AccessComplexity | String | Complexity level. |
| RiskSense.HostFinding.Vulnerability.Authentication | String | Authentication value represents attackers authorization to get network access. |
| RiskSense.HostFinding.Vulnerability.ConfidentialityImpact | String | Confidentiality impact measures the potential impact on confidentiality of a successfully exploited misuse vulnerability. |
| RiskSense.HostFinding.Vulnerability.Integrity | String | Integrity refers to the trustworthiness and veracity of information. |
| RiskSense.HostFinding.Vulnerability.AvailabilityImpact | String | Availability refers to accessibility of network resources. |
| RiskSense.HostFinding.Vulnerability.Trending | boolean | This signifies whether the vulnerability (which is associated with the hostFinding) has been reported by our internal functions as being trending. |
| RiskSense.HostFinding.Vulnerability.VulnLastTrendingOn | String | Date when last trending vulnerability was found. |
| RiskSense.HostFinding.ThreatCount | Number | The total number of threats. |
| RiskSense.HostFinding.Threat.Title | String | The title of the threat. |
| RiskSense.HostFinding.Threat.Category | String | The threat category. |
| RiskSense.HostFinding.Threat.Severity | String | The severity level of the threat. |
| RiskSense.HostFinding.Threat.Description | String | The threat description. |
| RiskSense.HostFinding.Threat.Cve | Unknown | The Common Vulnerabilities and Exposures name of the threat. |
| RiskSense.HostFinding.Threat.Source | String | The source of the threat. |
| RiskSense.HostFinding.Threat.Published | String | The time when the threat was published. |
| RiskSense.HostFinding.Threat.Updated | String | The time when the threat was last updated. |
| RiskSense.HostFinding.Threat.ThreatLastTrendingOn | String | The last time when threat was in trending. |
| RiskSense.HostFinding.Threat.Trending | boolean | Whether the threat is trending. |
| RiskSense.HostFinding.Patch.Name | String | The patch name of the host finding. |
| RiskSense.HostFinding.Patch.Url | String | The patch URL of the host finding. |
| RiskSense.HostFinding.TagCount | Number | The total number of tags associated with host finding. |
| RiskSense.HostFinding.Tag.ID | Number | The tag identifier of the host finding. |
| RiskSense.HostFinding.Tag.Name | String | The tag name of the host finding. |
| RiskSense.HostFinding.Tag.Category | String | The tag category of the host finding. |
| RiskSense.HostFinding.Tag.Description | String | The tag description of the host finding. |
| RiskSense.HostFinding.Tag.Created | String | The time when the tag was created. |
| RiskSense.HostFinding.Tag.Updated | String | The time when the tag was last updated. |
| RiskSense.HostFinding.Tag.Color | String | The color of the tag. |
| RiskSense.HostFinding.TagAssetCount | Number | The total number of tag assets. |
| RiskSense.HostFinding.TagAsset.ID | Number | The ID of the tag asset. |
| RiskSense.HostFinding.TagAsset.Name | String | The name of the tag asset. |
| RiskSense.HostFinding.TagAsset.Category | String | The category of the tag asset. |
| RiskSense.HostFinding.TagAsset.Description | String | The description of the tag asset. |
| RiskSense.HostFinding.TagAsset.Created | String | The date and time when tag asset was created. |
| RiskSense.HostFinding.TagAsset.Updated | String | The time when the tag asset was last updated. |
| RiskSense.HostFinding.TagAsset.Color | String | The color name of the tag asset. |
| RiskSense.HostFinding.Output | String | The output of the host finding. |
| RiskSense.HostFinding.Severity | Number | The severity of the host finding. |
| RiskSense.HostFinding.SeverityDetail.Combined | Number | The combined name of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.Overridden | boolean | The overridden name of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.Scanner | String | The scanner of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.CvssV2 | Number | The CVSS v2 value of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.CvssV3 | Number | The CVSS v3 value of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.Aggregated | Number | The aggregated value of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.State | String | The state of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.StateName | String | The state name of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.ExpirationDate | String | The time when the severity detail expired. |
| RiskSense.HostFinding.RiskRating | Number | The risk rate of the host finding. |
| RiskSense.HostFinding.Xrs3Impact | String | The impact of xrs3 for the host finding. |
| RiskSense.HostFinding.Xrs3ImpactOnCategory | String | The category impact of xrs3 for the host finding. |
| RiskSense.HostFinding.LastFoundOn | String | The latest time when the particular host finding is found. |
| RiskSense.HostFinding.DiscoveredOn | String | The time when the host finding was discovered. |
| RiskSense.HostFinding.ResolvedOn | String | The time when the host finding was resolved. |
| RiskSense.HostFinding.ScannerName | String | The name of the scanner of the host finding. |
| RiskSense.HostFinding.FindingType | String | The finding type of the host finding. |
| RiskSense.HostFinding.MachineID | String | The machine ID of the host finding. |
| RiskSense.HostFinding.StatusEmbedded.State | String | The current state of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.StateName | String | The state name of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.StateDescription | String | The state description of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.Status | boolean | The status of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.DurationInDays | String | The time duration (In days) of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.DueDate | String | The due date of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.ExpirationDate | String | The time when the status is expired associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReportCount | Number | The total number of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.ID | Number | The ID of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Title | String | The title of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Label | String | The label of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Pii | String | The PII number of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Source | String | The source of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.IsManualExploit | boolean | Whether the manual finding report is an exploit. |
| RiskSense.HostFinding.ManualFindingReport.EaseOfExploit | String | The total number of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.NoteCount | Number | Number of notes found for the host finding. |
| RiskSense.HostFinding.Note.Date | String | The time when the note was added by the user for the host finding. |
| RiskSense.HostFinding.Note.Note | String | The notes that were added by the user for the host finding. |
| RiskSense.HostFinding.Note.UserID | Number | The User ID of the user who added the note for the host finding. |
| RiskSense.HostFinding.Note.UserName | String | The username of the user who added a note for the host finding. |
| RiskSense.HostFinding.Assignment.ID | Number | The unique ID of the assignment associated with the host finding. |
| RiskSense.HostFinding.Assignment.FirstName | String | The first name of the assigned user for the host finding. |
| RiskSense.HostFinding.Assignment.LastName | String | The last name of the assigned user for the host finding. |
| RiskSense.HostFinding.Assignment.ReceiveEmails | boolean | Indicates whether the email was received. |
| RiskSense.HostFinding.Assignment.Email | String | The email address of the assigned user for the host finding. |
| RiskSense.HostFinding.Assignment.Username | String | The username of the assigned user for the host finding. |
| RiskSense.HostFinding.Services | String | The name of the services for the host finding. |
| Ticket.ID | String | The ID of the ticket associated with the host finding. |
| Ticket.State | String | The state of the ticket associated with the host finding. |
| Host.Hostname | String | The hostname of the host. |
| Host.ID | String | The unique ID within the tool retrieving the host. |
| Host.IP | String | The IP address of the host. |
| CVE.ID | String | Common Vulnerabilities and Exposures ID. |
| CVE.Description | String | Description of the CVE. |
| CVE.CVSS | String | The CVSS represents the severity of the risk (informational, low, medium, high, critical). |
| RiskSense.HostFinding.Ticket.TicketNumber | String | The number of tickets associated with the host finding. |
| RiskSense.HostFinding.Ticket.TicketStatus | String | The status of the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.DeepLink | String | The deeplink associated with the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.Type | String | The type of ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.ConnectorName | String | The connector name of the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.DetailedStatus | String | The detailed status of the ticket associated with the host finding. |
| RiskSense.HostFinding.GroupID | Number | The unique ID of the group associated with the host finding. |
| RiskSense.HostFinding.GroupName | String | The name of the group associated with the host finding. |
Command Example
!risksense-get-host-findings fieldname="Host Name" value=loz.xg.mil sort_by="Risk Rating" sort_direction="Descending" size="2"
Context Example
{
"Host": [
{
"IP": "116.145.139.179",
"Hostname": "loz.xg.mil",
"ID": 3569982
},
{
"IP": "116.145.139.179",
"Hostname": "loz.xg.mil",
"ID": 3569982
}
],
"CVE": [
{
"ID": "CVE-2007-0882",
"CVSS": 10,
"Description": "Argument injection vulnerability in the telnet daemon (in.telnetd) in Solaris 10 and 11 (SunOS 5.10 and 5.11) misinterprets certain client \"-f\" sequences as valid requests for the login program to skip authentication, which allows remote attackers to log into certain accounts, as demonstrated by the bin account."
},
{
"ID": "CVE-2011-4862",
"CVSS": 10,
"Description": "Buffer overflow in libtelnet/encrypt.c in telnetd in FreeBSD 7.3 through 9.0, MIT Kerberos Version 5 Applications (aka krb5-appl) 1.0.2 and earlier, Heimdal 1.5.1 and earlier, GNU inetutils, and possibly other products allows remote attackers to execute arbitrary code via a long encryption key, as exploited in the wild in December 2011."
}
],
"RiskSense.HostFinding": [
{
"ResolvedOn": "2019-06-12",
"Group": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Network": {
"Type": "IP",
"ID": 78038,
"Name": "IP Network"
},
"StatusEmbedded": {
"Status": false,
"StateDescription": "Finding was approved in risk acceptance workflow",
"StateName": "RA Approved",
"State": "ACCEPTED",
"ExpirationDate": "",
"DurationInDays": "3246",
"DueDate": "2019-12-01T00:00:00"
},
"Title": "Solaris 10 and Solaris 11 (SolarisExpress) Remote Access Telnet Daemon Flaw",
"TagAsset": [
{
"Category": "Location",
"Updated": "2019-06-19T19:23:08",
"Name": "Data_Center_1",
"Created": "2019-04-24T21:35:12",
"Color": "#dd8361",
"ID": 215551
},
{
"Category": "People",
"Updated": "2019-04-24T21:39:59",
"Name": "Linux_Team_2",
"Created": "2019-04-24T21:39:59",
"Color": "#78a19b",
"ID": 215554
}
],
"GroupCount": 1,
"Note": [
{
"Date": "2019-04-24T23:00:57.973",
"Note": "These devices are to be decommissioned soon",
"UserID": 2425,
"UserName": "Ryan Riley"
}
],
"Source": "QUALYS",
"SeverityDetail": {
"CvssV3": null,
"CvssV2": 10,
"Scanner": "5",
"Overridden": false,
"StateName": null,
"State": null,
"ExpirationDate": "",
"Aggregated": 10,
"Combined": 10
},
"Assessment": [
{
"Date": "2019-04-23",
"ID": 67442,
"Name": "First Assessment"
}
],
"TagCount": 5,
"Severity": 10,
"RiskRating": 10,
"SourceID": "QUALYS38574",
"Assignment": [],
"HostName": "loz.xg.mil",
"Xrs3ImpactOnCategory": null,
"TagAssetCount": 2,
"Host": {
"Rs3": 644,
"External": true,
"Criticality": 5,
"Port": [
{
"ID": 42841210,
"Number": 21
},
{
"ID": 42841323,
"Number": 22
},
{
"ID": 42841347,
"Number": 23
},
{
"ID": 42841183,
"Number": 25
},
{
"ID": 42841178,
"Number": 111
},
{
"ID": 42841312,
"Number": 123
},
{
"ID": 42841336,
"Number": 587
},
{
"ID": 42841279,
"Number": 852
},
{
"ID": 42841222,
"Number": 6112
},
{
"ID": 42841168,
"Number": 7100
},
{
"ID": 42841236,
"Number": 8005
},
{
"ID": 42841197,
"Number": 8007
},
{
"ID": 42841329,
"Number": 32771
},
{
"ID": 42841246,
"Number": 32772
},
{
"ID": 42841259,
"Number": 32775
},
{
"ID": 42841269,
"Number": 32776
},
{
"ID": 42841361,
"Number": 32777
},
{
"ID": 42841370,
"Number": 32778
},
{
"ID": 42841172,
"Number": 32779
}
]
},
"Services": "",
"Ticket": [],
"ThreatCount": 5,
"Xrs3Impact": null,
"DiscoveredOn": "2010-07-22",
"HostID": 3569982,
"NoteCount": 1,
"Vulnerability": [
{
"Trending": false,
"AttackVector": "Network",
"VulnLastTrendingOn": null,
"BaseScore": 10,
"AvailabilityImpact": "Complete",
"Authentication": "None",
"AccessComplexity": "Low",
"ConfidentialityImpact": "Complete",
"Cve": "CVE-2007-0882",
"Integrity": "Complete",
"ThreatCount": 5
}
],
"Patch": [],
"Threat": [
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-13T15:32:52",
"Trending": false,
"Severity": null,
"Title": "Sun Solaris Telnet Remote Authentication Bypass Vulnerability",
"Source": "METASPLOIT",
"Published": "2007-02-17T00:00:00",
"Cve": "CVE-2007-0882",
"Description": "This module exploits the argument injection vulnerability\n in the telnet daemon (in.telnetd) of Solaris 10 and 11."
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-08T07:54:43",
"Trending": false,
"Severity": null,
"Title": "Sun Solaris Telnet - Remote Authentication Bypass (Metasploit)",
"Source": "EXPLOIT DB",
"Published": "2010-06-22T00:00:00",
"Cve": "CVE-2007-0882",
"Description": "Sun Solaris Telnet - Remote Authentication Bypass (Metasploit)"
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-08T07:54:43",
"Trending": false,
"Severity": null,
"Title": "Solaris 10/11 Telnet - Remote Authentication Bypass (Metasploit)",
"Source": "EXPLOIT DB",
"Published": "2007-02-12T00:00:00",
"Cve": "CVE-2007-0882",
"Description": "Solaris 10/11 Telnet - Remote Authentication Bypass (Metasploit)"
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-08T07:54:43",
"Trending": false,
"Severity": null,
"Title": "SunOS 5.10/5.11 in.TelnetD - Remote Authentication Bypass",
"Source": "EXPLOIT DB",
"Published": "2007-02-11T00:00:00",
"Cve": "CVE-2007-0882",
"Description": "SunOS 5.10/5.11 in.TelnetD - Remote Authentication Bypass"
},
{
"Category": "Worm",
"ThreatLastTrendingOn": null,
"Updated": "2019-08-16T15:50:12",
"Trending": false,
"Severity": null,
"Title": "Solaris.Wanuk.Worm",
"Source": "SYMANTEC",
"Published": "2007-02-28T00:00:00",
"Cve": "CVE-2007-0882",
"Description": ""
}
],
"Output": "Detected service telnet and os SOLARIS 9-11",
"ID": 115469505,
"ManualFindingReport": [],
"HostIpAddress": "116.145.139.179",
"ManualFindingReportCount": 0,
"FindingType": "Auth/Unauthenticated",
"Tag": [
{
"Category": "Location",
"Updated": "2019-06-19T19:23:08",
"Name": "Data_Center_1",
"Created": "2019-04-24T21:35:12",
"Color": "#dd8361",
"ID": 215551,
"Description": ""
},
{
"Category": "People",
"Updated": "2019-04-24T21:39:59",
"Name": "Linux_Team_2",
"Created": "2019-04-24T21:39:59",
"Color": "#78a19b",
"ID": 215554,
"Description": ""
},
{
"Category": "Project",
"Updated": "2019-10-31T03:40:55",
"Name": "PCI Assets",
"Created": "2019-08-28T18:50:30",
"Color": "#648d9f",
"ID": 225750,
"Description": ""
},
{
"Category": "Custom",
"Updated": "2019-11-19T23:40:40",
"Name": "CVSS_Sev_Crit_Test",
"Created": "2019-11-19T23:40:40",
"Color": "#648d9f",
"ID": 230966,
"Description": "CVSS Crits"
},
{
"Category": "Custom",
"Updated": "2019-11-19T23:41:36",
"Name": "RR_Crit_Test",
"Created": "2019-11-19T23:41:36",
"Color": "#648d9f",
"ID": 230967,
"Description": "Risk Rating Crit Test"
}
],
"LastFoundOn": "2010-07-22",
"MachineID": "",
"Port": null,
"ScannerName": "QUALYS"
},
{
"ResolvedOn": "2019-06-12",
"Group": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Network": {
"Type": "IP",
"ID": 78038,
"Name": "IP Network"
},
"StatusEmbedded": {
"Status": false,
"StateDescription": "Finding was approved in risk acceptance workflow",
"StateName": "RA Approved",
"State": "ACCEPTED",
"ExpirationDate": "",
"DurationInDays": "2690",
"DueDate": "2019-12-01T00:00:00"
},
"Title": "FreeBSD Telnetd Code Execution Vulnerability (FreeBSD-SA-11:08)",
"TagAsset": [
{
"Category": "Location",
"Updated": "2019-06-19T19:23:08",
"Name": "Data_Center_1",
"Created": "2019-04-24T21:35:12",
"Color": "#dd8361",
"ID": 215551
},
{
"Category": "People",
"Updated": "2019-04-24T21:39:59",
"Name": "Linux_Team_2",
"Created": "2019-04-24T21:39:59",
"Color": "#78a19b",
"ID": 215554
}
],
"GroupCount": 1,
"Note": [],
"Source": "QUALYS",
"SeverityDetail": {
"CvssV3": null,
"CvssV2": 10,
"Scanner": "4",
"Overridden": false,
"StateName": null,
"State": null,
"ExpirationDate": "",
"Aggregated": 10,
"Combined": 8
},
"Assessment": [
{
"Date": "2019-04-23",
"ID": 67442,
"Name": "First Assessment"
}
],
"TagCount": 5,
"Severity": 8,
"RiskRating": 10,
"SourceID": "QUALYS119834",
"Assignment": [],
"HostName": "loz.xg.mil",
"Xrs3ImpactOnCategory": null,
"TagAssetCount": 2,
"Host": {
"Rs3": 644,
"External": true,
"Criticality": 5,
"Port": [
{
"ID": 42841210,
"Number": 21
},
{
"ID": 42841323,
"Number": 22
},
{
"ID": 42841347,
"Number": 23
},
{
"ID": 42841183,
"Number": 25
},
{
"ID": 42841178,
"Number": 111
},
{
"ID": 42841312,
"Number": 123
},
{
"ID": 42841336,
"Number": 587
},
{
"ID": 42841279,
"Number": 852
},
{
"ID": 42841222,
"Number": 6112
},
{
"ID": 42841168,
"Number": 7100
},
{
"ID": 42841236,
"Number": 8005
},
{
"ID": 42841197,
"Number": 8007
},
{
"ID": 42841329,
"Number": 32771
},
{
"ID": 42841246,
"Number": 32772
},
{
"ID": 42841259,
"Number": 32775
},
{
"ID": 42841269,
"Number": 32776
},
{
"ID": 42841361,
"Number": 32777
},
{
"ID": 42841370,
"Number": 32778
},
{
"ID": 42841172,
"Number": 32779
}
]
},
"Services": "",
"Ticket": [],
"ThreatCount": 6,
"Xrs3Impact": null,
"DiscoveredOn": "2012-01-29",
"HostID": 3569982,
"NoteCount": 0,
"Vulnerability": [
{
"Trending": false,
"AttackVector": "Network",
"VulnLastTrendingOn": null,
"BaseScore": 10,
"AvailabilityImpact": "Complete",
"Authentication": "None",
"AccessComplexity": "Low",
"ConfidentialityImpact": "Complete",
"Cve": "CVE-2011-4862",
"Integrity": "Complete",
"ThreatCount": 6
}
],
"Patch": [],
"Threat": [
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-08T07:49:42",
"Trending": false,
"Severity": null,
"Title": "TelnetD encrypt_keyid - Function Pointer Overwrite",
"Source": "EXPLOIT DB",
"Published": "2011-12-26T00:00:00",
"Cve": "CVE-2011-4862",
"Description": "TelnetD encrypt_keyid - Function Pointer Overwrite"
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-08T07:49:44",
"Trending": false,
"Severity": null,
"Title": "Linux BSD-derived Telnet Service Encryption Key ID - Remote Buffer Overflow (Metasploit)",
"Source": "EXPLOIT DB",
"Published": "2012-01-14T00:00:00",
"Cve": "CVE-2011-4862",
"Description": "Linux BSD-derived Telnet Service Encryption Key ID - Remote Buffer Overflow (Metasploit)"
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-29T16:00:18",
"Trending": false,
"Severity": null,
"Title": "Telnet Service Encryption Key ID Overflow Detection",
"Source": "METASPLOIT",
"Published": "2011-12-27T00:00:00",
"Cve": "CVE-2011-4862",
"Description": "Detect telnet services vulnerable to the encrypt option Key ID overflow (BSD-derived telnetd)"
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-13T15:32:41",
"Trending": false,
"Severity": null,
"Title": "Linux BSD-derived Telnet Service Encryption Key ID Buffer Overflow",
"Source": "METASPLOIT",
"Published": "2011-12-27T00:00:00",
"Cve": "CVE-2011-4862",
"Description": "This module exploits a buffer overflow in the encryption option handler of the\n Linux BSD-derived telnet service (inetutils or krb5-telnet). Most Linux distributions\n use NetKit-derived telnet daemons, so this flaw only applies to a small subset of\n Linux systems running telnetd."
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-13T15:32:40",
"Trending": false,
"Severity": null,
"Title": "FreeBSD Telnet Service Encryption Key ID Buffer Overflow",
"Source": "METASPLOIT",
"Published": "2011-12-27T00:00:00",
"Cve": "CVE-2011-4862",
"Description": "This module exploits a buffer overflow in the encryption option handler of the\n FreeBSD telnet service."
},
{
"Category": "Exploit",
"ThreatLastTrendingOn": null,
"Updated": "2020-02-08T07:49:41",
"Trending": false,
"Severity": null,
"Title": "FreeBSD - Telnet Service Encryption Key ID Buffer Overflow (Metasploit)",
"Source": "EXPLOIT DB",
"Published": "2012-01-14T00:00:00",
"Cve": "CVE-2011-4862",
"Description": "FreeBSD - Telnet Service Encryption Key ID Buffer Overflow (Metasploit)"
}
],
"Output": "Remote encryption-supported telnet server is potentially affected by "FreeBSD Telnetd Code Execution Vulnerability"",
"ID": 115469517,
"ManualFindingReport": [],
"HostIpAddress": "116.145.139.179",
"ManualFindingReportCount": 0,
"FindingType": "Auth/Unauthenticated",
"Tag": [
{
"Category": "Location",
"Updated": "2019-06-19T19:23:08",
"Name": "Data_Center_1",
"Created": "2019-04-24T21:35:12",
"Color": "#dd8361",
"ID": 215551,
"Description": ""
},
{
"Category": "People",
"Updated": "2019-04-24T21:39:59",
"Name": "Linux_Team_2",
"Created": "2019-04-24T21:39:59",
"Color": "#78a19b",
"ID": 215554,
"Description": ""
},
{
"Category": "Project",
"Updated": "2019-10-31T03:40:55",
"Name": "PCI Assets",
"Created": "2019-08-28T18:50:30",
"Color": "#648d9f",
"ID": 225750,
"Description": ""
},
{
"Category": "Custom",
"Updated": "2019-11-19T23:40:40",
"Name": "CVSS_Sev_Crit_Test",
"Created": "2019-11-19T23:40:40",
"Color": "#648d9f",
"ID": 230966,
"Description": "CVSS Crits"
},
{
"Category": "Custom",
"Updated": "2019-11-19T23:41:36",
"Name": "RR_Crit_Test",
"Created": "2019-11-19T23:41:36",
"Color": "#648d9f",
"ID": 230967,
"Description": "Risk Rating Crit Test"
}
],
"LastFoundOn": "2012-01-29",
"MachineID": "",
"Port": null,
"ScannerName": "QUALYS"
}
]
}
Human Readable Output
Total host findings: 16 Page: 0/7 Client: The Demo Client
Host finding(s) details
| ID | Host Name | IP Address | Title | Risk | Threats | RS3 | Criticality | Severity | Groups | State | Tags | Asset Tags | Note | Manual Finding Report Count |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 115469505 | loz.xg.mil | 116.145.139.179 | Solaris 10 and Solaris 11 (SolarisExpress) Remote Access Telnet Daemon Flaw | 10.0 | 5 | 644 | 5 | 10.0 | 1 | ACCEPTED | 5 | 2 | 1 | 0 |
| 115469517 | loz.xg.mil | 116.145.139.179 | FreeBSD Telnetd Code Execution Vulnerability (FreeBSD-SA-11:08) | 10.0 | 6 | 644 | 5 | 8.0 | 1 | ACCEPTED | 5 | 2 | 0 | 0 |
6. risksense-get-apps
Looks up the application details. The application details can be searched based on input parameters like fieldname (Name, Network, Address), operator (EXACT, IN, LIKE, BETWEEN), page, size, sort by and sort direction.
Base Command
risksense-get-apps
Input
| Argument Name | Description | Required |
|---|---|---|
| fieldname | The RiskSense application attribute that should be considered for filtering the results. The available choices are ‘Name’, ‘Network’, or ‘Address’. Apart from the available choices, one can provide the attributes supported by RiskSense API. Refer to the API /application/filter API to get the list of supported attributes. The uid of filter attributes must be provided here. e.g. assessment_labels, asset_tags, cvss3BaseI, etc. If specified, ‘value’ argument is mandatory. | Optional |
| operator | The match operator should be applied for filtering the hosts based on ‘fieldname’ and ‘value’. Available options are ‘EXACT’ (filter records exactly matching the criteria), ‘IN’ (filter records matching any one of the comma-separated values), or ‘LIKE’ (filter records with the value matching the specified pattern). All the records fieldname value contains the string provided in value; ‘BETWEEN’ - filter the records with fieldname value falling in the numerical/date range provided. This argument also accepts other operator values supported by the RiskSense API. Refer to the API documentation for the list of supported operators. | Optional |
| value | The value of the apps property mentioned in ‘fieldname’ to be considered for filter criteria. | Optional |
| exclude | The exclude flag that determines whether the returned records matches filter criteria or not. The default is “false”. | Optional |
| page | The index of the page. The index is a numeric value and starting with 0. | Optional |
| size | The maximum number of records to fetch in one page. | Optional |
| sort_by | The fieldname that should be considered for sorting the returned records. | Optional |
| sort_direction | The sorting direction to apply to returned records. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.Application.ID | Number | The unique ID within the tool retrieving the application. |
| RiskSense.Application.GroupID | Number | The group ID of the application. |
| RiskSense.Application.GroupName | String | The group name of the application. |
| RiskSense.Application.Group.ID | Number | The ID of the group belonging to the Application. |
| RiskSense.Application.Group.Name | String | The name of the group belonging to the Application. |
| RiskSense.Application.Network.ID | Number | The network ID of the application. |
| RiskSense.Application.Network.Name | String | The network name of the application. |
| RiskSense.Application.Network.Type | String | The network type of the application. |
| RiskSense.Application.ClientID | Number | The client ID of the application. |
| RiskSense.Application.HostID | Number | The host ID of the application. |
| RiskSense.Application.Uri | String | The reference URI of the application. |
| RiskSense.Application.Name | String | The name of the application. |
| RiskSense.Application.Description | String | The detailed description of the application. |
| RiskSense.Application.NoteCount | Number | The total number of notes found in the application. |
| RiskSense.Application.DiscoveredOn | String | The time when the application was discovered. |
| RiskSense.Application.LastFoundOn | String | The time when the application was last found. |
| RiskSense.Application.Total | Number | The total number of open findings of the application. |
| RiskSense.Application.Critical | Number | The number of open findings of the application with critical severity. |
| RiskSense.Application.High | Number | The number of open findings of the application with high severity. |
| RiskSense.Application.Medium | Number | The number of open findings of the application with medium severity. |
| RiskSense.Application.Low | Number | The number of open findings of the application with low severity. |
| RiskSense.Application.Info | Number | The number of open findings of the application with info severity. |
| RiskSense.Application.Icon.Type | String | The type of icon of the application. |
| RiskSense.Application.Icon.OverlayText | String | The overlay text of the icon of the application. |
| RiskSense.Application.TagCount | Number | The total number of tags of the application. |
| RiskSense.Application.UrlCount | Number | The total number of URLs of the application. |
| RiskSense.Application.Href | String | The deeplink pointing to the application details on RiskSense. |
| RiskSense.Application.CMDB.ManufacturedBy | String | The name of the manufacturer in the configuration management DB (CMDB) from application details. |
| RiskSense.Application.CMDB.Model | String | The CMDB model name of the application. |
| RiskSense.Application.CMDB.MacAddress | String | The CMDB MAC address of the application. |
| RiskSense.Application.CMDB.Location | String | The CMDB location of the application. |
| RiskSense.Application.CMDB.ManagedBy | String | The CMDB entity name that managed the application. |
| RiskSense.Application.CMDB.OwnedBy | String | The CMDB entity name that owned the application. |
| RiskSense.Application.CMDB.SupportedBy | String | The CMDB entity name that supported the application |
| RiskSense.Application.CMDB.SupportGroup | String | The CMDB supporting group of the application. |
| RiskSense.Application.CMDB.SysID | String | The CMDB system ID of the application. |
| RiskSense.Application.CMDB.OperatingSystem | String | The CMDB operating system of the application. |
| RiskSense.Application.CMDB.LastScanDate | String | The CMDB last scan date of the application. |
| RiskSense.Application.CMDB.FerpaComplianceAsset | Boolean | The Family Educational Rights and Privacy Act. |
| RiskSense.Application.CMDB.HipaaComplianceAsset | Boolean | Health Insurance Portability and Accountability Act. |
| RiskSense.Application.CMDB.PciComplianceAsset | String | The Payment Card Industry (PCI) Council continues to make changes to ensure that their standards are up to date with emerging threats and changes in the market. |
| RiskSense.Application.Ticket.TicketNumber | String | The number of the ticket associated with the application. |
| RiskSense.Application.Ticket.TicketStatus | String | The status of the ticket associated with the application. |
| RiskSense.Application.Ticket.Type | String | The type of ticket associated with the application. |
| RiskSense.Application.Ticket.ConnectorName | String | The connector name of the ticket associated with the application. |
| RiskSense.Application.Ticket.DetailedStatus | String | The detailed status of ticket associated with the application. |
| RiskSense.Application.Ticket.DeepLink | String | The deeplink associated with the ticket associated with the application. |
| RiskSense.Application.Source.Name | String | The name of the source associated with the application. |
| RiskSense.Application.Source.UuID | String | The unique ID of the source associated with the application. |
| RiskSense.Application.Source.ScannerType | String | The type of scanner of the source associated with the application.. |
| RiskSense.Application.Note.UserID | String | The user ID of the user who added a note for the application. |
| RiskSense.Application.Note.UserName | String | The username of the user who added a note for the application. |
| RiskSense.Application.Note.Note | String | The notes that were added by the user for the application. |
| RiskSense.Application.Note.Date | String | The time when the note was added by the user for the application. |
| RiskSense.Application.Tag.ID | Number | The ID of the tag. |
| RiskSense.Application.Tag.Name | String | The name of the tag. |
| RiskSense.Application.Tag.Category | String | The category of the tag. |
| RiskSense.Application.Tag.Description | String | The description of the tag. |
| RiskSense.Application.Tag.Created | String | The time when the tag was created. |
| RiskSense.Application.Tag.Updated | String | The time when the tag was last updated. |
| RiskSense.Application.Tag.Color | String | The color code of the tag of the application. |
| Ticket.ID | String | The ID of the ticket associated with the application. |
| Ticket.State | String | The state of the ticket associated with the application. |
Command Example
!risksense-get-apps fieldname=Network value=App-data sort_by="Total Findings" sort_direction="Descending" size="3"
Context Example
{
"RiskSense.Application": [
{
"Network": {
"Type": "IP",
"ID": 91502,
"Name": "App-data"
},
"Note": [
{
"Date": "2020-01-28T12:21:06",
"Note": "Hiiii",
"UserID": 5969,
"UserName": "Ravindra Sojitra"
}
],
"Source": [
{
"ScannerType": "SAST",
"Name": "VERACODESAST",
"UuID": "VERACODESAST"
}
],
"Critical": 2,
"Low": 21,
"TagCount": 0,
"Medium": 281,
"Description": null,
"ClientID": 747,
"GroupID": 7990,
"Tag": [],
"Groups": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Ticket": [],
"Icon": [
{
"Type": "VERACODESAST",
"OverlayText": null
},
{
"Type": "OWASP",
"OverlayText": "A1"
},
{
"Type": "OWASP",
"OverlayText": "A3"
},
{
"Type": "OWASP",
"OverlayText": "A2"
},
{
"Type": "WASC",
"OverlayText": "SQL Injection"
},
{
"Type": "WASC",
"OverlayText": "HTTP Response Splitting"
},
{
"Type": "WASC",
"OverlayText": "OS Commanding"
},
{
"Type": "WASC",
"OverlayText": "URl Redirector Abuse"
},
{
"Type": "WASC",
"OverlayText": "HTTP Request Splitting"
},
{
"Type": "WASC",
"OverlayText": "Brute Force"
},
{
"Type": "WASC",
"OverlayText": "Session Fixation"
}
],
"Info": 1,
"DiscoveredOn": "2019-06-11",
"HostID": null,
"Name": "RS TestApp 1",
"NoteCount": 1,
"Uri": "RS TestApp 1",
"GroupName": "Default Group",
"ID": 19391,
"CMDB": {
"MacAddress": null,
"SupportGroup": null,
"SysID": null,
"HipaaComplianceAsset": false,
"OperatingSystem": null,
"ManufacturedBy": null,
"ManagedBy": null,
"Location": null,
"OwnedBy": null,
"Model": null,
"LastScanDate": "2019-06-11",
"FerpaComplianceAsset": false,
"SupportedBy": null,
"PciComplianceAsset": false
},
"UrlCount": 74,
"High": 20,
"Href": "http://platform.risksense.com/api/v1/client/747/application/search?page=0&size=3&sort=findingsDistribution.total,desc",
"LastFoundOn": "2019-06-11",
"Total": 325
},
{
"Network": {
"Type": "IP",
"ID": 91502,
"Name": "App-data"
},
"Note": [],
"Source": [
{
"ScannerType": "DAST",
"Name": "HPWEBINSPECT",
"UuID": "HPWEBINSPECT"
}
],
"Critical": 19,
"Low": 157,
"TagCount": 0,
"Medium": 8,
"Description": null,
"ClientID": 747,
"GroupID": 7990,
"Tag": [],
"Groups": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Ticket": [],
"Icon": [
{
"Type": "WEBINSPECT",
"OverlayText": null
},
{
"Type": "OWASP",
"OverlayText": "A6"
},
{
"Type": "OWASP",
"OverlayText": "A5"
},
{
"Type": "OWASP",
"OverlayText": "A1"
},
{
"Type": "OWASP",
"OverlayText": "A2"
},
{
"Type": "OWASP",
"OverlayText": "A3"
},
{
"Type": "OWASP",
"OverlayText": "A7"
},
{
"Type": "WASC",
"OverlayText": "Directory Indexing"
},
{
"Type": "WASC",
"OverlayText": "Information Leakage"
},
{
"Type": "WASC",
"OverlayText": "Path Traversal"
},
{
"Type": "WASC",
"OverlayText": "Predictable Resource Location"
},
{
"Type": "WASC",
"OverlayText": "Insufficient Authentication"
},
{
"Type": "WASC",
"OverlayText": "Insufficient Authorization"
},
{
"Type": "WASC",
"OverlayText": "LDAP Injection"
},
{
"Type": "WASC",
"OverlayText": "Cross-site Request Forgery"
},
{
"Type": "WASC",
"OverlayText": "Cross-site Scripting"
},
{
"Type": "WASC",
"OverlayText": "OS Commanding"
},
{
"Type": "WASC",
"OverlayText": "Improper Output Handling"
},
{
"Type": "WASC",
"OverlayText": "Buffer Overflow"
}
],
"Info": 0,
"DiscoveredOn": "2019-06-12",
"HostID": null,
"Name": "http://zero.webappsecurity.com:80",
"NoteCount": 0,
"Uri": "http://zero.webappsecurity.com:80",
"GroupName": "Default Group",
"ID": 19396,
"CMDB": {
"MacAddress": null,
"SupportGroup": null,
"SysID": null,
"HipaaComplianceAsset": false,
"OperatingSystem": null,
"ManufacturedBy": null,
"ManagedBy": null,
"Location": null,
"OwnedBy": null,
"Model": null,
"LastScanDate": null,
"FerpaComplianceAsset": false,
"SupportedBy": null,
"PciComplianceAsset": false
},
"UrlCount": 152,
"High": 0,
"Href": "http://platform.risksense.com/api/v1/client/747/application/search?page=0&size=3&sort=findingsDistribution.total,desc",
"LastFoundOn": "2019-06-11",
"Total": 184
},
{
"Network": {
"Type": "IP",
"ID": 91502,
"Name": "App-data"
},
"Note": [],
"Source": [
{
"ScannerType": "DAST",
"Name": "IBMAPPSCANENTERPRISE",
"UuID": "IBMAPPSCANENTERPRISE"
}
],
"Critical": 28,
"Low": 13,
"TagCount": 0,
"Medium": 0,
"Description": null,
"ClientID": 747,
"GroupID": 7990,
"Tag": [],
"Groups": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Ticket": [],
"Icon": [
{
"Type": "IBM_APP_SCANNER",
"OverlayText": null
}
],
"Info": 0,
"DiscoveredOn": "2019-06-12",
"HostID": null,
"Name": "https:/test.thatcompany.com",
"NoteCount": 0,
"Uri": "https:/test.thatcompany.com",
"GroupName": "Default Group",
"ID": 19395,
"CMDB": {
"MacAddress": null,
"SupportGroup": null,
"SysID": null,
"HipaaComplianceAsset": false,
"OperatingSystem": null,
"ManufacturedBy": null,
"ManagedBy": null,
"Location": null,
"OwnedBy": null,
"Model": null,
"LastScanDate": null,
"FerpaComplianceAsset": false,
"SupportedBy": null,
"PciComplianceAsset": false
},
"UrlCount": 33,
"High": 0,
"Href": "http://platform.risksense.com/api/v1/client/747/application/search?page=0&size=3&sort=findingsDistribution.total,desc",
"LastFoundOn": "2019-06-11",
"Total": 41
}
]
}
Human Readable Output
Total applications: 7 Page: 0/2 Client: The Demo Client
RiskSense application(s) details
| ID | Address | Name | Network | Total Findings | Critical Findings | High Findings | Medium Findings | Low Findings | Info Findings | Groups | URLs | Tags | Notes |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 19391 | RS TestApp 1 | RS TestApp 1 | App-data | 325 | 2 | 20 | 281 | 21 | 1 | 1 | 74 | 0 | 1 |
| 19396 | http://zero.webappsecurity.com:80 | http://zero.webappsecurity.com:80 | App-data | 184 | 19 | 0 | 8 | 157 | 0 | 1 | 152 | 0 | 0 |
| 19395 | https:/test.thatcompany.com | https:/test.thatcompany.com | App-data | 41 | 28 | 0 | 0 | 13 | 0 | 1 | 33 | 0 | 0 |
7. risksense-get-host-finding-detail
Gets in-depth details of a single host finding. The command accepts the host finding ID as an argument.
Base Command
risksense-get-host-finding-detail
Input
| Argument Name | Description | Required |
|---|---|---|
| hostfinding_id | The unique host finding ID. The host finding ID is either known by RiskSense users or it can be found in the human-readable output or context data(RiskSense.HostFinding.ID) after executing ‘risksense-get-host-findings’ command. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.HostFinding.ID | String | The unique ID of the host finding. |
| RiskSense.HostFinding.Source | String | Host discovered by the scanner. |
| RiskSense.HostFinding.SourceID | String | Scanner ID of the discovered scanner. |
| RiskSense.HostFinding.Title | String | The title of the host finding. |
| RiskSense.HostFinding.Port | Number | The port number of the host finding. |
| RiskSense.HostFinding.GroupCount | Number | The total number of groups for the host finding. |
| RiskSense.HostFinding.Group.ID | Number | The unique ID of the group associated with the host finding. |
| RiskSense.HostFinding.Group.Name | String | The name of the group associated with the host finding. |
| RiskSense.HostFinding.GroupID | Number | The unique ID of the group associated with the host finding. |
| RiskSense.HostFinding.GroupName | String | The name of the group associated with the host finding. |
| RiskSense.HostFinding.HostID | Number | The unique ID of the host associated with the host finding. |
| RiskSense.HostFinding.HostName | String | The hostname of the host associated with the host finding. |
| RiskSense.HostFinding.HostIpAddress | String | The IP address of the host associated with the host finding. |
| RiskSense.HostFinding.Host.Criticality | Number | The criticality of the host associated with the host finding. |
| RiskSense.HostFinding.Host.External | boolean | Whether the host is external. |
| RiskSense.HostFinding.Host.Port.ID | Number | The unique ID of the host(s) port associated with the host finding. |
| RiskSense.HostFinding.Host.Port.Number | Number | The port number of the host associated with the host finding. |
| RiskSense.HostFinding.Host.Rs3 | Number | The Asset Security Score calculated by the RiskSense platform (includes vulnerability risk on related web applications). |
| RiskSense.HostFinding.Network.ID | Number | The network ID of the host finding. |
| RiskSense.HostFinding.Network.Name | String | The name of the network used by the host finding. |
| RiskSense.HostFinding.Network.Type | String | The type of the network used by the host finding. |
| RiskSense.HostFinding.Assessment.ID | Number | The assessment ID of the host finding. |
| RiskSense.HostFinding.Assessment.Name | String | The name of the assessment associated with the host finding. |
| RiskSense.HostFinding.Assessment.Date | String | The time when the assessment is created. |
| RiskSense.HostFinding.Vulnerability.Cve | String | The name of the Common Vulnerabilities and Exposures associated with the host finding. |
| RiskSense.HostFinding.Vulnerability.BaseScore | Number | CVE Score. |
| RiskSense.HostFinding.Vulnerability.ThreatCount | Number | The total number of threats associated with the host finding. |
| RiskSense.HostFinding.Vulnerability.AttackVector | String | Vector information in which the host finding was attacked. |
| RiskSense.HostFinding.Vulnerability.AccessComplexity | String | Complexity level. |
| RiskSense.HostFinding.Vulnerability.Authentication | String | Authentication value represents attackers authorization to get network access. |
| RiskSense.HostFinding.Vulnerability.ConfidentialityImpact | String | Confidentiality impact measures the potential impact on the confidentiality of a successfully exploited misuse vulnerability. |
| RiskSense.HostFinding.Vulnerability.Integrity | String | Integrity refers to the level of trust and veracity of the information. |
| RiskSense.HostFinding.Vulnerability.AvailabilityImpact | String | Availability refers to accessibility of network resources. |
| RiskSense.HostFinding.Vulnerability.Trending | boolean | Whether the vulnerability (which is associated with the hostFinding) has been reported by our internal functions as being trending. |
| RiskSense.HostFinding.Vulnerability.VulnLastTrendingOn | String | Date when the last trending vulnerability was found. |
| RiskSense.HostFinding.ThreatCount | Number | The total number of threats. |
| RiskSense.HostFinding.Threat.Title | String | The title of the threat. |
| RiskSense.HostFinding.Threat.Category | String | The category of the threat. |
| RiskSense.HostFinding.Threat.Severity | String | The severity level of the threat. |
| RiskSense.HostFinding.Threat.Description | String | The threat description. |
| RiskSense.HostFinding.Threat.Cve | Unknown | The Common Vulnerabilities and Exposures name of the threat. |
| RiskSense.HostFinding.Threat.Source | String | The source of the threat. |
| RiskSense.HostFinding.Threat.Published | String | The time when threat was published. |
| RiskSense.HostFinding.Threat.Updated | String | The time when the threat was last updated. |
| RiskSense.HostFinding.Threat.ThreatLastTrendingOn | String | The last time when the threat was trending. |
| RiskSense.HostFinding.Threat.Trending | boolean | Whether the threat is trending. |
| RiskSense.HostFinding.Patch.Name | String | The patch name of the host finding. |
| RiskSense.HostFinding.Patch.Url | String | The patch URL of the host finding. |
| RiskSense.HostFinding.TagCount | Number | The total number of tags associated with host finding. |
| RiskSense.HostFinding.Tag.ID | Number | The tag identifier of the host finding. |
| RiskSense.HostFinding.Tag.Name | String | The tag name of the host finding. |
| RiskSense.HostFinding.Tag.Category | String | The tag category of the host finding. |
| RiskSense.HostFinding.Tag.Description | String | The tag description of the host finding. |
| RiskSense.HostFinding.Tag.Created | String | The time when the tag was created. |
| RiskSense.HostFinding.Tag.Updated | String | The time when the tag was last updated. |
| RiskSense.HostFinding.Tag.Color | String | The color of the tag. |
| RiskSense.HostFinding.TagAssetCount | Number | The total number of tag assets. |
| RiskSense.HostFinding.TagAsset.ID | Number | The ID of the tag asset. |
| RiskSense.HostFinding.TagAsset.Name | String | The name of the tag asset. |
| RiskSense.HostFinding.TagAsset.Category | String | The category of the tag asset. |
| RiskSense.HostFinding.TagAsset.Description | String | The description of the tag asset. |
| RiskSense.HostFinding.TagAsset.Created | String | The time and date when the tag asset was created. |
| RiskSense.HostFinding.TagAsset.Updated | String | The time when the tag asset was last updated. |
| RiskSense.HostFinding.TagAsset.Color | String | The color name of the tag asset. |
| RiskSense.HostFinding.Output | String | The output of the host finding. |
| RiskSense.HostFinding.Severity | Number | The severity of the host finding. |
| RiskSense.HostFinding.SeverityDetail.Combined | Number | The combined name of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.Overridden | boolean | The overridden name of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.Scanner | String | The scanner of severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.CvssV2 | Number | The CVSS v2 value of severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.CvssV3 | Number | The CVSS v3 value of severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.Aggregated | Number | The aggregated value of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.State | String | The state of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.StateName | String | The state name of the severity detail for the host finding. |
| RiskSense.HostFinding.SeverityDetail.ExpirationDate | String | The time when the severity detail expired. |
| RiskSense.HostFinding.RiskRating | Number | The risk rate of the host finding. |
| RiskSense.HostFinding.Xrs3Impact | String | The impact of xrs3 for the host finding. |
| RiskSense.HostFinding.Xrs3ImpactOnCategory | String | The category impact of xrs3 for the host finding. |
| RiskSense.HostFinding.LastFoundOn | String | The latest time when the particular host finding was found. |
| RiskSense.HostFinding.DiscoveredOn | String | The time when the host finding was discovered. |
| RiskSense.HostFinding.ResolvedOn | String | The time when the host finding was resolved. |
| RiskSense.HostFinding.ScannerName | String | The name of the scanner of the host finding. |
| RiskSense.HostFinding.FindingType | String | The finding type of the host finding. |
| RiskSense.HostFinding.MachineID | String | The machine ID of the host finding. |
| RiskSense.HostFinding.StatusEmbedded.State | String | The current state of the embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.StateName | String | The state name of the embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.StateDescription | String | The state description of the embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.Status | boolean | The status of the embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.DurationInDays | String | The time duration (in days) of the embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.DueDate | String | The due date of embedded status associated with the host finding. |
| RiskSense.HostFinding.StatusEmbedded.ExpirationDate | String | The time when status is expired associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReportCount | Number | The total number of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.ID | Number | The ID of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Title | String | The title of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Label | String | The label of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Pii | String | The pii number of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.Source | String | The source of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.ManualFindingReport.IsManualExploit | boolean | To check whether manual finding report is exploit or not. |
| RiskSense.HostFinding.ManualFindingReport.EaseOfExploit | String | The total number of manual finding reports associated with the host finding. |
| RiskSense.HostFinding.NoteCount | Number | Number of notes found. |
| RiskSense.HostFinding.Note.Date | String | The time when the note was added by the user for the host finding. |
| RiskSense.HostFinding.Note.Note | String | The notes that are added by the user for the host finding. |
| RiskSense.HostFinding.Note.UserID | Number | The User ID of the user who added a note for the host finding. |
| RiskSense.HostFinding.Note.UserName | String | The username of the user who added a note for the host finding. |
| RiskSense.HostFinding.Assignment.ID | Number | The unique ID of the assignment associated with the host finding. |
| RiskSense.HostFinding.Assignment.FirstName | String | The first name of the assigned user for the host finding. |
| RiskSense.HostFinding.Assignment.LastName | String | The last name of the assigned user for the host finding. |
| RiskSense.HostFinding.Assignment.ReceiveEmails | boolean | Indicates whether email is received or not. |
| RiskSense.HostFinding.Assignment.Email | String | The email of the assigned user for the host finding. |
| RiskSense.HostFinding.Assignment.Username | String | The username of the assigned user for the host finding. |
| RiskSense.HostFinding.Services | String | The name of the services for the host finding. |
| Ticket.ID | String | The ID of the ticket associated with the host finding. |
| Ticket.State | String | The state of the ticket associated with the host finding. |
| Host.Hostname | String | The hostname of the host. |
| Host.ID | String | The unique ID within the tool retrieving the host. |
| Host.IP | String | The IP address of the host. |
| CVE.ID | String | Common Vulnerabilities and Exposures ID. |
| CVE.Description | String | Description about the CVE. |
| CVE.CVSS | String | The CVSS represents the severity of the risk (informational, low, medium, high, critical). |
| RiskSense.HostFinding.Ticket.TicketNumber | String | The number of the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.TicketStatus | String | The status of the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.DeepLink | String | The deeplink associated with the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.Type | String | The type of the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.ConnectorName | String | The connector name of the ticket associated with the host finding. |
| RiskSense.HostFinding.Ticket.DetailedStatus | String | The detailed status of the ticket associated with the host finding. |
Command Example
!risksense-get-host-finding-detail hostfinding_id=115469504
Context Example
{
"RiskSense.HostFinding": [
{
"HostID": 3569980,
"HostName": "lmd.ql.nl",
"HostIpAddress": "31.207.62.145",
"ID": 115469504,
"Source": "QUALYS",
"SourceID": "QUALYS38574",
"Title": "Solaris 10 and Solaris 11 (SolarisExpress) Remote Access Telnet Daemon Flaw",
"Port": null,
"GroupCount": 1,
"Group": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Host": {
"Criticality": 5,
"External": true,
"Port": [
{
"ID": 42841324,
"Number": 21
},
{
"ID": 42841352,
"Number": 22
},
{
"ID": 42841261,
"Number": 23
},
{
"ID": 42841311,
"Number": 25
},
{
"ID": 42841250,
"Number": 111
},
{
"ID": 42841211,
"Number": 123
},
{
"ID": 42841239,
"Number": 587
},
{
"ID": 42841345,
"Number": 852
},
{
"ID": 42841176,
"Number": 4045
},
{
"ID": 42841331,
"Number": 6112
},
{
"ID": 42841226,
"Number": 6481
},
{
"ID": 42841297,
"Number": 7100
},
{
"ID": 42841170,
"Number": 8400
},
{
"ID": 42841182,
"Number": 8402
},
{
"ID": 42841359,
"Number": 32771
},
{
"ID": 42841189,
"Number": 32772
},
{
"ID": 42841340,
"Number": 32775
},
{
"ID": 42841196,
"Number": 32776
},
{
"ID": 42841476,
"Number": 32777
},
{
"ID": 42841287,
"Number": 32778
},
{
"ID": 42841363,
"Number": 32780
},
{
"ID": 42841302,
"Number": 32794
}
],
"Rs3": 600
},
"Network": {
"ID": 78038,
"Name": "IP Network",
"Type": "IP"
},
"Assessment": [
{
"ID": 67442,
"Name": "First Assessment",
"Date": "2019-04-23"
}
],
"Vulnerability": [
{
"Cve": "CVE-2007-0882",
"BaseScore": 10,
"ThreatCount": 5,
"AttackVector": "Network",
"AccessComplexity": "Low",
"Authentication": "None",
"ConfidentialityImpact": "Complete",
"Integrity": "Complete",
"AvailabilityImpact": "Complete",
"Trending": false,
"VulnLastTrendingOn": null
}
],
"ThreatCount": 5,
"Threat": [
{
"Title": "Sun Solaris Telnet Remote Authentication Bypass Vulnerability",
"Category": "Exploit",
"Severity": null,
"Description": "This module exploits the argument injection vulnerability\n in the telnet daemon (in.telnetd) of Solaris 10 and 11.",
"Cve": "CVE-2007-0882",
"Source": "METASPLOIT",
"Published": "2007-02-17T00:00:00",
"Updated": "2020-02-13T15:32:52",
"ThreatLastTrendingOn": null,
"Trending": false
},
{
"Title": "Sun Solaris Telnet - Remote Authentication Bypass (Metasploit)",
"Category": "Exploit",
"Severity": null,
"Description": "Sun Solaris Telnet - Remote Authentication Bypass (Metasploit)",
"Cve": "CVE-2007-0882",
"Source": "EXPLOIT DB",
"Published": "2010-06-22T00:00:00",
"Updated": "2020-02-08T07:54:43",
"ThreatLastTrendingOn": null,
"Trending": false
},
{
"Title": "Solaris 10/11 Telnet - Remote Authentication Bypass (Metasploit)",
"Category": "Exploit",
"Severity": null,
"Description": "Solaris 10/11 Telnet - Remote Authentication Bypass (Metasploit)",
"Cve": "CVE-2007-0882",
"Source": "EXPLOIT DB",
"Published": "2007-02-12T00:00:00",
"Updated": "2020-02-08T07:54:43",
"ThreatLastTrendingOn": null,
"Trending": false
},
{
"Title": "SunOS 5.10/5.11 in.TelnetD - Remote Authentication Bypass",
"Category": "Exploit",
"Severity": null,
"Description": "SunOS 5.10/5.11 in.TelnetD - Remote Authentication Bypass",
"Cve": "CVE-2007-0882",
"Source": "EXPLOIT DB",
"Published": "2007-02-11T00:00:00",
"Updated": "2020-02-08T07:54:43",
"ThreatLastTrendingOn": null,
"Trending": false
},
{
"Title": "Solaris.Wanuk.Worm",
"Category": "Worm",
"Severity": null,
"Description": "",
"Cve": "CVE-2007-0882",
"Source": "SYMANTEC",
"Published": "2007-02-28T00:00:00",
"Updated": "2019-08-16T15:50:12",
"ThreatLastTrendingOn": null,
"Trending": false
}
],
"Patch": [],
"TagCount": 5,
"Tag": [
{
"ID": 215551,
"Name": "Data_Center_1",
"Category": "Location",
"Description": "",
"Created": "2019-04-24T21:35:12",
"Updated": "2019-06-19T19:23:08",
"Color": "#dd8361"
},
{
"ID": 215554,
"Name": "Linux_Team_2",
"Category": "People",
"Description": "",
"Created": "2019-04-24T21:39:59",
"Updated": "2019-04-24T21:39:59",
"Color": "#78a19b"
},
{
"ID": 225750,
"Name": "PCI Assets",
"Category": "Project",
"Description": "",
"Created": "2019-08-28T18:50:30",
"Updated": "2019-10-31T03:40:55",
"Color": "#648d9f"
},
{
"ID": 230966,
"Name": "CVSS_Sev_Crit_Test",
"Category": "Custom",
"Description": "CVSS Crits",
"Created": "2019-11-19T23:40:40",
"Updated": "2019-11-19T23:40:40",
"Color": "#648d9f"
},
{
"ID": 230967,
"Name": "RR_Crit_Test",
"Category": "Custom",
"Description": "Risk Rating Crit Test",
"Created": "2019-11-19T23:41:36",
"Updated": "2019-11-19T23:41:36",
"Color": "#648d9f"
}
],
"TagAssetCount": 2,
"TagAsset": [
{
"ID": 215551,
"Name": "Data_Center_1",
"Category": "Location",
"Created": "2019-04-24T21:35:12",
"Updated": "2019-06-19T19:23:08",
"Color": "#dd8361"
},
{
"ID": 215554,
"Name": "Linux_Team_2",
"Category": "People",
"Created": "2019-04-24T21:39:59",
"Updated": "2019-04-24T21:39:59",
"Color": "#78a19b"
}
],
"Output": "Detected service telnet and os SOLARIS 9-11",
"Severity": 10,
"SeverityDetail": {
"Combined": 10,
"Overridden": false,
"Scanner": "5",
"CvssV2": 10,
"CvssV3": null,
"Aggregated": 10,
"State": null,
"StateName": null,
"ExpirationDate": ""
},
"RiskRating": 10,
"Xrs3Impact": null,
"Xrs3ImpactOnCategory": null,
"LastFoundOn": "2010-07-22",
"DiscoveredOn": "2010-07-22",
"ResolvedOn": "2019-06-12",
"ScannerName": "QUALYS",
"FindingType": "Auth/Unauthenticated",
"MachineID": "",
"StatusEmbedded": {
"State": "ACCEPTED",
"StateName": "RA Approved",
"StateDescription": "Finding was approved in risk acceptance workflow",
"Status": false,
"DurationInDays": "3246",
"DueDate": "2019-12-01T00:00:00",
"ExpirationDate": ""
},
"ManualFindingReportCount": 0,
"ManualFindingReport": [],
"NoteCount": 0,
"Note": [],
"Assignment": [],
"Services": "",
"Ticket": []
}
],
"Host": [
{
"ID": 3569980,
"Hostname": "lmd.ql.nl",
"IP": "31.207.62.145"
}
],
"CVE": [
{
"ID": "CVE-2007-0882",
"CVSS": 10,
"Description": "Argument injection vulnerability in the telnet daemon (in.telnetd) in Solaris 10 and 11 (SunOS 5.10 and 5.11) misinterprets certain client \"-f\" sequences as valid requests for the login program to skip authentication, which allows remote attackers to log into certain accounts, as demonstrated by the bin account."
}
]
}
Human Readable Output
Client: The Demo Client
Group Details
Name: Default Group
Host Finding Details
| Host Name | Ip Address | Network | Source | Risk Rating | Title |
|---|---|---|---|---|---|
| lmd.ql.nl | 31.207.62.145 | IP Network | QUALYS | 10.0 | Solaris 10 and Solaris 11 (SolarisExpress) Remote Access Telnet Daemon Flaw |
Threat(s) (5)
| Title | Category | Source | CVEs | Published | Updated |
|---|---|---|---|---|---|
| Sun Solaris Telnet Remote Authentication Bypass Vulnerability | Exploit | METASPLOIT | CVE-2007-0882 | 2007-02-17T00:00:00 | 2020-02-13T15:32:52 |
| Sun Solaris Telnet - Remote Authentication Bypass (Metasploit) | Exploit | EXPLOIT DB | CVE-2007-0882 | 2010-06-22T00:00:00 | 2020-02-08T07:54:43 |
| Solaris 10/11 Telnet - Remote Authentication Bypass (Metasploit) | Exploit | EXPLOIT DB | CVE-2007-0882 | 2007-02-12T00:00:00 | 2020-02-08T07:54:43 |
| SunOS 5.10/5.11 in.TelnetD - Remote Authentication Bypass | Exploit | EXPLOIT DB | CVE-2007-0882 | 2007-02-11T00:00:00 | 2020-02-08T07:54:43 |
| Solaris.Wanuk.Worm | Worm | SYMANTEC | CVE-2007-0882 | 2007-02-28T00:00:00 | 2019-08-16T15:50:12 |
Vulnerabilities (1)
| Name | V2/Score | Threat Count | Attack Vector | Access Complexity | Authentication |
|---|---|---|---|---|---|
| CVE-2007-0882 | 10.0 | 5 | Network | Low | None |
Status
| State | Current State | Description | Duration | Due Date |
|---|---|---|---|---|
| ACCEPTED | RA Approved | Finding was approved in risk acceptance workflow | 3246 day(s) | 2019-12-01T00:00:00 |
Tag(s) (5)
| Name | Category | Created | Updated |
|---|---|---|---|
| Data_Center_1 | Location | 2019-04-24T21:35:12 | 2019-06-19T19:23:08 |
| Linux_Team_2 | People | 2019-04-24T21:39:59 | 2019-04-24T21:39:59 |
| PCI Assets | Project | 2019-08-28T18:50:30 | 2019-10-31T03:40:55 |
| CVSS_Sev_Crit_Test | Custom | 2019-11-19T23:40:40 | 2019-11-19T23:40:40 |
| RR_Crit_Test | Custom | 2019-11-19T23:41:36 | 2019-11-19T23:41:36 |
Manual Finding Report(s) (0)
No entries.
Ticket(s) (0)
No entries.
Assessment(s) (1)
| Name | Date |
|---|---|
| First Assessment | 2019-04-23 |
Host Finding Description
Solaris 10 and 11 hosts are vulnerable to a telnet daemon flaw.
The telnet daemon passes switches directly to the login process which looks for a switch that allows root to login to any account without a password. If your telnet daemon is running as root it allows unauthenticated remote logins.
Telnet poses a risk because data transferred between clients may not be encrypted. Telnet is also a frequent target for port scanners.
8. risksense-get-app-detail
Gets in-depth details of a single application. The command accepts an application ID as an argument.
Base Command
risksense-get-app-detail
Input
| Argument Name | Description | Required |
|---|---|---|
| application_id | The application ID is unique for the application. The application ID is either known by RiskSense users or it can be searched in context output (RiskSense.Application.ID) or in the human-readable output of ‘risksense-get-apps’ command. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.Application.ID | Number | The unique ID within the tool retrieving the application. |
| RiskSense.Application.GroupID | Number | The group ID of the application. |
| RiskSense.Application.GroupName | String | The group name of the application. |
| RiskSense.Application.Group.ID | Number | The ID of the group belonging to the Application. |
| RiskSense.Application.Group.Name | String | The name of the group belonging to the Application. |
| RiskSense.Application.Network.ID | Number | The network ID of the application. |
| RiskSense.Application.Network.Name | String | The network name of the application. |
| RiskSense.Application.Network.Type | String | The network type of the application. |
| RiskSense.Application.ClientID | Number | The client ID of the application. |
| RiskSense.Application.HostID | Number | The host ID of the application. |
| RiskSense.Application.Uri | String | The reference URI of the application. |
| RiskSense.Application.Name | String | The name of the application. |
| RiskSense.Application.Description | String | The detailed description of the application. |
| RiskSense.Application.NoteCount | Number | The total number of notes found in the application. |
| RiskSense.Application.DiscoveredOn | String | The time when the application was discovered. |
| RiskSense.Application.LastFoundOn | String | The time when the application was last found. |
| RiskSense.Application.Total | Number | The total number of open findings of the application. |
| RiskSense.Application.Critical | Number | The number of open findings of the application with critical severity. |
| RiskSense.Application.High | Number | The number of open findings of the application with high severity. |
| RiskSense.Application.Medium | Number | The number of open findings of the application with medium severity. |
| RiskSense.Application.Low | Number | The number of open findings of the application with low severity. |
| RiskSense.Application.Info | Number | The number of open findings of the application with info severity. |
| RiskSense.Application.Icon.Type | String | The icon type of the application. |
| RiskSense.Application.Icon.OverlayText | String | The overlay text of the icon of the application. |
| RiskSense.Application.TagCount | Number | The total number of tags of the application. |
| RiskSense.Application.UrlCount | Number | The total number of URLs of the application. |
| RiskSense.Application.Href | String | The deeplink pointing to the application details on RiskSense. |
| RiskSense.Application.CMDB.ManufacturedBy | String | The name of the manufacturer in configuration management DB (CMDB) from application details. |
| RiskSense.Application.CMDB.Model | String | The CMDB model name of the application. |
| RiskSense.Application.CMDB.MacAddress | String | The CMDB MAC Address of the application. |
| RiskSense.Application.CMDB.Location | String | The CMDB location of the application. |
| RiskSense.Application.CMDB.ManagedBy | String | The CMDB entity name that managed the application. |
| RiskSense.Application.CMDB.OwnedBy | String | The CMDB entity name that owned the application. |
| RiskSense.Application.CMDB.SupportedBy | String | The CMDB entity name that supported the application |
| RiskSense.Application.CMDB.SupportGroup | String | The CMDB supporting group of the application. |
| RiskSense.Application.CMDB.SysID | String | The CMDB system ID of the application. |
| RiskSense.Application.CMDB.OperatingSystem | String | The CMDB Operating system of the application. |
| RiskSense.Application.CMDB.LastScanDate | String | The CMDB last scan date of the application. |
| RiskSense.Application.CMDB.FerpaComplianceAsset | Boolean | The Family Educational Rights and Privacy Act. |
| RiskSense.Application.CMDB.HipaaComplianceAsset | Boolean | Health Insurance Portability and Accountability Act. |
| RiskSense.Application.CMDB.PciComplianceAsset | String | The Payment Card Industry (PCI) Council continues to make changes to ensure that their standards are up to date with emerging threats and changes in the market. |
| RiskSense.Application.Ticket.TicketNumber | String | The number of the ticket associated with the application. |
| RiskSense.Application.Ticket.TicketStatus | String | The status of the ticket associated with the application. |
| RiskSense.Application.Ticket.Type | String | The type of the ticket associated with the application. |
| RiskSense.Application.Ticket.ConnectorName | String | The connector name of the ticket associated with the application. |
| RiskSense.Application.Ticket.DetailedStatus | String | The detailed status of ticket associated with the application. |
| RiskSense.Application.Ticket.DeepLink | String | The deeplink associated with the ticket associated with the application. |
| RiskSense.Application.Source.Name | String | The name of the source associated with the application. |
| RiskSense.Application.Source.UuID | String | The unique ID of the source associated with the application. |
| RiskSense.Application.Source.ScannerType | String | The type of scanner of the source associated with the application.. |
| RiskSense.Application.Note.UserID | String | The user ID of the user who added a note for the application. |
| RiskSense.Application.Note.UserName | String | The username of the user who added a note for the application. |
| RiskSense.Application.Note.Note | String | The notes that are added by the user for the application. |
| RiskSense.Application.Note.Date | String | The time when the note was added by the user for the application. |
| RiskSense.Application.Tag.ID | Number | The ID of the tag. |
| RiskSense.Application.Tag.Name | String | The name of the tag. |
| RiskSense.Application.Tag.Category | String | The category of the tag. |
| RiskSense.Application.Tag.Description | String | The description of the tag. |
| RiskSense.Application.Tag.Created | String | The time when the tag was created. |
| RiskSense.Application.Tag.Updated | String | The time when the tag was last updated. |
| RiskSense.Application.Tag.Color | String | The color code of the tag of the application. |
| Ticket.ID | String | The ID of the ticket associated with the application. |
| Ticket.State | String | The state of the ticket associated with the application. |
Command Example
!risksense-get-app-detail application_id=19394
Context Example
{
"RiskSense.Application": [
{
"Network": {
"Type": "IP",
"ID": 91502,
"Name": "App-data"
},
"Note": [
{
"Date": "2020-01-15T23:16:12",
"Note": "Add note to app",
"UserID": 2222,
"UserName": "Natalia Donaldson"
},
{
"Date": "2020-01-15T23:26:43",
"Note": "Add note to app",
"UserID": 2222,
"UserName": "Natalia Donaldson"
},
{
"Date": "2020-01-17T05:00:12",
"Note": "Add note to app",
"UserID": 2222,
"UserName": "Natalia Donaldson"
}
],
"Source": [
{
"ScannerType": "DAST",
"Name": "IBMAPPSCANENTERPRISE",
"UuID": "IBMAPPSCANENTERPRISE"
}
],
"Critical": 0,
"Low": 15,
"TagCount": 1,
"Medium": 0,
"Description": null,
"ClientID": 747,
"GroupID": 7990,
"Tag": [
{
"Category": "Project",
"Updated": "2020-01-17T23:59:22",
"Name": "PCI Orch Test ",
"Created": "2020-01-17T23:59:22",
"Color": "#af3a29",
"ID": 234039,
"Description": "PCI Orch Test"
}
],
"Groups": [
{
"ID": 7990,
"Name": "Default Group"
}
],
"Ticket": [],
"Icon": [
{
"Type": "IBM_APP_SCANNER",
"OverlayText": null
}
],
"Info": 0,
"DiscoveredOn": "2019-06-12",
"HostID": null,
"Name": "https://freebirddemo.dev.ccs.thatcompany.net",
"NoteCount": 3,
"Uri": "https://freebirddemo.dev.ccs.thatcompany.net",
"GroupName": "Default Group",
"ID": 19394,
"CMDB": {
"MacAddress": null,
"SupportGroup": null,
"SysID": null,
"HipaaComplianceAsset": false,
"OperatingSystem": null,
"ManufacturedBy": null,
"ManagedBy": null,
"Location": null,
"OwnedBy": null,
"Model": null,
"LastScanDate": null,
"FerpaComplianceAsset": false,
"SupportedBy": null,
"PciComplianceAsset": false
},
"UrlCount": 15,
"High": 0,
"Href": "http://platform.risksense.com/api/v1/client/747/application/search?page=0&size=20&sort=id,asc",
"LastFoundOn": "2019-06-11",
"Total": 15
}
]
}
Human Readable Output
Client: The Demo Client
Group Details
Name: Default Group
Sources
Scanner(s): IBMAPPSCANENTERPRISE
Application Details
| Address | Name | Network Name | Network Type | Discovered On | Last Found On |
|---|---|---|---|---|---|
| https://freebirddemo.dev.ccs.thatcompany.net | https://freebirddemo.dev.ccs.thatcompany.net | App-data | IP | 2019-06-12 | 2019-06-11 |
Findings Distribution
| Total | Critical | High | Medium | Low | Info |
|---|---|---|---|---|---|
| 15 | 0 | 0 | 0 | 15 | 0 |
Tag(s) (1)
| Name | Category | Description | Created | Updated |
|---|---|---|---|---|
| PCI Orch Test | Project | PCI Orch Test | 2020-01-17T23:59:22 | 2020-01-17T23:59:22 |
Ticket(s) (0)
No entries.
8. risksense-apply-tag
Apply the new or existing tag to the asset, creates a new tag if it does not exist in RiskSense.
Base Command
risksense-apply-tag
Input
| Argument Name | Description | Required |
|---|---|---|
| tagname | Tag name which applies to the asset(s). | Required |
| assettype | Type of asset available in RiskSense to apply the tag. Apart from the available choices, you can provide the asset type supported by RiskSense API. | Required |
| propagate_to_all_findings | If the given argument is set to true, then it applies the tag to assets as well as findings of assets. Note - It only works if the tag with the given name does not exist. | Optional |
| fieldname | The RiskSense asset attribute by which to filter the assets to apply the tag. It can be an attribute of Host, Application, Host Finding, Application Finding. If specified, the ‘value’ argument is mandatory. | Optional |
| operator | The match operator should be applied for filtering the assets to apply the tag based on ‘fieldname’ and ‘value’. Can be ‘EXACT’ - filter records exactly matching the criteria; ‘IN’ - filter records matching any one of the comma-separated values; ‘LIKE’ - filter records with the value matching the specified pattern. All the records fieldname value contains the string provided in value; ‘BETWEEN’ - filter the records with fieldname value falling in the numerical/date range provided. This argument also accepts other operator values supported by the RiskSense API. Refer to the API documentation for the list of supported operators. | Optional |
| exclude | The exclude flag that determines whether to apply the tag on assets matches filter criteria or not. Default set to false. If set to true, tag applied on an asset not matching the specified values. | Optional |
| value | The value of the asset property mentioned in ‘fieldname’ to be considered for filter criteria. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| RiskSense.TagAssociation.TagName | String | Name of the tag. |
| RiskSense.TagAssociation.AssociationID | Number | Tag association ID. |
| RiskSense.TagAssociation.Created | String | The time when the tag was associated. |
Command Example
!risksense-apply-tag tagname="Test" assettype="host"
Context Example
{
"RiskSense.TagAssociation":
{
"AssociationID": 2542063,
"Created": "2020-04-29T08:46:54",
"TagName": "Test"
}
}
Human Readable Output
Test tag applied to given asset(s).
Configuration parameters
url— URL (required)api_key— API Key (required)client_name— Client Name (required)request_timeout— HTTP Request Timeout (Specify the time interval in seconds. All the RiskSense API calls would timeout if the response is not returned within the configured time interval).insecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (9)
-
risksense-apply-tagApply the new or existing tag to the asset, creates a new tag if it does not exist in RiskSense.
-
risksense-get-app-detailGets in-depth details of a single application. The command accepts an application ID as an argument.
-
risksense-get-appsLooks up the application details. The application details can be searched based on input parameters like fieldname (Name, Network, Address), operator (EXACT, IN, LIKE, BETWEEN), page, size, sort by and sort direction.
-
risksense-get-host-detailGets in-depth details of a single host. This command accepts either hostname or host ID as an argument.
-
risksense-get-host-finding-detailGets in-depth details of a single host finding. The command accepts the host finding ID as an argument.
-
risksense-get-host-findingsA detailed host finding view with the severity level. Displays vulnerability information like CVE, Threats associated with current findings and origin of findings.
-
risksense-get-hostsGets details of the supplied host. The host details can be searched based on input parameters like fieldname (Host Name, IP Address, Criticality, etc), operator (EXACT, IN, LIKE, BETWEEN), page, size, sort by and sort direction.
-
risksense-get-unique-cvesLooks up vulnerability details for the supplied host finding with its base score.
-
risksense-get-unique-open-findingsFinds unique open host findings.The open findings can be searched based on input parameters like fieldname (Severity, Title, Source etc), operator (EXACT, IN, LIKE, BETWEEN), page and size.
from CommonServerPython import * """ IMPORTS """ import urllib3 # Disable insecure warnings urllib3.disable_warnings() """ CONSTANTS """ RISKSENSE_FIELD_MAPPINGS = { "Total Findings": "findingsDistribution.total", "Critical Findings": "findingsDistribution.critical", "High Findings": "findingsDistribution.high", "Medium Findings": "findingsDistribution.medium", "Low Findings": "findingsDistribution.low", "Info Findings": "findingsDistribution.info", "Severity": "severity", "Id": "id", "ID": "id", "Source": "source", "Risk Rating": "riskRating", "Network Name": "network.name", "Address": "url", "Name": "name", "Network": "network.name", "Title": "titles", "IP Address": "ipAddress", "Host Name": "hostName", "Criticality": "criticality", "RS3": "rs3", "BETWEEN": "RANGE", "ascending": "ASC", "descending": "DESC", } REGEX_FOR_YYYY_MM_DD = r"^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$" REGEX_FOR_INR_OR_FLOAT = r"^\d+?(\.\d+)?$" """ CLIENT CLASS""" class Client(BaseClient): """ Client to use in integration with powerful http_request. It extends the base client and uses the http_request method for the API request. Handle some exceptions externally. """ def __init__(self, base_url, request_timeout, verify, proxy, headers): super().__init__(base_url, verify=verify, proxy=proxy, headers=headers) # type: ignore self.request_timeout = request_timeout def http_request( self, method, url_suffix, full_url=None, headers=None, auth=None, json_data=None, params=None, data=None, files=None, resp_type="custom", ok_codes=(200, 201, 400, 401, 404, 521, 403), ): """ Override http_request method from BaseClient class. :type method: ``str`` :param method: The HTTP method, for example: GET, POST, and so on. :type url_suffix: ``str`` :param url_suffix: The API endpoint. :type full_url: ``str`` :param full_url: Bypasses the use of self._base_url + url_suffix. This is useful if you need to make a request to an address outside of the scope of the integration API. :type headers: ``dict`` :param headers: Headers to send in the request. If None, will use self._headers. :type auth: ``tuple`` :param auth: The authorization tuple (usually username/password) to enable Basic/Digest/Custom HTTP Auth. if None, will use self._auth. :type params: ``dict`` :param params: URL parameters to specify the query. :type data: ``dict`` :param data: The data to send in a 'POST' request. :type json_data: ``dict`` :param json_data: The dictionary to send in a 'POST' request. :type files: ``dict`` :param files: The file data to send in a 'POST' request. :type resp_type: ``str`` :param resp_type: Determines which data format to return from the HTTP request. The default is 'json'. Other options are 'text', 'content', 'xml' or 'response'. Use 'response' to return the full response object. :type ok_codes: ``tuple`` :param ok_codes: The request codes to accept as OK, for example: (200, 201, 204). If you specify "None", will use self._ok_codes. :return: Depends on the resp_type parameter :rtype: ``dict`` or ``str`` or ``requests.Response`` """ resp = self._http_request( method, url_suffix, full_url, headers, auth, json_data, params, data, files, self.request_timeout, resp_type, ok_codes, proxies=handle_proxy(), ) status_code = resp.status_code if status_code != 200: if status_code == 400: error_msg = str(resp.json().get("errors", "")) demisto.debug(f"RiskSense API call failed: Bad Request. One or more argument(s) are invalid. Error: {error_msg}") raise ValueError("RiskSense API call failed: Bad Request. One or more argument(s) are invalid.") elif status_code == 401: raise ValueError("Unauthenticated. Check the API key configured.") elif status_code == 403: raise ValueError("Unauthorized. Check the permissions associated with API key configured.") elif status_code == 404: raise ValueError("No record(s) found.") # handling any server error elif status_code >= 500: raise ValueError("API call failed. Server error received.") else: resp.raise_for_status() return resp.json() """ HELPER FUNCTIONS """ def validate_arguments(args): """ Validate argument of the commands :param args: command arguments :return: True if arguments are valid else return error :rtype: bool """ size = args.get("size", "10") page = args.get("page", "0") sort_order = args.get("sort_direction", "ascending").lower() exclusive_operator = args.get("exclude", "False").lower() if sort_order not in ["ascending", "descending"]: raise ValueError("Sort_direction argument should be either Ascending or Descending.") if exclusive_operator not in ["true", "false"]: raise ValueError("Exclude argument should be either true or false.") if not str(size).isdigit() or int(size) == 0: raise ValueError("Size argument must be a non-zero positive number. Accepted values between 1-1000.") if not str(page).isdigit(): raise ValueError("Page argument must be positive number.") if int(size) > 1000: raise ValueError("Maximum size supported by RiskSense is 1000.") return True def get_client_detail_from_context(client): """ Initializes a RiskSense context and set list of client id and client name in it. Client id is fetched from the Demisto's integration context if client name matches. if not, make an API call and updates integration context. This way we can eliminate the number of repeated API calls by retrieving client id using client name. :param client: client class object. :return: client detail ({id:, name:}) """ integration_context = demisto.getIntegrationContext() client_name = demisto.params().get("client_name") for client_detail in integration_context.get("RiskSenseContext", []): if client_name == client_detail["ClientName"]: return client_detail # list client API call resp_json = client.http_request("GET", url_suffix="") client_id = None for client in resp_json.get("_embedded", {}).get("clients", []): if client["name"] == client_name: client_id = client["id"] # prepare integration context client_details = integration_context.get("RiskSenseContext", []) client_detail = {"ClientName": client_name, "Id": client_id} client_details.append(client_detail) demisto.setIntegrationContext({"RiskSenseContext": client_details}) return client_detail def prepare_filter_payload(args, projection=None): """ Prepare body (raw-json) for post API request. Used in 'risksense-get-hosts', 'risksense-get-host-findings', 'risksense-get-apps' and 'risksense-get-unique-open-findings' commands. :param args: Demisto argument provided by user :param projection: projection is used to get detail response or basic response from RiskSense. :return: data in json format :rtype ``dict`` :raises ValueError exception if required params are missing """ # Fetching value of arguments. fieldname = args.get("fieldname", "") operator = args.get("operator", "") exclusive_operator = args.get("exclude", "").lower() value = args.get("value", "") page = args.get("page") # defaultValue 0 size = args["size"] # defaultValue 10 sort_by = args["sort_by"] sort_order = args["sort_direction"].lower() # defaultValue asc data = {} # type: Dict[str, Any] filters = [] # type: List[Dict[str, Any]] sort_detail = [] # type: List[Dict[str, Any]] # If either of fieldname, value, operator or exculsive_operator are provided # then validate their required fields if fieldname or value or operator or exclusive_operator: if not fieldname: raise ValueError("fieldname is missing.") if not value: raise ValueError("value is missing.") if not operator: operator = "EXACT" if not exclusive_operator: exclusive_operator = "false" if operator in RISKSENSE_FIELD_MAPPINGS: operator = RISKSENSE_FIELD_MAPPINGS[operator] if fieldname in RISKSENSE_FIELD_MAPPINGS: fieldname = RISKSENSE_FIELD_MAPPINGS[fieldname] # Check validation of IP Address in case of operator = EXACT if fieldname == "ipAddress" and operator == "EXACT" and not is_ip_valid(value, True): raise ValueError("IP Address is invalid.") # Check validation of multiple values validate_values_for_between_operator(args) filters.append({"field": fieldname, "exclusive": exclusive_operator, "operator": operator, "value": value.lower()}) data["filters"] = filters # Adding sorting parameter in request API if sort_by and sort_order: if sort_by in RISKSENSE_FIELD_MAPPINGS: sort_by = RISKSENSE_FIELD_MAPPINGS[sort_by] sort_detail = [{"field": sort_by, "direction": RISKSENSE_FIELD_MAPPINGS[sort_order]}] data["projection"] = projection data["sort"] = sort_detail data["page"] = page data["size"] = size return data def add_filter_to_request(data, additional_fieldname, exclusive_operator, operator, value): """ Adding additional filter to API-request. :param data: prepared request :param additional_fieldname: fieldname is used to create an additional filter. :param exclusive_operator: exclusive_operator is used to create an additional filter. :param operator: operator is used to create additional filter. :param value: value is used to create additional filter. :return: dict """ filters = data.get("filters", []) filtr = {"field": additional_fieldname, "exclusive": exclusive_operator, "operator": operator, "value": value} filters.append(filtr) data["filters"] = filters return data def get_host_context(resp_host): """ Prepare host context data as per Demisto's standard. :param resp_host: response from host command. :return: Dictionary representing the Demisto standard host context. """ return { "ID": resp_host.get("id", ""), "Hostname": resp_host.get("hostName", ""), "IP": resp_host.get("ipAddress", ""), "OS": resp_host.get("operatingSystemScanner", {}).get("name", ""), } def get_host_hr(resp_host): """ Prepares human readable json for command 'risksense-get-hosts' command. :param resp_host: response from host command. :return: None """ owner = [ owner.get("value", "") for owner in resp_host.get("configurationManagementDB", []) if owner.get("key", "") == "owned_by" ] return { "ID": resp_host.get("id", ""), "RS3": resp_host.get("rs3", ""), "xRS3": resp_host.get("xRS3", ""), "Host Name": resp_host.get("hostName", ""), "Criticality": resp_host.get("criticality", ""), "IP Address": resp_host.get("ipAddress", ""), "Network": resp_host.get("network", {}).get("name", ""), "Group": len(resp_host.get("groups", [])), "Total Findings": resp_host.get("findingsDistribution", {}).get("total", {}).get("value", 0), "Critical Findings": resp_host.get("findingsDistribution", {}).get("critical", {}).get("value", 0), "High Findings": resp_host.get("findingsDistribution", {}).get("high", {}).get("value", 0), "Medium Findings": resp_host.get("findingsDistribution", {}).get("medium", {}).get("value", 0), "Low Findings": resp_host.get("findingsDistribution", {}).get("low", {}).get("value", 0), "Info Findings": resp_host.get("findingsDistribution", {}).get("info", {}).get("value", 0), "OS": resp_host.get("operatingSystemScanner", {}).get("name", ""), "Tags": len(resp_host.get("tags", [])), "Notes": len(resp_host.get("notes", [])), "Owner": owner[0] if len(owner) == 1 else ",".join(owner), "External": resp_host.get("external", ""), } def get_services(services): """ Get all services from the response and make the comma-separated string. :param services: List of services. :return: comma-separated list. """ return ", ".join(services) def get_risksense_host_context(href, resp_host): """ Prepare context data under RiskSense host. :param href: Reference link from host resp. :param resp_host: Response from host command. :return: None """ return { "ID": resp_host.get("id", ""), "ClientID": resp_host.get("clientId", ""), "GroupID": resp_host.get("group", {}).get("id", ""), "GroupName": resp_host.get("group", {}).get("name", ""), # Prepare Group details "Group": get_group_detail(resp_host.get("groups", [])), "Rs3": resp_host.get("rs3", ""), "Xrs3": resp_host.get("xRS3", ""), "Criticality": resp_host.get("criticality", ""), # Prepare Tag details "Tag": get_tag_details(resp_host.get("tags", [])), "NetworkID": resp_host.get("network", {}).get("id", ""), "NetworkName": resp_host.get("network", {}).get("name", ""), "NetworkType": resp_host.get("network", {}).get("type", ""), "DiscoveredOn": resp_host.get("discoveredOn", ""), "LastFoundOn": resp_host.get("lastFoundOn", ""), "LastScanTime": resp_host.get("lastScanTime", ""), "HostName": resp_host.get("hostName", ""), "IpAddress": resp_host.get("ipAddress", ""), # Prepare port numbers in comma separated format "PortNumbers": get_port_numbers(resp_host.get("ports", [])), "OS": { "Name": resp_host.get("operatingSystemScanner", {}).get("name", ""), "Family": resp_host.get("operatingSystemScanner", {}).get("family", ""), "Class": resp_host.get("operatingSystemScanner", {}).get("class", ""), "Vendor": resp_host.get("operatingSystemScanner", {}).get("vendor", ""), }, "CMDB": get_cmdb_detail(resp_host.get("configurationManagementDB", [])), "Services": get_services(resp_host.get("services", [])), "Note": get_note_detail(resp_host.get("notes", [])), "Source": get_source_detail(resp_host.get("sources", [])), "Ticket": get_ticket_detail(resp_host.get("tickets", [])), "LastVulnTrendingOn": resp_host.get("lastVulnTrendingOn", ""), "LastThreatTrendingOn": resp_host.get("lastThreatTrendingOn", ""), "OldestOpenFindingWithThreatDiscoveredOn": resp_host.get("oldestOpenFindingWithThreatDiscoveredOn", ""), "Xrs3date": resp_host.get("xRS3date", ""), "DiscoveredByRS": resp_host.get("discoveredByRS", False), "Href": href, "Total": resp_host.get("findingsDistribution", {}).get("total", {}).get("value", 0), "Critical": resp_host.get("findingsDistribution", {}).get("critical", {}).get("value", 0), "High": resp_host.get("findingsDistribution", {}).get("high", {}).get("value", 0), "Medium": resp_host.get("findingsDistribution", {}).get("medium", {}).get("value", 0), "Low": resp_host.get("findingsDistribution", {}).get("low", {}).get("value", 0), "Info": resp_host.get("findingsDistribution", {}).get("info", {}).get("value", 0), } def get_tag_details(tags): """ Iterate over tag detail from response. :param tags: Tags detail from the response. :return: List of tag elements that include required field from tag details. """ return [ { "ID": tag.get("id", ""), "Name": tag.get("name", ""), "Category": tag.get("category", ""), "Description": tag.get("description", ""), "Created": tag.get("created", ""), "Updated": tag.get("updated", ""), "Color": tag.get("color", ""), } for tag in tags ] def get_port_numbers(ports): """ Get all port number from response and make comma-separated string :param ports: Port portion from response. :return: Comma-separated port numbers. """ return ", ".join([str(port["number"]) for port in ports]) def get_cmdb_detail(cmdb_details): """ Iterate over CMDB details from response and convert them into RiskSense context. :param cmdb_details: CMDB details from response :return: List of CMDB elements which includes required fields from resp. """ return [ { "Order": cmdb_detail.get("order", ""), "Key": cmdb_detail.get("key", ""), "Value": cmdb_detail.get("value", ""), "Label": cmdb_detail.get("label", ""), } for cmdb_detail in cmdb_details ] def get_note_detail(notes): """ Iterate over note details from response and prepare RiskSense context. :param notes: note details from the response. :return: List of note elements that include required fields from resp. """ return [ { "UserID": note.get("user", {}).get("id", ""), "UserName": note.get("user", {}).get("name", ""), "Note": note.get("note", ""), "Date": note.get("date", ""), } for note in notes ] def get_source_detail(sources): """ Iterate over source details from response and prepare RiskSense context. :param sources: source details from response. :return: List of source details which includes required fields from resp. """ return [ {"Name": source.get("name", ""), "UuID": source.get("uuid", ""), "ScannerType": source.get("scannerType", "")} for source in sources ] def get_ticket_detail(tickets): """ Iterate over ticket details from response. :param tickets: ticket details from the response. :return: List of ticket details which include required fields from resp. """ return [ { "TicketNumber": ticket.get("ticketNumber", ""), "TicketStatus": ticket.get("ticketStatus", ""), "DeepLink": ticket.get("deepLink", ""), "Type": ticket.get("type", ""), "ConnectorName": ticket.get("connectorName", ""), "DetailedStatus": ticket.get("detailedStatus", ""), } for ticket in tickets ] def prepare_payload_for_detail_commands(args): """ Prepares body (raw-json) for post API request. Use in 'risksense-get-host-detail", "risksense-get-app-detail" and "risksense-get-host-finding-detail" commands. :param args: Demisto argument provided by user :return: data in json format :rtype ``dict`` :raises ValueError exception if args key are not defined. """ field = "" value = "" argument = {"host": "hostname", "host_id": "id", "application_id": "id", "hostfinding_id": "id"} for key, val in argument.items(): if key in args: value = args.get(key) field = val if not field: raise ValueError("Argument is mandatory.") # Check validation of multiple values if len(value.split(",")) > 1: raise ValueError("Multiple values are not supported by command.") filter_dict = {"field": field, "exclusive": False, "operator": "EXACT", "value": value} return {"filters": [filter_dict], "projection": "detail"} def get_findings_distribution_hr(findings_dict): """ Prepare findings distribution for human readable in 'risksense-get-host-detail' and 'risksense-get-app-detail' commands. :param findings_dict: Dictionary of finding distributions. :return: List containing finding distribution dictionary. """ return [ { "Total": findings_dict.get("total", {}).get("value", 0), "Critical": findings_dict.get("critical", {}).get("value", 0), "High": findings_dict.get("high", {}).get("value", 0), "Medium": findings_dict.get("medium", {}).get("value", 0), "Low": findings_dict.get("low", {}).get("value", 0), "Info": findings_dict.get("info", {}).get("value", 0), }, {}, ] # To present human readable horizontally def get_host_details_hr(host_dict): """ Prepare host detail dictionary for human readable in 'risksense-get-host-detail' command. :param host_dict: Dictionary containing host detail. :return: List containing host detail dictionary. """ return [ { "Name": host_dict.get("hostName", ""), "IP": host_dict.get("ipAddress", ""), "RS3": host_dict.get("rs3", ""), "Discovered On": host_dict.get("discoveredOn", ""), "Last Found On": host_dict.get("lastFoundOn", ""), }, {}, ] # To present human readable horizontally def get_operating_system_hr(os_dict): """ Prepare operating system detail for human readable in 'risksense-get-host-detail' command. :param os_dict: Dictionary containing operating system detail. :return: List containing operating system detail dictionary. """ return [ { "Name": os_dict.get("name", ""), "Vendor": os_dict.get("vendor", ""), "Class": os_dict.get("class", ""), "Family": os_dict.get("family", ""), }, {}, ] # To present human readable horizontally def get_tag_details_hr(tags): """ Iterate over tags list for human readable in 'risksense-get-host-detail', 'risksense-get-app-detail' commands. if only one record found it will add blank dictionary to list to display horizontally in table. :param tags: Tags detail from the response. :return: List of tag elements that include required field from tag details. """ tag_list = [ { "ID": tag.get("id", ""), "Name": tag.get("name", ""), "Category": tag.get("category", ""), "Description": tag.get("description", ""), "Created": tag.get("created", ""), "Updated": tag.get("updated", ""), } for tag in tags ] # To present human readable horizontally if len(tags) == 1: tag_list.append({}) return tag_list def get_source_detail_hr(sources): """ Iterate over source details from response. make comma-separated string from sources. :param sources: source details from response. :return: String of multiple source names. """ return ", ".join([source.get("name", "") for source in sources]) def get_ticket_detail_hr(tickets): """ Iterate over tickets list for human readable in 'risksense-get-host-detail' and 'risksense-get-app-detail' commands. if only one record found it will add blank dictionary to list to display horizontally in table. :param tickets: ticket details from the response. :return: List of ticket details which include required fields from resp. """ ticket_list = [ { "Ticket Number": ticket.get("ticketNumber", ""), "Ticket Status": ticket.get("ticketStatus", ""), "Deep Link": ticket.get("deepLink", ""), "Type": ticket.get("type", ""), "Connector Name": ticket.get("connectorName", ""), "Detailed Status": ticket.get("detailedStatus", ""), } for ticket in tickets ] # To present human readable horizontally if len(tickets) == 1: ticket_list.append({}) return ticket_list def get_host_detail_hr(host_detail_dict): """ Prepare human readable string for the 'risksense-get-host-detail' command. :param host_detail_dict: Dictionary of host detail. :return: String represent human readable output. """ hr = "### Group Details: " if host_detail_dict.get("group", {}).get("name", ""): hr += "\n Name: " + host_detail_dict.get("group", {}).get("name", "") else: hr += "\n No data." hr += "\n ### Sources:" if host_detail_dict.get("sources", []): hr += "\n Scanner(s): " + get_source_detail_hr(host_detail_dict.get("sources")) else: hr += "\n No data." hr += "\n ### Most Recently Identified Service(s): " if host_detail_dict.get("services", []): hr += "\n" + get_services(host_detail_dict.get("services")) + "\n" else: hr += "\n No data.\n" hr += tableToMarkdown( "Host Details:", get_host_details_hr(host_detail_dict), ["Name", "IP", "RS3", "Discovered On", "Last Found On"], removeNull=True, ) findings_distribution = get_findings_distribution_hr(host_detail_dict.get("findingsDistribution", {})) hr += "\n" + tableToMarkdown( "Findings Distribution:", findings_distribution, ["Total", "Critical", "High", "Medium", "Low", "Info"], removeNull=True ) hr += tableToMarkdown( "Operating System: ", get_operating_system_hr(host_detail_dict.get("operatingSystemScanner", {})), ["Name", "Vendor", "Class", "Family"], removeNull=True, ) hr += tableToMarkdown( "Tag(s) (" + str(len(host_detail_dict.get("tags", []))) + "):", get_tag_details_hr(host_detail_dict.get("tags", [])), ["Name", "Category", "Description", "Created", "Updated"], removeNull=True, ) hr += tableToMarkdown( "Ticket(s) (" + str(len(host_detail_dict.get("tickets", []))) + "):", get_ticket_detail_hr(host_detail_dict.get("tickets", [])), ["Ticket Number", "Ticket Status", "Deep Link", "Type", "Connector Name"], removeNull=True, ) return hr def prepare_unique_cves_payload(args): """ Prepare body (raw-json) for post API request. Used in "risksense-get-unique-cves" command. :param args: Demisto argument provided by user :return: data in json format :rtype ``dict`` """ request_data = {} # type: Dict[str, Any] value = args.get("hostFindingId") # Check validation of multiple value if len(value.split(",")) > 1: raise ValueError("Multiple values are not supported by this command.") request_data["filters"] = [{"field": "id", "operator": "EXACT", "value": value}] request_data["projection"] = "detail" request_data["page"] = 0 request_data["size"] = 10 return request_data def get_vulnerabilities_hr(vulnerability_list): """ Extract attributes for human readable from each vulnerabilities. Used in the 'risksense-get-unique-cves' command. :param vulnerability_list: List of vulnerabilities. :return: List represent vulnerabilities detail in human readable form. """ return [ { "Name": vuln_info_dict.get("cve", ""), "V2/Score": vuln_info_dict.get("baseScore", ""), "Attack Vector": vuln_info_dict.get("attackVector", ""), "Attack Complexity": vuln_info_dict.get("accessComplexity", ""), "Authentication": vuln_info_dict.get("authentication", ""), "Confidentiality Impact": vuln_info_dict.get("confidentialityImpact", ""), "Integrity Impact": vuln_info_dict.get("integrity", ""), "Availability Impact": vuln_info_dict.get("availabilityImpact", ""), "Summary": vuln_info_dict["summary"], } for vuln_info_dict in vulnerability_list ] def get_unique_cves_context(unique_cves_list, host_finding_id): """ Iterate over vulnerability list and extract attribute for context data. This method is used in 'risksense-get-unique-cves' command. :param unique_cves_list: List of vulnerabilities. :param host_finding_id: The unique host finding ID :return: None. """ return [ { "HostFindingID": host_finding_id, "Cve": unique_cves_dict.get("cve", ""), "BaseScore": unique_cves_dict.get("baseScore", ""), "ThreatCount": unique_cves_dict.get("threatCount", ""), "AttackVector": unique_cves_dict.get("attackVector", ""), "AccessComplexity": unique_cves_dict.get("accessComplexity", ""), "Authentication": unique_cves_dict.get("authentication", ""), "ConfidentialityImpact": unique_cves_dict.get("confidentialityImpact", ""), "Integrity": unique_cves_dict.get("integrity", ""), "AvailabilityImpact": unique_cves_dict.get("availabilityImpact", ""), "Trending": unique_cves_dict.get("trending", ""), "VulnLastTrendingOn": unique_cves_dict.get("vulnLastTrendingOn", ""), } for unique_cves_dict in unique_cves_list ] def get_unique_open_finding_context(unique_open_findings_dict, href): """ Prepare open findings dictionary for context data. This method is used in 'risksense-get-unique-open-findings' command. :param unique_open_findings_dict: Dictionary representing open host findings. :param href: hyperlink for page. :return: None. """ return { "Title": unique_open_findings_dict.get("title", ""), "Severity": unique_open_findings_dict.get("severity", ""), "HostCount": unique_open_findings_dict.get("hostCount", ""), "Source": unique_open_findings_dict.get("source", ""), "SourceID": unique_open_findings_dict.get("sourceId", ""), "Href": href, } def get_unique_open_finding_hr(unique_open_finding): """ Prepare open findings dictionary for human readable data. This method is used in 'risksense-get-unique-open-findings' command. :param unique_open_finding: Dictionary representing open host findings. :return: None. """ return { "Title": unique_open_finding.get("title", ""), "Severity": unique_open_finding.get("severity", ""), "Asset Count": unique_open_finding.get("hostCount", ""), "Source": unique_open_finding.get("source", ""), "Source ID": unique_open_finding.get("sourceId", ""), } def get_group_detail(groups): """ Iterate over group details from the response and retrieve details of groups. :param groups: list of group details from response :return: list of detailed element of groups :rtype: list """ return [{"ID": group.get("id", ""), "Name": group.get("name", "")} for group in groups] def get_port_detail(ports): """ Iterate over ports details from response and retrieve details of ports. :param ports: list of ports details from response :return: list of detailed element of ports :rtype: list """ return [{"ID": port.get("id", ""), "Number": port.get("number", "")} for port in ports] def get_host_detail(host): """ Retrieve host details from response. :param host: host details from response :return: host details :rtype: dict """ return { "Criticality": host.get("criticality", ""), "External": host.get("external", ""), "Port": get_port_detail(host.get("ports", [])), "Rs3": host.get("rs3", ""), } def get_network_detail(network): """ Retrieve network details from response. :param network: network details from response :return: network detail :rtype: dict """ return {"ID": network.get("id", ""), "Name": network.get("name", ""), "Type": network.get("type", "")} def get_assessment_detail(assessments): """ Iterate over assessments details from response and retrieve details from assessments. :param assessments: list of assessments from response :return: list of detailed elements of assessments :rtype: list """ return [ {"ID": assessment.get("id", ""), "Name": assessment.get("name", ""), "Date": assessment.get("date", "")} for assessment in assessments ] def get_vulnerability_detail(vulnerabilities): """ Iterate over vulnerabilities details from response and retrieve details related vulnerabilities. :param vulnerabilities: list of vulnerabilities from response :return: list of detailed elements of vulnerabilities :rtype: list """ return [ { "Cve": vulnerability.get("cve", ""), "BaseScore": vulnerability.get("baseScore", ""), "ThreatCount": vulnerability.get("threatCount", ""), "AttackVector": vulnerability.get("attackVector", ""), "AccessComplexity": vulnerability.get("accessComplexity", ""), "Authentication": vulnerability.get("authentication", ""), "ConfidentialityImpact": vulnerability.get("confidentialityImpact", ""), "Integrity": vulnerability.get("integrity", ""), "AvailabilityImpact": vulnerability.get("availabilityImpact", ""), "Trending": vulnerability.get("trending", ""), "VulnLastTrendingOn": vulnerability.get("vulnLastTrendingOn", ""), "Description": vulnerability.get("summary", ""), } for vulnerability in vulnerabilities ] def get_threat_detail(threats): """ Iterate over threat details from the response and retrieve details of threats. :param threats: list of threats from response :return: list of detailed elements of threats :rtype: list """ return [ { "Title": threat.get("title", ""), "Category": threat.get("category", ""), "Severity": threat.get("severity", ""), "Description": threat.get("description", ""), "Cve": threat.get("cves", []), "Source": threat.get("source", ""), "Published": threat.get("published", ""), "Updated": threat.get("updated", ""), "ThreatLastTrendingOn": threat.get("threatLastTrendingOn", ""), "Trending": threat.get("trending", ""), } for threat in threats ] def get_patch_detail(patches): """ Iterate over patch details from the response and retrieve details of the patch. :param patches: List of patch from response. :return: List of detailed elements of patch :rtype: list """ return [{"Name": patch.get("name", ""), "Url": patch.get("url", "")} for patch in patches] def get_tags_asset(tag_assets): """ Iterate over tag assets list from response and retrieve details of tag assets :param tag_assets: List of tag assets from response :return: List of detailed elements of tag assets :rtype: list """ return [ { "ID": tag_asset.get("id", ""), "Name": tag_asset.get("name", ""), "Category": tag_asset.get("category", ""), "Created": tag_asset.get("created", ""), "Updated": tag_asset.get("updated", ""), "Color": tag_asset.get("color", ""), "Description": tag_asset.get("description", ""), } for tag_asset in tag_assets ] def get_severity_detail(severity_detail): """ Retrieve details of severity related fields. :param severity_detail: severity details from response :return: severity detail :rtype: dict """ return { "Combined": severity_detail.get("combined", ""), "Overridden": severity_detail.get("overridden", ""), "Scanner": severity_detail.get("scanner", ""), "CvssV2": severity_detail.get("cvssV2", ""), "CvssV3": severity_detail.get("cvssV3", ""), "Aggregated": severity_detail.get("aggregated", ""), "State": severity_detail.get("state", ""), "StateName": severity_detail.get("stateName", ""), "ExpirationDate": severity_detail.get("expirationDate", ""), } def get_status_embeded_detail(status_embedded): """ Retrieve details of status related fields. :param status_embedded: status details from response :return: status detail :rtype: dict """ return { "State": status_embedded.get("state", ""), "StateName": status_embedded.get("stateName", ""), "StateDescription": status_embedded.get("stateDescription", ""), "Status": status_embedded.get("status", ""), "DurationInDays": status_embedded.get("durationInDays", ""), "DueDate": status_embedded.get("dueDate", ""), "ExpirationDate": status_embedded.get("expirationDate", ""), } def get_manual_finding_report_detail(manual_finding_reports): """ Iterate over manual finding report detail from response. :param manual_finding_reports: manual finding report detail from the response :return: List of manual finding report elements. """ return [ { "ID": manual_finding_report.get("id", ""), "Title": manual_finding_report.get("title", ""), "Label": manual_finding_report.get("label", ""), "Pii": manual_finding_report.get("pii", ""), "Source": manual_finding_report.get("source", ""), "IsManualExploit": manual_finding_report.get("isManualExploit", ""), "EaseOfExploit": manual_finding_report.get("easeOfExploit", ""), } for manual_finding_report in manual_finding_reports ] def get_assignment_detail(assignments): """ Iterate over assignments detail from response. :param assignments: assignments detail from response. :return: list of assignment elements. """ return [ { "ID": assignment.get("id", ""), "FirstName": assignment.get("firstName", ""), "LastName": assignment.get("lastName", ""), "ReceiveEmails": assignment.get("receiveEmails", ""), "Email": assignment.get("email", ""), "Username": assignment.get("username", ""), } for assignment in assignments ] def get_risksense_host_finding_context(resp_hostfinding): """ Prepare context data for "risksense-get-host-findings" and "risksense-get-host-finding-detail" command. :param resp_hostfinding: host finding response :return: list of host finding context """ return { "HostID": resp_hostfinding.get("host", {}).get("hostId", ""), "HostName": resp_hostfinding.get("host", {}).get("hostName", ""), "HostIpAddress": resp_hostfinding.get("host", {}).get("ipAddress", ""), "ID": resp_hostfinding.get("id", ""), "Source": resp_hostfinding.get("source", ""), "SourceID": resp_hostfinding.get("sourceId", ""), "Title": resp_hostfinding.get("title", ""), "Port": resp_hostfinding.get("port", ""), "GroupCount": len(resp_hostfinding.get("groups", [])), "Group": get_group_detail(resp_hostfinding.get("groups", [])), "Host": get_host_detail(resp_hostfinding.get("host", {})), "Network": get_network_detail(resp_hostfinding.get("network", {})), "Assessment": get_assessment_detail(resp_hostfinding.get("assessments", [])), "Vulnerability": get_vulnerability_detail(resp_hostfinding.get("vulnerabilities", {}).get("vulnInfoList", [])), "ThreatCount": len(resp_hostfinding.get("threats", {}).get("threats", [])), "Threat": get_threat_detail(resp_hostfinding.get("threats", {}).get("threats", [])), "Patch": get_patch_detail(resp_hostfinding.get("patches", [])), "TagCount": len(resp_hostfinding.get("tags", [])), "Tag": get_tag_details(resp_hostfinding.get("tags", [])), "TagAssetCount": len(resp_hostfinding.get("tagsAsset", [])), "TagAsset": get_tags_asset(resp_hostfinding.get("tagsAsset", [])), "Output": resp_hostfinding.get("output", ""), "Severity": resp_hostfinding.get("severity", ""), "SeverityDetail": get_severity_detail(resp_hostfinding.get("severityEmbedded", {})), "RiskRating": resp_hostfinding.get("riskRating", ""), "Xrs3Impact": resp_hostfinding.get("xrs3Impact", ""), "Xrs3ImpactOnCategory": resp_hostfinding.get("xrs3ImpactOnCategory", ""), "LastFoundOn": resp_hostfinding.get("lastFoundOn", ""), "DiscoveredOn": resp_hostfinding.get("discoveredOn", ""), "ResolvedOn": resp_hostfinding.get("resolvedOn", ""), "ScannerName": resp_hostfinding.get("scannerName", ""), "FindingType": resp_hostfinding.get("findingType", ""), "MachineID": resp_hostfinding.get("machineId", ""), "StatusEmbedded": get_status_embeded_detail(resp_hostfinding.get("statusEmbedded", {})), "ManualFindingReportCount": len(resp_hostfinding.get("manualFindingReports", [])), "ManualFindingReport": get_manual_finding_report_detail(resp_hostfinding.get("manualFindingReports", [])), "NoteCount": len(resp_hostfinding.get("notes", [])), "Note": get_note_detail(resp_hostfinding.get("notes", [])), "Assignment": get_assignment_detail(resp_hostfinding.get("assignments", [])), "Services": get_services(resp_hostfinding.get("services", [])), "Ticket": get_ticket_detail(resp_hostfinding.get("tickets", [])), "GroupID": resp_hostfinding.get("group", {}).get("id", ""), "GroupName": resp_hostfinding.get("group", {}).get("name", ""), } def get_assignee(assignments): """ Retrieve information if assignments and convert comma-separated string of firstName. :param assignments: assignment details from response. :return: comma-separated string """ return ", ".join([assignment["firstName"] for assignment in assignments]) def get_host_finding_hr(host_finding): """ Prepare json data for human-readable for host finding commands. :param host_finding: host finding details from response. :return: dict """ return { "ID": host_finding["id"], "Risk": host_finding.get("riskRating", ""), "Severity": host_finding.get("severity", ""), "Host Name": host_finding.get("host", {}).get("hostName", ""), "IP Address": host_finding.get("host", {}).get("ipAddress", ""), "Title": host_finding.get("title", ""), "Criticality": host_finding.get("host", {}).get("criticality", ""), "Groups": len(host_finding.get("groups", [])), "Port": host_finding.get("port", ""), "RS3": host_finding.get("host", {}).get("rs3", ""), "State": host_finding.get("statusEmbedded", {}).get("state", ""), "Assignments": get_assignee(host_finding.get("assignments", [])), "Manual Finding Report Count": len(host_finding.get("manualFindingReports", [])), "Threats": len(host_finding.get("threats", {}).get("threats", [])), "Tags": len(host_finding.get("tags", [])), "Asset Tags": len(host_finding.get("tagsAsset", [])), "Note": len(host_finding.get("notes", [])), } def get_icon_detail(icon_details): """ Iterate over icon details from response. This method is used in "risksense-get-apps" command. :param icon_details: Icon details from response. :return: List of required icon detail dictionary. """ return [ {"Type": icon_detail.get("type", ""), "OverlayText": icon_detail.get("overlayText", "")} for icon_detail in icon_details ] def get_cmdb_detail_apps(cmdb_detail): """ Iterate over CMDB details from response. This method is used in "risksense-get-apps" command. :param cmdb_detail: CMDB details from response :return: List of CMDB elements which includes required fields from resp. """ return { "ManufacturedBy": cmdb_detail.get("manufacturedBy", ""), "Model": cmdb_detail.get("model", ""), "MacAddress": cmdb_detail.get("macAddress", ""), "Location": cmdb_detail.get("location", ""), "ManagedBy": cmdb_detail.get("managedBy", ""), "OwnedBy": cmdb_detail.get("ownedBy", ""), "SupportedBy": cmdb_detail.get("supportedBy", ""), "SupportGroup": cmdb_detail.get("supportGroup", ""), "SysID": cmdb_detail.get("sysId", ""), "OperatingSystem": cmdb_detail.get("operatingSystem", ""), "LastScanDate": cmdb_detail.get("lastScanDate", ""), "FerpaComplianceAsset": cmdb_detail.get("ferpaComplianceAsset", ""), "HipaaComplianceAsset": cmdb_detail.get("hipaaComplianceAsset", ""), "PciComplianceAsset": cmdb_detail.get("pciComplianceAsset", ""), } def get_apps_context(apps_context, app_detail, href): """ Prepare context data for "risksense-get-apps" command. :param apps_context: List of host elements which is retrieved from response as context data. :param app_detail: response from apps command. :param href: hyperlink for page. :return: None """ apps_context_detail = { "ID": app_detail.get("id", ""), "GroupID": app_detail.get("group", {}).get("id", ""), "GroupName": app_detail.get("group", {}).get("name", ""), "Groups": get_group_detail(app_detail.get("groups", [])), "Network": get_network_detail(app_detail.get("network", {})), "ClientID": app_detail.get("clientId", ""), "HostID": app_detail.get("hostId", ""), "Uri": app_detail.get("uri", ""), "Name": app_detail.get("name", ""), "Description": app_detail.get("description", ""), "NoteCount": len(app_detail.get("notes", [])), "DiscoveredOn": app_detail.get("discoveredOn", ""), "LastFoundOn": app_detail.get("lastFoundOn", ""), "Total": app_detail.get("findingsDistribution", {}).get("total", {}).get("value", 0), "Critical": app_detail.get("findingsDistribution", {}).get("critical", {}).get("value", 0), "High": app_detail.get("findingsDistribution", {}).get("high", {}).get("value", 0), "Medium": app_detail.get("findingsDistribution", {}).get("medium", {}).get("value", 0), "Low": app_detail.get("findingsDistribution", {}).get("low", {}).get("value", 0), "Info": app_detail.get("findingsDistribution", {}).get("info", {}).get("value", 0), "Icon": get_icon_detail(app_detail.get("icons", [])), "TagCount": len(app_detail.get("tags", [])), "UrlCount": app_detail.get("urlCount", 0), "Href": href, "CMDB": get_cmdb_detail_apps(app_detail.get("configurationManagementDB", {})), "Ticket": get_ticket_detail(app_detail.get("tickets", [])), "Source": get_source_detail(app_detail.get("sources", [])), "Note": get_note_detail(app_detail.get("notes", [])), "Tag": get_tag_details(app_detail.get("tags", [])), } apps_context.append(apps_context_detail) def get_apps_hr(app_detail): """ Prepare human readable json for command 'risksense-get-apps' command. :param app_detail: response from host command. :return: None """ return { "ID": app_detail.get("id", ""), "Address": app_detail.get("uri", ""), "Name": app_detail.get("name", ""), "Network": app_detail.get("network", {}).get("name", ""), "Groups": len(app_detail.get("groups", [])), "URLs": app_detail.get("urlCount", 0), "Total Findings": app_detail.get("findingsDistribution", {}).get("total", {}).get("value", 0), "Critical Findings": app_detail.get("findingsDistribution", {}).get("critical", {}).get("value", 0), "High Findings": app_detail.get("findingsDistribution", {}).get("high", {}).get("value", 0), "Medium Findings": app_detail.get("findingsDistribution", {}).get("medium", {}).get("value", 0), "Low Findings": app_detail.get("findingsDistribution", {}).get("low", {}).get("value", 0), "Info Findings": app_detail.get("findingsDistribution", {}).get("info", {}).get("value", 0), "Tags": len(app_detail.get("tags", [])), "Notes": len(app_detail.get("notes", [])), } def get_host_finding_details_hr(host_finding_detail): """ Prepare human readable json for "risksense-get-host-finding-detail" command. Including basic details of host finding. :param host_finding_detail: host finding details from response :return: List of dict """ return [ { "Title": host_finding_detail.get("title", ""), "Host Name": host_finding_detail.get("host", {}).get("hostName", ""), "Ip Address": host_finding_detail.get("host", {}).get("ipAddress", ""), "Source": host_finding_detail.get("source", ""), "Network": host_finding_detail.get("network", {}).get("name", ""), "Risk Rating": host_finding_detail.get("riskRating", ""), }, {}, ] # To present human readable horizontally def get_host_finding_threat_hr(threats): """ Prepare human readable json for "risksense-get-host-finding-detail" command. Including threats details. :param threats: threats details from response :return: list of dict """ threats_list = [ { "Title": threat.get("title", ""), "Category": threat.get("category", ""), "Source": threat.get("source", ""), "CVEs": ", ".join(threat.get("cves", "")), "Published": threat.get("published", ""), "Updated": threat.get("updated", ""), } for threat in threats ] # To present human readable horizontally if len(threats) == 1: threats_list.append({}) return threats_list def get_host_finding_vulnerabilities_hr(vulnerabilities): """ Prepare human readable json for "risksense-get-host-finding-detail" command. Including vulnerabilities details. :param vulnerabilities: vulnerabilities details from response. :return: list of dict """ vulnerabilities_list = [ { "Name": vulnerability.get("cve", ""), "V2/Score": vulnerability.get("baseScore", ""), "Threat Count": vulnerability.get("threatCount", ""), "Attack Vector": vulnerability.get("attackVector", ""), "Access Complexity": vulnerability.get("accessComplexity", ""), "Authentication": vulnerability.get("authentication", ""), } for vulnerability in vulnerabilities ] # To present human readable horizontally if len(vulnerabilities) == 1: vulnerabilities_list.append({}) return vulnerabilities_list def get_host_finding_status_hr(status): """ Prepare human readable json for "risksense-get-host-finding-detail" command. Including status details. :param status: status details from response. :return: list of dict """ return [ { "State": status.get("state", ""), "Current State": status.get("stateName", ""), "Description": status.get("stateDescription", ""), "Duration": str(status.get("durationInDays", 0)) + " day(s)", "Due Date": status.get("dueDate", ""), "Resolved On": status.get("expirationDate", ""), }, {}, ] # To present human readable horizontally def get_manual_finding_report_detail_hr(manual_finding_report): """ Prepare human readable json for "risksense-get-host-finding-detail" command. including manual finding report details. :param manual_finding_report: manual finding report details from response. :return: list of dict """ manual_finding_reports_list = get_manual_finding_report_detail(manual_finding_report) # To present human readable horizontally if len(manual_finding_reports_list) == 1: manual_finding_reports_list.append({}) return manual_finding_reports_list def get_assessment_detail_hr(assessment_details): """ Prepare human readable json for "risksense-get-host-finding-detail" command. including assessment details. :param assessment_details: assessment details from response. :return: list of dict """ assessment_detail_list = get_assessment_detail(assessment_details) # To present human readable horizontally if len(assessment_detail_list) == 1: assessment_detail_list.append({}) return assessment_detail_list def get_host_finding_detail_hr(host_finding_detail): """ Prepare human readable json for "risksense-get-host-finding-detail" command. :param host_finding_detail: host finding details from response. :return: human readable string """ hr = "### Group Details: " + "\n" if host_finding_detail.get("group", {}).get("name", ""): hr += "Name: " + host_finding_detail["group"]["name"] + "\n" else: hr += "\n No data.\n" hr += tableToMarkdown( "Host Finding Details:", get_host_finding_details_hr(host_finding_detail), ["Host Name", "Ip Address", "Network", "Source", "Risk Rating", "Title"], removeNull=True, ) threats = host_finding_detail.get("threats", {}).get("threats", []) hr += "\n" + tableToMarkdown( "Threat(s) (" + str(len(threats)) + "):", get_host_finding_threat_hr(threats), ["Title", "Category", "Source", "CVEs", "Published", "Updated"], removeNull=True, ) vulnerabilities = host_finding_detail.get("vulnerabilities", {}).get("vulnInfoList", []) hr += "\n" + tableToMarkdown( "Vulnerabilities (" + str(len(vulnerabilities)) + "):", get_host_finding_vulnerabilities_hr(vulnerabilities), ["Name", "V2/Score", "Threat Count", "Attack Vector", "Access Complexity", "Authentication"], removeNull=True, ) status_detail = host_finding_detail.get("statusEmbedded", {}) hr += "\n" + tableToMarkdown( "Status:", get_host_finding_status_hr(status_detail), ["State", "Current State", "Description", "Duration", "Due Date", "Resolved On"], removeNull=True, ) tags = host_finding_detail.get("tags", []) hr += "\n" + tableToMarkdown( "Tag(s) (" + str(len(tags)) + "):", get_tag_details_hr(tags), ["Name", "Category", "Created", "Updated"], removeNull=True ) manual_report = host_finding_detail.get("manualFindingReports", []) hr += "\n" + tableToMarkdown( "Manual Finding Report(s) (" + str(len(manual_report)) + "):", get_manual_finding_report_detail_hr(manual_report), ["Title", "Label", "Pil", "Source"], removeNull=True, ) ticket_detail = host_finding_detail.get("tickets", []) hr += "\n" + tableToMarkdown( "Ticket(s) (" + str(len(ticket_detail)) + "):", get_ticket_detail_hr(ticket_detail), ["Ticket Number", "Ticket Status", "Deep Link", "Type", "Connector Name", "Detailed Status"], removeNull=True, ) assessment_detail = host_finding_detail.get("assessments", []) hr += "\n" + tableToMarkdown( "Assessment(s) (" + str(len(assessment_detail)) + "):", get_assessment_detail_hr(assessment_detail), ["Name", "Date"], removeNull=True, ) host_finding_description = host_finding_detail.get("description", "") if host_finding_description: hr += "\n" + "### Host Finding Description:" + "\n" + host_finding_description return hr def get_app_details_hr(app_dict): """ Prepare application detail dictionary for human readable in 'risksense-get-app-detail' command. :param app_dict: Dictionary containing application detail. :return: List containing application detail dictionary. """ return [ { "Address": app_dict.get("uri", ""), "Name": app_dict.get("name", ""), "Network Name": app_dict.get("network", {}).get("name", ""), "Network Type": app_dict.get("network", {}).get("type", ""), "Discovered On": app_dict.get("discoveredOn", ""), "Last Found On": app_dict.get("lastFoundOn", ""), }, {}, ] # To present human readable horizontally def get_app_detail_hr(app_detail_dict): """ Prepare human readable data for 'risksense-get-app-detail' command. :param app_detail_dict: Dictionary of application detail. :return: String represent human readable output. """ hr = "### Group Details: " if app_detail_dict.get("group", {}).get("name", ""): hr += "\n Name: " + app_detail_dict.get("group", {}).get("name", "") else: hr += "\n No data." hr += "\n ### Sources: " if app_detail_dict.get("sources", []): hr += "\n Scanner(s): " + get_source_detail_hr(app_detail_dict.get("sources", [])) + "\n" else: hr += "\n No data.\n" hr += tableToMarkdown( "Application Details:", get_app_details_hr(app_detail_dict), ["Address", "Name", "Network Name", "Network Type", "Discovered On", "Last Found On"], removeNull=True, ) findings_distribution = get_findings_distribution_hr(app_detail_dict.get("findingsDistribution", {})) hr += "\n" + tableToMarkdown( "Findings Distribution:", findings_distribution, ["Total", "Critical", "High", "Medium", "Low", "Info"], removeNull=True ) hr += tableToMarkdown( "Tag(s) (" + str(len(app_detail_dict.get("tags", []))) + "):", get_tag_details_hr(app_detail_dict.get("tags", [])), ["Name", "Category", "Description", "Created", "Updated"], removeNull=True, ) hr += tableToMarkdown( "Ticket(s) (" + str(len(app_detail_dict.get("tickets", []))) + "):", get_ticket_detail_hr(app_detail_dict.get("tickets", [])), ["Ticket Number", "Ticket Status", "Deep Link", "Type", "Connector Name"], removeNull=True, ) app_description = app_detail_dict.get("description", "") if app_description: hr += "\n ### Application Description:" + "\n" + app_description return hr def get_request_timeout(): """ Validate and return the request timeout parameter. The parameter must be a positive integer. Default value is set to 60 seconds for API request timeout. :params req_timeout: Request timeout value. :return: boolean """ try: request_timeout = int(demisto.params().get("request_timeout")) if request_timeout <= 0: raise ValueError return request_timeout except ValueError: raise ValueError("HTTP Request Timeout parameter must be a positive integer.") def get_self_link(resp): """ Retrieve self link from response. :param resp: JSON response :return: self link """ return resp.get("_links", {}).get("self", {}).get("href", "") def fetch_page_details(resp): """ Parse total element, page number and total pages from the page. :param resp: json response. :return: page details. """ total_element = resp.get("page", {}).get("totalElements", 0) page_number = resp.get("page", {}).get("number", 0) total_pages = resp.get("page", {}).get("totalPages", 0) return page_number, total_element, total_pages def get_cve_context(cve_list): """ Prepare CVE context data as per the Demisto standard. :param cve_list: cve list from response. :return: List of cves dictionary representing the Demisto standard context. """ return [ {"ID": cve_dict.get("cve", ""), "CVSS": cve_dict.get("baseScore", ""), "Description": cve_dict.get("summary", "")} for cve_dict in cve_list ] def get_ticket_context(ticket_list): """ Prepare ticket context data as per the Demisto standard. :param ticket_list: ticket list from response. :return: List of ticket dictionary representing the Demisto standard context. """ return [ {"ID": ticket_dict.get("ticketNumber", ""), "State": ticket_dict.get("ticketStatus", "")} for ticket_dict in ticket_list ] def get_host_context_for_host_finding(resp_host): """ Prepare host context data as per the Demisto standard. :param resp_host: response from host command. :return: Dictionary representing the Demisto standard host context. """ return { "ID": resp_host.get("hostId", ""), "Hostname": resp_host.get("hostName", ""), "IP": resp_host.get("ipAddress", ""), } def validate_values_for_between_operator(args): """ Validate value of BETWEEN operator :param args: Demisto arguments provided by user :return: """ operator = args.get("operator", "") value = args.get("value", "") if operator == "BETWEEN": values = value.split(",") if len(values) != 2: raise ValueError("BETWEEN operator requires exact two values.") if not ( bool(re.match(REGEX_FOR_INR_OR_FLOAT, values[0])) and bool(re.match(REGEX_FOR_INR_OR_FLOAT, values[1])) or bool(re.match(REGEX_FOR_YYYY_MM_DD, values[0])) and bool(re.match(REGEX_FOR_YYYY_MM_DD, values[1])) ): raise ValueError("Value must be in number format or YYYY-MM-DD date format for BETWEEN operator.") def get_user_id_from_integration_context(client): """ Initializes a RiskSense context and set user id in context. User id is fetched from the Demisto's integration context is available otherwise, make an API call and updates integration context. :param client: client class object. :return: user id """ integration_context = demisto.getIntegrationContext() user_id = integration_context.get("RiskSenseUserContext", {}).get("userId", "") if not user_id: url = client._base_url url = url.replace("/client", "/user/profile") resp_json = client.http_request("GET", url_suffix="", full_url=url) if resp_json.get("userId", ""): user_id = resp_json.get("userId", "") else: raise ValueError("Unable to find user Id.") demisto.setIntegrationContext({"RiskSenseUserContext": {"userId": user_id}}) return user_id def prepare_payload_for_create_tag(tag_name, client, propagate_to_all_findings): """ Prepare request body (raw-json) to create tag in RiskSense. :param tag_name: The name of the tag. :param client: Client class object. :param propagate_to_all_findings: If the given argument is set to true, then it applies the tag to assets as well as findings of assets. :return: data in json format :rtype ``dict`` """ return { "fields": [ {"uid": "TAG_TYPE", "value": "CUSTOM"}, {"uid": "NAME", "value": tag_name}, {"uid": "DESCRIPTION", "value": "Tag Created for " + tag_name}, {"uid": "OWNER", "value": get_user_id_from_integration_context(client)}, {"uid": "COLOR", "value": "#648d9f"}, {"uid": "PROPAGATE_TO_ALL_FINDINGS", "value": propagate_to_all_findings}, ] } def create_tag(tag_name, client_id, client, propagate_to_all_findings): """ Create the tag with given tag name. :param tag_name: name of the tag. :param client_id: Client id. :param client: Client class object. :param propagate_to_all_findings: If the given argument is set to true, then it applies the tag to assets as well as findings of assets. :return: Tag Id """ url_suffix = "/" + str(client_id) + "/tag" data = prepare_payload_for_create_tag(tag_name, client, propagate_to_all_findings) resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) tag_id = resp.get("id", "") return tag_id if tag_id else None def search_tag_id(tag_name, client_id, client): """ Search tag in RiskSense tag API. If available then return tagID. :param tag_name: name of the tag to search. :param client_id: Client id. :param client: Client class object. """ url_suffix = "/" + str(client_id) + "/tag/search" # Tag search payload filter_dict = {"field": "name", "exclusive": False, "operator": "EXACT", "value": tag_name} data = {"filters": [filter_dict], "projection": "basic"} # Only projection basic is supported. # Request search tag API resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) tags = resp.get("_embedded", {}).get("tags", []) if tags: return tags[0].get("id") return None def prepare_request_payload_for_tag(args, tag_id): """ Prepare body (raw-json) for post API request. Used in 'risksense-apply-tag' command. :param args: Demisto argument provided by user :param tag_id: The id of the tag. :return: data in json format :rtype ``dict`` :raises ValueError exception if required params are missing """ # Fetching value of arguments. fieldname = args.get("fieldname", "") operator = args.get("operator", "") exclusive_operator = args.get("exclude", "").lower() value = args.get("value", "") filter_data = {} # type: Dict[str, Any] filters = [] # type: List[Dict[str, Any]] data = {} # type: Dict[str, Any] # If either of fieldname, value, operator or exculsive_operator are provided # then validate their required fields if fieldname or value or operator or exclusive_operator: if not fieldname: raise ValueError("fieldname is missing.") if not value: raise ValueError("value is missing.") if not operator: operator = "EXACT" if not exclusive_operator: exclusive_operator = "false" if operator in RISKSENSE_FIELD_MAPPINGS: operator = RISKSENSE_FIELD_MAPPINGS[operator] if fieldname in RISKSENSE_FIELD_MAPPINGS: fieldname = RISKSENSE_FIELD_MAPPINGS[fieldname] # Check validation of IP Address in case of operator = EXACT if fieldname == "ipAddress" and operator == "EXACT" and not is_ip_valid(value, True): raise ValueError("IP Address is invalid.") # Check validation of between operator. validate_values_for_between_operator(args) filters.append({"field": fieldname, "exclusive": exclusive_operator, "operator": operator, "value": value.lower()}) filter_data["filters"] = filters data["filterRequest"] = filter_data data["isRemove"] = False data["tagId"] = tag_id return data def get_apply_tag_context(resp, tag_name): """ Prepare context for apply tag command. :param resp: response. :param tag_name: Name of the tag. :return: Dictionary of tag context. """ return {"AssociationID": resp.get("id", ""), "Created": resp.get("created", ""), "TagName": tag_name} """ REQUESTS FUNCTIONS """ def test_module(client): """ Performs basic GET request :param client: client object. :return: None """ client_name = demisto.params().get("client_name", "-") try: resp_json = client.http_request("GET", url_suffix="") except DemistoException: raise ValueError("Test connectivity failed. Check the configuration parameters provided.") clients = resp_json.get("_embedded", {}).get("clients", []) # Verifying client name mentioned in integration configuration if not any(client_info.get("name", "") == client_name for client_info in clients): raise ValueError("Invalid client name configured.") demisto.results("ok") def get_hosts_command(client, args): """ Retrieve information about host(s) based on arguments. Perform sorting based on argument. By default, it will sort by 'rs3' field. :param client: client object :param args: filter criteria provided by user. :return: standard output. """ # validate command arguments validate_arguments(args) # gather client detail from integration context client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/host/search" # Prepares filter request body data = prepare_filter_payload(args, "detail") resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) page_number, total_element, total_pages = fetch_page_details(resp) if total_element == 0: return "No host(s) found for the given argument.", {}, {} if page_number >= total_pages: raise ValueError("Invalid page navigation.") resp_list_host = resp.get("_embedded", {}).get("hosts", []) href = get_self_link(resp) ec = {} # type: Dict[str, Any] hr = "" if resp and "_embedded" in resp: host_context = [] # type: List[Dict[str, Any]] host_ticket_context = [] # type: List[Dict[str, Any]] risksense_host_context = [] # type: List[Dict[str, Any]] host_details_hr = [] # type: List[Dict[str, Any]] hr += "### Total hosts found: " + str(total_element) + "\t\t" hr += "Page: " + str(page_number) + "/" + str(total_pages - 1) + "\t\t" hr += "Client: " + client_name + "\n" for resp_host in resp_list_host: # creating hr host_details_hr.append(get_host_hr(resp_host)) # creating Demisto's standard host context host_context.append(get_host_context(resp_host)) # creating Demisto's standard ticket context host_ticket_context.extend(get_ticket_context(resp_host.get("tickets", []))) # creating RiskSense context risksense_host_context.append(get_risksense_host_context(href, resp_host)) hr += tableToMarkdown( "RiskSense host(s) details:", host_details_hr, [ "RS3", "Host Name", "Total Findings", "Critical Findings", "High Findings", "Medium Findings", "Low Findings", "Info Findings", "Owner", "ID", "OS", "Tags", "Notes", "xRS3", "Criticality", "IP Address", "Network", "Group", "External", ], removeNull=True, ) ec = {"Host(val.ID == obj.ID)": host_context, "RiskSense.Host(val.ID == obj.ID)": risksense_host_context} if host_ticket_context: ec["Ticket(val.ID == obj.ID)"] = host_ticket_context else: hr += "No host(s) found for given argument." return hr, ec, resp def get_host_detail_command(client, args): """ Retrieve information about particular host based on host name or host id. :param client: client object :param args: Demisto argument provided by user. :return: standard output. """ data = prepare_payload_for_detail_commands(args) client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/host/search" resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) if resp.get("page", {}).get("totalElements") == 0: return "No host detail found for the given argument.", {}, {} hr = "" ec = {} # type: Dict[str, Any] if resp and "_embedded" in resp: host_context = [] # type: List[Dict[str, Any]] risksense_host_context = [] # type: List[Dict[str, Any]] host_ticket_context = [] # type: List[Dict[str, Any]] host_detail_dict = resp.get("_embedded", {}).get("hosts")[0] href = get_self_link(resp) # Human readable. hr += "### Client: " + client_name + "\n" hr += get_host_detail_hr(host_detail_dict) # standard context. host_context.append(get_host_context(host_detail_dict)) # creating Demisto's standard ticket context host_ticket_context.extend(get_ticket_context(host_detail_dict.get("tickets", []))) risksense_host_context.append(get_risksense_host_context(href, host_detail_dict)) ec = {"Host(val.ID == obj.ID)": host_context, "RiskSense.Host(val.ID == obj.ID)": risksense_host_context} if host_ticket_context: ec["Ticket(val.ID == obj.ID)"] = host_ticket_context else: hr += "No host detail found for given argument." return hr, ec, resp def get_unique_cves_command(client, args): """ Retrieve unique CVEs that contains vulnerabilities based on hostfinding_id. :param client: client object :param args: Demisto argument provided by user. :return: standard output. """ client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/hostFinding/search" data = prepare_unique_cves_payload(args) resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) if resp.get("page", {}).get("totalElements") == 0: return "No unique cves found for the given argument.", {}, {} hr = "" ec = {} # type: Dict[str, Any] if resp and "_embedded" in resp: host_findings = resp.get("_embedded", {}).get("hostFindings", []) host_findings_context = [] # type: List[Dict[str, Any]] host_finding_cve_context = [] # type: List[Dict[str, Any]] for host_finding in host_findings: vulnerabilities = host_finding.get("vulnerabilities", {}).get("vulnInfoList", []) if len(vulnerabilities) == 0: return "No vulnerabilities found for the given argument.", {}, {} # Human readable. hr += "### Client: " + client_name + "\n" hr += tableToMarkdown( "Vulnerabilities found:", get_vulnerabilities_hr(vulnerabilities), [ "Name", "V2/Score", "Attack Vector", "Attack Complexity", "Authentication", "Confidentiality Impact", "Integrity Impact", "Availability Impact", "Summary", ], removeNull=True, ) # Prepare context data host_findings_context.extend(get_unique_cves_context(vulnerabilities, args.get("hostFindingId", ""))) # creating Demisto's standard CVE context host_finding_cve_context.extend(get_cve_context(vulnerabilities)) ec = { "RiskSense.UniqueVulnerabilities(val.Cve == obj.Cve && val.HostFindingID == obj.HostFindingID)": host_findings_context } if host_finding_cve_context: ec[outputPaths["cve"]] = host_finding_cve_context else: hr += "No Vulnerabilities found for a given argument." return hr, ec, resp def get_host_findings_command(client, args): """ Retrieves information about host findings based on arguments. Finding status can be 'Open' or 'Closed'.By default return all host findings. :param client: Object of client class :param args: Demisto arguments provided by user :return: Standard output """ # validate command arguments validate_arguments(args) client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/hostFinding/search" # Status of host findings status = args.get("status", "") data = prepare_filter_payload(args, "detail") if status: # adding additional filters data = add_filter_to_request(data, "generic_state", "false", "EXACT", status) # making final API call resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) page_number, total_element, total_pages = fetch_page_details(resp) if total_element == 0: return "No host finding(s) found for given argument(s).", {}, {} if page_number >= total_pages: raise ValueError("Invalid page navigation.") ec = {} # type: Dict[str, Any] hr = "" if resp and "_embedded" in resp: resp_list_hostfinding = resp.get("_embedded", {}).get("hostFindings", []) host_finding_details_hr = [] # type: List[Dict[str, Any]] risksense_host_finding_context = [] # type: List[Dict[str, Any]] host_finding_ticket_context = [] # type: List[Dict[str, Any]] host_finding_cve_context = [] # type: List[Dict[str, Any]] host_context = [] # type: List[Dict[str, Any]] for resp_hostfinding in resp_list_hostfinding: host_finding_details_hr.append(get_host_finding_hr(resp_hostfinding)) risksense_host_finding_context.append(get_risksense_host_finding_context(resp_hostfinding)) # creating Demisto's standard host context host_context.append(get_host_context_for_host_finding(resp_hostfinding.get("host", {}))) # creating Demisto's standard ticket context host_finding_ticket_context.extend(get_ticket_context(resp_hostfinding.get("tickets", []))) # creating Demisto's standard CVE context host_finding_cve_context.extend(get_cve_context(resp_hostfinding.get("vulnerabilities", {}).get("vulnInfoList", []))) # human Readable hr += ( "### Total " + status.lower() + " host findings: " + str(total_element) if status else "### Total host findings: " + str(total_element) ) hr += "\t\t Page: " + str(page_number) + "/" + str(total_pages - 1) hr += "\t\t Client: " + client_name hr += "\n" + tableToMarkdown( status.capitalize() + " host finding(s) details:" if status else "Host finding(s) details:", host_finding_details_hr, [ "ID", "Host Name", "IP Address", "Title", "Risk", "Threats", "RS3", "Criticality", "Severity", "Groups", "Port", "State", "Assignments", "Tags", "Asset Tags", "Note", "Manual Finding Report Count", ], removeNull=True, ) # context data ec = {"RiskSense.HostFinding(val.ID == obj.ID)": risksense_host_finding_context, "Host(val.ID == obj.ID)": host_context} if host_finding_ticket_context: ec["Ticket(val.ID == obj.ID)"] = host_finding_ticket_context if host_finding_cve_context: ec[outputPaths["cve"]] = host_finding_cve_context else: hr += "No host finding(s) found for given argument(s)." return hr, ec, resp def get_unique_open_findings_command(client, args): """ Retrieve information about open host findings based on arguments. Perform sorting based on argument. By default, it will sort by 'severity' field. :param client: client object :param args: demisto argument provided by user. :return: standard output. """ # validate command arguments validate_arguments(args) client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/uniqueHostFinding/search" projection = "basic" if args.get("fieldname", "") == "Title": args["fieldname"] = "title" if args.get("sort_by", "") == "Title": args["sort_by"] = "title" # preparing request payload data = prepare_filter_payload(args, projection) resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) page_number, total_element, total_pages = fetch_page_details(resp) if total_element == 0: return "No unique open finding(s) found for the given argument(s).", {}, {} if page_number >= total_pages: raise ValueError("Invalid page navigation.") unique_open_finding_context = [] # type: List[Dict[str, Any]] unique_open_finding_hr = [] # type: List[Dict[str, Any]] ec = {} # type: Dict[str, Any] hr = "" if resp and "_embedded" in resp: unique_open_finding_list = resp.get("_embedded", {}).get("uniqueHostFindings", []) href = get_self_link(resp) for unique_open_finding in unique_open_finding_list: # context unique_open_finding_context.append(get_unique_open_finding_context(unique_open_finding, href)) # Human Readable unique_open_finding_hr.append(get_unique_open_finding_hr(unique_open_finding)) hr += "### Total unique open findings: " + str(total_element) hr += "\t\t Page: " + str(page_number) + "/" + str(total_pages - 1) hr += "\t\t Client: " + client_name + "\n" hr += tableToMarkdown( "Unique open finding(s) details:", unique_open_finding_hr, ["Title", "Severity", "Asset Count", "Source", "Source ID"], removeNull=True, ) ec = {"RiskSense.UniqueHostFinding": unique_open_finding_context} else: hr += "No unique open finding(s) found for given argument(s)." return hr, ec, resp def get_apps_command(client, args): """ Retrieve information about applications based on arguments. Perform sorting based on argument. By default, it will sort by 'Name' field. :param client: Client object :param args: Demisto argument(s) provided by user. :return: standard output. """ # validate command arguments validate_arguments(args) client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/application/search" projection = "detail" data = prepare_filter_payload(args, projection) resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) apps_context = [] # type: List[Dict[str, Any]] apps_hr = [] # type: List[Dict[str, Any]] ec = {} # type: Dict[str, Any] hr = "" page_number, total_element, total_pages = fetch_page_details(resp) if total_element == 0: return "No application(s) found for the given arguments.", {}, {} if page_number >= total_pages: raise ValueError("Invalid page navigation.") if resp and "_embedded" in resp: href = get_self_link(resp) apps_list = resp.get("_embedded", {}).get("applications", []) app_ticket_context = [] # type: List[Dict[str, Any]] for app in apps_list: # Context get_apps_context(apps_context, app, href) # creating Demisto's standard ticket context app_ticket_context.extend(get_ticket_context(app.get("tickets", []))) # Human Readable apps_hr.append(get_apps_hr(app)) hr += "### Total applications: " + str(total_element) + "\t\t" hr += "Page: " + str(page_number) + "/" + str(total_pages - 1) hr += "\t\tClient: " + client_name + "\n" hr += tableToMarkdown( "RiskSense application(s) details:", apps_hr, [ "ID", "Address", "Name", "Network", "Total Findings", "Critical Findings", "High Findings", "Medium Findings", "Low Findings", "Info Findings", "Groups", "URLs", "Tags", "Notes", ], removeNull=True, ) ec = {"RiskSense.Application(val.ID == obj.ID)": apps_context} if app_ticket_context: ec["Ticket(val.ID == obj.ID)"] = app_ticket_context else: hr += "No application(s) found for given argument." return hr, ec, resp def get_host_finding_detail_command(client, args): """ Retrieve information about particular host finding based on host finding id. :param client: object of client :param args: Demisto arguments provided by the user :return: command output """ client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/hostFinding/search" data = prepare_payload_for_detail_commands(args) resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) total_element = resp.get("page", {}).get("totalElements", "") if total_element == 0: return "No host finding details found for the given argument.", {}, {} ec = {} # type: Dict[str, Any] hr = "" if resp and "_embedded" in resp: host_finding_detail = resp.get("_embedded", {}).get("hostFindings", "")[0] host_finding_ticket_context = [] # type: List[Dict[str, Any]] host_finding_cve_context = [] # type: List[Dict[str, Any]] host_context = [] # type: List[Dict[str, Any]] risksense_host_finding_context = [get_risksense_host_finding_context(host_finding_detail)] # type: List[Dict[str, Any]] # creating Demisto's standard host context host_context.append(get_host_context_for_host_finding(host_finding_detail.get("host", {}))) # creating Demisto's standard ticket context host_finding_ticket_context.extend(get_ticket_context(host_finding_detail.get("tickets", []))) # creating Demisto's standard CVE context host_finding_cve_context.extend(get_cve_context(host_finding_detail.get("vulnerabilities", {}).get("vulnInfoList", []))) # Human Readable. hr += "### Client: " + client_name + "\n" hr += get_host_finding_detail_hr(host_finding_detail) # context. ec = {"RiskSense.HostFinding(val.ID == obj.ID)": risksense_host_finding_context, "Host(val.ID == obj.ID)": host_context} if host_finding_ticket_context: ec["Ticket(val.ID == obj.ID)"] = host_finding_ticket_context if host_finding_cve_context: ec[outputPaths["cve"]] = host_finding_cve_context else: hr += "No host finding details found for given argument." return hr, ec, resp def get_app_detail_command(client, args): """ Retrieve information about particular application based on application id. :param client: client object :param args: demisto argument provided by user. :return: command output. """ data = prepare_payload_for_detail_commands(args) client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] client_name = client_detail["ClientName"] url_suffix = "/" + str(client_id) + "/application/search" resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) hr = "" ec = {} # type: Dict[str, Any] if resp.get("page", {}).get("totalElements") == 0: return "No application detail found for the given argument.", {}, {} if resp and "_embedded" in resp: app_detail_context = [] # type: List[Dict[str, Any]] app_ticket_context = [] # type: List[Dict[str, Any]] app_detail_dict = resp.get("_embedded", {}).get("applications")[0] href = get_self_link(resp) # Human readable. hr += "### Client: " + client_name + "\n" hr += get_app_detail_hr(app_detail_dict) # Context. get_apps_context(app_detail_context, app_detail_dict, href) # creating Demisto's standard ticket context app_ticket_context.extend(get_ticket_context(app_detail_dict.get("tickets", []))) ec = {"RiskSense.Application(val.ID == obj.ID)": app_detail_context} if app_ticket_context: ec["Ticket(val.ID == obj.ID)"] = app_ticket_context else: hr += "No application detail found for given argument." return hr, ec, resp def apply_tag_command(client, args): """ Apply new or existing tag to asset, creates a new tag if it does not exist in RiskSense. :param client: client object :param args: demisto argument provided by user. :return: command output. """ client_detail = get_client_detail_from_context(client) client_id = client_detail["Id"] asset_type = args.get("assettype", "") url_suffix = "/" + str(client_id) + "/" + asset_type + "/tag" tag_name = args.get("tagname", "") propagate_to_all_findings = args.get("propagate_to_all_findings", "false") if args.get("exclude", "false").lower() not in ["true", "false"]: raise ValueError("Exclude argument should be either true or false.") if propagate_to_all_findings.lower() not in ["true", "false"]: raise ValueError("Value of propagate_to_all_findings argument should be either true or false.") # Check special character in tag name. if bool(re.match(r"[`*+=\\.;,\'\"@!#$%^&*()<>?/\|}{\]\[~]", tag_name)): raise ValueError("No special characters are allowed in the tag name.") # Check tag name length. if len(tag_name) < 2: raise ValueError("Tag name must be at least 2 characters.") tag_id = search_tag_id(tag_name, client_id, client) hr = "" ec = {} # type: Dict[str, Any] if not tag_id: tag_id = create_tag(tag_name, client_id, client, propagate_to_all_findings) if not tag_id: raise ValueError("Unable to Create tag.") data = prepare_request_payload_for_tag(args, tag_id) resp = client.http_request("POST", url_suffix=url_suffix, json_data=data) if resp: # Human Readable hr += "### " + tag_name + " tag applied to given asset(s)." # Context. ec = {"RiskSense.TagAssociation(val.AssociationID == obj.AssociationID)": get_apply_tag_context(resp, tag_name)} else: hr += "### Unable to apply tag." return hr, ec, resp """ COMMANDS MANAGER / SWITCH PANEL """ def main(): """ PARSE AND VALIDATE INTEGRATION PARAMS """ params = demisto.params() api_key = params.get("api_key") # Service base URL base_url = urljoin(params["url"], "/api/v1/client") # Request timeout request_timeout = get_request_timeout() # Should we use SSL use_ssl = not params.get("insecure", False) # Should we use system proxy settings use_proxy = params.get("proxy") # Headers to be sent in requests headers = {"x-api-key": api_key, "Content-Type": "application/json", "Accept": "application/json"} # Initialize Client object client = Client(base_url, request_timeout, verify=use_ssl, proxy=use_proxy, headers=headers) command = demisto.command() # Commands dict commands = { "risksense-get-hosts": get_hosts_command, "risksense-get-host-detail": get_host_detail_command, "risksense-get-unique-cves": get_unique_cves_command, "risksense-get-host-findings": get_host_findings_command, "risksense-get-unique-open-findings": get_unique_open_findings_command, "risksense-get-apps": get_apps_command, "risksense-get-host-finding-detail": get_host_finding_detail_command, "risksense-get-app-detail": get_app_detail_command, "risksense-apply-tag": apply_tag_command, } # Run the commands try: if command == "test-module": test_module(client) elif command in commands: return_outputs(*commands[command](client, demisto.args())) except Exception as e: return_error(f"Failed to execute {demisto.command()} command.\nError: {str(e)}") if __name__ in ["__main__", "builtin", "builtins"]: main()