ThreatConnect Deprecated

Deprecated. Use the ThreatConnect v3 integration instead.

Data Enrichment & Threat Intelligence · ThreatConnect

Details

IDThreatConnect
ProviderDataminr
CategoryData Enrichment & Threat Intelligence
From Version5.0.0
Docker Imagedemisto/threatconnect-sdk:1.0.0.7659
Supported ModulesAgentix XSIAM

README

Use the ThreatConnect integration to identify, manage, and block threats.

This integration was integrated and tested with ThreatConnect Python SDK v2.

Configure ThreatConnect on Cortex XSOAR

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for ThreatConnect1.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Access ID
    • Secret Key
    • baseUrl
    • Default Organization
    • ProxyIP (or http://${ip} )
    • ProxyPort
    • Rating threshold for Malicious Indicators
    • Confidence threshold for Malicious Indicators
    • Indicator Reputation Freshness (in days)
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.

  1. Search for an IP indicator: ip
  2. Search for a URL indicator: url
  3. Search for a file indicator: file
  4. Retrieve possible owners from an account: tc-owners
  5. Retrieve all indicators: tc-indicators
  6. Get all tags: tc-get-tags
  7. Tag an existing indicator: tc-tag-indicator
  8. Get an indicator: tc-get-indicator
  9. Get all indicators with a specific tag: tc-get-indicators-by-tag
  10. Add a new indicator: tc-add-indicator
  11. Create a new incident: tc-create-incident
  12. Fetch incidents: tc-fetch-incidents
  13. Associate an indicator to an incident: tc-incident-associate-indicator
  14. Check domain reputation: domain
  15. Get incidents related to an indicator: tc-get-incident-associate-indicators
  16. Update an indicator: tc-update-indicator
  17. Remove a tag from an indicator: tc-delete-indicator-tag
  18. Delete an indicator: tc-delete-indicator
  19. Create a group from a campaign: tc-create-campaign
  20. Create a group from an event: tc-create-event
  21. Create a group from threats: tc-create-threat
  22. Delete a group: tc-delete-group
  23. Add an attribute to an event: tc-add-group-attribute
  24. Get a list of events: tc-get-events
  25. Get all groups: tc-get-groups
  26. Add a security label to a group: tc-add-group-security-label
  27. Add tags to a group: tc-add-group-tag
  28. Get all indicator types: tc-get-indicator-types
  29. Associate an indicator to a group: tc-group-associate-indicator
  30. Create a document group: tc-create-document-group
  31. Retrieve a single group: tc-get-group
  32. Retrieves the attribute of a group: tc-get-group-attributes
  33. Retrieves the security labels of a group: tc-get-group-security-labels
  34. Retrieves the tags of a group: tc-get-group-tags
  35. Downloads the contents of a document: tc-download-document
  36. Returns indicators associated with a group: tc-get-group-indicators
  37. Returns indicators associated with a specified group: tc-get-associated-groups
  38. Associates one group with another group: tc-associate-group-to-group

1. Search for an IP address indicator


Searches for an indicator of type IP address.

Base Command

ip

Input
Argument Name Description Required
ip The IPv4 or IPv6 address. Required
owners A CSV list of a client's organizations, sources, or communities to which a user has permissions. For example, users with admin permissions can search for indicators belonging to all owners. Optional
ratingThreshold A list of results filtered by indicators whose threat rating is greater than the specified value. Can be "0" - "Unknown", "1" - "Suspicious", "2" - "Low", "3" - Moderate, "4" - High, or "5" - "Critical". Optional
confidenceThreshold A list of results filtered by indicators whose confidence rating is greater than the specified value. Can be "0%" - "Unknown," "1% " - "Discredited", "2-29%" - "Improbable," "30-49%" - "Doubtful," "50-69%" - "Possible", "70-89%" - "Probable," or "90-100%" - "Confirmed". Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The date on which the indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
IP.Address string The IP address of the indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.

 

Command Example
!ip ip=7.77.7.7
Context Example

50242697-cfc09b80-03d3-11e9-9615-35fc485fa84c_1_Search_for_an_IP_indicator.png

Human Readable Output

50281763-2e7c2880-0459-11e9-88ea-ed6532e56bad_1_Human_Readable_Output.png

2. Search for an indicator of type URL


Searches for an indicator of type URL.

Base Command

url

Input
Argument Name Description Required
url The URL for which to search. For example, "www.demisto.com". Required
owners A CSV list of a client's organizations, sources, or communities to which a client’s API user has been granted permission. For example, "owner1", "owner2", or "owner3". Optional
ratingThreshold A list of results filtered by indicators whose threat rating is greater than the specified value. Can be "0" - "Unknown", "1" - "Suspicious", "2" - "Low", "3" - Moderate, "4" - High, or "5" - "Critical". Optional
confidenceThreshold A list of results filtered by indicators whose confidence rating is greater than the specified value. Can be "0%" - "Unknown," "1% " - "Discredited", "2-29%" - "Improbable," "30-49%" - "Doubtful," "50-69%" - "Possible", "70-89%" - "Probable," or "90-100%" - "Confirmed". Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The date on which the indicator was last modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
URL.Data string The data of the URL indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.

 

Command Example
!url url=https://a.co.il
Context Example

50274409-df78c800-0445-11e9-9a30-6f3335a6a60a_2_Search_for_a_URL_indicator_Context_Example.png

Human Readable Output

3. Search for an indicator of type file


Searches for an indicator of type file.

Base Command

file

Input
Argument Name Description Required
file The hash of the file. Can be "MD5", "SHA-1", or "SHA-256". Required
owners A CSV list of a client's organizations, sources, or communities to which a user has permissions. For example, users with admin permissions can search for indicators belonging to all owners. Optional
ratingThreshold A list of results filtered by indicators whose threat rating is greater than the specified value. Can be "0" - "Unknown", "1" - "Suspicious", "2" - "Low", "3" - Moderate, "4" - High, or "5" - "Critical". Optional
confidenceThreshold A list of results filtered by indicators whose confidence rating is greater than the specified value. Can be "0%" - "Unknown," "1% " - "Discredited", "2-29%" - "Improbable," "30-49%" - "Doubtful," "50-69%" - "Possible", "70-89%" - "Probable," or "90-100%" - "Confirmed". Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The last date on which the indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.File.MD5 string The MD5 hash of the indicator.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator.
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
File.MD5 string The MD5 hash of the indicator.
File.SHA1 string The SHA1 hash of the indicator.
File.SHA256 string The SHA256 hash of the indicator.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example

50275319-bd804500-0447-11e9-927f-3e272f74bb60.png

Human Readable Output

50281206-64201200-0457-11e9-8b72-4db2d9aadb0a.png

4. Retrieves all owners for the current account


Retrieves all owners for the current account.

Base Command

tc-owners

 
Context Output
Path Type Description
TC.Owner.Name string The name of the owner.
TC.Owner.ID string The ID of the owner.
TC.Owner.Type string The type of the owner.
 

 

5. Retrieve a list of all indicators


Retrieves a list of all indicators.

Base Command

tc-indicators

Input
Argument Name Description Required
owner A list of results filtered by the owner of the indicator. Optional
limit The maximum number of results that can be returned. The default is 500. Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The last date on which the indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
IP.Address string The IP address of the indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The name of the domain.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example
!tc-indicators limit=5
Context Example

50281877-96327380-0459-11e9-8c94-a1136e0949a7.png

Human Readable Output

50281832-6edba680-0459-11e9-8ac2-e0f00b97db98.png

6. Return a list of all ThreatConnect tags


Returns a list of all ThreatConnect tags.

Base Command

tc-get-tags

Input
Argument Name Description Required
tag The name of the tag Required
indicator
The indicator to tag. For example, for an IP indicator, "8.8.8.8".
Required
owner
A list of indicators filtered by the owner.
 Required

 

Context Output
Path Type Description
TC.Tags Unknown A list of tags.

 

Command Example
!tc-get-tags
Human Readable Output

50281926-c37f2180-0459-11e9-83bb-8d6abeb79d48.png

7. Add a tag to an existing indicator


Adds a tag to an existing indicator.

Base Command

tc-tag-indicator

Input
Argument Name Description Required
tag The name of the tag. Required
indicator The indicator to tag. For example, for an IP indicator, "8.8.8.8". Required
owner A list of indicators filtered by the owner. Optional

 

Command Example
!tc-tag-indicator indicator=7.77.7.7 tag=NewTagName
Human Readable Output

50282035-18bb3300-045a-11e9-9a51-1bc93a3b7df0_7_Tag_an_existing_indicator_Human_Readable_Output.png

8. Retrieves information about an indicator


Retrieves information about an indicator.

Base Command

tc-get-indicator

Input
Argument Name Description Required
indicator The name of the indicator by which to search. The command retrieves information from all owners. Can be an IP address, a URL, or a file hash. Required
ratingThreshold A list of results filtered by indicators whose threat rating is greater than the specified value. Can be "0" - "Unknown", "1" - "Suspicious", "2" - "Low", "3" - Moderate, "4" - High, or "5" - "Critical". Optional
confidenceThreshold A list of results filtered by indicators whose confidence rating is greater than the specified value. Can be "0%" - "Unknown," "1% " - "Discredited", "2-29%" - "Improbable," "30-49%" - "Doubtful," "50-69%" - "Possible", "70-89%" - "Probable," or "90-100%" - "Confirmed". Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The last date on which the indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
IP.Address string The IP address of the indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the indicator of the URL.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The domain name of the indicator.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example
!tc-get-indicator indicator=7.77.7.7
Human Readable Output

50282140-78b1d980-045a-11e9-995b-a9fc2595b663_8_Get_an_indicator_Human_Readable_Output.png

9. Fetch all indicators that have a tag


Fetches all indicators that have a tag.

Base Command

tc-get-indicators-by-tag

Input
Argument Name Description Required
tag The name of the tag by which to filter. Required
owner A list of indicators filtered by the owner. Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the tagged indicator.
TC.Indicator.Type string The type of the tagged indicator.
TC.Indicator.ID string The ID of the tagged indicator.
TC.Indicator.Description string The description of the tagged indicator.
TC.Indicator.Owner string The owner of the tagged indicator.
TC.Indicator.CreateDate date The date on which the tagged indicator was created.
TC.Indicator.LastModified date The last date on which the tagged indicator was modified.
TC.Indicator.Rating number The threat rating of the tagged indicator.
TC.Indicator.Confidence number The confidence rating of the tagged indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
DBotScore.Indicator string The value assigned by DBot for the tagged indicator.
DBotScore.Type string The type assigned by DBot for the tagged indicator.
DBotScore.Score number The score assigned by DBot for the tagged indicator.
DBotScore.Vendor string The vendor used to calculate the score.
IP.Address string The IP address of the tagged indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the tagged indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The domain name of the tagged indicator.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example
!tc-get-indicators-by-tag tag=NewTagName
Human Readable Output

50281832-6edba680-0459-11e9-8ac2-e0f00b97db98_9_Get_all_indicators_with_a_specific_tag_Human_Readable.png

10. Add a new indicator to ThreatConnect


Adds a new indicator to ThreatConnect.

Base Command

tc-add-indicator

Input
Argument Name Description Required
indicator The indicator to add. Required
rating The threat rating of the indicator. Can be "0" - "Unknown", "1" - "Suspicious", "2" - "Low", "3" - Moderate, "4" - High, or "5" - "Critical". Optional
confidence The confidence rating of the indicator. Can be "0%" - "Unknown," "1% " - "Discredited", "2-29%" - "Improbable," "30-49%" - "Doubtful," "50-69%" - "Possible", "70-89%" - "Probable," or "90-100%" - "Confirmed". Optional
owner The owner of the new indicator. The default is the "defaultOrg" parameter. Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name the indicator.
TC.Indicator.Type string The type of indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the added indicator was created.
TC.Indicator.LastModified date The last date on which the added indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
IP.Address string The IP address of the indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The name of the added indicator of the domain.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example
!tc-add-indicator indicator="9.9.4.4" rating="2" confidence="87"
Human Readable Output

50282140-78b1d980-045a-11e9-995b-a9fc2595b663.png

11. Create a new incident group


Creates a new incident group.

Base Command

tc-create-incident

Input
Argument Name Description Required
owner The owner of the new incident. The default is the "defaultOrg" parameter. Optional
incidentName The name of the incident group. Required
eventDate The creation time of an incident in the "2017-03-21T00:00:00Z" format. Optional
tag The tag applied to the incident. Optional
securityLabel The security label applied to the incident. Can be "TLP:RED", "TLP:GREEN", "TLP:AMBER", or "TLP:WHITE". Optional
description The description of the incident. Optional

 

Context Output
Path Type Description
TC.Incident.Name string The name of the new incident group.
TC.Incident.Owner string The owner of the new incident.
TC.Incident.EventDate date The date on which the event that indicates an incident occurred.
TC.Incident.Tag string The name of the tag of the new incident.
TC.Incident.SecurityLabel string The security label of the new incident.
TC.Incident.ID Unknown The ID of the new incident.

 

Command Example
!tc-create-incident incidentName="NewIncident" description="NewIncident" severity="Critical" category="Intrusion" company=Demisto tag=demisto

 

12. Fetch incidents from ThreatConnect


Fetches incidents from ThreatConnect.

Base Command

tc-fetch-incidents

Input
Argument Name Description Required
incidentId The fetched incidents filtered by ID. Optional
owner The fetched incidents filtered by owner. Optional
incidentName The fetched incidents filtered by incident name. Optional

 

Context Output
Path Type Description
TC.Incident string The name of the group of fetched incidents.
TC.Incident.ID string The ID of the fetched incidents.
TC.Incident.Owner string The owner of the fetched incidents.

 

Command Example
!tc-fetch-incidents incidentId=64862

 

13. Associate an indicator with an existing incident


Associates an indicator with an existing incident. The indicator must exist before running this command. To add an indicator, run the tc-add-indicator command.

Base Command

tc-incident-associate-indicator

Input
Argument Name Description Required
indicatorType The type of the indicator. Can be "ADDRESSES", "EMAIL_ADDRESSES", "URLS", "HOSTS", "FILES", or "CUSTOM_INDICATORS". Required
incidentId The ID of the incident to which the indicator is associated. Required
indicator The name of the indicator. Required
owner A list of indicators filtered by the owner. Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator associated was created.
TC.Indicator.LastModified date The last date on which the indicator associated was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
IP.Address string IP address of the associated indicator of the file.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the associated indicator of the file.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The name of the indicator of the domain.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example
!tc-incident-associate-indicator indicator=46.148.22.18 incidentId=64862 indicatorType=ADDRESSES
Human Readable Output

14. Search for an indicator of type domain


Searches for an indicator of type domain.

Base Command

domain

Input
Argument Name Description Required
domain The name of the domain. Required
owners A CSV list of a client's organizations, sources, or communities to which a user has permissions. For example, users with admin permissions can search for indicators belonging to all owners. Optional
ratingThreshold A list of results filtered by indicators whose threat rating is greater than the specified value. Can be "0" - "Unknown", "1" - "Suspicious", "2" - "Low", "3" - Moderate, "4" - High, or "5" - "Critical". Optional
confidenceThreshold A list of results filtered by indicators whose confidence rating is greater than the specified value. Can be "0%" - "Unknown," "1% " - "Discredited", "2-29%" - "Improbable," "30-49%" - "Doubtful," "50-69%" - "Possible", "70-89%" - "Probable," or "90-100%" - "Confirmed". Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the of the indicator.
TC.Indicator.Type string The type of the domain.
TC.Indicator.ID string The ID of the domain.
TC.Indicator.Description string The description of the domain.
TC.Indicator.Owner string The owner of the domain.
TC.Indicator.CreateDate date The date on which the indicator of the domain was created.
TC.Indicator.LastModified date The last date on which the indicator of the domain was modified.
TC.Indicator.Rating number The threat rating of the domain.
TC.Indicator.Confidence number The confidence rating of the domain.
TC.Indicator.WhoisActive string The active indicator (for domains only).
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
Domain.Name string The name of the domain.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.

 

Command Example
!domain domain=com-mapsfinder.info
Human Readable Output

45597328-339d8780-b9d3-11e8-8f72-94a09c8c75ee.png

15. Return indicators related to a specific incident


Returns indicators that are related to a specific incident.

Base Command

tc-get-incident-associate-indicators

ermission 2

Input
Argument Name Description Required
incidentId The ID of the incident. Required
owner A list of indicators filtered by the owner. Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the returned indicator.
TC.Indicator.Type string The type of the returned indicator.
TC.Indicator.ID string The ID of the returned indicator.
TC.Indicator.Description string The description of the returned indicator.
TC.Indicator.Owner string The owner of the returned indicator.
TC.Indicator.CreateDate date The date on which the returned indicator was created.
TC.Indicator.LastModified date The last date on which the returned indicator was modified.
TC.Indicator.Rating number The threat rating of the returned indicator.
TC.Indicator.Confidence number The confidence rating of the returned indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
DBotScore.Indicator string The value assigned by DBot for the indicator.
DBotScore.Type string The type assigned by DBot for the indicator.
DBotScore.Score number The score assigned by DBot for the indicator.
DBotScore.Vendor string The vendor used to calculate the score.
IP.Address string The IP address of the returned indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the returned indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The name of the domain.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

Command Example
!tc-get-incident-associate-indicators incidentId=64862

16. Update the indicator in ThreatConnect


Updates the indicator in ThreatConnect.

Base Command

tc-update-indicator

Input
Argument Name Description Required
indicator The name of the updated indicator. Required
rating The threat rating of the updated indicator. Optional
confidence The confidence rating of the updated indicator. Optional
size The size of the file of the updated indicator. Optional
dnsActive The active DNS indicator (only for hosts). Optional
whoisActive The active indicator (only for hosts). Optional
updatedValues A CSV list of field:value pairs to update. For example, "rating=3", "confidence=42", and "description=helloWorld". Optional
falsePositive The updated indicator set as a false positive. Can be "True" or "False". Optional
observations The number observations on the updated indicator. Optional
securityLabel The security label applied to the incident. Can be "TLP:RED", "TLP:GREEN", "TLP:AMBER", or "TLP:WHITE". Optional
threatAssessConfidence Assesses the confidence rating of the indicator. Optional
threatAssessRating Assesses the threat rating of the indicator. Optional

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The last date on which the indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
IP.Address string The IP address of the indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The domain name of the indicator.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

17. Remove a tag from a specified indicator


Removes a tag from a specified indicator.

Base Command

tc-delete-indicator-tag

Input
Argument Name Description Required
indicator The name of the indicator from which to remove a tag. Required
tag The name of the tag to remove from the indicator. Required

 

Context Output
Path Type Description
TC.Indicator.Name string The name of the indicator.
TC.Indicator.Type string The type of the indicator.
TC.Indicator.ID string The ID of the indicator.
TC.Indicator.Description string The description of the indicator.
TC.Indicator.Owner string The owner of the indicator.
TC.Indicator.CreateDate date The date on which the indicator was created.
TC.Indicator.LastModified date The last date on which the indicator was modified.
TC.Indicator.Rating number The threat rating of the indicator.
TC.Indicator.Confidence number The confidence rating of the indicator.
TC.Indicator.WhoisActive string The active indicator (for domains only).
TC.Indicator.File.MD5 string The MD5 hash of the indicator of the file.
TC.Indicator.File.SHA1 string The SHA1 hash of the indicator of the file.
TC.Indicator.File.SHA256 string The SHA256 hash of the indicator of the file.
IP.Address string The IP address of the indicator.
IP.Malicious.Vendor string For malicious IP addresses, the vendor that made the decision.
IP.Malicious.Description string For malicious IP addresses, the full description.
URL.Data string The data of the URL of the indicator.
URL.Malicious.Vendor string For malicious URLs, the vendor that made the decision.
URL.Malicious.Description string For malicious URLs, the full description.
Domain.Name string The domain name of the indicator.
Domain.Malicious.Vendor string For malicious domains, the vendor that made the decision.
Domain.Malicious.Description string For malicious domains, the full description.
File.MD5 string The MD5 hash of the file.
File.SHA1 string The SHA1 hash of the file.
File.SHA256 string The SHA256 hash of the file.
File.Malicious.Vendor string For malicious files, the vendor that made the decision.
File.Malicious.Description string For malicious files, the full description.

 

18. Delete an indicator from ThreatConnect


Deletes an indicator from ThreatConnect.

Base Command

tc-delete-indicator

Input
Argument Name Description Required
indicator The name of the indicator to delete. Required

 

Command Example

19. Create a group based on the Campaign type


Creates a group based on the "Campaign" type.

Base Command

tc-create-campaign

Input
Argument Name Description Required
name The name of the campaign group. Required
firstSeen The earliest date on which the campaign was seen. Optional
owner The owner of the new incident. The default is the "defaultOrg" parameter. Optional
description The description of the campaign. Optional
tag The name of the tag to apply to the campaign. Optional
securityLabel The security label of the campaign. For example, "TLP:Green". Optional

 

Context Output
Path Type Description
TC.Campaign.Name string The name of the campaign.
TC.Campaign.Owner string The owner of the campaign.
TC.Campaign.FirstSeen date The earliest date on which the campaign was seen.
TC.Campaign.Tag string The tag of the campaign.
TC.Campaign.SecurityLevel string The security label of the campaign.
TC.Campaign.ID string The ID of the campaign.

 

 

20. Create a group based on the Event type


Creates a group based on the "Event" type.

Base Command

tc-create-event

Input
Argument Name Description Required
name The name of the event group. Required
eventDate The date on which the event occurred. If the date is not specified, the current date is used. Optional
status The status of the event. Can be "Needs Review", "False Positive", "No Further Action", or "Escalated". Optional
owner The owner of the event. Optional
description The description of the event. Optional
tag The tag of the event. Optional

 

Context Output
Path Type Description
TC.Event.Name string The name of the event.
TC.Event.Date date The date of the event.
TC.Event.Status string The status of the event.
TC.Event.Owner string The owner of the event.
TC.Event.Tag string The tag of the event.
TC.Event.ID string The ID of the event.

 

 

21. Create a group based on the Threats type


Creates a group based on the "Threats" type.

Base Command

tc-create-threat

Input
Argument Name Description Required
name The name of the threat group. Required

 

Context Output
Path Type Description
TC.Threat.Name string The name of the threat.
TC.Threat.ID string The ID of the threat.

 

 

22. Delete a group


Deletes a group.

Base Command

tc-delete-group

Input
Argument Name Description Required
groupID The ID of the group to delete. Required
type The type of the group to delete. Can be "Incidents", "Events", "Campaigns", or "Threats". Required

 

23. Add an attribute to a specified group


Adds an attribute to a specified group.

Base Command

tc-add-group-attribute

Input
Argument Name Description Required
group_id The ID of the group to which to add attributes. To get the ID of the group, run the tc-get-groups command. Required
attribute_type The type of attribute to add to the group. The type is located in the UI in a specific group or under Org Config. Required
attribute_value The value of the attribute. Required
group_type The type of the group. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required

 

Context Output
Path Type Description
TC.Group.DateAdded Date The date on which the attribute was added.
TC.Group.LastModified Date The date on which the added attribute was last modified.
TC.Group.Type String The type of the group to which the attribute was added.
TC.Group.Value String The value of the attribute added to the group.
TC.Group.ID Number The group ID to which the attribute was added.

 

Command Example
!tc-add-group-attribute attribute_type="EXTERNAL ID" attribute_value=123456789 group_id=4406377 group_type=events

24. Return a list of events


Returns a list of events.

Base Command

tc-get-events

 
Context Output
Path Type Description
TC.Event.DateAdded Date The date on which the event was added.
TC.Event.EventDate Date The date on which the event occurred.
TC.Event.ID Number The ID of the event.
TC.Event.OwnerName String The name of the owner of the event.
TC.Event.Status String The status of the event.

 

Command Example
!tc-get-events

25. Return all groups


Returns all groups, filtered by the group type.

Base Command

tc-get-groups

Input
Argument Name Description Required
group_type The type of the group. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required

 

Context Output
Path Type Description
TC.Group.DateAdded Date The date on which the group was added.
TC.Group.EventDate Date The date on which the event occurred.
TC.Group.Name String The name of the group.
TC.Group.OwnerName String The name of the owner of the group.
TC.Group.Status String The status of the group.
TC.Group.ID Number The ID of the group.

 

Command Example
!tc-get-groups group_type=events

26. Add a security label to a group


Adds a security label to a group.

Base Command

tc-add-group-security-label

Input
Argument Name Description Required
group_id The ID of the group to which to add the security label. To get the ID, run the tc-get-groups command. Required
group_type The type of the group to which to add the security label. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
security_label_name The name of the security label to add to the group. For example, "TLP:GREEN". Required

  

Command Example
!tc-add-group-security-label group_id=4406377 group_type=events security_label_name=TLP:GREEN

27. Adds tags to a specified group


Adds tags to a specified group.

Base Command

tc-add-group-tag

Input
Argument Name Description Required
group_id The ID of the group to which to add the tag. To get the ID, run the tc-get-groups command. Required
group_type The type of the group to which to add the tag. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
tag_name The name of the tag to add to the group. Required

 

 

Command Example
!tc-add-group-tag group_id=4378343 group_type=events tag_name=phishing

28. Returns all indicator types


Returns all indicator types available.

Base Command

tc-get-indicator-types

Input
Argument Name Description Required
group_id
The ID of the group to which to add the tag. To get the ID, run the tc-get-groups command.
Required
group_type
The type of the group to which to add the tag.
Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents",
"intrusionSets", "reports", "signatures", or "threats".
Required
tag_name The name of the indicator. For example, "indicator_type=emailAddresses" where "indicator=a@a.co.il". Required

 

Context Output
Path Type Description
TC.IndicatorType.ApiBranch String The branch of the API.
TC.IndicatorType.ApiEntity String The entity of the API.
TC.IndicatorType.CasePreference String The case preference of the indicator. For example, "sensitive", "upper", or "lower".
TC.IndicatorType.Custom Boolean Whether the indicator is a custom indicator.
TC.IndicatorType.Parsable Boolean Whether the indicator can be parsed.
TC.IndicatorType.Value1Type String The name of the indicator.
TC.IndicatorType.Value1Label String The value label of the indicator.

 

Command Example
!tc-get-indicator-types

29. Associates an indicator with a group


Associates an indicator with a group.

Base Command

tc-group-associate-indicator

Input
Argument Name Description Required
indicator_type The type of the indicator. To get the available types, run the tc-get-indicator-types command. The indicator must be spelled as displayed in the ApiBranch column of the UI. Required
indicator The name of the indicator. For example, "indicator_type=emailAddresses" where "indicator=a@a.co.il". Required
group_type The type of the group. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group. To get the ID of the group, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.GroupID Number The ID of the group.
TC.Group.GroupType String The type of the group.
TC.Group.Indicator String The name of the indicator.
TC.Group.IndicatorType String The type of the indicator.

 

Command Example
!tc-group-associate-indicator group_id=4406377 group_type=events indicator_type=emailAddresses indicator=a@a.co.il

30. Create a document group


Creates a document group.

Base Command

tc-create-document-group

Input
Argument Name Description Required
file_name The name of the file to display in the UI. Required
name The name of the file. Required
malware Whether the file is malware. If "true", ThreatConnect creates a password-protected ZIP file on your local machine that contains the sample and uploads the ZIP file. Optional
password The password of the ZIP file. Optional
security_label The security label of the group. Optional
description A description of the group. Optional
entry_id The file of the ID of the entry, as displayed in the War Room. Required

 

Context Output
Path Type Description
TC.Group.Name String The name of the group.
TC.Group.Owner String The owner of the group.
TC.Group.EventDate Date The date on which the group was created.
TC.Group.Description String The description of the group.
TC.Group.SecurityLabel String The security label of the group.
TC.Group.ID Number The ID of the group to which the attribute was added.

 

Command Example
!tc-create-document-group file_name="sample.pdf" name="sample.pdf" EntryID="13094@b2672a50-1db8-4424-8dcc-2136f4548ce4"

31. Retrieve a single group


Retrieves a single group.

Base Command

tc-get-group

Input
Argument Name Description Required
group_type The type of group for which to return the ID. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group to retrieve. To get the ID, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.DateAdded Date The date on which the group was added.
TC.Group.EventDate Date The date on which the event occurred.
TC.Group.Name String The name of the group.
TC.Group.Owner.ID Number The ID of the group owner.
TC.Group.Owner.Name String The name of the group owner.
TC.Group.Owner.Type String The type of the owner.
TC.Group.Status String The status of the group.

 

Command Example

!tc-get-group group_id=4579650 group_type=events

Context Example
{
    "TC.Group": {
        "DateAdded": "2019-09-18T10:08:37Z",
        "EventDate": "2019-09-18T10:08:37Z",
        "ID": 4579650,
        "Name": "MyTest",
        "Owner": {
            "ID": 737,
            "Name": "Demisto Inc.",
            "Type": "Organization"
        },
        "Status": "Needs Review"
    }
}
Human Readable Output

ThreatConnect Group information

DateAdded EventDate ID Name Owner Status
2019-09-18T10:08:37Z 2019-09-18T10:08:37Z 4579650 MyTest Type: Organization
Name: Demisto Inc.
ID: 737
Needs Review

 

32. Retrieve the attribute of a group


Retrieves the attribute of a group.

Base Command

tc-get-group-attributes

Input
Argument Name Description Required
group_type The type of group for which to return the attribute. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group for which to return the attribute. To get the ID, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.Attribute.DateAdded Date The date on which the group was added.
TC.Group.Attribute.Displayed Boolean Whether the attribute is displayed on the UI.
TC.Group.Attribute.AttributeID Number The ID of the attribute.
TC.Group.Attribute.LastModified Date The date on which the attribute was last modified.
TC.Group.Attribute.Type String The type of the attribute.
TC.Group.Attribute.Value String The value of the attribute.

 

Command Example

!tc-get-group-attributes group_id=4579650 group_type=events

Context Example
{
    "TC.Group.Attribute": [
        {
            "AttributeID": 20279371,
            "DateAdded": "2019-09-18T10:13:06Z",
            "Displayed": false,
            "GroupID": 4579650,
            "LastModified": "2019-09-18T10:13:06Z",
            "Type": "External ID",
            "Value": "123456789"
        },
        {
            "AttributeID": 20279370,
            "DateAdded": "2019-09-18T10:11:37Z",
            "Displayed": false,
            "GroupID": 4579650,
            "LastModified": "2019-09-18T10:11:37Z",
            "Type": "External ID",
            "Value": "123456789"
        },
        {
            "AttributeID": 20279368,
            "DateAdded": "2019-09-18T10:10:07Z",
            "Displayed": false,
            "GroupID": 4579650,
            "LastModified": "2019-09-18T10:10:07Z",
            "Type": "External ID",
            "Value": "123456789"
        },
        {
            "AttributeID": 20279366,
            "DateAdded": "2019-09-18T10:08:38Z",
            "Displayed": false,
            "GroupID": 4579650,
            "LastModified": "2019-09-18T10:08:38Z",
            "Type": "External ID",
            "Value": "123456789"
        }
    ]
}
Human Readable Output

ThreatConnect Group Attributes

AttributeID Type Value DateAdded LastModified Displayed
20279371 External ID 123456789 2019-09-18T10:13:06Z 2019-09-18T10:13:06Z false
20279370 External ID 123456789 2019-09-18T10:11:37Z 2019-09-18T10:11:37Z false
20279368 External ID 123456789 2019-09-18T10:10:07Z 2019-09-18T10:10:07Z false
20279366 External ID 123456789 2019-09-18T10:08:38Z 2019-09-18T10:08:38Z false

 

33. Retrieve the security labels of a group


Retrieves the security labels of a group.

Base Command

tc-get-group-security-labels

Input
Argument Name Description Required
group_type The type of group for which to return the security labels. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group for which to return the security labels. To get the ID, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.SecurityLabel.Name String The name of the security label.
TC.Group.SecurityLabel.Description String The description of the security label.
TC.Group.SecurityLabel.DateAdded Date The date on which the security label was added.

 

Command Example

!tc-get-group-security-labels group_id=4579650 group_type=events

Context Example
{
    "TC.Group.SecurityLabel": [
        {
            "DateAdded": "2016-08-31T00:00:00Z",
            "Description": "This security label is used for information that is useful for the awareness of all participating organizations as well as with peers within the broader community or sector.",
            "GroupID": 4579650,
            "Name": "TLP:GREEN"
        }
    ]
}
Human Readable Output

ThreatConnect Group Security Labels

Name Description DateAdded
TLP:GREEN This security label is used for information that is useful for the awareness of all participating organizations as well as with peers within the broader community or sector. 2016-08-31T00:00:00Z

 

34. Retrieves the tags of a group


Retrieves the tags of a group.

Base Command

tc-get-group-tags

Input
Argument Name Description Required
group_type The type of group for which to return the tags. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group for which to return the tags. To get the ID, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.Tag.Name String The name of the tag.

 

Command Example

!tc-get-group-tags group_id=4579650 group_type=events

Context Example
{
    "TC.Group.Tag": [
        {
            "GroupID": 4579650,
            "Name": "Testing"
        }
    ]
}
Human Readable Output

ThreatConnect Group Tags

Name
Testing

 

35. Downloads the contents of a document


Downloads the contents of a document.

Base Command

tc-download-document

Input
Argument Name Description Required
document_id The ID of the document. Required

 

Context Output
Path Type Description
File.Size Number The size of the file.
File.SHA1 String The SHA1 hash of the file.
File.SHA256 String The SHA256 hash of the file.
File.Name String The name of the file.
File.SSDeep String The ssdeep hash of the file (same as displayed in file entries).
File.EntryID String The entry ID of the file.
File.Info String The information of the file.
File.Type String The type of the file.
File.MD5 String The MD5 hash of the file.
File.Extension String The extension of the file.

 

Command Example

!tc-download-document document_id=1234567

36. Returns indicators associated with a group


Returns indicators associated with a group.

Base Command

tc-get-group-indicators

Input
Argument Name Description Required
group_type The type of the group for which to return the indicators. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group for which to return the indicators. To get the ID, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.Indicator.Summary String The summary of the indicator.
TC.Group.Indicator.ThreatAssessConfidence String The confidence rating of the indicator.
TC.Group.Indicator.IndicatorID Number The ID of the indicator.
TC.Group.Indicator.DateAdded Date The date on which the indicator was added.
TC.Group.Indicator.Type String The type of the indicator.
TC.Group.Indicator.Rating Number The threat rating of the indicator.
TC.Group.Indicator.ThreatAssertRating Number The rating of the threat assert.
TC.Group.Indicator.OwnerName String The name of the owner of the indicator.
TC.Group.Indicator.LastModified Date The date that the indicator was last modified.

 

Command Example

!tc-get-group-indicators group_id=4579650 group_type=events

Context Example
{
    "TC.Group.Indicator": [
        {
            "Confidence": null,
            "DateAdded": "2019-01-03T16:08:07Z",
            "GroupID": 4579650,
            "IndicatorID": 63441869,
            "LastModified": "2019-01-03T16:08:15Z",
            "OwnerName": "Demisto Inc.",
            "Rating": 2,
            "Summary": "a@a.co.il",
            "ThreatAssertRating": 2,
            "ThreatAssessConfidence": 0,
            "Type": "EmailAddress"
        }
    ]
}
Human Readable Output

ThreatConnect Group Indicators

DateAdded GroupID IndicatorID LastModified OwnerName Rating Summary ThreatAssertRating ThreatAssessConfidence Type
2019-01-03T16:08:07Z 4579650 63441869 2019-01-03T16:08:15Z Demisto Inc. 2.0 a@a.co.il 2.0 0.0 EmailAddress

 

37. Returns indicators associated with a specific group


Returns indicators associated with a specified group.

Base Command

tc-get-associated-groups

Input
Argument Name Description Required
group_type The type of group. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group. To get the ID, run the tc-get-groups command. Required

 

Context Output
Path Type Description
TC.Group.AssociatedGroup.DateAdded Date The date on which group was added.
TC.Group.AssociatedGroup.GroupID Number The ID of the group.
TC.Group.AssociatedGroup.Name String The name of the group.
TC.Group.AssociatedGroup.OwnerName String The name of the owner of the group.
TC.Group.AssociatedGroup.Type String The type of the group.

 

Command Example

!tc-get-associated-groups group_id=4579650 group_type=events

Context Example
{
    "TC.Group.AssociatedGroup": [
        {
            "DateAdded": "2019-01-13T18:13:19Z",
            "GroupID": 3594873,
            "Name": "NewCampaign",
            "OwnerName": "Demisto Inc.",
            "Type": "Campaign"
        }
    ]
}
Human Readable Output

ThreatConnect Associated Groups

GroupID Name Type OwnerName DateAdded
3594873 NewCampaign Campaign Demisto Inc. 2019-01-13T18:13:19Z

 

38. Associates one group with another group


Associates one group with another group.

Base Command

tc-associate-group-to-group

Input
Argument Name Description Required
group_type The type of the group. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
group_id The ID of the group. To get the ID of the group, run the tc-get-groups command. Required
associated_group_type The type of group to associate. Can be "adversaries", "campaigns", "documents", "emails", "events", "incidents", "intrusionSets", "reports", "signatures", or "threats". Required
associated_group_id The ID of the group to associate. Required

 

Context Output
Path Type Description
TC.Group.AssociatedGroup.AssociatedGroupID Number The ID of the associated group.
TC.Group.AssociatedGroup.AssociatedGroupType String The type of the associated group.
TC.Group.AssociatedGroup.GroupID Number The ID of the group to associate to.
TC.Group.AssociatedGroup.GroupType String The type of the group to associate to.

 

Command Example

!tc-associate-group-to-group associated_group_id=3594873 associated_group_type=campaigns group_id=4410738 group_type=events

Context Example
{
    "TC.Group.AssociatedGroup": {
        "AssociatedGroupID": 3594873,
        "AssociatedGroupType": "campaigns",
        "GroupID": 4410738,
        "GroupType": "events"
    }
}
Human Readable Output

The group 3594873 was associated successfully.

Configuration parameters

  • accessId — Access ID (required)
  • secretKey — Secret Key (required)
  • baseUrl — baseUrl (required)
  • defaultOrg — Default Organization
  • proxyIp — ProxyIP (or http://${ip} )
  • proxyPort — ProxyPort
  • rating — Rating threshold for Malicious Indicators
  • confidence — Confidence threshold for Malicious Indicators
  • freshness — Indicator Reputation Freshness (in days)

Commands (38)

  • domain Deprecated

    Searches for an indicator of type domain.

  • file Deprecated

    Searches for an indicator of type file.

  • ip Deprecated

    Searches for an indicator of type IP address.

  • tc-add-group-attribute Deprecated

    Adds an attribute to a specified group.

  • tc-add-group-security-label Deprecated

    Adds a security label to a group.

  • tc-add-group-tag Deprecated

    Adds tags to a specified group.

  • tc-add-indicator Deprecated

    Adds a new indicator to ThreatConnect.

  • tc-associate-group-to-group Deprecated

    Associates one group with another group.

  • tc-create-campaign Deprecated

    Creates a group based on the "Campaign" type.

  • tc-create-document-group Deprecated

    Creates a document group.

  • tc-create-event Deprecated

    Creates a group based on the "Event" type.

  • tc-create-incident Deprecated

    Creates a new incident group.

  • tc-create-threat Deprecated

    Creates a group based on the "Threats" type.

  • tc-delete-group Deprecated

    Deletes a group.

  • tc-delete-indicator Deprecated

    Deletes an indicator from ThreatConnect.

  • tc-delete-indicator-tag Deprecated

    Removes a tag from a specified indicator.

  • tc-download-document Deprecated

    Downloads the contents of a document.

  • tc-fetch-incidents Deprecated

    Fetches incidents from ThreatConnect.

  • tc-get-associated-groups Deprecated

    Returns indicators associated with a specified group.

  • tc-get-events Deprecated

    Returns a list of events.

  • tc-get-group Deprecated

    Retrieves a single group.

  • tc-get-group-attributes Deprecated

    Retrieves the attribute of a group.

  • tc-get-group-indicators Deprecated

    Returns indicators associated with a group.

  • tc-get-group-security-labels Deprecated

    Retrieves the security labels of a group.

  • tc-get-group-tags Deprecated

    Retrieves the tags of a group.

  • tc-get-groups Deprecated

    Returns all groups, filtered by the group type.

  • tc-get-incident-associate-indicators Deprecated

    Returns indicators that are related to a specific incident.

  • tc-get-indicator Deprecated

    Retrieves information about an indicator.

  • tc-get-indicator-types Deprecated

    Returns all indicator types available.

  • tc-get-indicators-by-tag Deprecated

    Fetches all indicators that have a tag.

  • tc-get-tags Deprecated

    Returns a list of all ThreatConnect tags.

  • tc-group-associate-indicator Deprecated

    Associates an indicator with a group.

  • tc-incident-associate-indicator Deprecated

    Associates an indicator with an existing incident. The indicator must exist before running this command. To add an indicator, run the tc-add-indicator command.

  • tc-indicators Deprecated

    Retrieves a list of all indicators.

  • tc-owners Deprecated

    Retrieves all owners for the current account.

  • tc-tag-indicator Deprecated

    Adds a tag to an existing indicator.

  • tc-update-indicator Deprecated

    Updates the indicator in ThreatConnect.

  • url Deprecated

    Searches for an indicator of type URL.

import demistomock as demisto
from CommonServerPython import *
from CommonServerUserPython import *

''' IMPORTS '''
from urlparse import urlparse
from datetime import timedelta
from distutils.util import strtobool
from threatconnect import ThreatConnect
from threatconnect.RequestObject import RequestObject
from threatconnect.Config.ResourceType import ResourceType
from threatconnect.Config.FilterOperator import FilterOperator

'''GLOBAL VARS'''
FRESHNESS = int(demisto.params()['freshness'])
MAX_CONTEXT = 100

''' HELPER FUNCTIONS '''


def get_client():
    params = demisto.params()
    access = params['accessId']
    secret = params['secretKey']
    default_org = params.get('defaultOrg')
    url = params['baseUrl']
    proxy_ip = params['proxyIp']
    proxy_port = params['proxyPort']

    tc = ThreatConnect(access, secret, default_org, url)
    if proxy_ip and proxy_port and len(proxy_ip) > 0 and len(proxy_port) > 0:
        tc.set_proxies(proxy_ip, int(proxy_port))

    return tc


def calculate_freshness_time(freshness):
    t = datetime.now() - timedelta(days=freshness)
    return t.strftime('%Y-%m-%dT00:00:00Z')


def create_context(indicators, include_dbot_score=False):
    context = {
        'DBotScore': [],
        outputPaths['ip']: [],
        outputPaths['url']: [],
        outputPaths['domain']: [],
        outputPaths['file']: [],
        'TC.Indicator(val.ID && val.ID === obj.ID)': [],
    }  # type: dict
    tc_type_to_demisto_type = {
        'Address': 'ip',
        'URL': 'url',
        'Host': 'domain',
        'File': 'file'
    }
    type_to_value_field = {
        'Address': 'ip',
        'URL': 'text',
        'Host': 'hostName',
        'File': 'md5'
    }

    for ind in indicators:
        indicator_type = tc_type_to_demisto_type.get(ind['type'], ind['type'])
        value_field = type_to_value_field.get(ind['type'], 'summary')
        value = ind.get(value_field, ind.get('summary', ''))

        if ind.get('confidence') is not None:  # returned in specific indicator request - SDK
            confidence = int(ind['confidence'])
        else:
            # returned in general indicator request - REST API
            confidence = int(ind.get('threatAssessConfidence', 0))

        if ind.get('rating') is not None:  # returned in specific indicator request - SDK
            rating = int(ind['rating'])
        else:
            # returned in general indicator request - REST API
            rating = int(ind.get('threatAssessRating', 0))

        if confidence >= demisto.params()['rating'] and rating >= demisto.params()['confidence']:
            dbot_score = 3
            desc = ''
            if hasattr(ind, 'description'):
                desc = ind.description
            mal = {
                'Malicious': {
                    'Vendor': 'ThreatConnect',
                    'Description': desc,
                }
            }
            if indicator_type == 'ip':
                mal['Address'] = value

            elif indicator_type == 'file':
                mal['MD5'] = value
                mal['SHA1'] = ind.get('sha1')
                mal['SHA256'] = ind.get('sha256')

            elif indicator_type == 'url':
                mal['Data'] = value

            elif indicator_type == 'domain':
                mal['Name'] = value

            context_path = outputPaths.get(indicator_type)
            if context_path is not None:
                context[context_path].append(mal)

        elif rating >= 1:
            dbot_score = 2
        else:
            dbot_score = 1

        if include_dbot_score:
            context['DBotScore'].append({
                'Indicator': value,
                'Score': dbot_score,
                'Type': indicator_type,
                'Vendor': 'ThreatConnect'
            })

        context['TC.Indicator(val.ID && val.ID === obj.ID)'].append({
            'ID': ind['id'],
            'Name': value,
            'Type': ind['type'],
            'Owner': ind['ownerName'],
            'Description': ind.get('description'),
            'CreateDate': ind['dateAdded'],
            'LastModified': ind['lastModified'],
            'Rating': rating,
            'Confidence': confidence,

            # relevant for domain
            'Active': ind.get('whoisActive'),

            # relevant for file
            'File.MD5': ind.get('md5'),
            'File.SHA1': ind.get('sha1'),
            'File.SHA256': ind.get('sha256'),
        })

    context = {k: createContext(v, removeNull=True)[:MAX_CONTEXT] for k, v in context.items() if len(v) > 0}
    return context, context.get('TC.Indicator(val.ID && val.ID === obj.ID)', [])


# pylint: disable=E1101
def get_indicators(indicator_value=None, indicator_type=None, owners=None, rating_threshold=-1, confidence_threshold=-1,
                   freshness=None):
    tc = get_client()
    indicators_obj = tc.indicators()
    _filter = indicators_obj.add_filter()

    if indicator_value is not None:
        _filter.add_indicator(indicator_value)
    if indicator_type is not None:
        _filter.add_pf_type(indicator_type, FilterOperator.EQ)

    if owners is not None:
        owners = owners.split(",")
        _filter.add_owner(owners)

    if rating_threshold != -1:
        _filter.add_pf_rating(rating_threshold, FilterOperator.GE)
    if confidence_threshold != -1:
        _filter.add_pf_confidence(confidence_threshold, FilterOperator.GE)
    if freshness is not None:
        _filter.add_pf_last_modified(calculate_freshness_time(freshness), FilterOperator.GE)

    raw_indicators = indicators_obj.retrieve()

    indicators = [json.loads(indicator.json) for indicator in raw_indicators]

    return indicators


''' FUNCTIONS '''


def ip_command():
    args = demisto.args()
    owners = args.get('owners', demisto.params().get('defaultOrg'))
    if not owners:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')
    rating_threshold = int(args.get('ratingThreshold', -1))
    confidence_threshold = int(args.get('confidenceThreshold', -1))
    ip_addr = args['ip']

    ec, indicators = ip(ip_addr, owners, rating_threshold, confidence_threshold)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect IP Reputation for: {}'.format(ip_addr), indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def ip(ip_addr, owners, rating_threshold, confidence_threshold):
    indicators = get_indicators(ip_addr, 'Address', owners, rating_threshold, confidence_threshold)

    if not indicators:
        demisto.results('Make sure that the indicator exists in your ThreatConnect environment')
    ec, indicators = create_context(indicators, include_dbot_score=True)

    return ec, indicators


def url_command():
    args = demisto.args()
    owners = args.get('owners', demisto.params().get('defaultOrg'))
    if not owners:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')
    url_addr = args['url']
    parsed_url = urlparse(url_addr)
    if not parsed_url.scheme:
        return_error('Please provide a valid URL including a protocol (http/https)')
    rating_threshold = int(args.get('ratingThreshold', -1))
    confidence_threshold = int(args.get('confidenceThreshold', -1))

    ec, indicators = url(url_addr, owners, rating_threshold, confidence_threshold)
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect URL Reputation for: {}'.format(url_addr), indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def url(url_addr, owners, rating_threshold, confidence_threshold):
    indicators = get_indicators(url_addr, 'URL', owners, rating_threshold, confidence_threshold)
    if not indicators:
        demisto.results('Make sure that the indicator exists in your ThreatConnect environment')
    ec, indicators = create_context(indicators, include_dbot_score=True)

    return ec, indicators


def file_command():
    args = demisto.args()
    owners = args.get('owners', demisto.params().get('defaultOrg'))
    if not owners:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')
    file_name = args['file']
    rating_threshold = int(args.get('ratingThreshold', -1))
    confidence_threshold = int(args.get('confidenceThreshold', -1))

    ec, indicators = _file(file_name, owners, rating_threshold, confidence_threshold)
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect File Report for: {}'.format(file_name), indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def _file(url_addr, owners, rating_threshold, confidence_threshold):
    indicators = get_indicators(url_addr, 'File', owners, rating_threshold, confidence_threshold)
    if not indicators:
        demisto.results('Make sure that the indicator exists in your ThreatConnect environment')
    ec, indicators = create_context(indicators, include_dbot_score=True)

    return ec, indicators


def domain_command():
    args = demisto.args()
    owners = args.get('owners', demisto.params().get('defaultOrg'))
    if not owners:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')
    rating_threshold = int(args.get('ratingThreshold', -1))
    confidence_threshold = int(args.get('confidenceThreshold', -1))
    domain_addr = args['domain']

    ec, indicators = domain(domain_addr, owners, rating_threshold, confidence_threshold)
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect Domain Reputation for: {}'.format(domain_addr), indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def domain(domain_addr, owners, rating_threshold, confidence_threshold):
    indicators = get_indicators(domain_addr, 'Host', owners, rating_threshold, confidence_threshold)
    ec, indicators = create_context(indicators, include_dbot_score=True)

    return ec, indicators


def tc_owners_command():
    raw_owners = tc_owners()
    owners = []
    for owner in raw_owners['data']['owner']:
        owners.append({
            'ID': owner['id'],
            'Type': owner['type'],
            'Name': owner['name']
        })

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_owners,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect Owners:', owners),
        'EntryContext': {'TC.Owner(val.ID && val.ID === obj.ID)': owners}
    })


