Pushing Events to XSOAR with Generic Webhooks

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
L4 Transporter

Title_XSOAR-with-Generic-Webhooks_palo-alto-networks.jpg

 

The use case is simple, we want to push an event into Cortex XSOAR to create an Incident and run the associated playbook.  

 

When it comes to pushing Incidents into XSOAR, many look first to the XSOAR API. They reference the API guide for their XSOAR 6.x or XSOAR 8.x instance, create an API key and off they go! 

 

Pro Tip: Use the /incident/json endpoint to create your Incidents when using the API.

 

Often overlooked in this use case is the Generic Webhook Integration which is available from the Cortex XSOAR Marketplace

 

The Generic Webhook integration offers an alternative to using the API, and is this Authors go-to when asked for a recommendation to push Incidents into XSOAR.  

 

When I’m inevitably asked for my reasons, here are my top 3:

 

  1. Cortex XSOAR API keys can do more than create Incidents, the only thing the Generic Webhook integration can do is create Incidents, which means if you obtain the credentials used for it, well… ok you can create some Incidents
  2. Individual instances of the integration can be created with different authentication credentials for each service, giving you much finer grained control.  There is only one API, and we hate to leave API keys laying around
  3. Many systems support sending events via Webhook, versus custom scripting which may be required to use the XSOAR API

 

Configuring the Generic Webhook Integration

Configuration of the Generic Webhook Integration on both XSOAR 6.x and XSOAR 8.x is our first step. 

 

  1. Install the Generic Webhook content pack from the Cortex XSOAR Marketplace.
  2. Add an instance of the integration via Settings -> Integrations, adding the following:
    1. Name
    2. Listen Port
      1. You can pick any port above 1024, as long as it’s not being used by another long running integration!

 

XSOAR 6.x Instance ConfigurationXSOAR 6.x Instance Configuration

 

XSOAR 8.x Generic Webhook Instance ConfigurationXSOAR 8.x Generic Webhook Instance Configuration

 

For XSOAR 6.x, we recommend adding the following server configuration via Settings -> About -> Troubleshooting, which will allow us to use the servers HTTPS port to send our webhooks, versus the configured listening port:

 

instance.execute.external = true

 

Fig 3_XSOAR-with-Generic-Webhooks_palo-alto-networks.png

 

For XSOAR 8.x, this configuration is already done for you by default!  

 

Securing the Generic Webhook Integration

Optionally, but strongly recommended, you can secure each instance by specifying a username and password that will be used to authenticate via basic authentication from your external source.  

 

You can either add the username and password directly to the instance via its configuration, or better yet, you can store the information in an XSOAR credential.  This is preferred in the event you want to use the same username/password in multiple instances and want to easily rotate the password.

 

You can add a credential by going to Settings -> Integrations -> Credentials and creating a new one adding the username and password you want to use.

 

Fig 4_XSOAR-with-Generic-Webhooks_palo-alto-networks.png

 

After that you can modify the configuration of your instance to either use the credential, or a hard coded username and password.  You can select the ‘switch’ option to toggle between these options.

 

Fig 5_XSOAR-with-Generic-Webhooks_palo-alto-networks.png

 

Using the Generic Webhook Integration

We can test using the Generic Webhook Integration instances using CURL, Postman, or Python, or anything that can send a POST request to the service!

 

All we need is the URL, and a JSON body that contains the data we want to send to XSOAR.

 

URL Differences - XSOAR 6.x vs XSOAR 8.x

 

For XSOAR 6.x, assuming you added the recommended server configuration above, the URL we’ll use is as follows:

 

https[:]//<hostname of xsoar server>/instance/execute/<name of the webhook instance>

 

Example: https[:]//readyxsoarone.paloaltonetworks.com/instance/execute/readywebhookone

 

For XSOAR 8.x, the URL is a little different, as it adds ‘ext-’ to the beginning of the hostname:

 

https[:]//ext-<hostname of your xsoar 8 instance>/xsoar/instance/execute/<name of the webhook instance>

 

Example: 

https[:]//ext-readyxsoarone.crtx.us.paloaltonetworks.com/xsoar/instance/execute/readywebhookone

 

JSON Data

Next we can send in the data for the event in a JSON body, this data can be used for Classification and Mapping, to route events to different Incident Types in XSOAR, or map key data to Incident Fields.

 

For our example, we’ll send this:

{

"type":"Ready Webhook One",

"user":"beauchompers",

"details":"I hope you found this blog post useful!"

}

 

Sending Webhooks

We can use curl to send the events to our XSOAR server for testing, and there is an example Python3 script below as well!  We’ve escaped the URLs, so make sure to remove those in your testing!

 

Note: I’ve added the -v (verbose) and -k (skip cert check) flags, feel free to remove those. 

 

Sending to XSOAR 6.x:

 

curl -POST https://<insert instance name here>/instance/execute/<webhook instance name> -u "username:password" -H "Content-Type: application/json" -d '{"type":"Ready Webhook One","user":"beauchompers","details":"I hope you found this blog post useful!"}' -v -k

 

Example: 

curl -POST https[:]//readyxsoarone.paloaltonetworks.com/instance/execute/readywebhookone -u "readywebhookone:Password1" -H "Content-Type: application/json" -d '{"type":"Ready Webhook One","user":"beauchompers","details":"I hope you found this blog post useful!"}'

 

