Collect Palo Alto Networks IOC logs
This document explains how to ingest Palo Alto Networks indicators of compromise (IOCs) to Google Security Operations using STIX over TAXII. The stix_taxii ingestion script (a Cloud Run function) pulls indicators from a Palo Alto TAXII 2.1 server on a schedule and sends them to Google SecOps using the STIX log type.
Palo Alto Networks exposes IOCs as a STIX 2.1 feed over TAXII from Cortex XSOAR or XSIAM Threat Intelligence Management (TIM). The STIX parser in Google SecOps maps the common indicator types (IPv4 addresses, domains, URLs, file hashes, and email addresses) to the UDM.
Before you begin
Make sure you have the following prerequisites:
- A Google SecOps instance, and the Google SecOps ingestion authentication file (the service account JSON) and Customer ID.
- A Google Cloud project with billing enabled and permissions to create service accounts, Secret Manager secrets, Cloud Run functions, and Cloud Scheduler jobs.
Palo Alto Cortex XSOAR or XSIAM with a Threat Intelligence Management (TIM) license, and privileged access to configure integrations.
Set up the Palo Alto TAXII 2.1 feed in Cortex TIM
The TAXII2 Server integration publishes your Cortex XSOAR or XSIAM indicators as an outbound TAXII 2.1 feed that the ingestion script pulls.
- In Cortex XSOAR or XSIAM, install the TAXII Server content pack from Settings & Info > Settings > Integrations > Marketplace.
- Go to Settings > Integrations > Instances, search for TAXII2 Server, and click Add instance.
- Provide the following configuration details:
- Name: Enter a name for the instance (for example,
SecOps-TAXII). - Long Running Instance: Enable this option.
- TAXII2 Server version: Select 2.1.
- Credentials: Set the username and password that the ingestion script uses for HTTP Basic authentication.
- Name: Enter a name for the instance (for example,
In the Collection JSON field, paste the following. It publishes one collection named
SecOpsIOCsthat contains the indicator types theSTIXparser supports:{ "SecOpsIOCs": { "query": "type:IP or type:Domain or type:URL or type:File or type:Email", "description": "Indicators exported to Google SecOps" } }Click Save & exit and enable the instance. Confirm that the instance status shows as running.
In the Google SecOps playground or the integration's command bar, run the following commands and save the output:
!taxii-server-info !taxii-server-list-collectionsFrom the command output, save these values for the deployment step:
- Discovery URL: The API root URL returned by
!taxii-server-info(for example,https://ext-TENANT.crtx.REGION.paloaltonetworks.com/xsoar/instance/execute/SecOps-TAXII/threatintel/). - Collection name:
SecOpsIOCs. - Username and Password: The Basic authentication credentials you set.
- Discovery URL: The API root URL returned by
Enable required Google Cloud APIs
In the Google Cloud console, open Cloud Shell and run:
gcloud services enable \ cloudfunctions.googleapis.com \ cloudbuild.googleapis.com \ cloudscheduler.googleapis.com \ secretmanager.googleapis.com
Store credentials in Secret Manager
The script reads the Google SecOps service account JSON and the TAXII password from Secret Manager.
Create the Google SecOps ingestion service account secret from your ingestion authentication file:
gcloud secrets create secops-ingestion-sa --data-file=./ingestion-auth.jsonCreate the TAXII password secret:
printf '%s' 'YOUR_TAXII_PASSWORD' | gcloud secrets create taxii-password --data-file=-Save both resource names in the form
projects/PROJECT_ID/secrets/SECRET_NAME/versions/latest. You use them in.env.yml.
Create a service account for the function
Create a runtime service account for the Cloud Run function:
gcloud iam service-accounts create stix-taxii-sa \ --display-name="STIX/TAXII ingestion function"Grant it access to the two secrets:
gcloud secrets add-iam-policy-binding secops-ingestion-sa \ --member="serviceAccount:stix-taxii-sa@PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor" gcloud secrets add-iam-policy-binding taxii-password \ --member="serviceAccount:stix-taxii-sa@PROJECT_ID.iam.gserviceaccount.com" \ --role="roles/secretmanager.secretAccessor"
Deploy the ingestion script
The stix_taxii ingestion script is a Cloud Run function that pulls indicators from the TAXII server and streams them to Google SecOps using the Ingestion API. It always ingests using the STIX log type.
In Cloud Shell, clone the ingestion scripts repository:
git clone https://github.com/chronicle/ingestion-scripts.git cp -r ingestion-scripts/common ingestion-scripts/stix_taxii/common cd ingestion-scripts/stix_taxiiCreate a file named
.env.ymlwith the following contents. Replace the placeholder values with the ones you saved earlier:CHRONICLE_CUSTOMER_ID: "YOUR_CUSTOMER_ID" CHRONICLE_REGION: "us" CHRONICLE_SERVICE_ACCOUNT: "projects/PROJECT_ID/secrets/secops-ingestion-sa/versions/latest" TAXII_VERSION: "2.1" TAXII_DISCOVERY_URL: "https://ext-TENANT.crtx.REGION.paloaltonetworks.com/xsoar/instance/execute/SecOps-TAXII/threatintel/" TAXII_COLLECTION_NAMES: "SecOpsIOCs" TAXII_USERNAME: "YOUR_TAXII_USERNAME" TAXII_PASSWORD_SECRET_PATH: "projects/PROJECT_ID/secrets/taxii-password/versions/latest" POLL_INTERVAL: "60"Deploy the function:
gcloud functions deploy stix-taxii-ingestion \ --gen2 \ --entry-point main \ --trigger-http \ --runtime python312 \ --region us-central1 \ --service-account stix-taxii-sa@PROJECT_ID.iam.gserviceaccount.com \ --timeout 540 \ --memory 512MB \ --no-allow-unauthenticated \ --env-vars-file .env.ymlSave the function's trigger URL from the deployment output (for example,
https://us-central1-PROJECT_ID.cloudfunctions.net/stix-taxii-ingestion).
Schedule the function with Cloud Scheduler
Grant the service account permission to invoke the function:
gcloud functions add-invoker-policy-binding stix-taxii-ingestion \ --region=us-central1 \ --member="serviceAccount:stix-taxii-sa@PROJECT_ID.iam.gserviceaccount.com"Create a scheduler job that calls the function every hour (match the frequency to
POLL_INTERVAL):gcloud scheduler jobs create http stix-taxii-scheduler \ --location=us-central1 \ --schedule="0 */1 * * *" \ --uri="FUNCTION_TRIGGER_URL" \ --http-method=POST \ --oidc-service-account-email="stix-taxii-sa@PROJECT_ID.iam.gserviceaccount.com" \ --oidc-token-audience="FUNCTION_TRIGGER_URL"
Verify the deployment
Trigger an initial run:
gcloud scheduler jobs run stix-taxii-scheduler --location=us-central1Review the function logs:
gcloud functions logs read stix-taxii-ingestion --region=us-central1 --gen2 --limit=50In Google SecOps, search for events with the
STIXlog type to confirm that the indicators are ingested.
UDM mapping table
| Log Field | UDM Mapping | Logic |
|---|---|---|
observable.object.properties.type |
categorization |
Directly mapped |
type |
categorization |
Directly mapped |
x_ctix_confidence_score |
confidence_score |
Renamed/mapped |
name |
domain_and_ports.domain |
Directly mapped |
observable.object.properties.value |
domain_and_ports.domain |
Directly mapped |
value |
domain_and_ports.domain |
Directly mapped |
type |
feed_name |
Mapped: "ipv4","ipv4-addr", "scan_ip", "mal_ip" → STIX-IOC, `"phish_domain", "domain", "... |
src_ip |
ip_and_ports.ip_address |
Directly mapped |
value |
ip_and_ports.ip_address |
Directly mapped |
src_port |
ip_and_ports.ports |
Merged |
type |
ip_and_ports.ports |
Mapped: "ipv4","ipv4-addr", "scan_ip", "mal_ip" → src_port, ipv4-addr → src_port |
created |
metadata.event_timestamp |
Parsed as ISO8601 |
modified |
metadata.event_timestamp |
Parsed as ISO8601 |
timestamp |
metadata.event_timestamp |
Parsed as ISO8601 |
valid_from |
metadata.event_timestamp |
Parsed as ISO8601 |
valid_until |
metadata.event_timestamp |
Parsed as ISO8601 |
| N/A | feed_name |
Constant: STIX-IOC |
Change Log
View the Change Log for this parser
Need more help? Get answers from Community members and Google SecOps professionals.