@logger
def tc_owners():
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/owners')
    results = tc.api_request(ro)

    return results.json()


def tc_indicators_command():
    args = demisto.args()
    limit = int(args.get('limit', 500))
    owners = args.get('owners')
    ec, indicators, raw_response = tc_indicators(owners, limit)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_response,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect Indicators:', indicators, headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def tc_indicators(owners, limit):
    tc = get_client()
    tc.set_api_result_limit(limit)
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/indicators?resultLimit={}'.format(limit))

    if owners is not None:
        ro.set_owner(owners)
        ro.set_owner_allowed(True)

    response = tc.api_request(ro).json()
    indicators = response['data']['indicator']
    ec, indicators = create_context(indicators, include_dbot_score=True)

    return ec, indicators, response


def tc_get_tags_command():
    raw_response = tc_get_tags()
    tags = [t['name'] for t in raw_response['data']['tag']]

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_response,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect Tags:', tags, headers='Name'),
        'EntryContext': {'TC.Tags': tags}
    })


@logger
def tc_get_tags():
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/tags')

    return tc.api_request(ro).json()


def tc_tag_indicator_command():
    args = demisto.args()
    indicator = args['indicator']
    tag = args['tag']
    owners = args.get('owner')
    indicators = tc_tag_indicator(indicator, tag, owners)

    md = []
    for ind in indicators:
        md.append('Indicator {} with ID {}, was tagged with: {}'.format(indicator, ind.id, tag))

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['text'],
        'Contents': '\n'.join(md)
    })


