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

Add workflows for BeyondTrust Privilege Management Cloud #192 #198

Open
wants to merge 3 commits 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<WorkflowParameterValues xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/WorkflowParameterValues/V1">

<!-- PM Cloud Services Hostname : Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com') -->
<Value name="hostname" value="" />
<!-- Client ID -->
<Value name="client_id" value="" />
<!-- Client Secret -->
<Value name="client_secret" value="" />
<!-- Page Size : Audit activity is retrieved from your PM Cloud site in chunks of data (pages). The page size determines how many records are retrieved by any single request. (default: 200 - max: 200) -->
<Value name="page_size" value="200" />

</WorkflowParameterValues>
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Workflow
name="BeyondTrust PM Cloud - Activity Audits"
description="Retrieves activity audit data from a PM Cloud site via standard REST API calls"
version="23.1"
xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V1">

<Parameters>
<Parameter name="hostname"
label="PM Cloud Services Hostname"
description="Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com')"
required="true" />
<Parameter name="client_id"
label="Client ID"
required="true" />
<Parameter name="client_secret"
label="Client Secret"
required="true"
secret="true" />
<Parameter name="page_size"
label="Page Size"
description="Audit activity is retrieved from your PM Cloud site in chunks of data (pages). The page size determines how many records are retrieved by any single request. (default: 200 - max: 200)"
required="true"
default="200" />
</Parameters>

<Actions>

<!-- Initialize the last ingested date (current time minus 1 hour) -->
<Initialize path="/last_ingested_date" value="${time() - 3600000}" />
<!-- Prepare the start and end date filter, based on the current last ingested date -->
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" time="${/last_ingested_date}" timeZone="UTC" savePath="/start_date" />
<!-- Prepare the end date filter, which is the current time. -->
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" timeZone="UTC" savePath="/end_date" />
<Log type="INFO" message="Preparing to attempt activity audit ingestion from ${/hostname} starting at ${/start_date} through ${/end_date}" />

<!--
//////////////////////
// Get Access Token //
//////////////////////
-->
<Log type="DEBUG" message="Preparing to attempt authentication call to ${/hostname}" />
<CallEndpoint url="https://${/hostname}/oauth/connect/token" method="POST" savePath="/auth_token_response" >
<RequestHeader name="Accept" value="*/*" />
<!-- <BasicAuthentication username="${/client_id}" password="${/client_secret}" /> -->
<RequestHeader name="Authorization" value="Basic ${base64_encode('${/client_id}:${/client_secret}')}"/>
<UrlEncodedFormRequestBody>
<Parameter name="grant_type" value="client_credentials" />
</UrlEncodedFormRequestBody>
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/auth_token_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/auth_token_response/status_code != 200">
<Set path="/temp_message" value="Authentication attempt failed: ${/auth_token_response/body}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<!-- Extract the Access Token -->
<Log type="DEBUG" message="Successfully authenticated" />
<Set path="/access_token" value="${/auth_token_response/body/access_token}" />


<!--
////////////////////
// Request Events //
////////////////////
-->

<Set path="/page_number" value="1" />
<Set path="/total_ingested_count" value="0" />

<!-- Fetch all events, one page at a time -->
<DoWhile condition="/events_response/body/pageCount >= /page_number">

<Log type="DEBUG" message="Retrieving activity audit records from ${/hostname} starting at ${/start_date} through ${/end_date} (Page: ${/page_number} - Page Size: ${/page_size})" />

<!-- Fetch the current page -->
<CallEndpoint url="https://${/hostname}/management-api/v1/ActivityAudits/Details" method="GET" savePath="/events_response" >
<BearerAuthentication token="${/access_token}" />
<QueryParameter name="Filter.Created.Dates" value="${/start_date}" />
<QueryParameter name="Filter.Created.Dates" value="${/end_date}" />
<QueryParameter name="Filter.Created.SelectionMode" value="Range" />
<QueryParameter name="Pagination.PageSize" value="${/page_size}" />
<QueryParameter name="Pagination.PageNumber" value="${/page_number}" />
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/events_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/events_response/status_code != 200">
<Set path="/temp_message" value="Activity audits ingestion failed: ${/events_response/status_code} ${/events_response/status_message}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<Log type="DEBUG" message="Found a total of ${/events_response/body/totalRecordCount} activity audit record(s) spanning ${/events_response/body/pageCount} page(s) - current page is ${/page_number}" />