Sending to XSOAR 8.x:

 

curl -POST https://ext-<insert instance name here>/xsoar/instance/execute/<webhook instance name> -u "username:password" -H "Content-Type: application/json" -d '{"type":"Ready Webhook One","user":"beauchompers","details":"I hope you found this blog post useful!"}'

 

Example:

curl -POST https[:]//ext-readyxsoarone.crtx.us.paloaltonetworks.com/xsoar/instance/execute/readywebhookone -u "readywebhookone:Password1" -H "Content-Type: application/json" -d '{"type":"Ready Webhook One","user":"beauchompers","details":"I hope you found this blog post useful!"}'

 

Classification and Mapping

We can perform Classification and Mapping on the events we send to our instance(s) as well.  The easiest way to do this is to configure the integration instance to store samples of the events we send.  

 

To enable this, select the “Store sample events for mapping” option on the instance configuration:

  • Scroll down on XSOAR 6.x
  • Select “Advanced Settings” on XSOAR 8.x

 

Fig 6_XSOAR-with-Generic-Webhooks_palo-alto-networks.png

 

Once configured, you first need to send a few events to XSOAR before they will be available for use when creating a new Classifier or Incoming Mapper. 

 

You can create a new Classifier or Incoming Mapper from Settings -> Objects Setup -> Classification and Mapping.  

 

To view the Samples, you can do the following:

 

  1. Select Pull from Instance
  2. Select the instance name of your webhook integration.
  3. Samples will appear to be used in Classification and Mapping.

 

Fig 7_XSOAR-with-Generic-Webhooks_palo-alto-networks.png

 

Once completed, you can assign the classifier and/or mapper onto the webhook instance!

 

For more information on Classification and Mapping, check out video 3 in our XSOAR Engineer Training Series! 

 

Extra Credit - Using XSOAR Engines

You can also configure the Generic Webhook integration run via a single Cortex XSOAR Engine.

Note: The integration instance must be assigned to a single engine and not a Load Balancing Group.

 

The configuration is the same for XSOAR 6 and 8 when running on an Engine, select the listening port that you want to listen on for incoming requests, and then select the Engine that will run the integration instance.

By default, the instance will listen on HTTP, but it would be best practice to provide a certificate and private key to the integration instance to enable it to listen on HTTPS. 

 

rtsedaka_0-1693925208492.png

 

rtsedaka_1-1693925227810.png

 

When listening on an Engine, the URL is a little different, in this case, we only need the hostname and port that you selected in your configuration.  

 

You can configure authentication on the instance the same as if it were a server as well. You can change from https or http depending on how you configured it as well.

 

Sending to an XSOAR Engine:

curl -POST https://<insert engine hostname or ip>:<insert port you selected> -u "username:password" -H "Content-Type: application/json" -d '{"type":"Ready Webhook One","user":"beauchompers","details":"I hope you found this blog post useful!"}' -v -k

 

Example:

curl -POST https[:]//readyengineone.paloaltonetworks.com:8000 -u "readywebhookone:Password1" -H "Content-Type: application/json" -d '{"type":"Ready Webhook One","user":"beauchompers","details":"I hope you found this blog post useful!"}' -v -k

 

Extra Credit - Python Example Script

Below is an example of sending a webhook to an XSOAR 6 or 8 server using Python.  Add the server, instance name, version, username, and password to the top based on your XSOAR deployment!

 

Feel free to modify it yourself if you want it to work on an Engine, consider that your homework!

 

 

import requests
import urllib3
urllib3.disable_warnings()


# example script to create an incident from json using xsoar webhook integration
# setup: Add the server and the webhook instance name params
# usage: python3 xsoar-webhook.py


# add the instance name and the hostname or IP of the XSOAR server.
webhook_instance_name = ""
server = ""


# the xsoar version you are using, can be 6 or 8.
xsoar_version = "6"




# basic authentication is used, set the username/password here.
username = ""
password = ""




## DO NOT MODIFY BELOW HERE
# set the server URL based on the XSOAR version selected above.
if xsoar_version == "8":
url = f"https://ext-{server}/xsoar/instance/execute/{webhook_instance_name}"
else:
url = f"https://{server}/instance/execute/{webhook_instance_name}"


# example body
body = {
"type":"Ready Webhook One",
"key1":"ready key one",
"key2":"ready key two"
}


# headers
headers = {
'accept': 'application/json',
'content-type': 'application/json'
}


res = requests.post(url, headers=headers, auth=(username,password), json=body, verify=False)


# response from XSOAR return the Incident if 200, or the status code otherwise
if res.status_code == 200:
created_incident = res.json()[0].get("id")
created_type = res.json()[0].get("type")
print(f"\n\n{created_type.upper()} Incident {created_incident} created in XSOAR.\n\n")
# print(res.json())
else:
print(res.status_code)

 

Fin

We hope you enjoyed this post, and that you’ll consider the Generic Webhook Integration the next time you want to push an event to Cortex XSOAR!

 

  • 6380 Views
  • 0 comments
  • 1 Likes
Register or Sign-in
Labels
Top Liked Authors