def tc_tag_indicator(indicator, tag, owners=None):
    tc = get_client()
    indicators = tc.indicators()
    filter1 = indicators.add_filter()
    filter1.add_indicator(indicator)

    if owners is not None:
        owners = owners.split(",")
        filter1.add_owner(owners)

    indicators = indicators.retrieve()
    for indicator in indicators:
        indicator.add_tag(tag)
        indicator.commit()

    return indicators


def tc_get_indicator_command():
    args = demisto.args()
    owners = args.get('owners', demisto.params().get('defaultOrg'))
    if not owners:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')
    rating_threshold = int(args.get('ratingThreshold', -1))
    confidence_threshold = int(args.get('confidenceThreshold', -1))
    indicator = args['indicator']

    ec, indicators, raw_indicators = tc_get_indicator(indicator, owners, rating_threshold, confidence_threshold)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect indicator for: {}'.format(indicator), indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def tc_get_indicator(indicator, owners, rating_threshold, confidence_threshold):
    raw_indicators = get_indicators(indicator, owners=owners, rating_threshold=rating_threshold,
                                    confidence_threshold=confidence_threshold)
    ec, indicators = create_context(raw_indicators, include_dbot_score=True)

    return ec, indicators, raw_indicators


def tc_get_indicators_by_tag_command():
    args = demisto.args()
    tag = args['tag']
    owner = args.get('owner')
    response = tc_get_indicators_by_tag(tag, owner)
    raw_indicators = response['data']['indicator']
    ec, indicators = create_context(raw_indicators, include_dbot_score=True)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': response,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('ThreatConnect Indicators with tag: {}'.format(tag), indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def tc_get_indicators_by_tag(tag, owner):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    cmd = '/v2/tags/{}/indicators'.format(tag)
    if owner is not None:
        cmd += '?owner={}'.format(owner)

    ro.set_request_uri(cmd)

    return tc.api_request(ro).json()


