CheckPointSandBlast
Uploads files using polling. The service supports Microsoft Office files, as well as PDF, SWF, archives, and executables. Active content will be cleaned from any documents that you upload (Microsoft Office and PDF files only). Queries on existing IOCs, file status, analysis, and reports. Downloads files from the database. Supports both appliance and cloud. Supported Threat Emulation versions are any R80x.
Forensics & Malware Analysis · Check Point Threat Emulation (SandBlast)
Details
| ID | CheckPointSandBlast |
|---|---|
| Provider | CheckPoint Software Technologies |
| Category | Forensics & Malware Analysis |
| From Version | 6.5.0 |
| Docker Image | demisto/python3:3.12.13.10116658 |
| Supported Modules | Agentix XSIAM |
README
Check Point Threat Emulation (SandBlast)
Threat Emulation performs remote analysis by uploading files to a virtual SandBox. Uploaded files are monitored in multiple OS and microsoft office application versions. Malicious files are saved in the ThreatCloud. Safe files are available for download after inspection.
Upload files using polling, the service supports Microsoft Office files, as well as PDF, SWF, archives and executables. Active content will be cleaned from any documents that you upload (Microsoft Office and PDF files only). Query on existing IOCs, file status, analysis, reports. Download files from the database. Supports both appliance and cloud. Supported Threat Emulation versions are any R80x.
This integration was integrated and tested with version v1 of CheckPointSandBlast
Configure Check Point Threat Emulation (SandBlast) in Cortex
| Parameter | Description | Required |
|---|---|---|
| Server URL | https://te.checkpoint.com | True |
| Authorization - API Key | False | |
| Trust any certificate (not secure) | False | |
| Use system proxy settings | False | |
| Source Reliability | Reliability of the source providing the intelligence data. | True |
Commands
You can execute these commands from the 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.
file
Runs reputation on files.
Base Command
file
Input
| Argument Name | Description | Required |
|---|---|---|
| file | Hash of the file to query. Supports MD5, SHA1, and SHA256. | Required |
Context Output
| Path | Type | 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 | The vendor that reported the file as malicious. |
| File.Malicious.Description | String | A description explaining why the file was determined to be malicious. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| DBotScore.Reliability | String | Reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
Command example
!file file=e129988964fa250bc8186bfe6f399f12
Context Example
{
"DBotScore": [
{
"Indicator": "e129988964fa250bc8186bfe6f399f12",
"Reliability": "C - Fairly reliable",
"Score": 0,
"Type": "file",
"Vendor": "VirusTotal"
},
{
"Indicator": "e129988964fa250bc8186bfe6f399f12",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "file",
"Vendor": "CheckPointSandBlast"
}
],
"File": {
"MD5": "e129988964fa250bc8186bfe6f399f12",
"Malicious": {
"Description": {
"confidence": 0,
"malware_family": 0,
"malware_type": 0,
"severity": 0,
"signature_name": ""
},
"Vendor": "CheckPointSandBlast"
},
"SHA1": "a5e7aa50b66fdad3ae3b5e9ca66283a263bf7027",
"SHA256": "7e1eeaa9ac04812ce89eabb824d65073a3a37a1600ad1e1b7748ae12e04bb168"
}
}
Human Readable Output
Results of file hash: “e129988964fa250bc8186bfe6f399f12”
MD5 SHA1 SHA256 Malicious e129988964fa250bc8186bfe6f399f12 a5e7aa50b66fdad3ae3b5e9ca66283a263bf7027 7e1eeaa9ac04812ce89eabb824d65073a3a37a1600ad1e1b7748ae12e04bb168 Vendor: CheckPointSandBlast
Description: {“signature_name”: “”, “malware_family”: 0, “malware_type”: 0, “severity”: 0, “confidence”: 0}
sandblast-query
Use the Query API to have a client application look for either the analysis report of a specific file on the Check Point Threat Prevention service databases or the status of a file, uploaded for analysis. It is recommended to add file_name.
Base Command
sandblast-query
Input
| Argument Name | Description | Required |
|---|---|---|
| file_name | Name of the file to query. Recommended to use, without it status will be “PARTIALLY_FOUND”. | Optional |
| file_hash | File hash to query, accepted digests are: md5, sha1 and sha256. Only md5 returns ‘FOUND’ status. | Required |
| features | Features to use on the file. Possible values are: Threat Emulation, Anti-Virus, Threat Extraction, All. Default is All. | Optional |
| reports | Comma separated list of supported report formats. Note - Requesting for PDF and summary reports simultaneously is not supported. Possible values are: pdf, xml, tar, summary. Default is xml, summary. | Optional |
| method | Threat extraction request method. Possible values are: clean, pdf. Default is pdf. | Optional |
| extracted_parts | Comma separated list of fields to be cleaned in the file. Only relevant if method = clean. Possible values are: Linked Objects, Macros and Code, Sensitive Hyperlinks, PDF GoToR Actions, PDF Launch Actions, PDF URI Actions, PDF Sound Actions, PDF Movie Actions, PDF JavaScript Actions, PDF Submit Form Actions, Database Queries, Embedded Objects, Fast Save Data, Custom Properties, Statistic Properties, Summary Properties. Default is Linked Objects, Macros and Code, Sensitive Hyperlinks, PDF GoToR Actions, PDF Launch Actions, PDF URI Actions, PDF Sound Actions, PDF Movie Actions, PDF JavaScript Actions, PDF Submit Form Actions, Database Queries, Embedded Objects, Fast Save Data. | Optional |
Context Output
| Path | Type | Description | |
|---|---|---|---|
| SandBlast.Query.Status | String | Status of requested features. | |
| SandBlast.Query.MD5 | String | The file’s MD5. | |
| SandBlast.Query.SHA1 | String | The file’s SHA1. | |
| SandBlast.Query.SHA256 | String | The file’s SHA256. | |
| SandBlast.Query.FileType | String | File type can be different from the one sent in the query request (according to the type to identify). | |
| SandBlast.Query.FileName | String | Name of the file saved on Check Point databases. | |
| SandBlast.Query.Features | String | Features used. | |
| SandBlast.Query.AntiVirus.SignatureName | String | If the file is not detected by Anti-Virus, the signature name is empty. | |
| SandBlast.Query.AntiVirus.MalwareFamily | Number | ID for malware family, if available: {0-}. | |
| SandBlast.Query.AntiVirus.MalwareType | Number | ID for malware type, if available: {0-}. | |
| SandBlast.Query.AntiVirus.Severity | Number | 0 for benign files. Minimum: 0 Maximum: 4 | |
| SandBlast.Query.AntiVirus.Confidence | Number | 0 for benign files. Minimum: 0 Maximum 5 | |
| SandBlast.Query.AntiVirus.Status | String | Status of Anti-Virus on the requested file. | |
| SandBlast.Query.ThreatExtraction.Method | String | Method that was used. | |
| SandBlast.Query.ThreatExtraction.ExtractResult | String | CP_EXTRACT_RESULT_UNKNOWN (Default - returned if the POD did not receive an answer from the Threat Extraction engine in 60 seconds). CP_EXTRACT_RESULT_SUCCESS, CP_EXTRACT_RESULT_FAILURE, CP_EXTRACT_RESULT_TIMEOUT, CP_EXTRACT_RESULT_UNSUPPORTED_FILE, CP_EXTRACT_RESULT_NOT_SCRUBBED, CP_EXTRACT_RESULT_INTERNAL_ERROR, CP_EXTRACT_RESULT_DISK_LIMIT_REACHED, CP_EXTRACT_RESULT_ENCRYPTED_FILE, CP_EXTRACT_RESULT_DOCSEC_FILE, CP_EXTRACT_RESULT_OUT_OF_MEMORY | |
| SandBlast.Query.ThreatExtraction.ExtractedFileDownloadId | String | The download id of the extracted file, for download request. Only sent when extract_result = CP_EXTRACT_RESULT_SUCCESS | |
| SandBlast.Query.ThreatExtraction.OutputFileName | String | Clean file name. | |
| SandBlast.Query.ThreatExtraction.Time | String | Time for threat extraction completion. | |
| SandBlast.Query.ThreatExtraction.ExtractContent | String | Content of extracted file. | |
| SandBlast.Query.ThreatExtraction.TexProduct | Boolean | True if the queried file is already a Sandblast-safe copy. | |
| SandBlast.Query.ThreatExtraction.Status | String | Status of Threat Extraction on the requested file. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.InputExtension | String | Uploaded filename-extension as sent by the client. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.InputRealExtension | String | Extension as resolved by Threat Extraction. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.Message | String | Status message for scrub_result | |
| SandBlast.Query.ThreatExtraction.ExtractionData.ProtectionName | String | Potential malicious content extracted. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.ProtectionType | String | Protection done for scrub_method: Conversion to PDF | Content Removal |
| SandBlast.Query.ThreatExtraction.ExtractionData.ProtocolVersion | String | Protocol used. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.RealExtension | String | Real extension as resolved by Threat Extraction | |
| SandBlast.Query.ThreatExtraction.ExtractionData.Risk | Number | Represents the risk of the part that was extracted from the document. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.ScrubActivity | String | Readable result from Threat Extraction. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.ScrubMethod | String | Convert to PDF | Clean Document. |
| SandBlast.Query.ThreatExtraction.ExtractionData.ScrubResult | Number | Code result from Threat Extraction. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.ScrubTime | String | Threat Extraction process time. | |
| SandBlast.Query.ThreatExtraction.ExtractionData.ScrubbedContent | String | Content that was removed | |
| SandBlast.Query.ThreatEmulation.Trust | Number | Rating of the threat data and its relevance to this instance. It is recommended to block threats with confidence medium and above. | |
| SandBlast.Query.ThreatEmulation.Score | Number | Threat Emulation score. | |
| SandBlast.Query.ThreatEmulation.CombinedVerdict | String | Combined verdict of all the images. Benign reports are not supported for local gateways. | |
| SandBlast.Query.ThreatEmulation.Severity | Number | Combined severity of threats found. In case threats are not found, this field is not given. 1 - low, 2 - medium, 3 - high, 4 - critical. | |
| SandBlast.Query.ThreatEmulation.Confidence | Number | Rating of the threat data and its relevance to this instance. It is recommended to block threats with confidence 2 and above. 1 - low, 2 - medium, 3 - high. | |
| SandBlast.Query.ThreatEmulation.Images | String | Sand boxes used in Threat Emulation. Information about image types can be found in https://sc1.checkpoint.com/documents/TPAPI/CP_1.0_ThreatPreventionAPI_APIRefGuide/html_frameset.htm under “Query API” -> “Query Response Format” -> “Images Object Format”. | |
| SandBlast.Query.ThreatEmulation.Status | String | Status of Threat Emulation on the requested file. |
Command example
!sandblast-query file_hash=e129988964fa250bc8186bfe6f399f12 file_name=HelloWorld.pdf
Context Example
{
"SandBlast": {
"Query": {
"AntiVirus": {
"Confidence": 0,
"MalwareFamily": 0,
"MalwareType": 0,
"Severity": 0,
"SignatureName": "",
"Status": {
"code": 1001,
"label": "FOUND",
"message": "The request has been fully answered."
}
},
"Features": [
"te",
"av",
"extraction"
],
"FileName": "HelloWorld.pdf",
"FileType": "pdf",
"MD5": "e129988964fa250bc8186bfe6f399f12",
"SHA1": "a5e7aa50b66fdad3ae3b5e9ca66283a263bf7027",
"SHA256": "7e1eeaa9ac04812ce89eabb824d65073a3a37a1600ad1e1b7748ae12e04bb168",
"Status": {
"code": 1001,
"label": "FOUND",
"message": "The request has been fully answered."
},
"ThreatEmulation": {
"CombinedVerdict": "benign",
"Images": [
{
"id": "e50e99f3-5963-4573-af9e-e3f4750b55e2",
"report": {
"verdict": "benign"
},
"revision": 1,
"status": "found"
},
{
"id": "3ff3ddae-e7fd-4969-818c-d5f1a2be336d",
"report": {
"verdict": "benign"
},
"revision": 1,
"status": "found"
}
],
"Score": -2147483648,
"Status": {
"code": 1001,
"label": "FOUND",
"message": "The request has been fully answered."
},
"Trust": 0
},
"ThreatExtraction": {
"ExtractContent": "",
"ExtractResult": "CP_EXTRACT_RESULT_SUCCESS",
"ExtractedFileDownloadId": "11aa4b44-6699-43fe-b73a-d42435551b06",
"ExtractionData": {
"InputExtension": "pdf",
"InputRealExtension": "pdf",
"Message": "OK",
"ProtectionName": "Extract potentially malicious content",
"ProtectionType": "Conversion to PDF",
"ProtocolVersion": "",
"RealExtension": "pdf",
"Risk": 0,
"ScrubActivity": "PDF file was converted to PDF",
"ScrubMethod": "Convert to PDF",
"ScrubResult": 0,
"ScrubTime": "0.114",
"ScrubbedContent": ""
},
"Method": "pdf",
"OutputFileName": "HelloWorld.cleaned.pdf",
"Status": {
"code": 1001,
"label": "FOUND",
"message": "The request has been fully answered."
},
"TexProduct": false,
"Time": "0.114"
}
}
}
}
Human Readable Output
Query Results
File Info
Filename Filetype Label Message Md5 Sha1 Sha256 HelloWorld.pdf FOUND The request has been fully answered. e129988964fa250bc8186bfe6f399f12 a5e7aa50b66fdad3ae3b5e9ca66283a263bf7027 7e1eeaa9ac04812ce89eabb824d65073a3a37a1600ad1e1b7748ae12e04bb168 Threat Emulation
Combinedverdict benign Anti-Virus
Malwarefamily Malwaretype Confidence Severity 0 0 0 0 Threat Extraction
Extractresult Extractedfiledownloadid Risk CP_EXTRACT_RESULT_SUCCESS 11aa4b44-6699-43fe-b73a-d42435551b06 0
sandblast-upload
Use the Upload API to have a client application request that Check Point Threat Prevention modules scan and analyze a file. When you upload a file to the service, the file is encrypted. It is un-encrypted during analysis, and then deleted. This command uses polling with query. The stages of polling are ‘UPLOAD_SUCCESS’, ‘PENDING’ and ends with ‘FOUND’ or ‘PARTIALLY_FOUND’. Once the command is done polling it will return analyzed information about the file.
Base Command
sandblast-upload
Input
| Argument Name | Description | Required |
|---|---|---|
| interval_in_seconds | Interval in seconds between each poll. Default is 60. | Optional |
| timeout_in_seconds | Time out in seconds till polling ends. Default is 600. | Optional |
| file_id | ID of the file to upload, which will be taken from the uploaded file to XSOAR. | Required |
| file_name | Rename the file to upload, if empty the uploaded file will keep its original name. | Optional |
| features | Features to use on the file. Possible values are: Threat Emulation, Anti-Virus, Threat Extraction, All. Default is All. | Optional |
| image_ids | ID of available OS images. An image is an operating system configuration. Inputs must be of same length as image_revisions and will be paired according to position. Information about image types can be found in https://sc1.checkpoint.com/documents/TPAPI/CP_1.0_ThreatPreventionAPI_APIRefGuide/html_frameset.htm under “Query API” -> “Query Response Format” -> “Images Object Format”. Possible values are: e50e99f3-5963-4573-af9e-e3f4750b55e2, 7e6fe36e-889e-4c25-8704-56378f0830df, 8d188031-1010-4466-828b-0cd13d4303ff, 5e5de275-a103-4f67-b55b-47532918fa59, 3ff3ddae-e7fd-4969-818c-d5f1a2be336d, 6c453c9b-20f7-471a-956c-3198a868dc92, 10b4a9c6-e414-425c-ae8b-fe4dd7b25244. | Optional |
| image_revisions | Revisions of available OS images. An image is an operating system configuration. Inputs must be of same length as image_ids and will be paired according to position. | Optional |
| reports | Comma separated list of supported report formats. Note - Requesting for PDF and summary reports simultaneously is not supported. Possible values are: pdf, xml, tar, summary. Default is xml, summary. | Optional |
| method | Threat extraction request method. Possible values are: clean, pdf. Default is pdf. | Optional |
| extracted_parts | Comma separated list of fields to be cleaned in the file. Only relevant if method = clean. Possible values are: Linked Objects, Macros and Code, Sensitive Hyperlinks, PDF GoToR Actions, PDF Launch Actions, PDF URI Actions, PDF Sound Actions, PDF Movie Actions, PDF JavaScript Actions, PDF Submit Form Actions, Database Queries, Embedded Objects, Fast Save Data, Custom Properties, Statistic Properties, Summary Properties. Default is Linked Objects, Macros and Code, Sensitive Hyperlinks, PDF GoToR Actions, PDF Launch Actions, PDF URI Actions, PDF Sound Actions, PDF Movie Actions, PDF JavaScript Actions, PDF Submit Form Actions, Database Queries, Embedded Objects, Fast Save Data. | Optional |
Context Output
| Path | Type | Description | |
|---|---|---|---|
| SandBlast.Upload.Status | String | Status of requested features. | |
| SandBlast.Upload.MD5 | String | The file’s MD5. | |
| SandBlast.Upload.SHA1 | String | The file’s SHA1. | |
| SandBlast.Upload.SHA256 | String | The file’s SHA256. | |
| SandBlast.Upload.FileType | String | File type can be different from the one sent in the upload request (according to the type to identify). | |
| SandBlast.Upload.FileName | String | Name of the file saved on Check Point databases. | |
| SandBlast.Upload.Features | String | Features used. | |
| SandBlast.Upload.AntiVirus.SignatureName | String | If the file is not detected by Anti-Virus, the signature name is empty. | |
| SandBlast.Upload.AntiVirus.MalwareFamily | Number | ID for malware family, if available: {0-}. | |
| SandBlast.Upload.AntiVirus.MalwareType | Number | ID for malware type, if available: {0-}. | |
| SandBlast.Upload.AntiVirus.Severity | Number | 0 for benign files. Minimum: 0 Maximum: 4 | |
| SandBlast.Upload.AntiVirus.Confidence | Number | 0 for benign files. Minimum: 0 Maximum 5 | |
| SandBlast.Upload.AntiVirus.Status | String | Status of Anti-Virus on the requested file. | |
| SandBlast.Upload.ThreatExtraction.Method | String | Method that was used. | |
| SandBlast.Upload.ThreatExtraction.ExtractResult | String | CP_EXTRACT_RESULT_UNKNOWN (Default - returned if the POD did not receive an answer from the Threat Extraction engine in 60 seconds). CP_EXTRACT_RESULT_SUCCESS, CP_EXTRACT_RESULT_FAILURE, CP_EXTRACT_RESULT_TIMEOUT, CP_EXTRACT_RESULT_UNSUPPORTED_FILE, CP_EXTRACT_RESULT_NOT_SCRUBBED, CP_EXTRACT_RESULT_INTERNAL_ERROR, CP_EXTRACT_RESULT_DISK_LIMIT_REACHED, CP_EXTRACT_RESULT_ENCRYPTED_FILE, CP_EXTRACT_RESULT_DOCSEC_FILE, CP_EXTRACT_RESULT_OUT_OF_MEMORY | |
| SandBlast.Upload.ThreatExtraction.ExtractedFileDownloadId | String | The download id of the extracted file, for download request. Only sent when extract_result = CP_EXTRACT_RESULT_SUCCESS | |
| SandBlast.Upload.ThreatExtraction.OutputFileName | String | Clean file name. | |
| SandBlast.Upload.ThreatExtraction.Time | String | Time for threat extraction completion. | |
| SandBlast.Upload.ThreatExtraction.ExtractContent | String | Content of extracted file. | |
| SandBlast.Upload.ThreatExtraction.TexProduct | Boolean | True if the queried file is already a Sandblast-safe copy. | |
| SandBlast.Upload.ThreatExtraction.Status | String | Status of Threat Extraction on the requested file. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.InputExtension | String | Uploaded filename-extension as sent by the client. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.InputRealExtension | String | Extension as resolved by Threat Extraction. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.Message | String | Status message for scrub_result | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ProtectionName | String | Potential malicious content extracted. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ProtectionType | String | Protection done for scrub_method: Conversion to PDF | Content Removal |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ProtocolVersion | String | Protocol used. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.RealExtension | String | Real extension as resolved by Threat Extraction | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.Risk | Number | Represents the risk of the part that was extracted from the document. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ScrubActivity | String | Readable result from Threat Extraction. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ScrubMethod | String | Convert to PDF | Clean Document. |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ScrubResult | Number | Code result from Threat Extraction. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ScrubTime | String | Threat Extraction process time. | |
| SandBlast.Upload.ThreatExtraction.ExtractionData.ScrubbedContent | String | Content that was removed | |
| SandBlast.Upload.ThreatEmulation.Trust | Number | Rating of the threat data and its relevance to this instance. It is recommended to block threats with confidence medium and above. | |
| SandBlast.Upload.ThreatEmulation.Score | Number | Threat Emulation score. | |
| SandBlast.Upload.ThreatEmulation.CombinedVerdict | String | Combined verdict of all the images. Benign reports are not supported for local gateways. | |
| SandBlast.Upload.ThreatEmulation.Severity | Number | Combined severity of threats found. In case threats are not found, this field is not given. | |
| SandBlast.Upload.ThreatEmulation.Images | String | Sand boxes used in Threat Emulation. Information about image types can be found in https://sc1.checkpoint.com/documents/TPAPI/CP_1.0_ThreatPreventionAPI_APIRefGuide/html_frameset.htm under “Query API” -> “Query Response Format” -> “Images Object Format”. | |
| SandBlast.Upload.ThreatEmulation.Status | String | Status of Threat Emulation on the requested file. |
Command example
!sandblast-upload file_id=252@117def34-6ca2-4db3-86eb-c9378ad46e65
Context Example
{
"SandBlast": {
"Upload": {
"AntiVirus": {
"Confidence": 0,
"MalwareFamily": 0,
"MalwareType": 0,
"Severity": 0,
"SignatureName": "",
"Status": {
"code": 1001,
"label": "FOUND",
"message": "The request has been fully answered."
}
},
"Features": [
"te",
"av",
"extraction"
],
"FileName": "HelloWorld.pdf",
"FileType": ".pdf",
"MD5": "e129988964fa250bc8186bfe6f399f12",
"SHA1": "a5e7aa50b66fdad3ae3b5e9ca66283a263bf7027",
"SHA256": "7e1eeaa9ac04812ce89eabb824d65073a3a37a1600ad1e1b7748ae12e04bb168",
"Status": {
"code": 1003,
"label": "PENDING",
"message": "The request is pending."
},
"ThreatEmulation": {
"CombinedVerdict": "benign",
"Images": [
{
"id": "3ff3ddae-e7fd-4969-818c-d5f1a2be336d",
"report": {
"verdict": "benign"
},
"revision": 1,
"status": "found"
},
{
"id": "e50e99f3-5963-4573-af9e-e3f4750b55e2",
"report": {
"verdict": "benign"
},
"revision": 1,
"status": "found"
}
],
"Score": -2147483648,
"Status": {
"code": 1001,
"label": "FOUND",
"message": "The request has been fully answered."
},
"Trust": 0
},
"ThreatExtraction": {
"Method": "pdf",
"Status": {
"code": 1003,
"label": "PENDING",
"message": "The request is pending."
},
"TexProduct": false
}
}
}
}
Human Readable Output
Upload Results
File Info
Filename Filetype Label Message Md5 Sha1 Sha256 HelloWorld.pdf UPLOAD_SUCCESS The file was uploaded successfully. e129988964fa250bc8186bfe6f399f12 a5e7aa50b66fdad3ae3b5e9ca66283a263bf7027 7e1eeaa9ac04812ce89eabb824d65073a3a37a1600ad1e1b7748ae12e04bb168
sandblast-download
Use the Download API to download a scanned file from the ThreatCloud according to the file ID.
Base Command
sandblast-download
Input
| Argument Name | Description | Required |
|---|---|---|
| file_id | ID of the file to download, which will be taken from “Extractedfiledownloadid” from “Threat Extraction” results. | 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. |
| File.EntryID | String | The entry ID of the file. |
| File.Info | String | File information. |
| File.Type | String | The file type. |
| File.MD5 | String | The MD5 hash of the file. |
| File.Extension | String | The file extension. |
Command example
!sandblast-download file_id=9dc066ec-ae77-4c96-b176-8dc88db515a9
Context Example
{
"File": {
"EntryID": "279@117def34-6ca2-4db3-86eb-c9378ad46e65",
"Extension": "pdf",
"Info": "application/pdf",
"MD5": "63a6c12e9b7aa5fb8a1c758de8b87926",
"Name": "HelloWorld.cleaned.pdf",
"SHA1": "febf2e17da8f2d2264897069c6358c001f2fc62d",
"SHA256": "63d3c65cef4eda67d58d81150a9295393990ad81cbc6607e62092d708b9973bb",
"SHA512": "e7c5058ea2fbd6834fbcdb0699c713e58b54bd7f3e9e340cf48bd3feebe04ef52f9edf0876f051f15bb0f6d09c3b9ae685654267cc281279023e677e95a2c55e",
"SSDeep": "384:DGW1n7dLCkC4Ta3ZyCJhpVgizPvth6irUABhcLk5JcRzcpnSMTxZYH06ZJWY:yMa3gCJai3ZHBc8SMTxY",
"Size": 16228,
"Type": "PDF document, version 1.5"
}
}
Human Readable Output
sandblast-quota
Use the Quote API to have a client application get the current license and quota status of the API Key that you use in the authorization of the other APIs. For cloud services only.
Base Command
sandblast-quota
Input
There are no input arguments for this command.
Context Output
| Path | Type | Description |
|---|---|---|
| SandBlast.Quota.RemainQuotaHour | Number | Remaining quota hours. |
| SandBlast.Quota.RemainQuotaMonth | Number | Remaining quota months. |
| SandBlast.Quota.AssignedQuotaHour | Number | Assigned quota hours. |
| SandBlast.Quota.AssignedQuotaMonth | Number | Assigned quota months. |
| SandBlast.Quota.HourlyQuotaNextReset | String | Hourly quota next reset. |
| SandBlast.Quota.MonthlyQuotaNextReset | String | Monthly quota next reset. |
| SandBlast.Quota.QuotaId | String | Quota ID. |
| SandBlast.Quota.CloudMonthlyQuotaPeriodStart | String | Cloud monthly quota period start. |
| SandBlast.Quota.CloudMonthlyQuotaUsageForThisGw | Number | Cloud monthly quota usage for this GW. |
| SandBlast.Quota.CloudHourlyQuotaUsageForThisGw | Number | Cloud hourly quota usage for this GW. |
| SandBlast.Quota.CloudMonthlyQuotaUsageForQuotaId | Number | Cloud monthly quota usage for QuotaID. |
| SandBlast.Quota.CloudHourlyQuotaUsageForQuotaId | Number | Cloud hourly quota usage for QuotaID. |
| SandBlast.Quota.MonthlyExceededQuota | Number | Monthly exceeded quota. |
| SandBlast.Quota.HourlyExceededQuota | Number | Hourly exceeded quota. |
| SandBlast.Quota.CloudQuotaMaxAllowToExceedPercentage | Number | Cloud quota max allowed to exceed percentage. |
| SandBlast.Quota.PodTimeGmt | String | Pod time GMT. |
| SandBlast.Quota.QuotaExpiration | String | Quota expiration. |
| SandBlast.Quota.Action | String | Quota action. |
Command example
#### Context Example
```json
{
"SandBlast": {
"Quota": {
"Action": "ALLOW",
"AssignedQuotaHour": 500,
"AssignedQuotaMonth": 10000,
"CloudHourlyQuotaUsageForQuotaId": 2,
"CloudHourlyQuotaUsageForThisGw": 2,
"CloudMonthlyQuotaPeriodStart": "2022-08-01T00:00:00.000Z",
"CloudMonthlyQuotaUsageForQuotaId": 4,
"CloudMonthlyQuotaUsageForThisGw": 4,
"CloudQuotaMaxAllowToExceedPercentage": 1000,
"HourlyExceededQuota": 0,
"HourlyQuotaNextReset": "2022-08-01T15:00:00.000Z",
"MonthlyExceededQuota": 0,
"MonthlyQuotaNextReset": "2022-09-01T00:00:00.000Z",
"PodTimeGmt": "2022-08-01T14:42:44.000Z",
"QuotaExpiration": "2022-09-22T00:00:00.000Z",
"QuotaId": "D21T63R",
"RemainQuotaHour": 498,
"RemainQuotaMonth": 9996
}
}
}
Human Readable Output
Quota Information
Remainquotahour Remainquotamonth Assignedquotahour Assignedquotamonth Hourlyquotanextreset Monthlyquotanextreset Quotaid Cloudmonthlyquotaperiodstart Cloudmonthlyquotausageforthisgw Cloudhourlyquotausageforthisgw Cloudmonthlyquotausageforquotaid Cloudhourlyquotausageforquotaid Monthlyexceededquota Hourlyexceededquota Cloudquotamaxallowtoexceedpercentage Podtimegmt Quotaexpiration Action 498 9996 500 10000 2022-08-01T15:00:00.000Z 2022-09-01T00:00:00.000Z D21T63R 2022-08-01T00:00:00.000Z 4 2 4 2 0 0 1000 2022-08-01T14:42:44.000Z 2022-09-22T00:00:00.000Z ALLOW
Configuration parameters
url— Server URL (required)credentials—insecure— Trust any certificate (not secure)proxy— Use system proxy settingsintegrationReliability— Source Reliability
Commands (5)
-
fileRuns reputation on files.
-
sandblast-downloadUses the Download API to download a scanned file from the ThreatCloud according to the file ID.
-
sandblast-queryUse the Query API to have a client application look for either a specific file's analysis report on the Check Point Threat Prevention service databases or the status of a file, uploaded for analysis. It is recommended to add file_name.
-
sandblast-quotaUses the Quota API to have a client application get the current license and quota status of the API key used in the authorization of the other APIs. For cloud services only.
-
sandblast-uploadUses the Upload API to have a client application request for Check Point Threat Prevention modules to scan and analyze a file. When you upload a file to the service, the file is encrypted. It is un-encrypted during analysis and then deleted. This command uses polling with query. The stages of polling are 'UPLOAD_SUCCESS', 'PENDING' and ends with 'FOUND' or 'PARTIALLY_FOUND'. Once the command is done polling, it returns analyzed information about the file.
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 """ Check Point Threat Emulation (SandBlast) API Integration for Cortex XSOAR (aka Demisto). """ from typing import Any from CommonServerUserPython import * """ GLOBAL/PARAMS """ DEFAULT_INTERVAL = 60 DEFAULT_TIMEOUT = 600 MD5_SIZE = 32 SHA1_SIZE = 40 SHA256_SIZE = 64 DIGEST_BY_LENGTH = { MD5_SIZE: "md5", SHA1_SIZE: "sha1", SHA256_SIZE: "sha256", } EXTRACTED_PARTS_CODE_BY_DESCRIPTION = { "Linked Objects": 1025, "Macros and Code": 1026, "Sensitive Hyperlinks": 1034, "PDF GoToR Actions": 1137, "PDF Launch Actions": 1139, "PDF URI Actions": 1141, "PDF Sound Actions": 1142, "PDF Movie Actions": 1143, "PDF JavaScript Actions": 1150, "PDF Submit Form Actions": 1151, "Database Queries": 1018, "Embedded Objects": 1019, "Fast Save Data": 1021, "Custom Properties": 1017, "Statistic Properties": 1036, "Summary Properties": 1037, } FEATURE_BY_NAME = {"Threat Emulation": "te", "Anti-Virus": "av", "Threat Extraction": "extraction", "All": "all"} QUOTA_HEADERS = [ "RemainQuotaHour", "RemainQuotaMonth", "AssignedQuotaHour", "AssignedQuotaMonth", "HourlyQuotaNextReset", "MonthlyQuotaNextReset", "QuotaId", "CloudMonthlyQuotaPeriodStart", "CloudMonthlyQuotaUsageForThisGw", "CloudHourlyQuotaUsageForThisGw", "CloudMonthlyQuotaUsageForQuotaId", "CloudHourlyQuotaUsageForQuotaId", "MonthlyExceededQuota", "HourlyExceededQuota", "CloudQuotaMaxAllowToExceedPercentage", "PodTimeGmt", "QuotaExpiration", "Action", ] """ CLIENT CLASS """ class Client(BaseClient): """ API Client to communicate with Check Point Threat Prevention API. """ VERSION = "v1" def __init__(self, host: str, api_key: str, reliability: str, verify: bool = False, proxy: bool = False): """ Client constructor, set headers and call super class BaseClient. Args: host (str): Check Point Threat Emulation (SandBlast) API URL. api_key (str): API key to connect to the server. verify (bool): SSL verification handled by BaseClient. Defaults to False. proxy (bool): System proxy is handled by BaseClient. Defaults to False. """ super().__init__( base_url=f"{host}/tecloud/api/{Client.VERSION}/file", verify=verify, proxy=proxy, headers={"Authorization": api_key} ) self.reliability = reliability def query_request( self, features: list[str], reports: list[str], method: str, file_name: str = None, extracted_parts_codes: list[int] = None, **kwargs, ) -> dict[str, Any]: """ Return an analysis report or status of a file that was uploaded according to a file hash. Args: features (List[str]): Features to include in the query, options: te, av, extraction. reports (List[str]): Report format for the query, options: pdf, xml, tar, summary. method (str): Threat extraction method, options: clean, pdf. file_name (str): Name of the file to query. Defaults to None. extracted_parts_codes (List[int]): Cleans file according to inserted codes. Defaults to None. **kwargs: can hold - md5 (str): md5 digest of the file to query. Defaults to None. sha1 (str): sha1 digest of the file to query. Defaults to None. sha256 (str): sha256 digest of the file to query. Defaults to None. Returns: Dict[str, Any]: Analysis report or status of the queried file. """ json_data = remove_empty_elements( { "request": { "features": features, "md5": kwargs.get("md5"), "sha1": kwargs.get("sha1"), "sha256": kwargs.get("sha256"), "file_name": file_name, "te": { "reports": reports, }, "extraction": {"extracted_parts_codes": extracted_parts_codes, "method": method}, } } ) return self._http_request(method="POST", url_suffix="/query", json_data=json_data) def upload_request( self, file_path: str, file_name: str, file_type: str, features: list[str], image_ids: list[str], image_revisions: list[Optional[int]], reports: list[str], method: str, extracted_parts_codes: list[int] = None, ) -> dict[str, Any]: """ Once the file has been uploaded return an analysis report or status of a file that was uploaded. Args: file_path (str): Path to the file to upload. file_name (str): Name of the file to upload. file_type (str): Type (extension) of the file to upload. features (List[str]): Features to include when uploading, options: te, av, extraction. image_ids (List[str]): ID of available OS images. An image is an operating system configuration. image_revisions (List[int]): Revision of available OS images. An image is an operating system configuration. reports (List[str]): Report format to upload, options: pdf, xml, tar, summary. method (str): Threat extraction method, options: clean, pdf. extracted_parts_codes (List[int]): Cleans file according to inserted codes. Defaults to None. Returns: Dict[str, Any]: Analysis report or status of the uploaded file. """ request = json.dumps( remove_empty_elements( { "request": { "file_name": file_name, "file_type": file_type, "features": features, "te": { "reports": reports, "images": [ {"id": image_id, "image_revision": revision} for image_id, revision in zip(image_ids, image_revisions) ], }, "extraction": {"extracted_parts_codes": extracted_parts_codes, "method": method}, } } ) ) with open(file_path, "rb") as file_handler: file = (file_name, file_handler.read()) return self._http_request(method="POST", url_suffix="/upload", files={"request": request, "file": file}) def download_request(self, file_id: str) -> requests.Response: """ Return the file saved in the server. Args: file_id (str): ID of the file in the database. Returns: bytes: File in database. """ return self._http_request(method="GET", url_suffix="/download", params={"id": file_id}, resp_type="response") def quota_request(self) -> dict[str, Any]: """ Return the quota information about current API key. Returns: Dict[str, Any]: Quota information. """ return self._http_request( method="POST", url_suffix="/quota", ) """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: """ Tests API connectivity and authentication Returning 'ok' indicates that the integration works like it is supposed to. Connection to the service is successful. Raises exceptions if something goes wrong. Args: client (Client): Connection to the client class from which we can run the desired request. Returns: str: 'ok' if test passed, anything else will fail the test. """ try: client.query_request( file_name="test.pdf", features=["te", "av", "extraction"], reports=["xml", "summary"], method="pdf", **{"md5": "80f284ccdf2afae0f5347f4532584a61"}, # type:ignore ) except DemistoException as e: e_string = str(e) if "403" in e_string: return "Authorization Error: make sure API Key is correctly set" if "404" in e_string: return "URL Error: make sure URL is correctly set" return e_string return "ok" def file_command(client: Client, args: dict[str, Any]) -> list[CommandResults]: """ Get file_hash list from user input and check if they are in the correct format. Client will make a Query request with every file_hash, if the file_hash exists in the server a dbot_score will be calculated. Args: client (Client): Connection to the client class from which we can run the desired request. args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request. Raises: ValueError: In case the file_hash isn't Returns: List[CommandResults]: Indicator for every file_hash """ files = argToList(args["file"]) command_results: list[CommandResults] = [] for file_hash in files: try: hash_type = get_hash_type(file_hash) if hash_type not in ("md5", "sha1", "sha256"): raise ValueError(f'Hash "{file_hash}" is not of type SHA-256, SHA-1 or MD5') raw_response = client.query_request( features=["te", "av", "extraction"], reports=["xml", "summary"], method="pdf", **{hash_type: file_hash} ) label = dict_safe_get(raw_response, ["response", "status", "label"]) if label not in ("FOUND", "PARTIALLY_FOUND"): message = dict_safe_get(raw_response, ["response", "status", "message"]) command_results.append(CommandResults(readable_output=f'File not found: "{file_hash}"\n{message}')) continue file_indicator = get_file_indicator(file_hash, hash_type, raw_response, client.reliability) verdict_str = file_indicator.dbot_score.to_readable() score_description = { "confidence": dict_safe_get(raw_response, ["response", "te", "confidence"]), "severity": dict_safe_get(raw_response, ["response", "te", "severity"]), "signature_name": dict_safe_get(raw_response, ["response", "av", "malware_info", "signature_name"]), } outputs = remove_empty_elements( { "MD5": dict_safe_get(raw_response, ["response", "md5"]), "SHA1": dict_safe_get(raw_response, ["response", "sha1"]), "SHA256": dict_safe_get(raw_response, ["response", "sha256"]), verdict_str: {"Vendor": "CheckPointSandBlast", "Description": score_description}, } ) readable_output = tableToMarkdown( f'Results of file hash: "{file_hash}"', outputs, headers=[ "MD5", "SHA1", "SHA256", verdict_str, ], ) command_results.append( CommandResults( readable_output=readable_output, outputs_prefix=outputPaths.get("file"), indicator=file_indicator, outputs=outputs, raw_response=raw_response, ) ) except Exception as e: command_results.append(CommandResults(readable_output=f'Could not process file: "{file_hash}"\n{str(e)}')) return command_results def query_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Query information of a file. The command will be a bridge between the client request and the presented value to the user. Get arguments inputted by the user and send them to the client. Once a response has been received, process and return it so it can be sent to the user. Args: client (Client): Connection to the client class from which we can run the desired request. args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request. Raises: ValueError: reports input was invalid. ValueError: file_hash input was invalid. Returns: CommandResults: Information about the queried file. """ file_name = args.get("file_name", "") file_hash = args["file_hash"] features = argToList(args.get("features", "")) reports = argToList(args.get("reports")) method = args.get("method", "") extracted_parts = argToList(args.get("extracted_parts")) features = [FEATURE_BY_NAME[feature] for feature in features] if "all" in features: features = ["te", "av", "extraction"] if "te" in features and {"pdf", "summary"}.issubset(reports): raise ValueError("Requesting for PDF and summary reports simultaneously is not supported!") if method != "clean": extracted_parts_codes = None else: extracted_parts_codes = [EXTRACTED_PARTS_CODE_BY_DESCRIPTION[extracted_part] for extracted_part in extracted_parts] file_hash_size = len(file_hash) digest = DIGEST_BY_LENGTH.get(file_hash_size) if digest is None: raise ValueError("file_hash is not recognized!") raw_output = client.query_request( file_name=file_name, features=features, reports=reports, method=method, extracted_parts_codes=extracted_parts_codes, **{digest: file_hash}, ) output = raw_output.get("response", {"": ""}) readable_output = get_analysis_readable_output(features, output, "Query") output = get_analysis_context_output(output) return CommandResults( readable_output=readable_output, outputs_prefix="SandBlast.Query", outputs_key_field=["MD5", "SHA1", "SHA256"], outputs=output, raw_response=raw_output, ) def upload_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Upload a file to the server. The command will be a bridge between the client request and the presented value to the user. Get arguments inputted by the user and send them to the client. Once a response has been received, process and return it so it can be sent to the user. Args: client (Client): Connection to the client class from which we can run the desired request. args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request. Raises: ValueError: The new file's name extension is different from the original. ValueError: The length of image_id and image_revision isn't equal. ValueError: Reports input was invalid. Returns: CommandResults: Information about the uploaded file. """ file_id = args["file_id"] file_name = args.get("file_name") features = argToList(args.get("features")) image_ids = argToList(args.get("image_ids")) image_revisions = [arg_to_number(image_revision) for image_revision in argToList(args.get("image_revisions"))] reports = argToList(args.get("reports")) method = args.get("method", "") extracted_parts = argToList(args.get("extracted_parts")) file_entry = demisto.getFilePath(file_id) if not file_name: file_name = file_entry["name"] file_type = os.path.splitext(file_name)[1] if file_type != os.path.splitext(file_entry["name"])[1]: raise ValueError("New file name must have the same extension as the original file!") features = [FEATURE_BY_NAME[feature] for feature in features] if "all" in features: features = ["te", "av", "extraction"] if len(image_ids) != len(image_revisions): raise ValueError("Image IDs and image revisions must be of same length!") if "te" in features and {"pdf", "summary"}.issubset(reports): raise ValueError("Requesting for PDF and summary reports simultaneously is not supported!") if method != "clean": extracted_parts_codes = None else: extracted_parts_codes = [EXTRACTED_PARTS_CODE_BY_DESCRIPTION[extracted_part] for extracted_part in extracted_parts] raw_output = client.upload_request( file_path=file_entry["path"], file_name=file_name, file_type=file_type, features=features, image_ids=image_ids, image_revisions=image_revisions, reports=reports, method=method, extracted_parts_codes=extracted_parts_codes, ) output = raw_output.get("response", {"": ""}) readable_output = get_analysis_readable_output(features, output, "Upload") output = get_analysis_context_output(output) return CommandResults( readable_output=readable_output, outputs_prefix="SandBlast.Upload", outputs_key_field=["MD5", "SHA1", "SHA256"], outputs=output, raw_response=raw_output, ) def download_command(client: Client, args: dict[str, Any]) -> Any: """ Download a file from the server. The command will be a bridge between the client request and the presented value to the user. Get arguments inputted by the user and send them to the client. Once a response has been received, process and return it so it can be sent to the user. Args: client (Client): Connection to the client class from which we can run the desired request. args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request. Returns: Any: File from the server. """ file_id = args["file_id"] output = client.download_request(file_id) content_disposition = output.headers.get("Content-Disposition") split_content_disposition = content_disposition.split('"') if content_disposition is not None else [] if len(split_content_disposition) < 2: file_name = "file.pdf" else: file_name = split_content_disposition[1] return fileResult(filename=file_name, data=output.content) def quota_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Get quota information about an API key. The command will be a bridge between the client request and the presented value to the user. Once a response has been received, process and return it so it can be sent to the user. Args: client (Client): Connection to the client class from which we can run the desired request. args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request. Returns: CommandResults: Quota information about the API key. """ raw_outputs = client.quota_request() outputs = raw_outputs.get("response")[0] # type:ignore output = get_quota_context_output(outputs) readable_output = tableToMarkdown( "Quota Information", output, headers=QUOTA_HEADERS, headerTransform=string_to_table_header, removeNull=True, ) return CommandResults( readable_output=readable_output, outputs_prefix="SandBlast.Quota", outputs_key_field="QuotaId", outputs=output, raw_response=raw_outputs, ) """ POLLING COMMANDS """ def setup_upload_polling_command(client: Client, args: dict[str, Any]) -> CommandResults: """ Initiate polling command for upload command. Args: client (Client): Connection to the client class from which we can run the desired request. args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request. Returns: CommandResults: A result to return to the user which will be presented in a markdown value. The result itself will depend on the stage of polling. """ return upload_polling_command(args, client=client) @polling_function( name="sandblast-upload", interval=arg_to_number(demisto.args().get("interval_in_seconds", DEFAULT_INTERVAL)), timeout=arg_to_number(demisto.args().get("timeout_in_seconds", DEFAULT_TIMEOUT)), requires_polling_arg=False, ) def upload_polling_command(args: dict[str, Any], **kwargs) -> PollResult: """ Polling command to display the progress of the upload command. After the first run, progress will be shown through the query command. Once a new file is uploaded to the server, upload command will provide the status 'UPLOAD_SUCCESS' and pass arguments to the with query command. Query command will run till its status is 'FOUND' or 'PARTIALLY_FOUND', which is the ending term for the polling command. Args: args (Dict[str, Any]): Arguments passed down by the CLI to provide in the HTTP request and a Client. Returns: PollResult: A result to return to the user which will be set as a CommandResults. The result itself will depend on the stage of polling. """ if "file_hash" not in args: command_results = upload_command(kwargs["client"], args) else: command_results = query_command(kwargs["client"], args) raw_response = command_results.raw_response file_name = dict_safe_get(raw_response, ["response", "file_name"]) file_hash = dict_safe_get(raw_response, ["response", "md5"]) label = dict_safe_get(raw_response, ["response", "status", "label"]) if label in ("FOUND", "PARTIALLY_FOUND"): return PollResult( response=command_results, continue_to_poll=False, ) polling_args = {"file_name": file_name, "file_hash": file_hash, **args} return PollResult( response=command_results, continue_to_poll=True, args_for_next_run=polling_args, partial_result=command_results ) """ HELPER FUNCTIONS """ def get_analysis_context_output(output: dict[str, Any]) -> dict[str, Any]: av = dict_safe_get(output, ["av"]) malware_info = dict_safe_get(av, ["malware_info"]) extraction = dict_safe_get(output, ["extraction"]) extraction_data = dict_safe_get(extraction, ["extraction_data"]) te = dict_safe_get(output, ["te"]) return remove_empty_elements( { "Status": dict_safe_get(output, ["status"]), "MD5": dict_safe_get(output, ["md5"]), "SHA1": dict_safe_get(output, ["sha1"]), "SHA256": dict_safe_get(output, ["sha256"]), "FileType": dict_safe_get(output, ["file_type"]), "FileName": dict_safe_get(output, ["file_name"]), "Features": dict_safe_get(output, ["features"]), "AntiVirus": { "SignatureName": dict_safe_get(malware_info, ["signature_name"]), "MalwareFamily": dict_safe_get(malware_info, ["malware_family"]), "MalwareType": dict_safe_get(malware_info, ["malware_type"]), "Severity": dict_safe_get(malware_info, ["severity"]), "Confidence": dict_safe_get(malware_info, ["confidence"]), "Status": dict_safe_get(av, ["status"]), }, "ThreatExtraction": { "Method": dict_safe_get(extraction, ["method"]), "ExtractResult": dict_safe_get(extraction, ["extract_result"]), "ExtractedFileDownloadId": dict_safe_get(extraction, ["extracted_file_download_id"]), "OutputFileName": dict_safe_get(extraction, ["output_file_name"]), "Time": dict_safe_get(extraction, ["time"]), "ExtractContent": dict_safe_get(extraction, ["extract_content"]), "TexProduct": dict_safe_get(extraction, ["tex_product"]), "Status": dict_safe_get(extraction, ["status"]), "ExtractionData": { "InputExtension": dict_safe_get(extraction_data, ["input_extension"]), "InputRealExtension": dict_safe_get(extraction_data, ["input_real_extension"]), "Message": dict_safe_get(extraction_data, ["message"]), "ProtectionName": dict_safe_get(extraction_data, ["protection_name"]), "ProtectionType": dict_safe_get(extraction_data, ["protection_type"]), "ProtocolVersion": dict_safe_get(extraction_data, ["protocol_version"]), "RealExtension": dict_safe_get(extraction_data, ["real_extension"]), "Risk": dict_safe_get(extraction_data, ["risk"]), "ScrubActivity": dict_safe_get(extraction_data, ["scrub_activity"]), "ScrubMethod": dict_safe_get(extraction_data, ["scrub_method"]), "ScrubResult": dict_safe_get(extraction_data, ["scrub_result"]), "ScrubTime": dict_safe_get(extraction_data, ["scrub_time"]), "ScrubbedContent": dict_safe_get(extraction_data, ["scrubbed_content"]), }, }, "ThreatEmulation": { "Trust": dict_safe_get(te, ["trust"]), "Score": dict_safe_get(te, ["score"]), "CombinedVerdict": dict_safe_get(te, ["combined_verdict"]), "Images": dict_safe_get(te, ["images"]), "Status": dict_safe_get(te, ["status"]), }, } ) def get_analysis_readable_output(features: list[str], output: dict[str, Any], command: str) -> Any: """ Get a response outputs and set them to be readable outputs with tableToMarkdown. Args: features (Dict[str, Any]): Features in the HTTP response. output (Dict[str, Any]): HTTP response outputs which will be processed. command (str): Name of the calling command. Returns: Any: Readable outputs which have been set to Markdown """ readable_output = f"{command} Results\n" status_label = dict_safe_get(output, ["status", "label"]) output_file_info = { "FileName": dict_safe_get(output, ["file_name"]), "FileType": dict_safe_get(output, ["file_type"]), "Label": status_label, "Message": dict_safe_get(output, ["status", "message"]), "MD5": dict_safe_get(output, ["md5"]), "SHA1": dict_safe_get(output, ["sha1"]), "SHA256": dict_safe_get(output, ["sha256"]), } headers_file_info = [ "FileName", "FileType", "Label", "Message", "MD5", "SHA1", "SHA256", ] readable_output += tableToMarkdown( "File Info", output_file_info, headers=headers_file_info, headerTransform=string_to_table_header, removeNull=True, ) if status_label not in ("FOUND", "PARTIALLY_FOUND"): return readable_output if "te" in features: output_te = { "CombinedVerdict": dict_safe_get(output, ["te", "combined_verdict"]), "Severity": dict_safe_get(output, ["te", "severity"]), "Confidence": dict_safe_get(output, ["te", "confidence"]), "Verdict": dict_safe_get(output, ["te", "verdict"]), } headers_te = [ "CombinedVerdict", "Severity", "Confidence", "Verdict", ] readable_output += tableToMarkdown( "Threat Emulation", output_te, headers=headers_te, headerTransform=string_to_table_header, removeNull=True, ) if "av" in features: output_av = { "SignatureName": dict_safe_get(output, ["av", "malware_info", "signature_name"]), "MalwareFamily": dict_safe_get(output, ["av", "malware_info", "malware_family"]), "MalwareType": dict_safe_get(output, ["av", "malware_info", "malware_type"]), "Confidence": dict_safe_get(output, ["av", "malware_info", "confidence"]), "Severity": dict_safe_get(output, ["av", "malware_info", "severity"]), } headers_av = [ "SignatureName", "MalwareFamily", "MalwareType", "Confidence", "Severity", ] readable_output += tableToMarkdown( "Anti-Virus", output_av, headers=headers_av, headerTransform=string_to_table_header, removeNull=True, ) if "extraction" in features: output_extraction = { "ExtractResult": dict_safe_get(output, ["extraction", "extract_result"]), "ExtractedFileDownloadId": dict_safe_get(output, ["extraction", "extracted_file_download_id"]), "Risk": dict_safe_get(output, ["extraction", "extraction_data", "risk"]), } headers_extraction = [ "ExtractResult", "ExtractedFileDownloadId", "Risk", ] readable_output += tableToMarkdown( "Threat Extraction", output_extraction, headers=headers_extraction, headerTransform=string_to_table_header, removeNull=True, ) return readable_output def get_dbotscore(response: dict[str, Any]) -> int: """ Response received from the API request which holds fields that will help indicate the DBotScore. Args: response (Dict[str, Any]): Response received from the API request. Returns: int: A score to represent the reputation of an indicator. """ av_confidence = dict_safe_get(response, ["response", "av", "malware_info", "confidence"]) av_severity = dict_safe_get(response, ["response", "av", "malware_info", "severity"]) te_confidence = dict_safe_get(response, ["response", "te", "confidence"]) te_severity = dict_safe_get(response, ["response", "te", "severity"]) te_combined_verdict = dict_safe_get(response, ["response", "te", "combined_verdict"]) if ( av_confidence == 0 and av_severity == 0 and te_combined_verdict.lower() == "benign" and (te_severity == 0 or te_severity is None) and (te_confidence <= 1 or te_confidence is None) ): score = Common.DBotScore.GOOD elif te_severity == 1: score = Common.DBotScore.SUSPICIOUS else: score = Common.DBotScore.BAD return score def get_file_indicator(file_hash: str, hash_type: str, response: dict[str, Any], reliability: str) -> Common.File: """ Returns a file indicator that could potentially be malicious and will be checked for reputation. Args: file_hash (str): File hash value hash_type (str): File hash type. response (Dict[str, Any]): Response received from the API request. reliability (str): integration source reliability. Returns: Common.File: File indicator. """ dbot_score = Common.DBotScore( indicator=file_hash, indicator_type=DBotScoreType.FILE, integration_name="CheckPointSandBlast", reliability=reliability, score=get_dbotscore(response), ) file_name = dict_safe_get(response, ["response", "file_name"]) if not file_name: file_type = None else: file_type = os.path.splitext(file_name)[1] file_indicator = Common.File(dbot_score=dbot_score, name=file_name, file_type=file_type, **{hash_type: file_hash}) return file_indicator def get_date_string(timestamp_string: str = "0") -> str: """ Cast timestamp to int and convert it to a datetime string. Args: timestamp_string (str, optional): Holds a timestamp to be converted. Defaults to '0'. Returns: str: A string with the timestamp in datetime format. """ timestamp = int(timestamp_string) * 1000 return timestamp_to_datestring(timestamp) def get_quota_context_output(outputs: dict[str, Any]) -> dict[str, Any]: """ Convert outputs keys to PascalCase and convert any timestamp to date format. Args: outputs (Dict[str, Any]): API key quota information. Returns: Dict[str, Any]: outputs in a more readable form. """ response_by_context = { "RemainQuotaHour": "remain_quota_hour", "RemainQuotaMonth": "remain_quota_month", "AssignedQuotaHour": "assigned_quota_hour", "AssignedQuotaMonth": "assigned_quota_month", "HourlyQuotaNextReset": "hourly_quota_next_reset", "MonthlyQuotaNextReset": "monthly_quota_next_reset", "QuotaId": "quota_id", "CloudMonthlyQuotaPeriodStart": "cloud_monthly_quota_period_start", "CloudMonthlyQuotaUsageForThisGw": "cloud_monthly_quota_usage_for_this_gw", "CloudHourlyQuotaUsageForThisGw": "cloud_hourly_quota_usage_for_this_gw", "CloudMonthlyQuotaUsageForQuotaId": "cloud_monthly_quota_usage_for_quota_id", "CloudHourlyQuotaUsageForQuotaId": "cloud_hourly_quota_usage_for_quota_id", "MonthlyExceededQuota": "monthly_exceeded_quota", "HourlyExceededQuota": "hourly_exceeded_quota", "CloudQuotaMaxAllowToExceedPercentage": "cloud_quota_max_allow_to_exceed_percentage", "PodTimeGmt": "pod_time_gmt", "QuotaExpiration": "quota_expiration", "Action": "action", } context_outputs_with_date = [ "HourlyQuotaNextReset", "MonthlyQuotaNextReset", "CloudMonthlyQuotaPeriodStart", "PodTimeGmt", "QuotaExpiration", ] output: dict[str, Any] = {} for context_output, response in response_by_context.items(): output[context_output] = outputs.get(response) for key in context_outputs_with_date: output[key] = get_date_string(output[key]) return output """ MAIN FUNCTION """ def main() -> None: """ Getting data from instance setting and setting up the class Client with an API key. Checking user input command with if statements and a dictionary. """ params: dict[str, Any] = demisto.params() args: dict[str, Any] = demisto.args() command = demisto.command() api_key = params["credentials"]["password"] host = params["url"] verify_certificate = not params.get("insecure", False) proxy = params.get("proxy", False) reliability = params.get("integrationReliability", "C - Fairly reliable") commands = { "sandblast-query": query_command, "sandblast-upload": setup_upload_polling_command, "sandblast-download": download_command, "sandblast-quota": quota_command, "file": file_command, } demisto.debug(f"Command being called is {command}") try: client = Client( host=host, api_key=api_key, reliability=reliability, verify=verify_certificate, proxy=proxy, ) if command == "test-module": return_results(test_module(client)) elif command in commands: return_results(commands[command](client, args)) else: raise NotImplementedError(f"Command doesn't exist - {command}") except Exception as e: demisto.error(traceback.format_exc()) return_error(f"Failed to execute {command} command.\nError:\n{str(e)}") if __name__ in ("__main__", "__builtin__", "builtins"): main()