Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Rapid7 ThreatCommand workflow Signed-off-by: Benimanela [email protected] #167

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Community Developed/Rapid7-ThreatCommand/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Rapid& ThreatCommand Parameters Configuration
Parameter | Name | Default Value | Type | Required (True/False) | Description
--- | --- | --- | --- |--- |---
hostname | Host Name | https://api.ti.insight.rapid7.com | String | True | IP or URL for the instance.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this API use regional endpoints as outlined here - https://docs.rapid7.com/insight/product-apis/#supported-regions

These endpoints may have changed since this workflow was submitted, but just wanted to see if there's maybe a list worth providing to end users to make sure they use the correct endpoint for their region if appropriate.

account_id | Account ID | False | Authentication | True |
api_key | API Key | False | Authentication | True |
severity | Severity | "High", "Medium", "Low" | String | False | you can specify the alert severity to pull
is_closed | Is Closed | True | Bool | False | Change to folse for ignoring closed alerts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<WorkflowParameterValues xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/WorkflowParameterValues/V2">

<!-- "hostname" - ThreatCommand API host (default="https://api.ti.insight.rapid7.com")-->
<Value name="hostname" value="https://api.ti.insight.rapid7.com"/>
<!-- "account_id" - ThreatCommand Account id for QRadar (required) -->
<Value name="account_id" value=""/>
<!-- "api_secert" - ThreatCommand API key for QRadar (required) -->
<Value name="api_key" value=""/>

<!-- "severity" - ThreatCommand alert severity, can be multiple separated by commas, allowed values: "High", "Medium", "Low". (optional) -->
<Value name="severity" value="High, Medium, Low"/>
<!-- "is_closed" - Show closed/open alerts, default value: true. (optional) -->
<Value name="is_closed" value="true"/>
</WorkflowParameterValues>
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<Workflow name="Qmasters Rapid7 ThreatCommand workflow for QRadar" version="1.0" xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V2">
<Parameters>
<Parameter name="hostname" label="Host Name" required="true" />
<Parameter name="account_id" label="Account ID" required="true" secret="true" />
<Parameter name="api_key" label="API Key" required="true" secret="true" />
<Parameter name="severity" label="Severity" required="false" />
<Parameter name="is_closed" label="Is Cloased" required="false" default="false" />
</Parameters>

<Actions>
<!-- Clear the log source status before a new workflow run starts -->
<ClearStatus />

<!-- Prepare the start date filter, based on the current bookmark -->
<Initialize path="/bookmark" value="${time() - 604800000}" />

<!-- Get Alert List -->
<CallEndpoint url="${/hostname}/public/v2/data/alerts/alerts-list" method="GET" savePath="/get_alert_list" >
<BasicAuthentication username="${/account_id}" password="${/api_key}" />
<QueryParameter name="isClosed" value="${/is_closed}" />
<QueryParameter name="severity" value="${/severity}" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this parameter isn't required, you may want to consider setting omitIfEmpty=true so the parameter isn't included in the <CallEndpoint> if the value is just empty.

<QueryParameter name="foundDateFrom" value="${/bookmark}" />
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/get_alert_list/status_code != 200">
<If condition="/get_alert_list/status_code = 403" >
<Abort reason="Invalid ThreatCommand API Key" />
</If>

<If condition="/get_alert_list/status_code >= 500" >
<Abort reason="ThreatCommand API is not available" />
</If>

<Abort reason="ThreatCommand abort reason: ${/get_alert_list}" />
</If>

<!-- Initialize a list to contain all alerts -->
<Set path="/alerts" value="[]" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this API support paging? If so this will only get the first page of data and then more pages on subsequent runs.

Often with Alert based integrations this is usually fine but just wanted to probe that point.


<!-- Get Alerts -->
<ForEach item="/alert_id" items="/get_alert_list/body">
<CallEndpoint url="${/hostname}/public/v1/data/alerts/get-complete-alert/${/alert_id}" method="GET" savePath="/get_alert_${/alert_id}" >
<BasicAuthentication username="${/account_id}" password="${/api_key}" />
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/get_alert_${/alert_id}/status_code != 200">
<If condition="/get_alert_${/alert_id}/status_code = 404">
<Abort reason="ThreatCommand abort reason: ${/get_alert_${/alert_id}}"/>
</If>

<Abort reason="ThreatCommand abort reason: ${/get_alert_${/alert_id}}" />
</If>

<Add path="/alerts" value="${/get_alert_${/alert_id}/body}" />
</ForEach>

<!-- Post Event, if any -->
<If condition="count(/alerts) > 0">
<PostEvents path="/alerts" source="${/hostname}" />

<!-- Update the bookmark -->
<ParseDate pattern="yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'" timeZone="UTC" date="${max(/alerts/FoundDate)}" savePath="/last_event_time" />
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" timeZone="UTC" time="${/last_event_time + 1}" savePath="/bookmark" />
<ParseDate pattern="yyyy-MM-dd'T'HH:mm:ss[.SSS]'Z'" timeZone="UTC" date="${/bookmark}" savePath="/bookmark" />
</If>

</Actions>

<Tests>
<DNSResolutionTest host="${/hostname}" />
<TCPConnectionTest host="${/hostname}" />
<SSLHandshakeTest host="${/hostname}" />
<HTTPConnectionThroughProxyTest url="${/hostname}" expectedResponseStatus="404" />
</Tests>
</Workflow>