def tc_add_indicator_command():
    args = demisto.args()
    indicator = args['indicator']
    owner = args.get('owner', demisto.params().get('defaultOrg'))
    if not owner:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')

    rating = int(args.get('rating', 0))
    confidence = int(args.get('confidence', 0))

    tc_add_indicator(indicator, owner, rating, confidence)
    # get the indicator for full object data
    raw_indicators = get_indicators(indicator)
    ec, indicators = create_context(raw_indicators)
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('Created new indicator successfully:', indicators,
                                         headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def tc_add_indicator(indicator, organization, rating=0, confidence=0):
    tc = get_client()
    indicators = tc.indicators()
    indicator = indicators.add(indicator, organization)
    indicator.set_rating(rating)
    indicator.set_confidence(confidence)

    return json.loads(indicator.commit().json)


def tc_create_incident_command():
    args = demisto.args()
    incident_name = args['incidentName']
    owner = args.get('owner', demisto.params()['defaultOrg'])
    if not owner:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')

    event_date = args.get('eventDate', datetime.utcnow().isoformat().split('.')[0] + 'Z')
    tag = args.get('tag')
    security_label = args.get('securityLabel')
    description = args.get('description')

    raw_incident = tc_create_incident(incident_name, owner, event_date, tag, security_label, description)
    ec = {
        'ID': raw_incident['id'],
        'Name': raw_incident['name'],
        'Owner': raw_incident['ownerName'],
        'EventDate': raw_incident['eventDate'],
        'Tag': tag,
        'SecurityLabel': security_label
    }

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_incident,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': 'Incident {} Created Successfully'.format(incident_name),
        'EntryContext': {
            'TC.Incident(val.ID && val.ID === obj.ID)': createContext([ec], removeNull=True)
        }
    })