<!-- Update the last ingested date -->
<ForEach item="/event" items="/events_response/body/data">
<!-- Post Event -->
<PostEvent path="/event" source="${/hostname}"/>
<Set path="/total_ingested_count" value="${/total_ingested_count + 1}" />

<!-- Save the date as the last ingested date -->
<Set path="/event_created" value="${/event/created}" />
<ParseDate pattern="yyyy-MM-dd'T'HH:mm:ss[.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]" date="${/event_created}" timeZone="UTC" savePath="/event_timestamp" />
<If condition="/event_timestamp > /last_ingested_date">
<Set path="/last_ingested_date" value="${/event_timestamp + 1}" />
</If>
<Log type="DEBUG" message="Event ingested datetime is (${/event_timestamp}) for activity audit data ID: ${/event/id}" />
</ForEach>

<!-- Move to the next page -->
<Set path="/page_number" value="${/page_number + 1}" />

</DoWhile>

<Log type="INFO" message="Ingested ${/total_ingested_count} activity audits from ${/hostname} starting at ${/start_date} through ${/end_date}" />

</Actions>

<Tests>
<DNSResolutionTest host="${/hostname}" />
<TCPConnectionTest host="${/hostname}" />
<SSLHandshakeTest host="${/hostname}" />
<HTTPConnectionThroughProxyTest url="https://${/hostname}/bogus-path" expectedResponseStatus="404" />
</Tests>

</Workflow>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<WorkflowParameterValues xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/WorkflowParameterValues/V1">

<!-- PM Cloud Services Hostname : Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com') -->
<Value name="hostname" value="" />
<!-- Client ID -->
<Value name="client_id" value="" />
<!-- Client Secret -->
<Value name="client_secret" value="" />
<!-- Batch Size : Client events are retrieved through your PM Cloud site in chunks of data (batches). The batch size determines how many records are retrieved by any single request. (default: 1000 - max: 1000) -->
<Value name="batch_size" value="1000" />

</WorkflowParameterValues>
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Workflow
name="BeyondTrust PM Cloud - Client Events"
description="Retrieves client event data from a PM Cloud site via standard REST API calls"
version="23.1"
xmlns="http://qradar.ibm.com/UniversalCloudRESTAPI/Workflow/V1">

<Parameters>
<Parameter name="hostname"
label="PM Cloud Services Hostname"
description="Be sure to include the '-services' portion of the hostname (ex: if you access the web site at 'mysite.example.com' then the value to enter here would be 'mysite-services.example.com')"
required="true" />
<Parameter name="client_id"
label="Client ID"
required="true" />
<Parameter name="client_secret"
label="Client Secret"
required="true"
secret="true" />
<Parameter name="batch_size"
label="Batch Size"
description="Client events are retrieved through your PM Cloud site in chunks of data (batches). The batch size determines how many records are retrieved by any single request. (default: 1000 - max: 1000)"
required="true"
default="1000" />
</Parameters>

<Actions>

<!-- Initialize the last ingested date (current time minus 1 hour) -->
<Initialize path="/last_ingested_date" value="${time() - 3600000}" />
<!-- Prepare the start date filter, based on the current last ingested date -->
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" time="${/last_ingested_date}" timeZone="UTC" savePath="/start_date" />
<Log type="INFO" message="Preparing to attempt client event ingestion from ${/hostname} starting at ${/start_date}" />

