From e2ed1d7c2779bf88c12f28a9e462f79caa287a0a Mon Sep 17 00:00:00 2001 From: bluza Date: Wed, 2 Apr 2025 23:26:45 +0800 Subject: [PATCH 1/2] Add github workflow to automate packaging of playbooks --- .github/workflows/package.yml | 74 + .gitignore | 4 + README.md | 6 +- packaged_playbooks/README.md | 0 .../DomainTools_Auto_Pivots.yml | 2094 +++++++++++++++++ .../DomainTools_Auto_Pivots_README.md | 150 ++ ...s_Check_Domain_Risk_Score_By_Iris_Tags.yml | 311 +++ ..._Check_Domain_Risk_Score_By_Tags_README.md | 32 + ...ybook_-_Check_Domain_Risk_Score_by_Tag.tgz | Bin 0 -> 4169 bytes .../README.md | 18 + .../domaintools_monitor_iris_tags.csv | 3 + ...nTools_Alerting_Playbook_-_New_Domains.tgz | Bin 0 -> 4005 bytes .../README.md | 12 + 13 files changed, 2701 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/package.yml create mode 100644 .gitignore create mode 100644 packaged_playbooks/README.md create mode 100644 src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots.yml create mode 100644 src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md create mode 100644 src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Iris_Tags.yml create mode 100644 src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools_Alerting_Playbook_-_Check_Domain_Risk_Score_by_Tag.tgz create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/README.md create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/domaintools_monitor_iris_tags.csv create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools_Alerting_Playbook_-_New_Domains.tgz create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/README.md diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 0000000..8b14c6e --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,74 @@ +name: Auto packager of SOAR playbooks + +on: + push: + branches: + - main # only package the app in the `main` branch + pull_request: + workflow_dispatch: + +permissions: + contents: write + +jobs: + package: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + with: + fetch-depth: 2 # Fetch last commit for comparison + + - name: Detect changed playbook directories + id: changed_dirs + run: | + # Find modified directories inside src/ and extract their full paths + CHANGED_DIRS=$(git diff --name-only HEAD~1 HEAD src/ | awk -F'/' '$3 == "playbooks" {print $1"/"$2"/"$3"/"$4}' | sort -u | uniq | sed 's/^/"/;s/$/"/' | tr '\n' ' ') + if [[ -z "$CHANGED_DIRS" ]]; then + echo "No changes detected in src/." + echo "changed_dirs=" >> $GITHUB_ENV + else + echo "Changed directories: $CHANGED_DIRS" + echo "changed_dirs=$CHANGED_DIRS" >> $GITHUB_ENV + fi + + - name: Package changed playbooks + if: env.changed_dirs != null && env.changed_dirs != '' + run: | + for dir in ${{ env.changed_dirs }}; do + echo "Packaging: $dir" + category_folder=$(echo "$dir" | cut -d'/' -f2) + parent_folder=$(echo "$dir" | cut -d'/' -f3) + sub_folder=$(echo "$dir" | cut -d'/' -f4) + + echo "Category: category_folder, Parent: $parent_folder, Sub-folder: $sub_folder" + + mkdir -p "packaged_playbooks/$category_folder/$parent_folder" + echo "Created directory: packaged_playbooks/$category_folder/$parent_folder" + + tar -czvf "packaged_playbooks/$category_folder/$parent_folder/${sub_folder}.tgz" -C "src/$category_folder/$parent_folder" "$sub_folder" || echo "Tar failed!" + echo "Packaged $dir/ -> packaged_playbooks/$category_folder/$parent_folder/${sub_folder}.tgz" + done + + echo "Checking packaged files..." + ls -R packaged_playbooks/ + + - name: Commit and push packaged playbooks + if: env.changed_dirs != null && env.changed_dirs != '' && github.event_name != 'pull_request' # only commit and push if it's not a PR + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + git config --global user.name "dt-playbook-bot" + git config --global user.email "dt-playbook-bot@users.noreply.github.com" + + git add packaged_playbooks/ + git commit -m "Auto-package updated playbooks [dt-playbook-bot]" || echo "No changes to commit." + git push https://x-access-token:${GITHUB_TOKEN}@github.com/${{ github.repository }}.git main || echo "No changes to push." + + - name: Upload packaged playbooks + if: env.changed_dirs != null && env.changed_dirs != '' && github.event_name != 'pull_request' # only commit and push if it's not a PR + uses: actions/upload-artifact@v4 + with: + name: packaged-playbooks + path: packaged_playbooks/**/* diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80d03d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode/ +.DS_Store +*.pyc +.cpython* diff --git a/README.md b/README.md index ee0ce45..ae4cdcb 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -## DomainTools Playbooks: -Playbooks and automation scripts for SOAR applications that automate incident response activities by utilizing DomainTools intelligence. +## DomainTools Playbooks -Each integration’s playbooks are in separate folders at the root of this repo. Find your integration and download the playbooks. Each one has instructions on the README of the playbook directory - be sure to read those. +Playbooks and automation scripts for SOAR applications that automate incident response activities by utilizing DomainTools intelligence. +Each integration’s playbooks are in separate folders at the root of this repo. Find your integration and download the playbooks. Each one has instructions on the README of the playbook directory - be sure to read those. Happy Hunting! -DomainTools Integrations team diff --git a/packaged_playbooks/README.md b/packaged_playbooks/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots.yml b/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots.yml new file mode 100644 index 0000000..edf667c --- /dev/null +++ b/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots.yml @@ -0,0 +1,2094 @@ +id: DomainTools Auto Pivots +version: -1 +name: DomainTools Auto Pivots +description: 'This playbook retrieves the Iris Investigate profile of domain and automatically identifies potential connected infrastructure related to artifacts based on DomainTools Guided Pivot value. ' +tags: +- Domaintools +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: d517b724-8a70-4146-8029-cdb6b92b5970 + type: start + task: + id: d517b724-8a70-4146-8029-cdb6b92b5970 + version: -1 + name: "" + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "1" + separatecontext: false + view: |- + { + "position": { + "x": 642.5, + "y": 70 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "1": + id: "1" + taskid: 066e8866-1263-4541-839d-e1d68d4e4a5b + type: regular + task: + id: 066e8866-1263-4541-839d-e1d68d4e4a5b + version: -1 + name: Lookup Domain(s) + description: Returns a complete profile of the domain (SLD.TLD) using Iris Investigate. If parsing of FQDNs is desired, see domainExtractAndInvestigate. + script: '|||domain' + type: regular + iscommand: true + brand: "" + nexttasks: + '#none#': + - "8" + scriptarguments: + domain: + simple: ${inputs.domains} + include_context: + simple: "true" + separatecontext: false + view: |- + { + "position": { + "x": 642.5, + "y": 225 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "4": + id: "4" + taskid: c33e2f7d-a8c9-4107-895c-8f31efd48e07 + type: title + task: + id: c33e2f7d-a8c9-4107-895c-8f31efd48e07 + version: -1 + name: Look for High Risk Domains + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "34" + separatecontext: false + view: |- + { + "position": { + "x": 622.5, + "y": 1670 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "8": + id: "8" + taskid: cf6666ec-071b-41da-81f8-c41808bb0398 + type: regular + task: + id: cf6666ec-071b-41da-81f8-c41808bb0398 + version: -1 + name: Check Pivotable Domains + description: 'Get guided pivot counts.' + scriptName: CheckPivotableDomains + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "29" + scriptarguments: + domaintools_data: + simple: ${DomainTools} + max_google_adsense_count: + simple: ${inputs.dt_max_google_adsense_count} + max_google_analytics_count: + simple: ${inputs.dt_max_google_analytics_count}${inputs.dt_max_ssl_email_count} + max_ip_address_count: + simple: ${inputs.dt_max_ip_address_count} + max_mx_domain_count: + simple: ${inputs.dt_max_mx_domain_count} + max_mx_host_count: + simple: ${inputs.dt_max_mx_host_count} + max_mx_ip_count: + simple: ${inputs.dt_max_mx_ip_count} + max_name_server_host_count: + simple: ${inputs.dt_max_name_server_host_count} + max_name_server_ip_count: + simple: ${inputs.dt_max_name_server_ip_count} + max_registrant_contact_name_count: + simple: ${inputs.dt_max_registrant_contact_name_count} + max_registrant_org_count: + simple: ${inputs.dt_max_registrant_org_count} + max_registrar_count: + simple: ${inputs.dt_max_registrar_count} + max_soa_email_count: + simple: ${inputs.dt_max_soa_email_count} + max_ssl_email_count: + simple: ${inputs.dt_max_ssl_email_count} + max_ssl_info_hash_count: + simple: ${inputs.dt_max_ssl_info_hash_count} + max_ssl_info_organization_count: + simple: ${inputs.dt_max_ssl_info_organization_count} + max_ssl_subject_count: + simple: ${inputs.dt_max_ssl_subject_count} + separatecontext: false + view: |- + { + "position": { + "x": 642.5, + "y": 400 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "15": + id: "15" + taskid: b8ddfe87-8d73-4bb4-8c7c-f2cefd1338bf + type: regular + task: + id: b8ddfe87-8d73-4bb4-8c7c-f2cefd1338bf + version: -1 + name: Pivot NameServer Host + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + nameserver_host: + complex: + root: PivotableDomains.PivotableNameServerHost + filters: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableNameServerHost.pivotable + iscontext: true + accessor: items.value + separatecontext: false + view: |- + { + "position": { + "x": -710, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "16": + id: "16" + taskid: 538b72b5-bd59-43c7-863b-a4463921d890 + type: regular + task: + id: 538b72b5-bd59-43c7-863b-a4463921d890 + version: -1 + name: Pivot NameServer IP + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + nameserver_ip: + complex: + root: PivotableDomains.PivotableNameServerIp + filters: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableNameServerIp.pivotable + iscontext: true + accessor: items.value + separatecontext: false + view: |- + { + "position": { + "x": -267.5, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "17": + id: "17" + taskid: fb46caed-8e5c-45c3-8c9e-20114dd46ab2 + type: condition + + task: + id: fb46caed-8e5c-45c3-8c9e-20114dd46ab2 + version: -1 + name: Is Pivotable NS Host? + description: 'Is NS Host a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + Nameserver host: + - "15" + separatecontext: false + conditions: + - label: Nameserver host + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableNameServerHost.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": -710, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "18": + id: "18" + taskid: 3116eba1-d42b-4621-848f-7880b0880799 + type: condition + task: + id: 3116eba1-d42b-4621-848f-7880b0880799 + version: -1 + name: Is Pivotable NS IP? + description: 'Is NS IP a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + nameserver ip: + - "16" + separatecontext: false + conditions: + - label: nameserver ip + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableNameServerIp.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": -267.5, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "19": + id: "19" + taskid: 9ddf8e07-b134-4094-8e53-2750c84d085a + type: condition + task: + id: 9ddf8e07-b134-4094-8e53-2750c84d085a + version: -1 + name: Is Pivotable Registrant? + description: 'Is Registrant a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + registrant: + - "20" + separatecontext: false + conditions: + - label: registrant + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableRegistrantContactName.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": 182.5, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "20": + id: "20" + taskid: e2307b78-c2fc-473e-8317-c4efb6550505 + type: regular + task: + id: e2307b78-c2fc-473e-8317-c4efb6550505 + version: -1 + name: Pivot Registrant Name + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + registrant: + simple: ${PivotableDomains.PivotableRegistrantContactName.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 172.5, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "21": + id: "21" + taskid: 83a90792-329c-43a6-871b-33a4127213c5 + type: condition + task: + id: 83a90792-329c-43a6-871b-33a4127213c5 + version: -1 + name: Is Pivotable Registrant Org? + description: 'Is Registrant org a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + Registrant Org: + - "22" + separatecontext: false + conditions: + - label: Registrant Org + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableRegistrantOrg.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": 632.5, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "22": + id: "22" + taskid: 22cd10a4-733b-45a9-89b5-95539d38e077 + type: regular + task: + id: 22cd10a4-733b-45a9-89b5-95539d38e077 + version: -1 + name: Pivot Registrant Org + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + registrant_org: + simple: ${PivotableDomains.PivotableRegistrantOrg.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 622.5, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "23": + id: "23" + taskid: b225b62f-2d88-4eb8-88d9-79c5954b8306 + type: condition + task: + id: b225b62f-2d88-4eb8-88d9-79c5954b8306 + version: -1 + name: Is Pivotable SSL Org? + description: 'Is SSL org a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + SSL Org: + - "24" + separatecontext: false + conditions: + - label: SSL Org + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableSslInfoOrganization.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": 1050, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "24": + id: "24" + taskid: 488d8628-d5fd-4481-8dd7-7d9fb8cc703a + type: regular + task: + id: 488d8628-d5fd-4481-8dd7-7d9fb8cc703a + version: -1 + name: Pivot SSL Org + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + ssl_org: + simple: ${PivotableDomains.PivotableSslInfoOrganization.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 1050, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "25": + id: "25" + taskid: 1c077ccb-1256-4fca-873d-dd73e1101122 + type: condition + task: + id: 1c077ccb-1256-4fca-873d-dd73e1101122 + version: -1 + name: Is Pivotable SSL Hash? + description: 'Is SSL hash a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + ssl hash: + - "26" + separatecontext: false + conditions: + - label: ssl hash + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableSslInfoHash.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": 1500, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "26": + id: "26" + taskid: f0069e09-6d44-4c9b-826b-bc53566dba59 + type: regular + task: + id: f0069e09-6d44-4c9b-826b-bc53566dba59 + version: -1 + name: Pivot SSL Hash + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + ssl_hash: + simple: ${PivotableDomains.PivotableSslInfoHash.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 1500, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "27": + id: "27" + taskid: c03d7a1d-9ac1-488c-884d-d1528ab96298 + type: condition + task: + id: c03d7a1d-9ac1-488c-884d-d1528ab96298 + version: -1 + name: Is Pivotable SOA Email? + description: 'Is SOA email a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + soa email: + - "28" + separatecontext: false + conditions: + - label: soa email + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableSoaEmail.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": 1920, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "28": + id: "28" + taskid: c1d315ea-f8af-49cf-8ab1-c30c792ed03c + type: regular + task: + id: c1d315ea-f8af-49cf-8ab1-c30c792ed03c + version: -1 + name: Pivot SOA Email + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + email: + simple: ${PivotableDomains.PivotableSoaEmail.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 1920, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "29": + id: "29" + taskid: a344a967-a6e7-45b2-8559-f61b1ab03228 + type: title + task: + id: a344a967-a6e7-45b2-8559-f61b1ab03228 + version: -1 + name: Start Auto Pivoting + type: title + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "17" + - "18" + - "19" + - "21" + - "23" + - "25" + - "27" + - "30" + - "32" + - "40" + - "42" + - "44" + - "46" + - "48" + - "50" + - "52" + - "54" + separatecontext: false + view: |- + { + "position": { + "x": 642.5, + "y": 580 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "30": + id: "30" + taskid: 21de504b-add9-4ea0-8289-17bd63072a76 + type: condition + task: + id: 21de504b-add9-4ea0-8289-17bd63072a76 + version: -1 + name: Is Pivotable IP? + description: 'Is IP address a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + ip: + - "31" + separatecontext: false + conditions: + - label: ip + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableIpAddress.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": 2350, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "31": + id: "31" + taskid: 11298ba2-c21d-4b40-8476-0048cb651613 + type: regular + task: + id: 11298ba2-c21d-4b40-8476-0048cb651613 + version: -1 + name: Pivot IP + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + ip: + simple: ${PivotableDomains.PivotableIpAddress.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 2350, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "32": + id: "32" + taskid: 2b882c45-a316-4e99-8cac-f11d12270e1f + type: condition + task: + id: 2b882c45-a316-4e99-8cac-f11d12270e1f + version: -1 + name: Is Pivotable MX IP + description: 'Is MX IP a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + MX IP: + - "33" + separatecontext: false + conditions: + - label: MX IP + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableMxIp.pivotable + iscontext: true + right: + value: {} + view: |- + { + "position": { + "x": -1160, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "33": + id: "33" + taskid: 7db1ed88-3582-40dc-8349-d0d16206b4b8 + type: regular + task: + id: 7db1ed88-3582-40dc-8349-d0d16206b4b8 + version: -1 + name: Pivot MX IP + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + mailserver_ip: + simple: ${PivotableDomains.PivotableMxIp.items.value} + separatecontext: false + view: |- + { + "position": { + "x": -1170, + "y": 970 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "34": + id: "34" + taskid: 35986446-8d91-4f48-8d47-3d7ffe16e67b + type: condition + task: + id: 35986446-8d91-4f48-8d47-3d7ffe16e67b + version: -1 + name: Is there Any High Risk Score Domain? + description: 'Check high risk domains.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "36" + "yes": + - "37" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: greaterThanOrEqual + left: + value: + simple: DomainTools.Pivots.PivotedDomains.Analytics.OverallRiskScore + iscontext: true + right: + value: + simple: inputs.dt_riskscore_threshold + iscontext: true + view: |- + { + "position": { + "x": 622.5, + "y": 1810 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "36": + id: "36" + taskid: 930e0874-747f-4eed-8386-5453105bc8f5 + type: title + task: + id: 930e0874-747f-4eed-8386-5453105bc8f5 + version: -1 + name: Done + description: Prints a raw representation of a string or object, visualising things likes tabs and newlines. For instance, '\n' will be displayed instead of a newline character, or a Windows CR will be displayed as '\r\n'. This is useful for debugging issues where things aren't behaving as expected, such as when parsing a string with a regular expression. + type: title + iscommand: false + brand: "" + separatecontext: false + view: |- + { + "position": { + "x": 622.5, + "y": 2630 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "37": + id: "37" + taskid: 2b9385cc-c045-4478-8baf-3889f41d2eba + type: regular + task: + id: 2b9385cc-c045-4478-8baf-3889f41d2eba + version: -1 + name: Add High Risk Domain to Context + description: 'Add high risk domain to context.' + scriptName: AddDomainRiskScoreToContext + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "39" + scriptarguments: + domaintools_data: + complex: + root: DomainTools.Pivots.PivotedDomains + filters: + - - operator: greaterThanOrEqual + left: + value: + simple: DomainTools.Pivots.PivotedDomains.Analytics.OverallRiskScore + iscontext: true + right: + value: + simple: inputs.dt_riskscore_threshold + iscontext: true + separatecontext: false + view: |- + { + "position": { + "x": 160, + "y": 2000 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "38": + id: "38" + taskid: 3616ae76-1825-47bf-89e4-b382f630c95e + type: regular + task: + id: 3616ae76-1825-47bf-89e4-b382f630c95e + version: -1 + name: Manually Review High Risk Score Domains + description: 'Manually review high risk score domains.' + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "36" + separatecontext: false + defaultassigneecomplex: + simple: Analyst + view: |- + { + "position": { + "x": 160, + "y": 2430 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "39": + id: "39" + taskid: 990b24ad-dd36-4b96-8793-b36801e2024a + type: condition + task: + id: 990b24ad-dd36-4b96-8793-b36801e2024a + version: -1 + name: 'Should Wait for an Analyst Review? ' + description: 'Should Wait for an Analyst Review.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "36" + "yes": + - "38" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isTrue + left: + value: + simple: inputs.should_wait_for_analyst_review + iscontext: true + view: |- + { + "position": { + "x": 160, + "y": 2190 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "40": + id: "40" + taskid: dbcb5fa6-f951-4a8c-8e55-a1f1cb651373 + type: condition + task: + id: dbcb5fa6-f951-4a8c-8e55-a1f1cb651373 + version: -1 + name: Is Pivotable MX Host? + description: 'Is MX host a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + MX Host: + - "41" + separatecontext: false + conditions: + - label: MX Host + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableMxHost.pivotable + iscontext: true + view: |- + { + "position": { + "x": -1610, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "41": + id: "41" + taskid: d2fa4809-917f-48d1-85b5-414215c406c8 + type: regular + task: + id: d2fa4809-917f-48d1-85b5-414215c406c8 + version: -1 + name: Pivot MX Host + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + mailserver_host: + simple: ${PivotableDomains.PivotableMxHost.items.value} + separatecontext: false + view: |- + { + "position": { + "x": -1630, + "y": 970 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "42": + id: "42" + taskid: cff54b01-4a0f-420a-80b0-ccac9a99f0d5 + type: condition + task: + id: cff54b01-4a0f-420a-80b0-ccac9a99f0d5 + version: -1 + name: Is Pivotable MX Domain? + description: 'Is MX domain a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + mx domain: + - "43" + separatecontext: false + conditions: + - label: mx domain + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableMxDomain.pivotable + iscontext: true + view: |- + { + "position": { + "x": -2070, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "43": + id: "43" + taskid: 5bf98c03-d021-4144-80ff-2d8a70e0e49c + type: regular + task: + id: 5bf98c03-d021-4144-80ff-2d8a70e0e49c + version: -1 + name: Pviot MX Domain + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + mailserver_domain: + simple: ${PivotableDomains.PivotableMxDomain.items.value} + separatecontext: false + view: |- + { + "position": { + "x": -2090, + "y": 970 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "44": + id: "44" + taskid: dfd744f6-8fb0-4916-80d0-bd594a7a9711 + type: condition + task: + id: dfd744f6-8fb0-4916-80d0-bd594a7a9711 + version: -1 + name: Is Pivotable Registrar? + description: 'is registrar a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + registrar: + - "45" + separatecontext: false + conditions: + - label: registrar + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableRegistrar.pivotable + iscontext: true + view: |- + { + "position": { + "x": 2790, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "45": + id: "45" + taskid: d58dd774-b23d-4af1-88be-74dfa104861d + type: regular + task: + id: d58dd774-b23d-4af1-88be-74dfa104861d + version: -1 + name: Pivot Registrar + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + registrar: + simple: ${PivotableDomains.PivotableRegistrar.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 2790, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "46": + id: "46" + taskid: 8d9bde15-525e-4748-8a80-01fc3b5e6c41 + type: condition + task: + id: 8d9bde15-525e-4748-8a80-01fc3b5e6c41 + version: -1 + name: Is Pivotable SSL Subject? + description: 'Is SSL subject a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + SSL Subject: + - "47" + separatecontext: false + conditions: + - label: SSL Subject + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableSslSubject.pivotable + iscontext: true + view: |- + { + "position": { + "x": 3220, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "47": + id: "47" + taskid: c13bcb3d-56d1-4a53-8241-6a13059262fb + type: regular + task: + id: c13bcb3d-56d1-4a53-8241-6a13059262fb + version: -1 + name: Pivot SSL Subject + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + ssl_subject: + simple: ${PivotableDomains.PivotableSslSubject.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 3220, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "48": + id: "48" + taskid: f4abc552-69f0-40c1-8bb9-5be30639fa12 + type: condition + task: + id: f4abc552-69f0-40c1-8bb9-5be30639fa12 + version: -1 + name: Is Pivotable SSL Email? + description: 'Is SSL email a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + SSL Email: + - "49" + separatecontext: false + conditions: + - label: SSL Email + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableSslEmail.pivotable + iscontext: true + view: |- + { + "position": { + "x": 3670, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "49": + id: "49" + taskid: 3e6e805d-7d01-46b0-8d90-5ca6fc5ce8c2 + type: regular + task: + id: 3e6e805d-7d01-46b0-8d90-5ca6fc5ce8c2 + version: -1 + name: Pivot SSL Email + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + ssl_email: + simple: ${PivotableDomains.PivotableSslEmail.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 3660, + "y": 980 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "50": + id: "50" + taskid: ff4b596d-8de9-468a-8f1b-d3c46422b824 + type: condition + task: + id: ff4b596d-8de9-468a-8f1b-d3c46422b824 + version: -1 + name: Is Pivotable NS Domain? + description: 'Is NS domain a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + NS Domain: + - "51" + separatecontext: false + conditions: + - label: NS Domain + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableNameServerDomain.pivotable + iscontext: true + view: |- + { + "position": { + "x": 4100, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "51": + id: "51" + taskid: 76382550-5490-4c99-837f-a08e8059584e + type: regular + task: + id: 76382550-5490-4c99-837f-a08e8059584e + version: -1 + name: Pivot Nameserver Domain + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + nameserver_domain: + simple: ${PivotableDomains.PivotableNameServerDomain.items.value} + separatecontext: false + view: |- + { + "position": { + "x": 4080, + "y": 990 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "52": + id: "52" + taskid: 0da04d50-78c2-4b8d-841e-01cbb96f7adf + type: condition + task: + id: 0da04d50-78c2-4b8d-841e-01cbb96f7adf + version: -1 + name: Is Pivotable Google Analytics? + description: 'Is Google analytics a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + Google Analytics: + - "53" + separatecontext: false + conditions: + - label: Google Analytics + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableGoogleAnalytics.pivotable + iscontext: true + view: |- + { + "position": { + "x": -2510, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "53": + id: "53" + taskid: 311dd4f0-bf51-4375-8f48-11515620a153 + type: regular + task: + id: 311dd4f0-bf51-4375-8f48-11515620a153 + version: -1 + name: Pivot Google Analytics + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + google_analytics: + simple: ${PivotableDomains.PivotableGoogleAnalytics.items.value} + separatecontext: false + view: |- + { + "position": { + "x": -2530, + "y": 970 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "54": + id: "54" + taskid: c348790d-db73-4e67-8962-ae8a23c1e25f + type: condition + task: + id: c348790d-db73-4e67-8962-ae8a23c1e25f + version: -1 + name: Is Pivotable Adsense? + description: 'Is adsense a guided pivot.' + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "4" + Adsense: + - "55" + separatecontext: false + conditions: + - label: Adsense + condition: + - - operator: isTrue + left: + value: + simple: PivotableDomains.PivotableAdsense.pivotable + iscontext: true + view: |- + { + "position": { + "x": -2950, + "y": 770 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "55": + id: "55" + taskid: 357eb1ab-fcd3-4b67-8b28-345b642cb5e1 + type: regular + task: + id: 357eb1ab-fcd3-4b67-8b28-345b642cb5e1 + version: -1 + name: Pivot Adsense + description: Pivot on connected infrastructure (IP, email, SSL), or import domains from Iris Investigate using a search hash. Retrieves up to 5000 domains at a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + adsense: + simple: ${PivotableDomains.PivotableAdsense.items.value} + separatecontext: false + view: |- + { + "position": { + "x": -2960, + "y": 970 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false +view: |- + { + "linkLabelsPosition": { + "17_4_#default#": 0.44 + }, + "paper": { + "dimensions": { + "height": 2625, + "width": 7440, + "x": -2960, + "y": 70 + } + } + } +inputs: +- key: domains + value: {} + required: true + description: 'The domains to lookup. ' + playbookInputQuery: +- key: dt_riskscore_threshold + value: + simple: "50" + required: true + description: The risk score threshold to compare. + playbookInputQuery: +- key: should_wait_for_analyst_review + value: + simple: "false" + required: true + description: Flags if users should wait for an analyst to review. Default is false. Value can be either true/false only. + playbookInputQuery: +- key: dt_max_name_server_host_count + value: + simple: "250" + required: false + description: The max nameserver host pivot count threshold + playbookInputQuery: +- key: dt_max_registrant_contact_name_count + value: + simple: "200" + required: false + description: The max registrant contact name pivot count threshold + playbookInputQuery: +- key: dt_max_registrant_org_count + value: + simple: "200" + required: false + description: 'The max registrant org pivot count threshold ' + playbookInputQuery: +- key: dt_max_ssl_info_organization_count + value: + simple: "200" + required: false + description: the max ssl info organization pivot count threshold + playbookInputQuery: +- key: dt_max_ssl_info_hash_count + value: + simple: "350" + required: false + description: the max ssl info hash pivot count threshold + playbookInputQuery: +- key: dt_max_soa_email_count + value: + simple: "200" + required: false + description: the max soa email pivot count threshold + playbookInputQuery: +- key: dt_max_ip_address_count + value: + simple: "150" + required: false + description: the max ip address pivot count threshold + playbookInputQuery: +- key: dt_max_name_server_ip_count + value: + simple: "250" + required: false + description: the max nameserver ip pivot count threshold + playbookInputQuery: +- key: dt_max_mx_ip_count + value: + simple: "200" + required: false + description: the max MX ip pivot count threshold + playbookInputQuery: +- key: dt_max_ssl_email_count + value: + simple: "200" + required: false + description: The max ssl email pivot count threshold + playbookInputQuery: +- key: dt_max_registrar_count + value: {} + required: false + description: The max registrar pivot count threshold + playbookInputQuery: +- key: dt_max_ssl_subject_count + value: + simple: "200" + required: false + description: the max ssl subject pivot count threshold + playbookInputQuery: +- key: dt_max_name_server_domain_count + value: + simple: "200" + required: false + description: the max name server domain pivot count threshold + playbookInputQuery: +- key: dt_max_mx_host_count + value: + simple: "200" + required: false + description: the max MX host pivot count threshold + playbookInputQuery: +- key: dt_max_mx_domain_count + value: + simple: "200" + required: false + description: the max MX domain pivot count threshold + playbookInputQuery: +- key: dt_max_google_adsense_count + value: + simple: "200" + required: false + description: the max google adsense pivot count threshold + playbookInputQuery: +- key: dt_max_google_analytics_count + value: {} + required: false + description: the max google analytics pivot count threshold + playbookInputQuery: +outputs: +- contextPath: HighRiskPivotedDomains.Name + description: The domain name +- contextPath: HighRiskPivotedDomains.OverallRiskScore + description: The overall risk score of the domain +- contextPath: DomainTools.Pivots.PivotedDomains.Name + description: The DomainTools Domain Name. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.LastEnriched + description: The last time DomainTools enriched domain data. + type: Date +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.OverallRiskScore + description: The DomainTools Overall Risk Score. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.ProximityRiskScore + description: The DomainTools Proximity Risk Score. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.ThreatProfileRiskScore.RiskScore + description: The DomainTools Threat Profile Risk Score. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.ThreatProfileRiskScore.Threats + description: The DomainTools Threat Profile Threats. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.ThreatProfileRiskScore.Evidence + description: The DomainTools Threat Profile Evidence. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.WebsiteResponseCode + description: The Website Response Code. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.AlexaRank + description: The Alexa Rank. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.Tags + description: The DomainTools Tags. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantName + description: The name of the registrant. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantOrg + description: The organization of the registrant. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Country.value + description: The country value of the registrant contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Country.count + description: The Country count of the registrant contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Email.value + description: The Email value of the registrant contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Email.count + description: The Email count of the registrant contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Name.value + description: The name value of the registrant contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Name.count + description: The name count of the registrant contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Phone.value + description: The phone value of the registrant contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Phone.count + description: The phone count of the registrant contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.SOAEmail + description: The SOA record Email. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.SSLCertificateEmail + description: The SSL certificate Email. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Country.value + description: The country value of the administrator contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Country.count + description: The country count of the administrator contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Email.value + description: The Email value of the administrator contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Email.count + description: The Email count of the administrator contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Name.value + description: The name value of the administrator contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Name.count + description: The name count of the administrator contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Phone.value + description: The phone value of the administrator contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Phone.count + description: The phone count of the administrator contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Country.value + description: The country value of the technical contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Country.count + description: The country count of the technical contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Email.value + description: The Email value of the technical contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Email.count + description: The Email count of the technical contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Name.value + description: The name value of the technical contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Name.count + description: The name count of the technical contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Phone.value + description: The phone value of the technical contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Phone.count + description: The phone count of the technical contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Country.value + description: The country value of the billing contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Country.count + description: The country count of the billing contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Email.value + description: The Email value of the billing contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Email.count + description: The Email count of the billing contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Name.value + description: The name value of the billing contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Name.count + description: The name count of the billing contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Phone.value + description: The phone value of the billing contact. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Phone.count + description: The phone count of the billing contact. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.EmailDomains + description: The Email domains. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdditionalWhoisEmails.value + description: The value of the Additional Whois Emails. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Identity.AdditionalWhoisEmails.count + description: The count of the Additional Whois Emails. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Registration.DomainRegistrant + description: The registrant of the domain. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Registration.RegistrarStatus + description: The status of the registrar. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Registration.DomainStatus + description: The active status of the domain. + type: Boolean +- contextPath: DomainTools.Pivots.PivotedDomains.Registration.CreateDate + description: The date the domain was created. + type: Date +- contextPath: DomainTools.Pivots.PivotedDomains.Registration.ExpirationDate + description: The expiry date of the domain. + type: Date +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.address.value + description: The address value of the IP Addresses. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.address.count + description: The address count of the IP Addresses. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.asn.value + description: The ASN value of the IP Addresses. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.asn.count + description: The ASN count of the IP Addresses. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.country_code.value + description: The country code value of the IP Addresses. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.country_code.count + description: The country code count of the IP Addresses. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.isp.value + description: The ISP value of the IP Addresses. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.isp.count + description: The ISP count of the IP Addresses. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.IPCountryCode + description: The country code of the IP address. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.MailServers.domain.value + description: The domain value of the Mail Servers. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.MailServers.domain.count + description: The domain count of the Mail Servers. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.MailServers.host.value + description: The host value of the Mail Servers. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.MailServers.host.count + description: The host count of the Mail Servers. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.MailServers.ip.value + description: The IP value of the Mail Servers. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.MailServers.ip.count + description: The IP count of the Mail Servers. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SPFRecord + description: The SPF record. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.NameServers.domain.value + description: The domain value of the DomainTools Domains NameServers. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.NameServers.domain.count + description: The domain count of the DomainTools Domains NameServers. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.NameServers.host.value + description: The host value of the DomainTools Domains NameServers. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.NameServers.host.count + description: The host count of the DomainTools Domains NameServers. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.NameServers.ip.value + description: The IP value of the DomainTools Domains NameServers. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.NameServers.ip.count + description: The IP count of the DomainTools Domains NameServers. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.hash.value + description: The Hash value of the SSL certificate. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.hash.count + description: The Hash count of the SSL certificate. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.organization.value + description: The organization value of the SSL certificate. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.organization.count + description: The organization count of the SSL certificate. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.subject.value + description: The subject value of the SSL certificate. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.subject.count + description: The subject count of the SSL certificate. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.RedirectsTo.value + description: The Redirects To value of the domain. + type: String +- contextPath: DomainTools.Pivots.PivotedDomains.Hosting.RedirectsTo.count + description: The Redirects To count of the domain. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.GoogleAdsenseTrackingCode + description: The tracking code of Google Adsense. + type: Number +- contextPath: DomainTools.Pivots.PivotedDomains.Analytics.GoogleAnalyticTrackingCode + description: The tracking code of Google Analytics. + type: Number +tests: +- No tests (auto formatted) +fromversion: 6.9.0 diff --git a/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md b/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md new file mode 100644 index 0000000..eafef86 --- /dev/null +++ b/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md @@ -0,0 +1,150 @@ +## DomainTools Auto Pivots + +This playbook retrieves the Iris Investigate profile of domain and automatically identifies potential connected infrastructure related to artifacts based on DomainTools Guided Pivot value. + +## Dependencies +This playbook uses the following sub-playbooks, integrations, lists and scripts. + +### Sub-playbooks +This playbook does not use any sub-playbooks. + +### Integrations +* DomainTools Iris + +### Scripts +Please install this scripts by DomainTools first before running the playbook. +- `CheckPivotableDomains` +- `AddDomainRiskScoreToContext` + +### Commands +* domain +* domaintoolsiris-pivot + + +## Playbook Inputs +--- + +| **Name** | **Description** | **Default Value** | **Source** | **Required** | +| --- | --- | --- | --- | --- | +| domains | The domains to lookup. | None | None | Required | +| dt_riskscore_threshold | The minimum risk score threshold value to check. | 50 | None | Required | +| should_wait_for_analyst_review | Flags if users should wait for an analyst to review. Default is false. Value can be either true/false only. | false | None | Required | +| dt_max_name_server_host_count | The max nameserver host pivot count threshold | 250 | None | No | +| dt_max_registrant_contact_name_count | The max registrant contact name pivot count threshold | 200 | None | No | +| dt_max_registrant_org_count | The max registrant org pivot count threshold | 200 | None | No | +| dt_max_ssl_info_organization_count | The max ssl info organization pivot count threshold | 200 | None | No | +| dt_max_ssl_info_hash_count | The max ssl info hash pivot count threshold | 350 | None | No | +| dt_max_soa_email_count | The max soa email pivot count threshold | 200 | None | No | +| dt_max_ip_address_count | The max ip address pivot count threshold | 150 | None | No | +| dt_max_name_server_ip_count | The max nameserver ip pivot count threshold | 250 | None | No | +| dt_max_mx_ip_count | The max MX ip pivot count threshold | 200 | None | No | +| dt_max_ssl_email_count | The max ssl email pivot count threshold | 200 | None | No | +| dt_max_registrar_count | The max registrar pivot count threshold | 200 | None | No | +| dt_max_ssl_subject_count | The max ssl subject pivot count threshold | 200 | None | No | +| dt_max_name_server_domain_count | The max name server domain pivot count threshold | 200 | None | No | +| dt_max_mx_host_count | The max MX host pivot count threshold | 200 | None | No | +| dt_max_mx_domain_count | The max MX domain pivot count threshold | 200 | None | No | +| dt_max_google_adsense_count | The max google adsense pivot count threshold | 200 | None | No | +| dt_max_google_analytics_count | The max google analytics pivot count threshold | 200 | None | No | + + +## Playbook Outputs +--- +This playbook extracts results from the 'domaintoolsiris-pivot' command and incorporates them into the context. Furthermore, it identifies high-risk domains by applying a risk score threshold to the pivoted commands. + +*Output from `AddDomainRiskScoreToContext`:* +| **Path** | **Description** | **Type** | +| --- | --- | --- | +| HighRiskPivotedDomains.Name | The domain name | String | +| HighRiskPivotedDomains.OverallRiskScore | The overall risk score of the domain | Number | + + +*Output from `domaintoolsiris-pivot`:* +| **Path** | **Description** | **Type** | +| --- | --- | --- | +| DomainTools.Pivots.PivotedDomains.Name | The DomainTools domain name. | String | +| DomainTools.Pivots.PivotedDomains.LastEnriched | The last time DomainTools enriched domain data. | Date | +| DomainTools.Pivots.PivotedDomains.Analytics.OverallRiskScore | The DomainTools overall risk score. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.ProximityRiskScore | The DomainTools proximity risk score. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.ThreatProfileRiskScore.RiskScore | The DomainTools threat profile risk score. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.ThreatProfileRiskScore.Threats | The DomainTools threat profile threats. | String | +| DomainTools.Pivots.PivotedDomains.Analytics.ThreatProfileRiskScore.Evidence | The DomainTools threat profile evidence. | String | +| DomainTools.Pivots.PivotedDomains.Analytics.WebsiteResponseCode | The website response code. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.AlexaRank | The Alexa rank. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.Tags | The DomainTools Tags. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantName | The name of the registrant. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantOrg | The organization of the registrant. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Country.value | The country value of the registrant contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Country.count | The country count of the registrant contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Email.value | The email value of the registrant contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Email.count | The email count of the registrant contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Name.value | The name value of the registrant contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Name.count | The name count of the registrant contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Phone.value | The phone value of the registrant contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.RegistrantContact.Phone.count | The phone count of the registrant contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.SOAEmail | The SOA record Email. | String | +| DomainTools.Pivots.PivotedDomains.Identity.SSLCertificateEmail | The SSL certificate email. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Country.value | The country value of the administrator contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Country.count | The country count of the administrator contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Email.value | The email value of the administrator contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Email.count | The email count of the administrator contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Name.value | The name value of the administrator contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Name.count | The name count of the administrator contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Phone.value | The phone value of the administrator contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdminContact.Phone.count | The phone count of the administrator contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Country.value | The country value of the technical contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Country.count | The country count of the technical contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Email.value | The email value of the technical contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Email.count | The email count of the technical contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Name.value | The name value of the technical contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Name.count | The name count of the technical contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Phone.value | The phone value of the technical contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.TechnicalContact.Phone.count | The phone count of the technical contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Country.value | The country value of the billing contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Country.count | The country count of the billing contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Email.value | The email value of the billing contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Email.count | The email count of the billing contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Name.value | The name value of the billing contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Name.count | The name count of the billing contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Phone.value | The phone value of the billing contact. | String | +| DomainTools.Pivots.PivotedDomains.Identity.BillingContact.Phone.count | The phone count of the billing contact. | Number | +| DomainTools.Pivots.PivotedDomains.Identity.EmailDomains | The email domains. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdditionalWhoisEmails.value | The value of the additional Whois emails. | String | +| DomainTools.Pivots.PivotedDomains.Identity.AdditionalWhoisEmails.count | The count of the additional Whois emails. | Number | +| DomainTools.Pivots.PivotedDomains.Registration.DomainRegistrant | The registrant of the domain. | String | +| DomainTools.Pivots.PivotedDomains.Registration.RegistrarStatus | The status of the registrar. | String | +| DomainTools.Pivots.PivotedDomains.Registration.DomainStatus | The active status of the domain. | Boolean | +| DomainTools.Pivots.PivotedDomains.Registration.CreateDate | The date the domain was created. | Date | +| DomainTools.Pivots.PivotedDomains.Registration.ExpirationDate | The expiry date of the domain. | Date | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.address.value | The address value of the IP Addresses. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.address.count | The address count of the IP Addresses. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.asn.value | The ASN value of the IP Addresses. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.asn.count | The ASN count of the IP Addresses. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.country_code.value | The country code value of the IP Addresses. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.country_code.count | The country code count of the IP Addresses. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.isp.value | The ISP value of the IP Addresses. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.IPAddresses.isp.count | The ISP count of the IP Addresses. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.IPCountryCode | The country code of the IP address. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.MailServers.domain.value | The domain value of the mail servers. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.MailServers.domain.count | The domain count of the mail servers. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.MailServers.host.value | The host value of the mail servers. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.MailServers.host.count | The host count of the mail servers. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.MailServers.ip.value | The IP value of the mail servers. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.MailServers.ip.count | The IP count of the mail servers. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.SPFRecord | The SPF record. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.NameServers.domain.value | The domain value of the DomainTools domains name servers. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.NameServers.domain.count | The domain count of the domainTools Domains name servers. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.NameServers.host.value | The host value of the DomainTools domains name servers. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.NameServers.host.count | The host count of the DomainTools domains name servers. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.NameServers.ip.value | The IP value of the DomainTools domains name servers. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.NameServers.ip.count | The IP count of the DomainTools domains name servers. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.hash.value | The hash value of the SSL certificate. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.hash.count | The hash count of the SSL certificate. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.organization.value | The organization value of the SSL certificate. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.organization.count | The organization count of the SSL certificate. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.subject.value | The subject value of the SSL certificate. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.SSLCertificate.subject.count | The subject count of the SSL certificate. | Number | +| DomainTools.Pivots.PivotedDomains.Hosting.RedirectsTo.value | The redirects to value of the domain. | String | +| DomainTools.Pivots.PivotedDomains.Hosting.RedirectsTo.count | The redirects to count of the domain. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.GoogleAdsenseTrackingCode | The tracking code of Google Adsense. | Number | +| DomainTools.Pivots.PivotedDomains.Analytics.GoogleAnalyticTrackingCode | The tracking code of Google Analytics. | Number | diff --git a/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Iris_Tags.yml b/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Iris_Tags.yml new file mode 100644 index 0000000..9b70f2e --- /dev/null +++ b/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Iris_Tags.yml @@ -0,0 +1,311 @@ +id: DomainTools_Check_Domain_Risk_Score_By_Iris_Tags +version: -1 +vcShouldKeepItemLegacyProdMachine: false +name: DomainTools Check Domain Risk Score By Iris Tags +description: This playbook will alert a user if a monitored set of domains, labeled + by Iris Investigate tags, becomes high risk. To use it, tag domains in the Iris + Investigate UI. Enter a comma-separated list of tags to monitor to the playbook + input "dt_monitored_iris_tags" and run this playbook on a scheduled basis. It will + add any new high risk domains (based on the threshold defined in this playbook) + as indicators on the associated incident. +tags: +- Domaintools +starttaskid: "0" +tasks: + "0": + id: "0" + taskid: 89d688bd-2022-42de-86e8-e89f16fddd75 + type: start + task: + id: 89d688bd-2022-42de-86e8-e89f16fddd75 + version: -1 + name: "" + iscommand: false + brand: "" + description: '' + nexttasks: + '#none#': + - "1" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 50 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "1": + id: "1" + taskid: ab1c0140-232a-4f9b-8f17-032bfe53def0 + type: regular + task: + id: ab1c0140-232a-4f9b-8f17-032bfe53def0 + version: -1 + name: Query Domains by Iris Tag(s) + description: Pivot on connected infrastructure (IP, email, SSL), or import domains + from Iris Investigate using a search hash. Retrieves up to 5000 domains at + a time. Optionally attach the results to context with include_context=true. + script: DomainTools Iris|||domaintoolsiris-pivot + type: regular + iscommand: true + brand: DomainTools Iris + nexttasks: + '#none#': + - "4" + scriptarguments: + tagged_with_any: + complex: + root: inputs.dt_monitored_iris_tags + transformers: + - operator: trim + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 195 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "2": + id: "2" + taskid: 08cfdb90-ed08-4a4b-8cb4-a4d15eee3c10 + type: title + description: 'Title' + task: + id: 08cfdb90-ed08-4a4b-8cb4-a4d15eee3c10 + version: -1 + name: Done + type: title + iscommand: false + brand: "" + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 1100 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "3": + id: "3" + taskid: b33df737-cba2-4c75-8ec0-60dd106fa207 + type: regular + description: 'Manually Review High Risk Score Domains' + task: + id: b33df737-cba2-4c75-8ec0-60dd106fa207 + version: -1 + name: Manually Review High Risk Score Domains + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "2" + separatecontext: false + defaultassigneecomplex: + simple: Analyst + view: |- + { + "position": { + "x": -400, + "y": 920 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "4": + id: "4" + taskid: cfeb1fe9-de0e-46b9-8307-a18a3ad5a1e2 + type: condition + task: + id: cfeb1fe9-de0e-46b9-8307-a18a3ad5a1e2 + version: -1 + name: Is there any Active and High Risk Score Domain? + description: |- + Checks if one number(float) as bigger than the other(float) + Returns yes: if first > second + Returns no: if first <= second + Returns exception if one of the inputs is not a number + scriptName: IsGreaterThan + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "2" + "yes": + - "5" + scriptarguments: + first: + simple: ${DomainTools.Pivots.PivotedDomains.Analytics.OverallRiskScore} + second: + simple: ${inputs.dt_min_riskscore_threshold} + separatecontext: false + view: |- + { + "position": { + "x": 50, + "y": 370 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "5": + id: "5" + taskid: f9dd6ec0-6672-4116-8686-e0da296f1616 + type: regular + task: + id: f9dd6ec0-6672-4116-8686-e0da296f1616 + version: -1 + name: Add High Risk Domain to Indicator + description: Sets Data for a Domain in the Indicator Table + scriptName: SetIndicatorTableData + type: regular + iscommand: false + brand: "" + nexttasks: + '#none#': + - "6" + scriptarguments: + domaintools_data: + complex: + root: DomainTools.Pivots.PivotedDomains + filters: + - - operator: greaterThan + left: + value: + simple: DomainTools.Pivots.PivotedDomains.Analytics.OverallRiskScore + iscontext: true + right: + value: + simple: inputs.dt_min_riskscore_threshold + iscontext: true + - - operator: isTrue + left: + value: + simple: DomainTools.Pivots.PivotedDomains.Registration.DomainStatus + iscontext: true + separatecontext: false + view: |- + { + "position": { + "x": -390, + "y": 560 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false + "6": + id: "6" + taskid: 034fc5cb-6f90-4c37-8154-b995643d1edd + type: condition + description: 'Should wait for an analyst review?' + task: + id: 034fc5cb-6f90-4c37-8154-b995643d1edd + version: -1 + name: Should wait for an analyst review? + type: condition + iscommand: false + brand: "" + nexttasks: + '#default#': + - "2" + "yes": + - "3" + separatecontext: false + conditions: + - label: "yes" + condition: + - - operator: isTrue + left: + value: + simple: inputs.should_wait_for_analyst_review + iscontext: true + view: |- + { + "position": { + "x": -390, + "y": 710 + } + } + note: false + timertriggers: [] + ignoreworker: false + skipunavailable: false + quietmode: 0 + isoversize: false + isautoswitchedtoquietmode: false +view: |- + { + "linkLabelsPosition": { + "4_2_#default#": 0.57 + }, + "paper": { + "dimensions": { + "height": 1115, + "width": 830, + "x": -400, + "y": 50 + } + } + } +inputs: +- key: dt_min_riskscore_threshold + value: + simple: "70" + required: true + description: The minimum risk score threshold value to compare. + playbookInputQuery: null +- key: dt_monitored_iris_tags + value: + simple: blocklist,good + required: true + description: |- + The Iris tags to lookup. Values should be a comma separated value. + e.g. (tag1,tag2) + playbookInputQuery: null +- key: should_wait_for_analyst_review + value: + simple: "false" + required: true + description: Flags if users should wait for an analyst to review. Default is false. + Value can be either true/false only. + playbookInputQuery: null +outputs: [] +fromversion: 6.9.0 diff --git a/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md b/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md new file mode 100644 index 0000000..0f7a33f --- /dev/null +++ b/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md @@ -0,0 +1,32 @@ +## DomainTools Check Domain Risk Score By Tags Playbook + +This playbook call iris ivestigate api with a given "tag". Check active domains with high risk score then alerts user and outputs all high risk domains in the current incident indicators. + +## Dependencies +This playbook uses the following sub-playbooks, integrations, lists and scripts. + +### Sub-playbooks +This playbook does not use any sub-playbooks. + +### Integrations +* DomainTools Iris + +### Scripts +Please install this scripts by DomainTools first before running the playbook. +- `SetIndicatorTableData` + +### Commands +* domaintoolsiris-pivot + +## Playbook Inputs +--- + +| **Name** | **Description** | **Default Value** | **Source** | **Required** | +| --- | --- | --- | --- | --- | +| dt_min_riskscore_threshold | The minimum risk score threshold value to check. | None | None | Required | +| dt_monitored_iris_tags | The Iris tags to lookup. Values should be a comma separated value. e.g. (tag1,tag2) | None | None | Required | +| should_wait_for_analyst_review | Flags if users should wait for an analyst to review. Default is false. Value can be either true/false only. | false | None | Required | + +## Playbook Outputs +--- +This playbook outputs a high risk score domain as an indicator. \ No newline at end of file diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools_Alerting_Playbook_-_Check_Domain_Risk_Score_by_Tag.tgz b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools_Alerting_Playbook_-_Check_Domain_Risk_Score_by_Tag.tgz new file mode 100644 index 0000000000000000000000000000000000000000..5f9cdf56979bb3300c613e9ca3ff9d65c4a2115e GIT binary patch literal 4169 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 T^gKOJPx14AVhZ{$0C)fZ297q- literal 0 HcmV?d00001 diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/README.md b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/README.md new file mode 100644 index 0000000..e809816 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/README.md @@ -0,0 +1,18 @@ +## DomainTools Alerting Playbook - Check Domain Risk Score by Tag + +This playbook call iris ivestigate api with a given `tag`. Check active domains with high risk score then alerts user and outputs all high risk domains in a csv file. + +The flow will continue to retrieve new domains based on the scheduled run. + +#### DomainTools API Asset + +**The DomainTools playbooks in this repo will require an asset called `domaintoolscreds`** for a DomainTools API username and key. This asset is used to retrieve DomainTools data via the DomainTools API during playbook execution. +
+ +#### Before Installing +In this directory there is a csv called `domaintools_monitor_iris_tags.csv` that can be downloaded and used to import into the app under the "Custom Lists" tab on the "Playbooks" feature. With the `domaintoolscreds` asset loaded in, import the csv or create a custom list named `domaintools_monitor_iris_tags` and copy the contents of the csv into the custom list. +**The value in the list is the tags to query on iris investigate, the tags value should be a comma-seperated and can be changed by the analyst, but the first column should not be changed, otherwise the playbook will break.** + +#### Installation + +Download the tar file in this directory and import the playbook using that file. The asset accessed in the playbook is for DomainTools API credentials. Point the playbook to the `domaintoolscreds` asset, save the playbook, make sure it's active, and give it a shot. diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/domaintools_monitor_iris_tags.csv b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/domaintools_monitor_iris_tags.csv new file mode 100644 index 0000000..543c714 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/domaintools_monitor_iris_tags.csv @@ -0,0 +1,3 @@ +tags,"blocklist,good" +, +, diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools_Alerting_Playbook_-_New_Domains.tgz b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools_Alerting_Playbook_-_New_Domains.tgz new file mode 100644 index 0000000000000000000000000000000000000000..acf689401a0b3495f3bfc59c869e60c1b92a453e GIT binary patch literal 4005 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 LyHQr00C)fZ-JIVo literal 0 HcmV?d00001 diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/README.md b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/README.md new file mode 100644 index 0000000..697ae05 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/README.md @@ -0,0 +1,12 @@ +## DomainTools Alerting Playbook - New Domains + +This playbook retrieves domain in Iris Investigate from a given search hash with built-in `first_seen` param. The flow will continue to retrieve new domains based on the scheduled run + +#### DomainTools API Asset + +**The DomainTools playbooks in this repo will require an asset called `domaintoolscreds`** for a DomainTools API username and key. This asset is used to retrieve DomainTools data via the DomainTools API during playbook execution. Current action selected is `load_hash` and it requires `search_hash` input parameter. +
+ +#### Installation + +Download the tar file in this directory and import the playbook using that file. The asset accessed in the playbook is for DomainTools API credentials. Point the playbook to the `domaintoolscreds` asset, save the playbook, make sure it's active, and give it a shot. From 7635c3fd5a14872db84b9157e35ca41ab3ee6de0 Mon Sep 17 00:00:00 2001 From: bluza Date: Wed, 2 Apr 2025 23:31:38 +0800 Subject: [PATCH 2/2] add playbook for cortex and splunk SOAR --- .github/workflows/package.yml | 2 +- .../DomainTools_Auto_Pivots_README.md | 17 +- ..._Check_Domain_Risk_Score_By_Tags_README.md | 12 +- ...book - Check Domain Risk Score by Tag.json | 331 ++++++++++++++++++ ...aybook - Check Domain Risk Score by Tag.py | 249 +++++++++++++ ...ybook_-_Check_Domain_Risk_Score_by_Tag.tgz | Bin 4169 -> 0 bytes ...Tools Alerting Playbook - New Domains.json | 320 +++++++++++++++++ ...inTools Alerting Playbook - New Domains.py | 232 ++++++++++++ ...nTools_Alerting_Playbook_-_New_Domains.tgz | Bin 4005 -> 0 bytes 9 files changed, 1155 insertions(+), 8 deletions(-) create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.json create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.py delete mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools_Alerting_Playbook_-_Check_Domain_Risk_Score_by_Tag.tgz create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.json create mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.py delete mode 100644 src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools_Alerting_Playbook_-_New_Domains.tgz diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 8b14c6e..7d9863b 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -42,7 +42,7 @@ jobs: parent_folder=$(echo "$dir" | cut -d'/' -f3) sub_folder=$(echo "$dir" | cut -d'/' -f4) - echo "Category: category_folder, Parent: $parent_folder, Sub-folder: $sub_folder" + echo "Category: $category_folder, Parent: $parent_folder, Sub-folder: $sub_folder" mkdir -p "packaged_playbooks/$category_folder/$parent_folder" echo "Created directory: packaged_playbooks/$category_folder/$parent_folder" diff --git a/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md b/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md index eafef86..e06ed95 100644 --- a/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md +++ b/src/Cortex XSOAR/playbooks/DomainTools_Auto_Pivots/DomainTools_Auto_Pivots_README.md @@ -3,25 +3,31 @@ This playbook retrieves the Iris Investigate profile of domain and automatically identifies potential connected infrastructure related to artifacts based on DomainTools Guided Pivot value. ## Dependencies + This playbook uses the following sub-playbooks, integrations, lists and scripts. ### Sub-playbooks + This playbook does not use any sub-playbooks. ### Integrations + * DomainTools Iris ### Scripts + Please install this scripts by DomainTools first before running the playbook. -- `CheckPivotableDomains` -- `AddDomainRiskScoreToContext` + +* `CheckPivotableDomains` +* `AddDomainRiskScoreToContext` ### Commands + * domain * domaintoolsiris-pivot - ## Playbook Inputs + --- | **Name** | **Description** | **Default Value** | **Source** | **Required** | @@ -47,19 +53,20 @@ Please install this scripts by DomainTools first before running the playbook. | dt_max_google_adsense_count | The max google adsense pivot count threshold | 200 | None | No | | dt_max_google_analytics_count | The max google analytics pivot count threshold | 200 | None | No | - ## Playbook Outputs + --- This playbook extracts results from the 'domaintoolsiris-pivot' command and incorporates them into the context. Furthermore, it identifies high-risk domains by applying a risk score threshold to the pivoted commands. *Output from `AddDomainRiskScoreToContext`:* + | **Path** | **Description** | **Type** | | --- | --- | --- | | HighRiskPivotedDomains.Name | The domain name | String | | HighRiskPivotedDomains.OverallRiskScore | The overall risk score of the domain | Number | - *Output from `domaintoolsiris-pivot`:* + | **Path** | **Description** | **Type** | | --- | --- | --- | | DomainTools.Pivots.PivotedDomains.Name | The DomainTools domain name. | String | diff --git a/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md b/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md index 0f7a33f..3c626da 100644 --- a/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md +++ b/src/Cortex XSOAR/playbooks/DomainTools_Check_Domain_Risk_Score_By_Tags/DomainTools_Check_Domain_Risk_Score_By_Tags_README.md @@ -3,22 +3,29 @@ This playbook call iris ivestigate api with a given "tag". Check active domains with high risk score then alerts user and outputs all high risk domains in the current incident indicators. ## Dependencies + This playbook uses the following sub-playbooks, integrations, lists and scripts. ### Sub-playbooks + This playbook does not use any sub-playbooks. ### Integrations + * DomainTools Iris ### Scripts + Please install this scripts by DomainTools first before running the playbook. -- `SetIndicatorTableData` + +* `SetIndicatorTableData` ### Commands + * domaintoolsiris-pivot ## Playbook Inputs + --- | **Name** | **Description** | **Default Value** | **Source** | **Required** | @@ -28,5 +35,6 @@ Please install this scripts by DomainTools first before running the playbook. | should_wait_for_analyst_review | Flags if users should wait for an analyst to review. Default is false. Value can be either true/false only. | false | None | Required | ## Playbook Outputs + --- -This playbook outputs a high risk score domain as an indicator. \ No newline at end of file +This playbook outputs a high risk score domain as an indicator. diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.json b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.json new file mode 100644 index 0000000..c0574e5 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.json @@ -0,0 +1,331 @@ +{ + "blockly": false, + "blockly_xml": "", + "category": "Uncategorized", + "coa": { + "data": { + "description": "This playbook call iris ivestigate api with a given \"tag\". Check active domains with high risk score then alerts user and outputs all high risk domains in a csv file. \n\nThe flow will continue to retrieve new domains based on the scheduled run", + "edges": [ + { + "id": "port_0_to_port_3", + "sourceNode": "0", + "sourcePort": "0_out", + "targetNode": "3", + "targetPort": "3_in" + }, + { + "id": "port_3_to_port_4", + "sourceNode": "3", + "sourcePort": "3_out", + "targetNode": "4", + "targetPort": "4_in" + }, + { + "id": "port_4_to_port_5", + "sourceNode": "4", + "sourcePort": "4_out", + "targetNode": "5", + "targetPort": "5_in" + }, + { + "id": "port_5_to_port_7", + "sourceNode": "5", + "sourcePort": "5_out", + "targetNode": "7", + "targetPort": "7_in" + }, + { + "conditions": [ + { + "index": 1 + } + ], + "id": "port_7_to_port_1", + "sourceNode": "7", + "sourcePort": "7_out", + "targetNode": "1", + "targetPort": "1_in" + }, + { + "conditions": [ + { + "index": 0 + } + ], + "id": "port_7_to_port_8", + "sourceNode": "7", + "sourcePort": "7_out", + "targetNode": "8", + "targetPort": "8_in" + }, + { + "id": "port_8_to_port_9", + "sourceNode": "8", + "sourcePort": "8_out", + "targetNode": "9", + "targetPort": "9_in" + }, + { + "id": "port_9_to_port_1", + "sourceNode": "9", + "sourcePort": "9_out", + "targetNode": "1", + "targetPort": "1_in" + } + ], + "hash": "809d7bed39aa63ee08db85f2d8dbbb7660087019", + "nodes": { + "0": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_start", + "id": "0", + "type": "start" + }, + "errors": {}, + "id": "0", + "type": "start", + "warnings": {}, + "x": 20, + "y": 0 + }, + "1": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_finish", + "id": "1", + "type": "end" + }, + "errors": {}, + "id": "1", + "type": "end", + "warnings": {}, + "x": 20, + "y": 1116 + }, + "3": { + "data": { + "advanced": { + "customName": "get_iris_tags", + "customNameId": 0, + "join": [] + }, + "functionId": 1, + "functionName": "get_iris_tags", + "id": "3", + "inputParameters": [], + "outputVariables": [ + "iris_tags" + ], + "type": "code" + }, + "errors": {}, + "id": "3", + "type": "code", + "userCode": "\n # Write your custom code here...\n success, message, iris_tags = phantom.get_list(list_name='domaintools_monitor_iris_tags', values=\"tags\")\n tags = iris_tags['matches'][0]['value'][1]\n if not tags:\n phantom.error(\"dt debug - you must add atleast one(1) tag in domaintools_monitor_iris_tags list.\")\n return\n get_iris_tags__iris_tags = tags\n", + "warnings": {}, + "x": 0, + "y": 148 + }, + "4": { + "data": { + "action": "pivot action", + "actionType": "investigate", + "advanced": { + "join": [] + }, + "connector": "DomainTools Iris Investigate", + "connectorConfigs": [ + "domaintoolscreds" + ], + "connectorId": "f18b7ef9-0cbd-4dbb-b8ed-ce62e17f0603", + "connectorVersion": "v1", + "functionId": 1, + "functionName": "pivot_action_1", + "id": "4", + "parameters": { + "status": "Any" + }, + "requiredParameters": [ + { + "data_type": "string", + "default": "Any", + "field": "status" + }, + { + "data_type": "string", + "field": "pivot_type" + }, + { + "data_type": "string", + "field": "query_value" + } + ], + "type": "action" + }, + "errors": {}, + "id": "4", + "type": "action", + "userCode": "\n # Write your custom code here...\n parameters = []\n iris_tags = json.loads(phantom.get_run_data(key=\"get_iris_tags:iris_tags\"))\n parameters.append({\n \"status\": \"Any\",\n \"pivot_type\": \"tagged_with_any\",\n \"query_value\": iris_tags\n })\n \n", + "warnings": {}, + "x": 0, + "y": 296 + }, + "5": { + "data": { + "advanced": { + "customName": "check_risk_score", + "customNameId": 0, + "join": [] + }, + "functionId": 2, + "functionName": "check_risk_score", + "id": "5", + "inputParameters": [ + "pivot_action_1:action_result.data" + ], + "outputVariables": [ + "high_risk_domains", + "high_risk_domains_count", + "dt_min_risk_score" + ], + "type": "code" + }, + "errors": {}, + "id": "5", + "type": "code", + "userCode": "\n # Write your custom code here...\n queried_domains = []\n for results in pivot_action_1_result_item_0:\n for result in results:\n risk_score = result.get(\"domain_risk\", {}).get(\"risk_score\")\n domain = result.get(\"domain\")\n is_active = result.get(\"active\")\n queried_domains.append({\"domain\": domain, \"risk_score\": risk_score, \"active\": is_active})\n \n phantom.debug(f\"dt debug - checking {len(queried_domains)} domains from iris investigate.\")\n \n success, message, min_risk_score = phantom.get_list(list_name='domaintools_domain_risk', values=\"min_risk_score\")\n domaintools_min_risk_score = int(min_risk_score['matches'][0]['value'][1])\n \n high_risk_domains = []\n for domain in queried_domains:\n risk_score = int(domain.get(\"risk_score\"))\n is_active = domain.get(\"active\")\n \n if risk_score >= domaintools_min_risk_score and is_active:\n high_risk_domains.append(domain)\n \n check_risk_score__high_risk_domains = high_risk_domains\n check_risk_score__high_risk_domains_count = len(high_risk_domains)\n check_risk_score__dt_min_risk_score = domaintools_min_risk_score\n phantom.debug(f\"dt debug - Found {check_risk_score__high_risk_domains_count} high risk domain(s).\")\n \n \n", + "warnings": {}, + "x": 0, + "y": 444 + }, + "7": { + "data": { + "advanced": { + "customName": "", + "customNameId": -1, + "join": [] + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": ">=", + "param": "check_risk_score:custom_function:high_risk_domains_count", + "value": "1" + } + ], + "conditionIndex": 0, + "display": "If", + "logic": "and", + "type": "if" + }, + { + "comparisons": [ + { + "op": "==", + "param": "", + "value": "" + } + ], + "conditionIndex": 1, + "display": "Else", + "logic": "and", + "type": "else" + } + ], + "functionId": 1, + "functionName": "decision_1", + "id": "7", + "type": "decision" + }, + "errors": {}, + "id": "7", + "type": "decision", + "warnings": {}, + "x": 80, + "y": 592 + }, + "8": { + "data": { + "advanced": { + "customName": "output_high_risk_domains", + "customNameId": 0, + "join": [] + }, + "functionId": 4, + "functionName": "output_high_risk_domains", + "id": "8", + "inputParameters": [ + "check_risk_score:custom_function:high_risk_domains", + "check_risk_score:custom_function:out_filename", + "check_risk_score:custom_function:high_risk_domains_count" + ], + "outputVariables": [ + "out_filename", + "event_name" + ], + "type": "code" + }, + "errors": {}, + "id": "8", + "type": "code", + "userCode": "\n # Write your custom code here...\n from datetime import datetime\n import csv\n \n event_name = container.get(\"name\")\n file_name = f\"alert_high_risk_score_domains_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv\"\n phantom.debug(f\"dt debug - exporting {check_risk_score__high_risk_domains_count} domain to csv file.\")\n \n with open(f\"/opt/phantom/vault/tmp/{file_name}\", \"w\", newline='') as report_csv_file:\n headers = [\"domain\", \"risk_score\", \"active\"]\n writer = csv.DictWriter(report_csv_file, fieldnames=headers)\n \n writer.writeheader()\n for domain in check_risk_score__high_risk_domains or []:\n writer.writerow(domain)\n \n success, message, vault_id = phantom.vault_add(container=container, file_location=f\"/opt/phantom/vault/tmp/{file_name}\", file_name=file_name)\n phantom.debug(f\"dt debug - {message}\")\n \n if not success:\n phantom.error(f\"dt error - Error creating {file_name} file. Message: {message}\")\n return\n \n output_high_risk_domains__out_filename = file_name\n output_high_risk_domains__event_name = event_name\n", + "warnings": {}, + "x": 100, + "y": 780 + }, + "9": { + "data": { + "advanced": { + "customName": "alert_high_risk_domain", + "customNameId": 0, + "join": [] + }, + "approver": { + "type": "user", + "value": "admin" + }, + "functionId": 1, + "functionName": "alert_high_risk_domain", + "id": "9", + "message": "Found {0} domain with risk score >= {1}. For more details go to Event: {2} > \"Files\" tab > Download '{3}'.\n", + "parameters": [ + "check_risk_score:custom_function:high_risk_domains_count", + "check_risk_score:custom_function:dt_min_risk_score", + "output_high_risk_domains:custom_function:event_name", + "output_high_risk_domains:custom_function:out_filename" + ], + "responseTime": 30, + "responses": [], + "type": "prompt" + }, + "errors": {}, + "id": "9", + "type": "prompt", + "warnings": {}, + "x": 180, + "y": 940 + } + }, + "notes": "" + }, + "input_spec": null, + "output_spec": null, + "playbook_type": "automation", + "python_version": "3", + "schema": "5.0.9", + "version": "6.0.0.114895" + }, + "create_time": "2023-08-11T16:02:58.643261+00:00", + "draft_mode": false, + "labels": [ + "events" + ], + "tags": [] +} \ No newline at end of file diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.py b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.py new file mode 100644 index 0000000..9ca7455 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools Alerting Playbook - Check Domain Risk Score by Tag.py @@ -0,0 +1,249 @@ +""" +This playbook call iris ivestigate api with a given "tag". Check active domains with high risk score then alerts user and outputs all high risk domains in a csv file. \n\nThe flow will continue to retrieve new domains based on the scheduled run +""" + + +import phantom.rules as phantom +import json +from datetime import datetime, timedelta + + +@phantom.playbook_block() +def on_start(container): + phantom.debug('on_start() called') + + # call 'get_iris_tags' block + get_iris_tags(container=container) + + return + +@phantom.playbook_block() +def get_iris_tags(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("get_iris_tags() called") + + get_iris_tags__iris_tags = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + success, message, iris_tags = phantom.get_list(list_name='domaintools_monitor_iris_tags', values="tags") + tags = iris_tags['matches'][0]['value'][1] + if not tags: + phantom.error("dt debug - you must add atleast one(1) tag in domaintools_monitor_iris_tags list.") + return + get_iris_tags__iris_tags = tags + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="get_iris_tags:iris_tags", value=json.dumps(get_iris_tags__iris_tags)) + + pivot_action_1(container=container) + + return + + +@phantom.playbook_block() +def pivot_action_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("pivot_action_1() called") + + # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) + + parameters = [] + + parameters.append({ + "status": "Any", + "pivot_type": "", + "query_value": "", + }) + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + parameters = [] + iris_tags = json.loads(phantom.get_run_data(key="get_iris_tags:iris_tags")) + parameters.append({ + "status": "Any", + "pivot_type": "tagged_with_any", + "query_value": iris_tags + }) + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.act("pivot action", parameters=parameters, name="pivot_action_1", assets=["domaintoolscreds"], callback=check_risk_score) + + return + + +@phantom.playbook_block() +def check_risk_score(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("check_risk_score() called") + + pivot_action_1_result_data = phantom.collect2(container=container, datapath=["pivot_action_1:action_result.data"], action_results=results) + + pivot_action_1_result_item_0 = [item[0] for item in pivot_action_1_result_data] + + check_risk_score__high_risk_domains = None + check_risk_score__high_risk_domains_count = None + check_risk_score__dt_min_risk_score = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + queried_domains = [] + for results in pivot_action_1_result_item_0: + for result in results: + risk_score = result.get("domain_risk", {}).get("risk_score") + domain = result.get("domain") + is_active = result.get("active") + queried_domains.append({"domain": domain, "risk_score": risk_score, "active": is_active}) + + phantom.debug(f"dt debug - checking {len(queried_domains)} domains from iris investigate.") + + success, message, min_risk_score = phantom.get_list(list_name='domaintools_domain_risk', values="min_risk_score") + domaintools_min_risk_score = int(min_risk_score['matches'][0]['value'][1]) + + high_risk_domains = [] + for domain in queried_domains: + risk_score = int(domain.get("risk_score")) + is_active = domain.get("active") + + if risk_score >= domaintools_min_risk_score and is_active: + high_risk_domains.append(domain) + + check_risk_score__high_risk_domains = high_risk_domains + check_risk_score__high_risk_domains_count = len(high_risk_domains) + check_risk_score__dt_min_risk_score = domaintools_min_risk_score + phantom.debug(f"dt debug - Found {check_risk_score__high_risk_domains_count} high risk domain(s).") + + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="check_risk_score:high_risk_domains", value=json.dumps(check_risk_score__high_risk_domains)) + phantom.save_run_data(key="check_risk_score:high_risk_domains_count", value=json.dumps(check_risk_score__high_risk_domains_count)) + phantom.save_run_data(key="check_risk_score:dt_min_risk_score", value=json.dumps(check_risk_score__dt_min_risk_score)) + + decision_1(container=container) + + return + + +@phantom.playbook_block() +def decision_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("decision_1() called") + + # check for 'if' condition 1 + found_match_1 = phantom.decision( + container=container, + conditions=[ + ["check_risk_score:custom_function:high_risk_domains_count", ">=", 1] + ]) + + # call connected blocks if condition 1 matched + if found_match_1: + output_high_risk_domains(action=action, success=success, container=container, results=results, handle=handle) + return + + return + + +@phantom.playbook_block() +def output_high_risk_domains(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("output_high_risk_domains() called") + + check_risk_score__high_risk_domains = json.loads(_ if (_ := phantom.get_run_data(key="check_risk_score:high_risk_domains")) != "" else "null") # pylint: disable=used-before-assignment + check_risk_score__out_filename = json.loads(_ if (_ := phantom.get_run_data(key="check_risk_score:out_filename")) != "" else "null") # pylint: disable=used-before-assignment + check_risk_score__high_risk_domains_count = json.loads(_ if (_ := phantom.get_run_data(key="check_risk_score:high_risk_domains_count")) != "" else "null") # pylint: disable=used-before-assignment + + output_high_risk_domains__out_filename = None + output_high_risk_domains__event_name = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + from datetime import datetime + import csv + + event_name = container.get("name") + file_name = f"alert_high_risk_score_domains_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" + phantom.debug(f"dt debug - exporting {check_risk_score__high_risk_domains_count} domain to csv file.") + + with open(f"/opt/phantom/vault/tmp/{file_name}", "w", newline='') as report_csv_file: + headers = ["domain", "risk_score", "active"] + writer = csv.DictWriter(report_csv_file, fieldnames=headers) + + writer.writeheader() + for domain in check_risk_score__high_risk_domains or []: + writer.writerow(domain) + + success, message, vault_id = phantom.vault_add(container=container, file_location=f"/opt/phantom/vault/tmp/{file_name}", file_name=file_name) + phantom.debug(f"dt debug - {message}") + + if not success: + phantom.error(f"dt error - Error creating {file_name} file. Message: {message}") + return + + output_high_risk_domains__out_filename = file_name + output_high_risk_domains__event_name = event_name + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="output_high_risk_domains:out_filename", value=json.dumps(output_high_risk_domains__out_filename)) + phantom.save_run_data(key="output_high_risk_domains:event_name", value=json.dumps(output_high_risk_domains__event_name)) + + alert_high_risk_domain(container=container) + + return + + +@phantom.playbook_block() +def alert_high_risk_domain(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("alert_high_risk_domain() called") + + # set user and message variables for phantom.prompt call + + user = "admin" + role = None + message = """Found {0} domain with risk score >= {1}. For more details go to Event: {2} > \"Files\" tab > Download '{3}'.\n""" + + # parameter list for template variable replacement + parameters = [ + "check_risk_score:custom_function:high_risk_domains_count", + "check_risk_score:custom_function:dt_min_risk_score", + "output_high_risk_domains:custom_function:event_name", + "output_high_risk_domains:custom_function:out_filename" + ] + + phantom.prompt2(container=container, user=user, role=role, message=message, respond_in_mins=30, name="alert_high_risk_domain", parameters=parameters) + + return + + +@phantom.playbook_block() +def on_finish(container, summary): + phantom.debug("on_finish() called") + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + return \ No newline at end of file diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools_Alerting_Playbook_-_Check_Domain_Risk_Score_by_Tag.tgz b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - Check_Domain_Risk_Score_by_Tag/DomainTools_Alerting_Playbook_-_Check_Domain_Risk_Score_by_Tag.tgz deleted file mode 100644 index 5f9cdf56979bb3300c613e9ca3ff9d65c4a2115e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4169 zcmV-P5Vr3hiwFS4Th?R(|Lq-VZ`(MwpYtoY8gy;XI*w#JKCVk@SdA#I{Jj$H#Z@Jsz)}v(DMi?~TvDV8g`Tv!gsJ zdx}0)wbzfollPk1)w<8n=VuS_Z2Z9R0R6M?^XZPzDzH{~q7BB{a4;T@)XqTFdfndO zv_UDx)}OB;KE2MwSP!tQ+hH*3t+tGS(KlwSsG8pe4L^(BJ>sxWPXIW68dBxS$yG0E&@G z<;7=BuC3)Y@`&j8RCI!CXm1c%^U=n~9x@ygxtn0UffodM+#rMlvS*;Ve}fj5jXP-S zOr4L{7%gn~7H~k5x$A)BZUDH8JREoyhF&=MHi9rSd<<9|f*tyCjm?b>FT9O&LWbbv z#9FOgFF>5l9S@43H-7jcEdSGYos)&8^n~l~9t@i_CS7V6-o$yQt zj`$5kanK5hf*8#tM#uocplv*-s=rBSgxRh$`OS5JXn!-GW8de$Vnpn>hy9Hmgr$JO zv@!nyEDf-SO&#d7768*v7bF|cL1W#OzSuY-`X7J%bZdA^KX?3;WWU2fR5&6XqW=?cX!b(+`sT91g$4;d>o;FlJr00c~ zwB`l6SGVY1+cr82*8>IO6kj%oUN)}UsM+}N`>R)P-n@SExy*1!-IA}6A|XitMto`v0h`xY~Dv|p}^!6Y<%ScDKDKnr5zVAf`Yp>CWT_jUmNV* z=~PsNqHXItv$pB6rdCd{B~*)S*D(F2XnN&TvDG>l>j2&oM4UKux{<7yh(1lPcXB(w|ug#qo5 zdW0*9xBi5Gmi7mm)K_FT%KnyQq@Y^|`xo zg7QXYpsy@Pc=dg{!NjUrAk6VVbL&i4$eCZvMaKEqM~xeiHoSRUOto4Za4vgb*qhu$ zP=$tw)ppu8x&jpgI36`1%?8(aPWvX&&K%%K61bx8~w~^Sj3xO^u;gBz4 z)Y~MM9BZ%;U3x07WR2?H#!fTUr`9%#_i2dERxzAt86$M%3*wxN*vkex0*8b!Ckc+D zPQ)8&d{EF#zATQ11WNL(f*`D19^hYUxMKOs^n%sM3R=u8QFg@I8QF8%iSknL;dQLo@Gc8&o2VnbKAb6I(nORVwiox?rMv>E3QL3v5lll~9du z&tuDpU(@4tkr}SMP*!4;L$7-u)QnR*c7QeBp&J>wlNZcuBTntxprCZiB$Gct5}?yXqJz(TZIr3a37o-8J1FknV*;2GmjK4r2VzZhVF6t#{jm?5?&^a2WnxBps^S*0|L|f14mhVXIb( zv$1WZMHj{HY?wL0|FnE#27|Wov3WYfpjr470&Q#QtgsUlbROu|$*vOd>JHIw5#Euy zTH|qVxBvb zSOy(<5!PBLbgx!m0u#fK755?5j^o}oTOB{}7UXBM@%+EfSI^`D-OXjy* z_~YPP5N?R|8ZELD>|xR~9S~4iji;$=dUlFNU12bs41(jpH=ZzW36DL(1^=e=+L{NH z>0UF1h1hs(o1|a?{!~GMF@xW)-CKvaf2eWa+cr8=hn{WXTgTz96g|~Ii3;!vI3L8ck~z*c z<~VXbliQQ=p5N}FV+|NN%Mo$wLd8l$5fyER<_SYV+g~NE4wHz2O(r58#3v@nXVF0A-HlUpIvw`?e|M08({=$;(WJ$a)0azytJM|3|T`dp6az8ukgd7{tdh(13Y(dQA-Lph?) z<%m9)CweGH^l(q2;!q(PObBe$Ij~`0uPD(^u zxiFlZng?G7jH3t+(@7E~@Z27fX5HuMaww zG0>{SfM7nR5NMhKu*OA;55UTGBv z0`T|IrUs>^q&f@O{|LA1N_{g1Kk8>;y(7j8wh@ zKDF0OcrY!>cmR`iD~%_*s2We>Q?3wG=>3!^(^P4TrLiEg8mZ(5soH`tOvMBUtj?Bq z=(zqscPtm~oIggmlRoJ6~f$*xXXu#@en9Zlt2o2=O&b2Knt zJ~O8QztHII{4t`pymSSuq)xtq*sSFzEQrf#G*pnWU@E38m}4{6L5v`g!XSx^&p^pr2h+o4F^H%u3fvEy$Y7ev zWDuc0TrLBVocwGCu`Cy-GZ5nRl6(d!AryF5kkTMmsDxHKr!`1QO;uilH0~WU8%Q^< zNNrFAr(SM@YE?N*c7v449Ni!5_xn=**zhs@v6}wZsn$O7vW(2Gx@2TGcUR#0TfPi9 zd9c~ez6*Ep+wzUwH5q+!b6&m;jbrlM%^hxBR3eMA@o9=wqitoatM#SLeV=qP=S!9{iO?H#Iouubcg-5F=Ja23tA5(nDefeW7 z5$(Jj8>b|x4p@gWo5&%+;{;Q~s$eQYzvpZ|Dx1#F$6cxEeDoO8dC^t2FL#-xU+2t2 zed@UAj1IcoQh)xf9RDha$veu2?jCm!9%hlK4k^Ng%`bF?XY?2=Jf#^w_&R!&@`Hyt z?4u;<$CPIMh@zuJ-jC@)6MsyV>R9h!xj$0jo{;`yDv?WqELlyJ+i7(QkT@n6a)88Z zO6j#EasB8jZo5w^kh~R%yksEBmAzfEfh1Qe3eth(ErcB*A&4v&^HPFTi(!=Or@tRFM#caY9Cmy}Z3T(Mj!5=QHxStP0mFQtyGYZ^)ixxjd3{x3AM!mVu+h zG2AsP$9^EQnL6rvjw}s_k3U*e8hffl-OA&sq3*FfA;)n@$5jp~N4~E)FAb8%eYN7A z$2N0MBcS6atQZMZSd6CoYfKhiNXo%%{+9g0DBDSNmSqEyVx-QqDC@i6+I94s_z0YM zW=w=6tLNOqi6e+U=dHqf<@$s0}XE z?#212GwAoa1MMHGdZC6lClu2&7NB-4LJ)6b+r|vrNo&DkC4R7r3nBaOmFT3headg} T^gKOJPx14AVhZ{$0C)fZ297q- diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.json b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.json new file mode 100644 index 0000000..82ac4a9 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.json @@ -0,0 +1,320 @@ +{ + "blockly": false, + "blockly_xml": "", + "category": "Uncategorized", + "coa": { + "data": { + "description": "This playbook retrieves domain from a given search hash with built-in \u201cfirst_seen\u201d param. The flow will continue to retrieve new domains based on the scheduled run", + "edges": [ + { + "id": "port_0_to_port_2", + "sourceNode": "0", + "sourcePort": "0_out", + "targetNode": "2", + "targetPort": "2_in" + }, + { + "id": "port_2_to_port_3", + "sourceNode": "2", + "sourcePort": "2_out", + "targetNode": "3", + "targetPort": "3_in" + }, + { + "id": "port_3_to_port_5", + "sourceNode": "3", + "sourcePort": "3_out", + "targetNode": "5", + "targetPort": "5_in" + }, + { + "conditions": [ + { + "index": 0 + } + ], + "id": "port_5_to_port_4", + "sourceNode": "5", + "sourcePort": "5_out", + "targetNode": "4", + "targetPort": "4_in" + }, + { + "conditions": [ + { + "index": 1 + } + ], + "id": "port_5_to_port_1", + "sourceNode": "5", + "sourcePort": "5_out", + "targetNode": "1", + "targetPort": "1_in" + }, + { + "id": "port_4_to_port_6", + "sourceNode": "4", + "sourcePort": "4_out", + "targetNode": "6", + "targetPort": "6_in" + }, + { + "id": "port_6_to_port_7", + "sourceNode": "6", + "sourcePort": "6_out", + "targetNode": "7", + "targetPort": "7_in" + }, + { + "id": "port_7_to_port_1", + "sourceNode": "7", + "sourcePort": "7_out", + "targetNode": "1", + "targetPort": "1_in" + } + ], + "hash": "618c5bf8b59b745172ac2f3803581cead230f9fd", + "nodes": { + "0": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_start", + "id": "0", + "type": "start" + }, + "errors": {}, + "id": "0", + "type": "start", + "warnings": {}, + "x": 110, + "y": -1.9184653865522705e-13 + }, + "1": { + "data": { + "advanced": { + "join": [] + }, + "functionName": "on_finish", + "id": "1", + "type": "end" + }, + "errors": {}, + "id": "1", + "type": "end", + "warnings": {}, + "x": 110, + "y": 1116 + }, + "2": { + "data": { + "action": "load hash", + "actionType": "investigate", + "advanced": { + "join": [] + }, + "connector": "DomainTools Iris Investigate", + "connectorConfigs": [ + "domaintoolscreds" + ], + "connectorId": "f18b7ef9-0cbd-4dbb-b8ed-ce62e17f0603", + "connectorVersion": "v1", + "functionId": 1, + "functionName": "load_hash_1", + "id": "2", + "parameters": { + "search_hash": "" + }, + "requiredParameters": [ + { + "data_type": "string", + "field": "search_hash" + } + ], + "type": "action" + }, + "errors": {}, + "id": "2", + "type": "action", + "warnings": {}, + "x": 90, + "y": 148 + }, + "3": { + "data": { + "advanced": { + "customName": "parse_new_domains", + "customNameId": 0, + "join": [] + }, + "functionId": 1, + "functionName": "parse_new_domains", + "id": "3", + "inputParameters": [ + "load_hash_1:action_result.data" + ], + "outputVariables": [ + "new_domains", + "new_domains_count" + ], + "type": "code" + }, + "errors": {}, + "id": "3", + "type": "code", + "userCode": " \n # Write your custom code here...\n new_domains = []\n for results in load_hash_1_result_item_0:\n for result in results:\n risk_score = result.get(\"domain_risk\", {}).get(\"risk_score\")\n domain = result.get(\"domain\")\n is_active = result.get(\"active\")\n new_domains.append({\"domain\": domain, \"risk_score\": risk_score, \"active\": is_active})\n \n parse_new_domains__new_domains = new_domains\n parse_new_domains__new_domains_count = len(new_domains)\n", + "warnings": {}, + "x": 90, + "y": 296 + }, + "4": { + "data": { + "advanced": { + "customName": "create_event", + "customNameId": 0, + "join": [] + }, + "functionId": 2, + "functionName": "create_event", + "id": "4", + "inputParameters": [ + "parse_new_domains:custom_function:new_domains" + ], + "outputVariables": [ + "container_id", + "out_file_name", + "container_name" + ], + "type": "code" + }, + "errors": {}, + "id": "4", + "type": "code", + "userCode": "\n # Write your custom code here...\n from datetime import datetime\n now = datetime.now().strftime(\"%Y%m%d\")\n container_name = f\"new_domains_alert_{now}\"\n \n # make sure to create one event per day\n rest_url = phantom.get_rest_base_url()\n response = phantom.requests.get(\n f\"{rest_url}container?_filter_name='{container_name}'\",\n verify=False,\n )\n result = response.json()\n if result.get(\"count\") > 0: # get the current container\n phantom.debug(f\"dt debug - {container_name} container exist. Skipping creation of new event.\")\n container_id = result.get(\"data\")[0][\"id\"]\n container_name = result.get(\"data\")[0][\"name\"]\n else: # create a new one\n phantom.debug(f\"dt debug - creating container {container_name}\")\n success, message, container_id = phantom.create_container(name=container_name, label='events')\n container = phantom.get_container(container_id)\n container_name = container.get(\"name\")\n phantom.debug(\n f\"dt debug - create container results: success: {success}, message: {message}, container_id: {container_id}\")\n \n create_event__container_id = container_id\n create_event__out_file_name = f\"new_domains_alert_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv\"\n create_event__container_name = container_name\n", + "warnings": {}, + "x": 0, + "y": 624 + }, + "5": { + "data": { + "advanced": { + "join": [] + }, + "conditions": [ + { + "comparisons": [ + { + "conditionIndex": 0, + "op": ">=", + "param": "parse_new_domains:custom_function:new_domains_count", + "value": "1" + } + ], + "conditionIndex": 0, + "display": "If", + "logic": "and", + "type": "if" + }, + { + "comparisons": [ + { + "conditionIndex": 1, + "op": "==", + "param": "", + "value": "" + } + ], + "conditionIndex": 1, + "display": "Else", + "logic": "and", + "type": "else" + } + ], + "functionId": 1, + "functionName": "decision_1", + "id": "5", + "type": "decision" + }, + "errors": {}, + "id": "5", + "type": "decision", + "warnings": {}, + "x": 170, + "y": 444 + }, + "6": { + "data": { + "advanced": { + "customName": "output_new_domains_to_csv", + "customNameId": 0, + "join": [] + }, + "functionId": 3, + "functionName": "output_new_domains_to_csv", + "id": "6", + "inputParameters": [ + "parse_new_domains:custom_function:new_domains", + "create_event:custom_function:container_id", + "create_event:custom_function:out_file_name", + "parse_new_domains:custom_function:new_domains_count" + ], + "outputVariables": [], + "type": "code" + }, + "errors": {}, + "id": "6", + "type": "code", + "userCode": "\n # Write your custom code here...\n import csv\n \n file_name = create_event__out_file_name\n phantom.debug(f\"dt debug - exporting {parse_new_domains__new_domains_count} to csv file.\")\n \n with open(f\"/opt/phantom/vault/tmp/{file_name}\", \"w\", newline='') as report_csv_file:\n headers = [\"domain\", \"risk_score\", \"active\"]\n writer = csv.DictWriter(report_csv_file, fieldnames=headers)\n \n writer.writeheader()\n for domain in parse_new_domains__new_domains:\n writer.writerow(domain)\n \n phantom.vault_add(container=create_event__container_id, file_location=f\"/opt/phantom/vault/tmp/{file_name}\", file_name=file_name)\n\n", + "warnings": {}, + "x": 0, + "y": 780 + }, + "7": { + "data": { + "advanced": { + "customName": "alert_new_domains_found", + "customNameId": 0, + "join": [] + }, + "approver": { + "type": "user", + "value": "admin" + }, + "functionId": 1, + "functionName": "alert_new_domains_found", + "id": "7", + "message": "{0} New Domains found:\n\nFor more details go to Event: {1} > \"Files\" tab > Download '{2}'.", + "parameters": [ + "parse_new_domains:custom_function:new_domains_count", + "create_event:custom_function:container_name", + "create_event:custom_function:out_file_name" + ], + "responseTime": 15, + "responses": [], + "type": "prompt" + }, + "errors": {}, + "id": "7", + "type": "prompt", + "warnings": {}, + "x": 80, + "y": 936 + } + }, + "notes": "" + }, + "input_spec": null, + "output_spec": null, + "playbook_type": "automation", + "python_version": "3", + "schema": "5.0.9", + "version": "6.0.0.114895" + }, + "create_time": "2023-08-11T15:56:54.987868+00:00", + "draft_mode": false, + "labels": [ + "events" + ], + "tags": [] +} \ No newline at end of file diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.py b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.py new file mode 100644 index 0000000..dc3db87 --- /dev/null +++ b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools Alerting Playbook - New Domains.py @@ -0,0 +1,232 @@ +""" +This playbook retrieves domain from a given search hash with built-in “first_seen” param. The flow will continue to retrieve new domains based on the scheduled run +""" + + +import phantom.rules as phantom +import json +from datetime import datetime, timedelta + + +@phantom.playbook_block() +def on_start(container): + phantom.debug('on_start() called') + + # call 'load_hash_1' block + load_hash_1(container=container) + + return + +@phantom.playbook_block() +def load_hash_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("load_hash_1() called") + + # phantom.debug('Action: {0} {1}'.format(action['name'], ('SUCCEEDED' if success else 'FAILED'))) + + parameters = [] + + parameters.append({ + "search_hash": "", + }) + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.act("load hash", parameters=parameters, name="load_hash_1", assets=["domaintoolscreds"], callback=parse_new_domains) + + return + + +@phantom.playbook_block() +def parse_new_domains(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("parse_new_domains() called") + + load_hash_1_result_data = phantom.collect2(container=container, datapath=["load_hash_1:action_result.data"], action_results=results) + + load_hash_1_result_item_0 = [item[0] for item in load_hash_1_result_data] + + parse_new_domains__new_domains = None + parse_new_domains__new_domains_count = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + new_domains = [] + for results in load_hash_1_result_item_0: + for result in results: + risk_score = result.get("domain_risk", {}).get("risk_score") + domain = result.get("domain") + is_active = result.get("active") + new_domains.append({"domain": domain, "risk_score": risk_score, "active": is_active}) + + parse_new_domains__new_domains = new_domains + parse_new_domains__new_domains_count = len(new_domains) + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="parse_new_domains:new_domains", value=json.dumps(parse_new_domains__new_domains)) + phantom.save_run_data(key="parse_new_domains:new_domains_count", value=json.dumps(parse_new_domains__new_domains_count)) + + decision_1(container=container) + + return + + +@phantom.playbook_block() +def create_event(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("create_event() called") + + parse_new_domains__new_domains = json.loads(_ if (_ := phantom.get_run_data(key="parse_new_domains:new_domains")) != "" else "null") # pylint: disable=used-before-assignment + + create_event__container_id = None + create_event__out_file_name = None + create_event__container_name = None + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + from datetime import datetime + now = datetime.now().strftime("%Y%m%d") + container_name = f"new_domains_alert_{now}" + + # make sure to create one event per day + rest_url = phantom.get_rest_base_url() + response = phantom.requests.get( + f"{rest_url}container?_filter_name='{container_name}'", + verify=False, + ) + result = response.json() + if result.get("count") > 0: # get the current container + phantom.debug(f"dt debug - {container_name} container exist. Skipping creation of new event.") + container_id = result.get("data")[0]["id"] + container_name = result.get("data")[0]["name"] + else: # create a new one + phantom.debug(f"dt debug - creating container {container_name}") + success, message, container_id = phantom.create_container(name=container_name, label='events') + container = phantom.get_container(container_id) + container_name = container.get("name") + phantom.debug( + f"dt debug - create container results: success: {success}, message: {message}, container_id: {container_id}") + + create_event__container_id = container_id + create_event__out_file_name = f"new_domains_alert_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv" + create_event__container_name = container_name + ################################################################################ + ## Custom Code End + ################################################################################ + + phantom.save_run_data(key="create_event:container_id", value=json.dumps(create_event__container_id)) + phantom.save_run_data(key="create_event:out_file_name", value=json.dumps(create_event__out_file_name)) + phantom.save_run_data(key="create_event:container_name", value=json.dumps(create_event__container_name)) + + output_new_domains_to_csv(container=container) + + return + + +@phantom.playbook_block() +def decision_1(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("decision_1() called") + + # check for 'if' condition 1 + found_match_1 = phantom.decision( + container=container, + conditions=[ + ["parse_new_domains:custom_function:new_domains_count", ">=", 1] + ]) + + # call connected blocks if condition 1 matched + if found_match_1: + create_event(action=action, success=success, container=container, results=results, handle=handle) + return + + return + + +@phantom.playbook_block() +def output_new_domains_to_csv(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("output_new_domains_to_csv() called") + + parse_new_domains__new_domains = json.loads(_ if (_ := phantom.get_run_data(key="parse_new_domains:new_domains")) != "" else "null") # pylint: disable=used-before-assignment + create_event__container_id = json.loads(_ if (_ := phantom.get_run_data(key="create_event:container_id")) != "" else "null") # pylint: disable=used-before-assignment + create_event__out_file_name = json.loads(_ if (_ := phantom.get_run_data(key="create_event:out_file_name")) != "" else "null") # pylint: disable=used-before-assignment + parse_new_domains__new_domains_count = json.loads(_ if (_ := phantom.get_run_data(key="parse_new_domains:new_domains_count")) != "" else "null") # pylint: disable=used-before-assignment + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + import csv + + file_name = create_event__out_file_name + phantom.debug(f"dt debug - exporting {parse_new_domains__new_domains_count} to csv file.") + + with open(f"/opt/phantom/vault/tmp/{file_name}", "w", newline='') as report_csv_file: + headers = ["domain", "risk_score", "active"] + writer = csv.DictWriter(report_csv_file, fieldnames=headers) + + writer.writeheader() + for domain in parse_new_domains__new_domains: + writer.writerow(domain) + + phantom.vault_add(container=create_event__container_id, file_location=f"/opt/phantom/vault/tmp/{file_name}", file_name=file_name) + + ################################################################################ + ## Custom Code End + ################################################################################ + + alert_new_domains_found(container=container) + + return + + +@phantom.playbook_block() +def alert_new_domains_found(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None, custom_function=None, **kwargs): + phantom.debug("alert_new_domains_found() called") + + # set user and message variables for phantom.prompt call + + user = "admin" + role = None + message = """{0} New Domains found:\n\nFor more details go to Event: {1} > \"Files\" tab > Download '{2}'.""" + + # parameter list for template variable replacement + parameters = [ + "parse_new_domains:custom_function:new_domains_count", + "create_event:custom_function:container_name", + "create_event:custom_function:out_file_name" + ] + + phantom.prompt2(container=container, user=user, role=role, message=message, respond_in_mins=15, name="alert_new_domains_found", parameters=parameters) + + return + + +@phantom.playbook_block() +def on_finish(container, summary): + phantom.debug("on_finish() called") + + ################################################################################ + ## Custom Code Start + ################################################################################ + + # Write your custom code here... + + ################################################################################ + ## Custom Code End + ################################################################################ + + return \ No newline at end of file diff --git a/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools_Alerting_Playbook_-_New_Domains.tgz b/src/Splunk SOAR/playbooks/DomainTools_Alerting_Playbook - New_Domains/DomainTools_Alerting_Playbook_-_New_Domains.tgz deleted file mode 100644 index acf689401a0b3495f3bfc59c869e60c1b92a453e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4005 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 LyHQr00C)fZ-JIVo