@logger
def tc_create_incident(incident_name, owner, event_date, tag=None, security_label=None, description=None):
    tc = get_client()
    incidents = tc.incidents()
    incident = incidents.add(incident_name, owner)
    incident.set_event_date(event_date)
    if tag is not None:
        incident.add_tag(tag)
    if security_label is not None:
        incident.set_security_label(security_label)
    if description is not None:
        incident.add_attribute('Description', description)

    return json.loads(incident.commit().json)


def tc_fetch_incidents_command():
    args = demisto.args()
    incident_id = args.get('incidentId')
    incident_name = args.get('incidentName')
    owner = args.get('owner')

    raw_incidents = tc_fetch_incidents(incident_id, incident_name, owner)
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_incidents,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('Incidents:', raw_incidents, headerTransform=pascalToSpace),
        'EntryContext': {
            'TC.Incident(val.ID && val.ID === obj.ID)': createContext(raw_incidents, removeNull=True),
            'ThreatConnect.incidents': raw_incidents  # backward compatible
        }
    })


@logger
def tc_fetch_incidents(incident_id, incident_name, owner):
    tc = get_client()
    incidents = tc.incidents()
    if any((incident_id, owner, incident_name)):
        filter1 = incidents.add_filter()
        if incident_id is not None:
            filter1.add_id(int(incident_id))
        if owner is not None:
            filter1.add_owner(owner)
        if incident_name is not None:
            filter1.add_pf_name(incident_name)

    incidents.retrieve()
    return [json.loads(incident.json) for incident in incidents]