<!--
//////////////////////
// Get Access Token //
//////////////////////
-->
<Log type="DEBUG" message="Preparing to attempt authentication call to ${/hostname}" />
<CallEndpoint url="https://${/hostname}/oauth/connect/token" method="POST" savePath="/auth_token_response" >
<RequestHeader name="Accept" value="*/*" />
<!-- <BasicAuthentication username="${/client_id}" password="${/client_secret}" /> -->
<RequestHeader name="Authorization" value="Basic ${base64_encode('${/client_id}:${/client_secret}')}"/>
<UrlEncodedFormRequestBody>
<Parameter name="grant_type" value="client_credentials" />
</UrlEncodedFormRequestBody>
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/auth_token_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/auth_token_response/status_code != 200">
<Set path="/temp_message" value="Authentication attempt failed: ${/auth_token_response/body}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<!-- Extract the Access Token -->
<Log type="DEBUG" message="Successfully authenticated" />
<Set path="/access_token" value="${/auth_token_response/body/access_token}" />


<!--
////////////////////
// Request Events //
////////////////////
-->

<Set path="/total_ingested_count" value="0" />

<!-- Fetch all events, one batch at a time ... If the number of events returned in this batch is smaller than the batch size, it must be the last batch -->
<DoWhile condition="/events_response/body/totalRecordsReturned >= /batch_size">

<Log type="DEBUG" message="Retrieving client events from ${/hostname} starting at ${/start_date} (Batch Size: ${/batch_size})" />

<!-- Fetch the current batch -->
<CallEndpoint url="https://${/hostname}/management-api/v1/Events/FromStartDate" method="GET" savePath="/events_response" >
<BearerAuthentication token="${/access_token}" />
<QueryParameter name="StartDate" value="${/start_date}" />
<QueryParameter name="RecordSize" value="${/batch_size}" />
</CallEndpoint>

<!-- Handle Errors -->
<If condition="/events_response/status_code = 429">
<Set path="/temp_message" value="(HTTP 429) API rate limit hit. The polling process for this interval will exit and another attempt will be made on the next interval" />
<Log type="WARN" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</If>
<ElseIf condition="/events_response/status_code != 200">
<Set path="/temp_message" value="Client events ingestion failed: ${/events_response/status_code} ${/events_response/status_message}" />
<Log type="ERROR" message="${/temp_message}" />
<Abort reason="${/temp_message}" />
</ElseIf>

<Log type="DEBUG" message="Found a total of ${/events_response/body/totalRecordsReturned} client event(s) in this batch (Batch Size: ${/batch_size})" />

<!-- Update the last ingested date and start date so the next call picks up where this left off -->
<ForEach item="/event" items="/events_response/body/events">
<!-- Post Event -->
<PostEvent path="/event" source="${/hostname}"/>
<Set path="/total_ingested_count" value="${/total_ingested_count + 1}" />

<!-- Save the date as the last ingested date -->
<Set path="/event_created" value="${/event/event/ingested}" />
<ParseDate pattern="yyyy-MM-dd'T'HH:mm:ss[.SSSSSSS][.SSSSSS][.SSSSS][.SSSS][.SSS][.SS][.S]'+00:00'" date="${/event_created}" timeZone="UTC" savePath="/event_timestamp" />
<If condition="/event_timestamp > /last_ingested_date">
<Set path="/last_ingested_date" value="${/event_timestamp + 1}" />
<FormatDate pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" time="${/last_ingested_date}" timeZone="UTC" savePath="/start_date" />
</If>
<Log type="DEBUG" message="Event ingested datetime is (${/event_timestamp}) for client event ID: ${/event/id}" />
</ForEach>

</DoWhile>

<Log type="INFO" message="Ingested ${/total_ingested_count} client events from ${/hostname} starting at ${/start_date}" />

</Actions>

<Tests>
<DNSResolutionTest host="${/hostname}" />
<TCPConnectionTest host="${/hostname}" />
<SSLHandshakeTest host="${/hostname}" />
<HTTPConnectionThroughProxyTest url="https://${/hostname}/bogus-path" expectedResponseStatus="404" />
</Tests>

</Workflow>
Loading