def tc_get_incident_associate_indicators_command():
    args = demisto.args()
    incident_id = int(args['incidentId'])
    owners = args.get('owner')
    if owners is not None:
        owners = owners.split(",")

    raw_indicators = tc_get_incident_associate_indicators(incident_id, owners)
    ec, indicators = create_context(raw_indicators, include_dbot_score=True)
    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': tableToMarkdown('Incident Associated Indicators:', indicators, headerTransform=pascalToSpace),
        'EntryContext': ec
    })


@logger
def tc_get_incident_associate_indicators(incident_id, owners):
    tc = get_client()
    incidents = tc.incidents()
    _filter = incidents.add_filter()
    _filter.add_id(incident_id)

    incidents = incidents.retrieve()
    indicators = []
    for incident in incidents:
        for ind in incident.indicator_associations:
            if ind.type == 'File':
                indicators.append(ind.indicator['md5'])
            else:
                indicators.append(ind.indicator)
    if len(indicators) == 0:
        return []

    indicators_obj = tc.indicators()
    _filter = indicators_obj.add_filter()
    if owners is not None:
        _filter.add_owner(owners)
    for ind in indicators:
        _filter.add_indicator(ind)

    raw_indicators = indicators_obj.retrieve()
    return [json.loads(indicator.json) for indicator in raw_indicators]


def tc_incident_associate_indicator_command():
    args = demisto.args()
    incident_id = int(args['incidentId'])
    indicator = args['indicator']
    types = {
        'ADDRESSES': ResourceType.ADDRESSES,
        'EMAIL_ADDRESSES': ResourceType.EMAIL_ADDRESSES,
        'FILES': ResourceType.FILES,
        'HOSTS': ResourceType.HOSTS,
        'URLS': ResourceType.URLS,
    }
    indicator_type = types.get(args['indicatorType'], args['indicatorType'])
    owners = args.get('owner')
    if owners is not None:
        owners = owners.split(",")

    incidents = tc_incident_associate_indicator(incident_id, indicator_type, indicator, owners)
    md = []
    for inc in incidents:
        md.append('Incident {} with ID {}, was tagged with: {}'.format(inc['name'], inc['id'], indicator))

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['text'],
        'Contents': incidents,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': '\n'.join(md),
        'EntryContext': {'TC.Incident(val.ID && val.ID === obj.ID)': createContext(incidents, removeNull=True)}
    })


@logger
def tc_incident_associate_indicator(incident_id, indicator_type, indicator, owners):
    tc = get_client()
    incidents = tc.incidents()
    filter1 = incidents.add_filter()
    filter1.add_id(incident_id)
    if owners is not None:
        filter1.add_owner(owners)
    raw_incidents = incidents.retrieve()

    incidents = []
    for incident in raw_incidents:
        incident.associate_indicator(indicator_type, indicator)
        incidents.append(json.loads(incident.commit().json))

    return incidents


def tc_update_indicator_command():
    args = demisto.args()
    indicator = args['indicator']
    rating = args.get('rating')
    confidence = args.get('confidence')
    size = args.get('size')
    dns_active = args.get('dnsActive')
    whois_active = args.get('whoisActive')
    false_positive = args.get('falsePositive', 'False') == 'True'
    observations = int(args.get('observations', 0))
    security_label = args.get('securityLabel')
    threat_assess_confidence = int(args.get('threatAssessConfidence', -1))
    threat_assess_rating = int(args.get('threatAssessRating', -1))

    raw_indicators = tc_update_indicator(indicator, rating=rating, confidence=confidence, size=size,
                                         dns_active=dns_active, whois_active=whois_active,
                                         false_positive=false_positive, observations=observations,
                                         security_label=security_label,
                                         threat_assess_confidence=threat_assess_confidence,
                                         threat_assess_rating=threat_assess_rating)
    ec, indicators = create_context(raw_indicators)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': '\n'.join('Indicator {} Updated Successfully'.format(ind['ID']) for ind in indicators),
        'EntryContext': ec
    })


@logger
def tc_update_indicator(indicator, rating=None, confidence=None, size=None, dns_active=None, whois_active=None,
                        false_positive=False, observations=0, security_label=None, threat_assess_confidence=-1,
                        threat_assess_rating=-1):
    tc = get_client()
    indicators = tc.indicators()
    filter1 = indicators.add_filter()
    filter1.add_indicator(indicator)

    raw_indicators = []
    for ind in indicators.retrieve():
        if rating is not None:
            ind.set_rating(rating)
        if confidence is not None:
            ind.set_confidence(int(confidence))
        if false_positive:
            ind.add_false_positive()
        if observations != 0:
            ind.add_observation(observations)
        if security_label is not None:
            ind.add_security_label(security_label)
        if threat_assess_confidence != -1:
            ind.set_threat_assess_confidence(threat_assess_confidence)
        if threat_assess_rating != -1:
            ind.set_threat_assess_rating(threat_assess_rating)

        if ind.type == 'File' and size is not None:
            ind.add_size(size)
        if ind.type == 'Host' and dns_active is not None:
            ind.set_dns_active(dns_active)
        if ind.type == 'Host' and whois_active is not None:
            ind.set_whois_active(whois_active)

        raw_indicators.append(json.loads(ind.commit().json))

    return raw_indicators


def tc_delete_indicator_command():
    args = demisto.args()
    indicator = args['indicator']

    tc_delete_indicator(indicator)

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['text'],
        'Contents': 'Indicator {} removed Successfully'.format(indicator)
    })


@logger
def tc_delete_indicator(indicator):
    tc = get_client()
    indicators = tc.indicators()
    filter1 = indicators.add_filter()
    filter1.add_indicator(indicator)
    indicators = indicators.retrieve()
    for ind in indicators:
        ind.delete()


def tc_delete_indicator_tag_command():
    args = demisto.args()
    indicator = args['indicator']
    tag = args['tag']

    indicators = tc_delete_indicator_tag(indicator, tag)
    raw_indicators = [json.loads(ind.json) for ind in indicators]
    ec, _ = create_context(raw_indicators)

    md = []
    for ind in indicators:
        md.append('Removed tag {} from indicator {}.'.format(tag, ind.indicator))
    if len(md) == 0:
        md.append('No indicators found')

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['text'],
        'Contents': raw_indicators,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': '\n'.join(md),
        'EntryContext': ec
    })


@logger
def tc_delete_indicator_tag(indicator, tag, owners=None):
    tc = get_client()
    indicators = tc.indicators()
    filter1 = indicators.add_filter()
    filter1.add_indicator(indicator)

    if owners is not None:
        owners = owners.split(",")
        filter1.add_owner(owners)

    indicators = indicators.retrieve()
    for indicator in indicators:
        indicator.delete_tag(tag)
        indicator.commit()

    return indicators


def tc_create_campaign_command():
    args = demisto.args()
    name = args['name']
    owner = args.get('owner', demisto.params()['defaultOrg'])
    if owner == '':
        return_error('You must specify an owner in the command, or by using the Organization parameter.')

    first_seen = args.get('firstSeen', datetime.utcnow().isoformat().split('.')[0] + 'Z')
    tag = args.get('tag')
    security_label = args.get('securityLabel')
    description = args.get('description')

    raw_campaign = tc_create_campaign(name, owner, first_seen, tag, security_label, description)
    ec = {
        'ID': raw_campaign['id'],
        'Name': raw_campaign['name'],
        'Owner': raw_campaign['owner']['name'],
        'FirstSeen': raw_campaign['firstSeen'],
        'Tag': tag,
        'SecurityLabel': security_label
    }

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_campaign,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': 'Campaign {} Created Successfully'.format(name),
        'EntryContext': {
            'TC.Campaign(val.ID && val.ID === obj.ID)': createContext([ec], removeNull=True)
        }
    })


@logger
def tc_create_campaign(name, owner, first_seen, tag=None, security_label=None, description=None):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/groups/campaigns')
    body = {
        'name': name,
        'firstSeen': first_seen,
    }
    ro.set_body(json.dumps(body))
    response = tc.api_request(ro).json()

    if response.get('status') == 'Success':
        output = response.get('data', {}).get('campaign', {})
        event_id = output['id']
        if description is not None:
            # Associate Attribute description
            ro = RequestObject()
            ro.set_http_method('POST')
            ro.set_request_uri('/v2/groups/events/{}/attributes'.format(event_id))
            body = {
                'type': 'Description',
                'value': description,
                'displayed': 'true'
            }
            ro.set_body(json.dumps(body))
            tc.api_request(ro).json()

        return output
    else:
        return_error('Failed to create event')


def tc_create_event_command():
    args = demisto.args()
    name = args['name']
    event_date = args.get('EventDate', datetime.utcnow().isoformat().split('.')[0] + 'Z')
    status = args.get('status')
    owner = args.get('owner', demisto.params()['defaultOrg'])
    if owner == '':
        return_error('You must specify an owner in the command, or by using the Organization parameter.')

    description = args.get('description')
    tag = args.get('tag')

    raw_event = tc_create_event(name, owner, event_date, tag, status, description)
    ec = {
        'ID': raw_event['id'],
        'Name': raw_event['name'],
        'Owner': raw_event['owner']['name'],
        'Date': raw_event['eventDate'],
        'Tag': tag,
        'Status': status
    }

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_event,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': 'Incident {} Created Successfully'.format(name),
        'EntryContext': {
            'TC.Event(val.ID && val.ID === obj.ID)': createContext([ec], removeNull=True)
        }
    })


def tc_create_event(name, owner, event_date, tag=None, status=None, description=None):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/groups/events')
    body = {
        'name': name,
        'eventDate': event_date,
        'status': status
    }
    ro.set_body(json.dumps(body))
    response = tc.api_request(ro).json()

    if response.get('status') == 'Success':
        output = response.get('data', {}).get('event', {})
        event_id = output['id']
        if description is not None:
            # Associate Attribute description
            ro = RequestObject()
            ro.set_http_method('POST')
            ro.set_request_uri('/v2/groups/events/{}/attributes'.format(event_id))
            body = {
                'type': 'Description',
                'value': description,
                'displayed': 'true'
            }
            ro.set_body(json.dumps(body))
            tc.api_request(ro).json()

        return output
    else:
        return_error('Failed to create event')


def tc_create_threat_command():
    args = demisto.args()
    name = args['name']
    date = args.get('dateAdded', datetime.utcnow().isoformat().split('.')[0] + 'Z')
    owner = args.get('owner', demisto.params()['defaultOrg'])
    if owner == '':
        return_error('You must specify an owner in the command, or by using the Organization parameter.')

    raw_threat = tc_create_threat(name, owner, date)
    ec = {
        'ID': raw_threat['id'],
        'Name': raw_threat['name']
    }

    demisto.results({
        'Type': entryTypes['note'],
        'ContentsFormat': formats['json'],
        'Contents': raw_threat,
        'ReadableContentsFormat': formats['markdown'],
        'HumanReadable': 'Threat {} Created Successfully'.format(name),
        'EntryContext': {
            'TC.Threat(val.ID && val.ID === obj.ID)': createContext([ec], removeNull=True)
        }
    })


def tc_create_threat(name, owner, date):
    tc = get_client()
    threats = tc.threats()
    threat = threats.add(name, owner)
    threat.set_date_added(date)

    return json.loads(threat.commit().json)


def tc_delete_group_command():
    args = demisto.args()
    group_id = int(args['groupID'])
    group_type = args['type']

    success = tc_delete_group(group_id, group_type.lower())
    if success:
        demisto.results({
            'Type': entryTypes['note'],
            'ContentsFormat': formats['text'],
            'Contents': '{} {} deleted Successfully'.format(group_type.lower(), group_id)
        })
    else:
        return_error('Failed to delete {} {}'.format(group_type, group_id))


def tc_delete_group(group_id, group_type):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('DELETE')
    ro.set_request_uri('/v2/groups/{}/{}'.format(group_type, group_id))
    response = tc.api_request(ro).json()

    return response['status'] == 'Success'


def tc_add_group_attribute_request(group_type, group_id, attribute_type, attribute_value):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/groups/{}/{}/attributes'.format(group_type, group_id))
    body = {
        'type': attribute_type,
        'value': attribute_value,
        'displayed': 'true'
    }
    ro.set_body(json.dumps(body))
    response = tc.api_request(ro).json()

    return response


def tc_add_group_attribute():
    group_id = int(demisto.args().get('group_id'))
    group_type = demisto.args().get('group_type')
    attribute_type = demisto.args().get('attribute_type')
    attribute_value = demisto.args().get('attribute_value')
    headers = ['Type', 'Value', 'ID', 'DateAdded', 'LastModified']
    attribute = tc_add_group_attribute_request(group_type, group_id, attribute_type, attribute_value)
    data = attribute.get('data').get('attribute')
    contents = {
        'Type': data.get('type'),
        'Value': data.get('value'),
        'ID': data.get('id'),
        'DateAdded': data.get('dateAdded'),
        'LastModified': data.get('lastModified')
    }
    context = {
        'TC.Group(val.ID && val.ID === obj.ID)': contents
    }

    return_outputs(
        tableToMarkdown('The attribute was added successfully to group {}'.format(group_id), contents, headers,
                        removeNull=True),
        context,
        attribute
    )


def add_group_security_label_request(group_type, group_id, security_label):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/groups/{}/{}/securityLabels/{}'.format(group_type, group_id, security_label))

    response = tc.api_request(ro).json()

    return response.get('status') == 'Success'


def add_group_security_label():
    group_id = int(demisto.args().get('group_id'))
    group_type = demisto.args().get('group_type')
    security_label = demisto.args().get('security_label_name')

    add_group_security_label_request(group_type, group_id, security_label)

    demisto.results('The security label {} was added successfully to {} {}'.format(security_label, group_type,
                                                                                   group_id))


def add_group_tags_request(group_type, group_id, tag_name):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/groups/{}/{}/tags/{}'.format(group_type, group_id, tag_name))

    response = tc.api_request(ro).json()

    return response.get('status') == 'Success'


def add_group_tag():
    group_id = int(demisto.args().get('group_id'))
    group_type = demisto.args().get('group_type')
    tag_name = demisto.args().get('tag_name')

    add_group_tags_request(group_type, group_id, tag_name)

    demisto.results('The tag {} was added successfully to group {} {}'.format(tag_name, group_type, group_id))


def get_events_request():
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/events')

    return tc.api_request(ro).json()


def tc_get_events():
    raw_response = get_events_request()
    data = raw_response.get('data', {}).get('event', [])
    content = []
    headers = ['ID', 'Name', 'OwnerName', 'EventDate', 'DateAdded', 'Status']

    for event in data:
        content.append({
            'ID': event.get('id'),
            'Name': event.get('name'),
            'OwnerName': event.get('ownerName'),
            'DateAdded': event.get('dateAdded'),
            'EventDate': event.get('eventDate'),
            'Status': event.get('status')
        })
    context = {
        'TC.Event(val.ID && val.ID === obj.ID)': content
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Events', content, headers, removeNull=True),
        context,
        raw_response
    )


def tc_get_indicator_types_request():
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/types/indicatorTypes')

    return tc.api_request(ro).json()


def tc_get_indicator_types():
    raw_response = tc_get_indicator_types_request()
    data = raw_response.get('data', {}).get('indicatorType', [])
    content = []
    headers = ['Name', 'Custom', 'Parsable', 'ApiBranch', 'CasePreference', 'value1Label', 'Value1Type']

    for type_ in data:
        content.append({
            'Custom': type_.get('custom'),
            'Name': type_.get('name'),
            'Parsable': type_.get('parsable'),
            'ApiBranch': type_.get('apiBranch'),
            'ApiEntity': type_.get('apiEntity'),
            'CasePreference': type_.get('casePreference'),
            'Value1Label': type_.get('value1Label'),
            'Value1Type': type_.get('value1Type')
        })
    context = {
        'TC.IndicatorType(val.Name && val.Name === obj.Name)': content
    }

    return_outputs(
        tableToMarkdown('ThreatConnect indicator types', content, headers, removeNull=True),
        context,
        raw_response
    )


def associate_indicator_request(indicator_type, indicator, group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/indicators/{}/{}/groups/{}/{}'.format(indicator_type, indicator, group_type, group_id))
    response = tc.api_request(ro).json()

    return response


def associate_indicator():
    group_id = int(demisto.args().get('group_id'))
    group_type = demisto.args().get('group_type')
    indicator_type = demisto.args().get('indicator_type')
    indicator = demisto.args().get('indicator')

    response = associate_indicator_request(indicator_type, indicator, group_type, group_id)

    if response.get('status') == 'Success':
        contents = {
            'IndicatorType': indicator_type,
            'Indicator': indicator,
            'GroupType': group_type,
            'GroupID': group_id
        }
    else:
        return_error(response.get('message'))

    context = {
        'TC.Group(val.Indicator && val.Indicator === obj.Indicator)': contents
    }

    return_outputs(
        tableToMarkdown('The indicator was associated successfully', contents, removeNull=True),
        context
    )


def get_groups_request(group_type):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}'.format(group_type))

    return tc.api_request(ro).json()


def tc_get_groups():
    group_type = demisto.args().get('group_type')
    raw_response = get_groups_request(group_type)
    headers = ['ID', 'Name', 'OwnerName', 'EventDate', 'DateAdded', 'Status']
    if group_type == 'adversaries':
        data = raw_response.get('data', {}).get('adversarie', {})
    if group_type == 'campaigns':
        data = raw_response.get('data', {}).get('campaign', {})
    if group_type == 'documents':
        data = raw_response.get('data', {}).get('document', {})
    if group_type == 'emails':
        data = raw_response.get('data', {}).get('email', {})
    if group_type == 'events':
        data = raw_response.get('data', {}).get('event', {})
    if group_type == 'incidents':
        data = raw_response.get('data', {}).get('incident', {})
    if group_type == 'intrusionSets':
        data = raw_response.get('data', {}).get('intrusionSet', {})
    if group_type == 'reports':
        data = raw_response.get('data', {}).get('report', {})
    if group_type == 'signatures':
        data = raw_response.get('data', {}).get('signature', {})
    if group_type == 'threats':
        data = raw_response.get('data', {}).get('threat', {})

    content = []

    for group in data:
        content.append({
            'ID': group.get('id'),
            'Name': group.get('name'),
            'OwnerName': group.get('ownerName'),
            'DateAdded': group.get('dateAdded'),
            'EventDate': group.get('eventDate'),
            'Status': group.get('status')
        })
    context = {
        'TC.Group(val.ID && val.ID === obj.ID)': content
    }

    return_outputs(
        tableToMarkdown('ThreatConnect {}'.format(group_type), content, headers, removeNull=True),
        context,
        raw_response
    )


def get_group_request(group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}/{}'.format(group_type, group_id))

    return tc.api_request(ro).json()


def get_group():
    """
    Retrieve a single Group
    """
    group_type = demisto.args().get('group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)

    response = get_group_request(group_type, group_id).get('data', {})
    if group_type == 'adversaries':
        data = response.get('adversarie', {})
    if group_type == 'campaigns':
        data = response.get('campaign', {})
    if group_type == 'documents':
        data = response.get('document', {})
    if group_type == 'emails':
        data = response.get('email', {})
    if group_type == 'events':
        data = response.get('event', {})
    if group_type == 'incidents':
        data = response.get('incident', {})
    if group_type == 'intrusionSets':
        data = response.get('intrusionSet', {})
    if group_type == 'reports':
        data = response.get('report', {})
    if group_type == 'signatures':
        data = response.get('signature', {})
    if group_type == 'threats':
        data = response.get('threat', {})

    owner = {
        'Name': data.get('owner').get('name'),
        'ID': data.get('owner').get('id'),
        'Type': data.get('owner').get('type')
    }
    contents = {
        'ID': data.get('id'),
        'Name': data.get('name'),
        'Owner': owner,
        'DateAdded': data.get('dateAdded'),
        'EventDate': data.get('eventDate'),
        'Status': data.get('status')
    }

    context = {
        'TC.Group(val.ID && val.ID === obj.ID)': contents
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Group information', contents, removeNull=True),
        context,
        response
    )


def get_group_attributes_request(group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}/{}/attributes'.format(group_type, group_id))

    return tc.api_request(ro).json()


def get_group_attributes():
    """
    Retrieve a Group's Attributes
    """
    group_type = demisto.args().get('group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)
    contents = []
    headers = ['AttributeID', 'Type', 'Value', 'DateAdded', 'LastModified', 'Displayed']
    response = get_group_attributes_request(group_type, group_id)
    data = response.get('data', {}).get('attribute', [])

    if response.get('status') == 'Success':
        for attribute in data:
            contents.append({
                'GroupID': group_id,
                'AttributeID': attribute.get('id'),
                'Type': attribute.get('type'),
                'Value': attribute.get('value'),
                'DateAdded': attribute.get('dateAdded'),
                'LastModified': attribute.get('lastModified'),
                'Displayed': attribute.get('displayed')
            })

    else:
        return_error(response.get('message'))

    context = {
        'TC.Group.Attribute(val.GroupID && val.GroupID === obj.GroupID && val.AttributeID && val.AttributeID ==='
        ' obj.AttributeID)': contents
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Group Attributes', contents, headers, removeNull=True),
        context,
        response
    )


def get_group_security_labels_request(group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}/{}/securityLabels'.format(group_type, group_id))

    return tc.api_request(ro).json()


def get_group_security_labels():
    """
    Retrieve a Group's Security Labels
    """
    group_type = demisto.args().get('group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)
    contents = []
    headers = ['Name', 'Description', 'DateAdded']
    response = get_group_security_labels_request(group_type, group_id)
    data = response.get('data', {}).get('securityLabel', [])

    if response.get('status') == 'Success':
        for security_label in data:
            contents.append({
                'GroupID': group_id,
                'Name': security_label.get('name'),
                'Description': security_label.get('description'),
                'DateAdded': security_label.get('dateAdded')
            })

    else:
        return_error(response.get('message'))

    context = {
        'TC.Group.SecurityLabel(val.GroupID && val.GroupID === obj.GroupID && val.Name && val.Name === '
        'obj.Name)': contents
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Group Security Labels', contents, headers, removeNull=True),
        context
    )


def get_group_tags_request(group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}/{}/tags'.format(group_type, group_id))

    return tc.api_request(ro).json()


def get_group_tags():
    """
    Retrieve the Tags for a Group
    """
    group_type = demisto.args().get('group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)
    contents = []
    context_entries = []
    response = get_group_tags_request(group_type, group_id)
    data = response.get('data', {}).get('tag', [])

    if response.get('status') == 'Success':
        for tags in data:
            contents.append({
                'Name': tags.get('name')
            })

            context_entries.append({
                'GroupID': group_id,
                'Name': tags.get('name')
            })
    else:
        return_error(response.get('message'))

    context = {
        'TC.Group.Tag(val.GroupID && val.GroupID === obj.GroupID && val.Name && val.Name === obj.Name)': context_entries
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Group Tags', contents, removeNull=True),
        context,
        response
    )


def get_group_indicator_request(group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}/{}/indicators'.format(group_type, group_id))

    return tc.api_request(ro).json()


def get_group_indicator():
    """
    View Indicators associated with a given Group
    """
    group_type = demisto.args().get('group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)
    contents = []
    response = get_group_indicator_request(group_type, group_id)
    data = response.get('data', {}).get('indicator', [])

    if response.get('status') == 'Success':
        for indicator in data:
            contents.append({
                'GroupID': group_id,
                'IndicatorID': indicator.get('id'),
                'OwnerName': indicator.get('ownerName'),
                'Type': indicator.get('type'),
                'DateAdded': indicator.get('dateAdded'),
                'LastModified': indicator.get('lastModified'),
                'Rating': indicator.get('rating'),
                'Confidence': indicator.get('confidence'),
                'ThreatAssertRating': indicator.get('threatAssessRating'),
                'ThreatAssessConfidence': indicator.get('threatAssessConfidence'),
                'Summary': indicator.get('summary')
            })

    else:
        return_error(response.get('message'))

    context = {
        'TC.Group.Indicator(val.GroupID && val.GroupID === obj.GroupID && val.IndicatorID && val.IndicatorID === '
        'obj.IndicatorID)': contents
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Group Indicators', contents, removeNull=True),
        context,
        response
    )


def get_group_associated_request(group_type, group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('GET')
    ro.set_request_uri('/v2/groups/{}/{}/groups'.format(group_type, group_id))

    return tc.api_request(ro).json()


def get_group_associated():
    """
    View Indicators associated with a given Group
    """
    group_type = demisto.args().get('group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)
    contents = []
    headers = ['GroupID', 'Name', 'Type', 'OwnerName', 'DateAdded']
    response = get_group_associated_request(group_type, group_id)
    data = response.get('data', {}).get('group', [])

    if response.get('status') == 'Success':
        for group in data:
            contents.append({
                'GroupID': group.get('id'),
                'Name': group.get('name'),
                'Type': group.get('type'),
                'DateAdded': group.get('dateAdded'),
                'OwnerName': group.get('ownerName')
            })

    else:
        return_error(response.get('message'))

    context = {
        'TC.Group.AssociatedGroup(val.GroupID && val.GroupID === obj.GroupID)': contents
    }

    return_outputs(
        tableToMarkdown('ThreatConnect Associated Groups', contents, headers, removeNull=True),
        context,
        response
    )


def associate_group_to_group_request(group_type, group_id, associated_group_type, associated_group_id):
    tc = get_client()
    ro = RequestObject()
    ro.set_http_method('POST')
    ro.set_request_uri('/v2/groups/{}/{}/groups/{}/{}'.format(group_type, group_id, associated_group_type,
                                                              associated_group_id))

    return tc.api_request(ro).json()


def associate_group_to_group():
    """
    Associate one Group with another
    """

    group_type = demisto.args().get('group_type')
    associated_group_type = demisto.args().get('associated_group_type')
    try:
        group_id = int(demisto.args().get('group_id'))
    except TypeError as t:
        return_error('group_id must be a number', t)
    try:
        associated_group_id = int(demisto.args().get('associated_group_id'))
    except TypeError as t:
        return_error('associated_group_id must be a number', t)

    response = associate_group_to_group_request(group_type, group_id, associated_group_type, associated_group_id)

    if response.get('status') == 'Success':
        context_entries = {
            'GroupID': group_id,
            'GroupType': group_type,
            'AssociatedGroupID': associated_group_id,
            'AssociatedGroupType': associated_group_type
        }
        context = {
            'TC.Group.AssociatedGroup(val.GroupID && val.GroupID === obj.GroupID)': context_entries
        }
        return_outputs('The group {} was associated successfully.'.format(associated_group_id),
                       context,
                       response)
    else:
        return_error(response.get('message'))


def create_document_group_request(contents, file_name, name, owner, res, malware, password, security_label,
                                  description):
    tc = get_client()
    documents = tc.documents()

    document = documents.add(name, owner)
    document.set_file_name(file_name)

    # upload the contents of the file into the Document
    document.upload(contents)
    if malware:
        document.set_malware(True)
        document.set_password(password)
    if security_label:
        document.set_security_label(security_label)
    if description:
        document.add_attribute('Description', description)

    return json.loads(document.commit().json)


def create_document_group():
    file_name = demisto.args().get('file_name')
    name = demisto.args().get('name')
    malware = bool(strtobool(demisto.args().get('malware', False)))
    password = demisto.args().get('password')
    res = demisto.getFilePath(demisto.args()['entry_id'])
    owner = demisto.args().get('owner', demisto.params().get('defaultOrg'))
    if not owner:
        return_error('You must specify an owner in the command, or by using the Organization parameter.')

    security_label = demisto.args().get('securityLabel')
    description = demisto.args().get('description')

    # open a file handle for a local file and read the contents thereof
    f = open(res['path'], 'rb')
    contents = f.read()

    raw_document = create_document_group_request(contents, file_name, name, owner, res, malware, password,
                                                 security_label, description)
    content = {
        'ID': raw_document.get('id'),
        'Name': raw_document.get('name'),
        'Owner': raw_document.get('ownerName'),
        'EventDate': raw_document.get('eventDate'),
        'Description': description,
        'SecurityLabel': security_label
    }
    context = {
        'TC.Group(val.ID && val.ID === obj.ID)': content
    }
    return_outputs(tableToMarkdown('ThreatConnect document group was created successfully', content, removeNull=True),
                   context,
                   raw_document)


def get_document_request(document_id):

    tc = get_client()
    documents = tc.documents()
    # set a filter to retrieve only the Document with ID: 123456
    filter1 = documents.add_filter()
    filter1.add_id(document_id)
    try:
        # retrieve the Document
        documents.retrieve()
    except RuntimeError as e:
        return_error('Error: {0}'.format(str(e)))

    # iterate through the retrieved Documents (in this case there should only be one) and print its properties
    for document in documents:
        document.download()
        if document.contents is not None:
            return document
        else:
            return_error('No document was found.')


def download_document():
    """
    Download the contents of a Document
    """
    try:
        document_id = int(demisto.args().get('document_id'))
    except TypeError as t:
        return_error('document_id must be a number', t)
    document = get_document_request(document_id)

    file_name = document.file_name
    file_content = document.contents
    demisto.results(fileResult(file_name, file_content))


def test_integration():
    tc = get_client()
    owners = tc.owners()
    owners.retrieve()
    demisto.results('ok')


''' EXECUTION CODE '''
COMMANDS = {
    'test-module': test_integration,
    'ip': ip_command,
    'url': url_command,
    'file': file_command,
    'domain': domain_command,

    'tc-owners': tc_owners_command,
    'tc-indicators': tc_indicators_command,
    'tc-get-tags': tc_get_tags_command,
    'tc-tag-indicator': tc_tag_indicator_command,
    'tc-get-indicator': tc_get_indicator_command,
    'tc-get-indicators-by-tag': tc_get_indicators_by_tag_command,
    'tc-add-indicator': tc_add_indicator_command,

    'tc-create-incident': tc_create_incident_command,
    'tc-fetch-incidents': tc_fetch_incidents_command,
    'tc-get-incident-associate-indicators': tc_get_incident_associate_indicators_command,
    'tc-incident-associate-indicator': tc_incident_associate_indicator_command,
    'tc-update-indicator': tc_update_indicator_command,
    'tc-delete-indicator': tc_delete_indicator_command,
    'tc-delete-indicator-tag': tc_delete_indicator_tag_command,
    'tc-create-campaign': tc_create_campaign_command,
    'tc-create-event': tc_create_event_command,
    'tc-get-events': tc_get_events,
    'tc-add-group-attribute': tc_add_group_attribute,
    'tc-create-threat': tc_create_threat_command,
    'tc-delete-group': tc_delete_group_command,
    'tc-get-groups': tc_get_groups,
    'tc-add-group-security-label': add_group_security_label,
    'tc-add-group-tag': add_group_tag,
    'tc-get-indicator-types': tc_get_indicator_types,
    'tc-group-associate-indicator': associate_indicator,
    'tc-create-document-group': create_document_group,
    'tc-get-group': get_group,
    'tc-get-group-attributes': get_group_attributes,
    'tc-get-group-security-labels': get_group_security_labels,
    'tc-get-group-tags': get_group_tags,
    'tc-download-document': download_document,
    'tc-get-group-indicators': get_group_indicator,
    'tc-get-associated-groups': get_group_associated,
    'tc-associate-group-to-group': associate_group_to_group
}

try:
    command_func = demisto.command()
    LOG('command is %s' % (demisto.command(),))
    if command_func in COMMANDS.keys():
        COMMANDS[command_func]()

except Exception as e:
    LOG(e.message)
    LOG.print_log()
    return_error('error has occurred: {}'.format(e.message, ))