JoeSecurityV2
Access the full set of possibilities the JoeSandbox Cloud provides via the RESTful Web API v2.
Forensics & Malware Analysis · Joe Security
Details
| ID | JoeSecurityV2 |
|---|---|
| Provider | Joe Security GmbH |
| Category | Forensics & Malware Analysis |
| From Version | 6.8.0 |
| Docker Image | demisto/vendors-sdk:1.0.0.10120494 |
| Supported Modules | Agentix XSIAM EDR Cortex Cloud Cloud Runtime Security |
README
Access the full set of possibilities the Joe Sandbox Cloud provides via RESTful Web API v2.
This integration was integrated and tested with version 3.18.0 of jbxapi.
Some changes have been made that might affect your existing content.
If you are upgrading from a previous version of this integration, see Breaking Changes.
Configure Joe Security v2 on Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for Joe Security v2.
-
Click Add instance to create and configure a new integration instance.
Parameter Description Required Server URL True API Key True Source Reliability Reliability of the source providing the intelligence data. True Create relationships Create relationships between indicators as part of Enrichment. False Trust any certificate (not secure) False Use system proxy settings False - 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.
Note: Most of the commands have the full_display boolean argument that when set to true, indicators information, including their DBot Scores, will be displayed.
joe-is-online
Check if the Joe Sandbox analysis server is online or in maintenance mode.
Base Command
joe-is-online
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| Joe.ServerStatus.Online | Boolean | The server status. |
Command example
#### Context Example
```json
{
"Joe": {
"ServerStatus": {
"Online": true
}
}
}
Human Readable Output
Joe server is online
joe-analysis-info
Get information about an analysis.
Base Command
joe-analysis-info
Input
| Argument Name | Description | Required |
|---|---|---|
| webid | The analysis web ID. | Required |
| full_display | When set to true, indicators information, including their DBot Scores, will be displayed. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| File.Hashes.type | String | The hash type. |
| File.Hashes.value | String | The hash value. |
| File.Name | String | The full file name. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| File.MD5 | String | The MD5 hash of the file. |
| URL.Data | String | The URL. |
| Joe.Analysis.AnalysisID | String | The analysis ID Joe Security. |
| Joe.Analysis.Classification | String | The classification of the analysis. |
| Joe.Analysis.Comments | String | Comments regarding the analysis. |
| Joe.Analysis.detection | String | The analysis detection. Can be one of unknown, clean, suspicious, malicious. |
| Joe.Analysis.duration | Number | The duration of the analysis in seconds. |
| Joe.Analysis.encrypted | Boolean | True if the analysis data is encrypted. |
| Joe.Analysis.filename | String | The file name of the analysis. |
| Joe.Analysis.md5 | String | The file MD5. |
| Joe.Analysis.runs.detection | String | The run detection. Can be one of unknown, clean, suspicious, malicious. |
| Joe.Analysis.runs.error | Unknown | The run errors. |
| Joe.Analysis.runs.score | Number | The run score. |
| Joe.Analysis.runs.sigma | Boolean | The run sigma. |
| Joe.Analysis.runs.snort | Boolean | The run snort. |
| Joe.Analysis.runs.system | String | The run operation system. |
| Joe.Analysis.runs.yara | Boolean | The run YARA. |
| Joe.Analysis.score | Number | The run score. |
| Joe.Analysis.scriptname | String | The run script name. |
| Joe.Analysis.sha1 | String | The file SHA1. |
| Joe.Analysis.sha256 | String | The file SHA256. |
| Joe.Analysis.status | String | The status is one of submitted, running, finished. |
| Joe.Analysis.threatname | String | The analysis threat name. |
| Joe.Analysis.time | Date | The analysis time. |
| Joe.Analysis.webid | String | The web ID from Joe Security. |
Command example
!joe-analysis-info webid=2722073
Context Example
{
"Joe": {
"Analysis": [
{
"analysisid": "1",
"classification": "",
"comments": "(example)",
"detection": "clean",
"duration": 558,
"encrypted": false,
"filename": "test_file.txt",
"md5": "11111111111111111111111111111111",
"runs": [
{
"detection": "clean",
"error": null,
"score": 1,
"sigma": false,
"snort": false,
"system": "w10x64_21h1_office",
"yara": false
},
{
"detection": "clean",
"error": null,
"score": 0,
"sigma": false,
"snort": false,
"system": "w7x64_office",
"yara": false
}
],
"score": 1,
"scriptname": "example.jbs",
"sha1": "1111111111111111111111111111111111111111",
"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"status": "finished",
"tags": [],
"threatname": "Unknown",
"time": "2022-09-15T10:57:20+02:00",
"webid": "1111111"
}
]
}
}
Human Readable Output
Analysis Result
Id SampleName Status Time MD5 SHA1 SHA256 Systems Result Errors Comments 1 test_file.txt finished 2022-09-15T10:57:20+02:00 11111111111111111111111111111111 1111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111 w7x64_office,
w10x64_21h1_officeclean None (example)
joe-list-analysis
Lists all analyses.
Base Command
joe-list-analysis
Input
| Argument Name | Description | Required |
|---|---|---|
| page | Page number to display. | Optional |
| page_size | Determine how many entries to display on each page. | Optional |
| limit | Limit the number of entries to display. Default is 50. | Optional |
| full_display | When set to true, indicators information, including their DBot Scores, will be displayed. Possible values are: true, false. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| File.Hashes.type | String | The hash type. |
| File.Hashes.value | String | The hash value. |
| File.Name | String | The full file name. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| File.MD5 | String | The MD5 hash of the file. |
| URL.Data | String | The URL. |
| Joe.Analysis.AnalysisID | String | The analysis ID. |
| Joe.Analysis.Classification | String | The classification of the analysis. |
| Joe.Analysis.Comments | String | Comments regarding the analysis. |
| Joe.Analysis.detection | String | The analysis detection. Can be one of unknown, clean, suspicious, malicious. |
| Joe.Analysis.duration | Number | The duration of the analysis in seconds. |
| Joe.Analysis.encrypted | Boolean | True if the analysis data is encrypted. |
| Joe.Analysis.filename | String | The file name of the analysis. |
| Joe.Analysis.md5 | String | The file MD5. |
| Joe.Analysis.runs.detection | String | The run detection. Can be one of unknown, clean, suspicious, malicious. |
| Joe.Analysis.runs.error | Unknown | The run errors. |
| Joe.Analysis.runs.score | Number | The run score. |
| Joe.Analysis.runs.sigma | Boolean | The run sigma. |
| Joe.Analysis.runs.snort | Boolean | The run snort. |
| Joe.Analysis.runs.system | String | The run operation system. |
| Joe.Analysis.runs.yara | Boolean | The run YARA. |
| Joe.Analysis.score | Number | The run score. |
| Joe.Analysis.scriptname | String | The run script name. |
| Joe.Analysis.sha1 | String | The file SHA1. |
| Joe.Analysis.sha256 | String | The file SHA256. |
| Joe.Analysis.status | String | The status is one of submitted, running, finished. |
| Joe.Analysis.threatname | String | The analysis threat name. |
| Joe.Analysis.time | Date | The analysis time. |
| Joe.Analysis.webid | String | The web ID from Joe Security. |
Command example
!joe-list-analysis limit=1
Context Example
{
"Joe": {
"Analysis": [
{
"analysisid": "1",
"classification": "",
"comments": "(example)",
"detection": "clean",
"duration": 558,
"encrypted": false,
"filename": "test_file.txt",
"md5": "11111111111111111111111111111111",
"runs": [
{
"detection": "clean",
"error": null,
"score": 1,
"sigma": false,
"snort": false,
"system": "w10x64_21h1_office",
"yara": false
},
{
"detection": "clean",
"error": null,
"score": 0,
"sigma": false,
"snort": false,
"system": "w7x64_office",
"yara": false
}
],
"score": 1,
"scriptname": "example.jbs",
"sha1": "1111111111111111111111111111111111111111",
"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"status": "finished",
"tags": [],
"threatname": "Unknown",
"time": "2022-09-15T10:57:20+02:00",
"webid": "1111111"
}
]
}
}
Human Readable Output
Analysis Result
Id SampleName Status Time MD5 SHA1 SHA256 Systems Result Errors Comments 1 test_file.txt finished 2022-09-15T10:57:20+02:00 11111111111111111111111111111111 1111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111 w7x64_office,
w10x64_21h1_officeclean None (example)
joe-download-report
Download a resource belonging to a report. This can be the full report, dropped binaries, etc. See the integration README for the full list of supported report types.
Base Command
joe-download-report
Input
| Argument Name | Description | Required |
|---|---|---|
| webid | The Web ID. | Required |
| type | The resource type to download. Possible values are: html, json, pcap, pdf, xml, iocjson. Default is html. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| InfoFile.Name | string | Filename. |
| InfoFile.EntryID | string | The entry ID of the report |
| InfoFile.Size | number | File size. |
| InfoFile.Type | string | File type. e.g., “PE”. |
| InfoFile.Info | string | Basic information of the file. |
| File.Extension | string | File extension. |
Command example
!joe-download-report webid=1
Context Example
{
"InfoFile": {
"EntryID": "111@",
"Extension": "html",
"Info": "text/html; charset=utf-8",
"Name": "1_report.html",
"Size": 3823558,
"Type": "HTML document, ASCII text, with very long lines"
}
}
Human Readable Output
Returned file: 1_report.html Download
joe-download-sample
Download a sample.
Base Command
joe-download-sample
Input
| Argument Name | Description | Required |
|---|---|---|
| webid | Web ID. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| File.Size | number | File size. |
| File.SHA1 | string | SHA1 hash of the file |
| File.SHA256 | string | SHA256 hash of the file |
| File.Name | string | The sample name. |
| File.SSDeep | string | SSDeep hash of the file. |
| File.EntryID | string | War.Room entry ID of the file. |
| File.Info | string | Basic information of the file |
| File.Type | string | File type, e.g., “PE”. |
| File MD5 | string | MD5 hash of the file. |
| File.Extension | string | File extension. |
Command example
!joe-download-sample webid=2722073
Context Example
{
"File": {
"EntryID": "111@",
"Extension": "dontrun",
"Info": "dontrun",
"MD5": "11111111111111111111111111111111",
"Name": "1.dontrun",
"SHA1": "1111111111111111111111111111111111111111",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111",
"SHA512": "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
"SSDeep": "3:PFoESNt/FPl2X1sjO3//lGF/llllBl9SLEZWxIUclll7D8/+l/AltdUshMl//:PgG2s/RIUctM/+l/MusKl//",
"Size": 276,
"Type": "AppleDouble encoded Macintosh file"
}
}
Human Readable Output
Uploaded file: 1.dontrun Download
file
Retrieves files information from Joe Security.
Base Command
file
Input
| Argument Name | Description | Required |
|---|---|---|
| file | A comma-separated list of file names, SHA1, SHA256, or MD5 hashes. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| File.Name | String | Name of the file. |
| File.MD5 | String | MD5 hash of the file. |
| File.SHA1 | String | SHA1 hash of the file. |
| File.SHA256 | String | SHA256 hash of the file. |
| File.Tags | String | Tags of the file. |
| File.Name | String | Name of the file. |
| Joe.File.MD5 | String | MD5 hash of the file. |
| Joe.File.SHA1 | String | SHA1 hash of the file. |
| Joe.File.SHA256 | String | SHA256 hash of the file. |
| Joe.File.Tags | String | Tags of the file. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Score | Number | The actual score. |
| 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. |
Command example
!file file=example
Context Example
{
"DBotScore": [
{
"Indicator": "example",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "file",
"Vendor": "JoeSecurityV2"
}
],
"File": {
"Hashes": [
{
"type": "MD5",
"value": "11111111111111111111111111111111"
},
{
"type": "SHA1",
"value": "1111111111111111111111111111111111111111"
},
{
"type": "SHA256",
"value": "1111111111111111111111111111111111111111111111111111111111111111"
}
],
"MD5": "11111111111111111111111111111111",
"Name": "example",
"SHA1": "1111111111111111111111111111111111111111",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111"
},
"Joe": {
"File Name": "example",
"MD5": "11111111111111111111111111111111",
"SHA1": "1111111111111111111111111111111111111111",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111"
}
}
Human Readable Output
File Result
File Name Sha1 Sha256 Md5 example 1111111111111111111111111111111111111111 1111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111
url
Retrieves URL information from Joe Security.
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | A comma-separated list of URLs. | Required |
Context Output
| Path | Type | Description |
|---|---|---|
| URL.Data | String | The URL data. |
| Joe.URL.Name | String | Name of the URL. |
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Score | Number | The actual score. |
| 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. |
Command example
!url url=http://google.com
Context Example
{
"DBotScore": [
{
"Indicator": "http://google.com",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "url",
"Vendor": "JoeSecurityV2"
}
],
"Joe": {
"URL": "http://google.com"
},
"URL": {
"Data": "http://google.com"
}
}
Human Readable Output
Url Result
Url http://google.com
joe-list–lia-countries
Retrieve a list of localized internet anonymization countries.
Base Command
joe-list–lia-countries
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| Joe.LIACountry | String | A list of localized internet anonymization countries. |
Command example
#### Context Example
```json
{
"Joe": {
"LIACountry": [
"Argentina",
"Australia",
"Austria",
"Belgium",
"Brazil"
]
}
}
Human Readable Output
Results
Name Argentina Australia Austria Belgium Brazil
joe-list-lang-locales
Retrieve a list of available language and locale combinations.
Base Command
joe-list-lang-locales
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| Joe.LangLocale | String | A list of available language and locale combinations. |
Command example
#### Context Example
```json
{
"Joe": {
"LangLocale": [
"Arabic - Egypt",
"Arabic - Qatar",
"Arabic - Saudi Arabia",
"Chinese - PRC",
"Chinese - Taiwan",
"English - Australia"
]
}
}
Human Readable Output
Results
Name Arabic - Egypt Arabic - Qatar Arabic - Saudi Arabia Chinese - PRC Chinese - Taiwan English - Australia
joe-get-account-quota
Retrieve the account quota.
Base Command
joe-get-account-quota
Input
| Argument Name | Description | Required |
| — | — | — |
Context Output
| Path | Type | Description |
|---|---|---|
| Joe.AccountQuota | String | The account quota. |
| Joe.AccountQuota.quota.daily.current | Number | The current daily quota. |
| Joe.AccountQuota.quota.daily.limit | Number | The daily quota limit. |
| Joe.AccountQuota.quota.daily.remaining | Number | The remaining daily quota. |
| Joe.AccountQuota.quota.monthly.current | Number | The current monthly quota. |
| Joe.AccountQuota.quota.monthly.limit | Number | The monthly quota limit. |
| Joe.AccountQuota.quota.monthly.remaining | Number | The remaining monthly quota. |
| Joe.AccountQuota.type | String | The quota type. |
Command example
#### Context Example
```json
{
"Joe": {
"AccountQuota": {
"quota": {
"daily": {
"current": 0,
"limit": 100,
"remaining": 100
},
"monthly": {
"current": 150,
"limit": 250,
"remaining": 100
}
},
"type": "ultimate"
}
}
}
Human Readable Output
Results
Quota Type Daily Quota Current Daily Quota Limit Daily Quote Remaining Monthly Quota Current Monthly Quota Limit Monthly Quota Remaining ultimate 0 100 100 150 250 100
joe-submission-info
Retrieve the submission info.
Base Command
joe-submission-info
Input
| Argument Name | Description | Required |
|---|---|---|
| submission_ids | A comma-separated list of submission IDs. | Required |
| full_display | When set to true, indicators information, including their DBot Scores, will be displayed. Possible values are: true, false. Default is true. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| File.Hashes.type | String | The hash type. |
| File.Hashes.value | String | The hash value. |
| File.MD5 | String | The MD5 hash of the file. |
| File.Name | String | The full file name. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| URL.Data | String | The URL. |
| Joe.Analysis.AnalysisID | String | The analysis ID. |
| Joe.Analysis.Classification | String | The classification. |
| Joe.Analysis.Comments | String | The comments. |
| Joe.Analysis.detection | String | The detection. |
| Joe.Analysis.duration | Number | The duration. |
| Joe.Analysis.encrypted | Boolean | Whether the analysis is encrypted. |
| Joe.Analysis.filename | String | The filename. |
| Joe.Analysis.runs.detection | String | The detection. |
| Joe.Analysis.runs.error | Unknown | The error. |
| Joe.Analysis.runs.score | Number | The score. |
| Joe.Analysis.runs.sigma | Boolean | The sigma. |
| Joe.Analysis.runs.snort | Boolean | The snort. |
| Joe.Analysis.runs.system | String | The system. |
| Joe.Analysis.runs.yara | Boolean | The YARA. |
| Joe.Analysis.score | Number | The score. |
| Joe.Analysis.scriptname | String | The script name. |
| Joe.Analysis.status | String | The status. |
| Joe.Analysis.threatname | String | The threat name. |
| Joe.Analysis.time | Date | The time. |
| Joe.Analysis.webid | String | The web ID. |
| Joe.Submission.most_relevant_analysis.detection | String | The detection. |
| Joe.Submission.most_relevant_analysis.score | Number | The score. |
| Joe.Submission.most_relevant_analysis.webid | String | The web ID. |
| Joe.Submission.name | String | The name. |
| Joe.Submission.status | String | The status. |
| Joe.Submission.submission_id | String | The submission ID. |
| Joe.Submission.time | Date | The time. |
Command example
!joe-submission-info submission_ids=1111111
Context Example
{
"DBotScore": [
{
"Indicator": "example.txt",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "file",
"Vendor": "JoeSecurityV2"
}
],
"File": [
{
"Hashes": [
{
"type": "MD5",
"value": "11111111111111111111111111111111"
},
{
"type": "SHA1",
"value": "1111111111111111111111111111111111111111"
},
{
"type": "SHA256",
"value": "1111111111111111111111111111111111111111111111111111111111111111"
}
],
"MD5": "11111111111111111111111111111111",
"Name": "example.txt",
"SHA1": "1111111111111111111111111111111111111111",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111"
}
],
"Joe": {
"Analysis": [
{
"analysisid": "1",
"classification": "",
"comments": "example comment",
"detection": "clean",
"duration": 500,
"encrypted": false,
"filename": "example.txt",
"md5": "11111111111111111111111111111111",
"runs": [
{
"detection": "clean",
"error": null,
"score": 1,
"sigma": false,
"snort": false,
"system": "w10x64_21h1_office",
"yara": false
},
{
"detection": "clean",
"error": null,
"score": 0,
"sigma": false,
"snort": false,
"system": "w7x64_office",
"yara": false
}
],
"score": 1,
"scriptname": "example.jbs",
"sha1": "1111111111111111111111111111111111111111",
"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"status": "finished",
"tags": [],
"threatname": "Unknown",
"time": "2022-09-15T10:57:20+02:00",
"webid": "1"
}
],
"Submission": {
"most_relevant_analysis": {
"detection": "clean",
"score": 1,
"webid": "1"
},
"name": "example.zip",
"status": "finished",
"submission_id": "1111111",
"time": "2022-09-15T10:57:14+02:00"
}
}
}
Human Readable Output
Submission Results
Submission Id Sample Name Time Status Web Id Encrypted Analysis Id Classification Threat Name Score Detection SHA256 MD5 SHA1 File Name 1 example.zip 2022-09-15T10:57:14+02:00 finished 1 false 1 Unknown 1 clean 1111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111 1111111111111111111111111111111111111111 example.txt
joe-submit-sample
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
joe-submit-sample
Input
| Argument Name | Description | Required |
|---|---|---|
| entry_id | The War Room entry ID of the file to submit. | Required |
| file_name | The filename of the submitted sample | Optional |
| full_display | When set to true, indicators information, including their DBot Scores, will be displayed. Possible values are: true, false. Default is true. | Optional |
| timeout | The timeout for the polling in seconds. Default is 1200. | Optional |
| hide_polling_output | Hide polling output. | Optional |
| report_type | The report type. Possible values are: html, json, pcap, pdf, xml, iocjson. Default is html. | Optional |
| cookbook | Uploads a cookbook together with the sample. Needs to be a file-like object or a tuple in the shape (filename, file-like object). | Optional |
| comments | A comment to be added to the analysis. | Optional |
| tags | A comma-separated list of tags to be added to the analysis. | Optional |
| systems | A comma-separated list of operating systems to be used for the analysis. Possible values are: w7, w7x64, w7_1, w7_2, w7_4, w7_5, w7native, android2, android3, mac1, w7l, w7x64l, w10, android4, w7x64native, w7_3, w10native, android5native_1, w10x64, w7x64_hvm, android6, iphone1, w7_sec, macvm, w7_lang_packs, w7x64native_hvm, lnxubuntu1, lnxcentos1, android7_nougat. | Optional |
| internet_access | Whether to allow internet access for the analysis. Default is true. | Optional |
| archive_no_unpack | Whether to archive the sample without unpacking it. Default is false. | Optional |
| ssl_inspection | Whether to enable SSL inspection. Default is false. | Optional |
| localized_internet_country | The localized internet anonymization country. | Optional |
| internet_simulation | Whether to enable internet simulation. Default is false. | Optional |
| hybrid_code_analysis | Whether to enable hybrid code analysis. Default is true. | Optional |
| hybrid_decompilation | Whether to enable hybrid decompilation. Default is false. | Optional |
| vba_instrumentation | Whether to enable VBA instrumentation. Default is true. | Optional |
| js_instrumentation | Whether to enable JS instrumentation. Default is true. | Optional |
| java_jar_tracing | Whether to enable Java JAR tracing. Default is true. | Optional |
| dotnet_tracing | Whether to enable .NET tracing. Default is true. | Optional |
| amsi_unpacking | Whether to enable Microsoft Antimalware Scan Interface unpacking. Default is true. | Optional |
| fast_mode | Whether to enable fast mode. It focuses on fast analysis and detection versus deep forensic analysis. Default is false. | Optional |
| secondary_results | Whether to enable secondary results, such as Yara rule generation, classification via Joe Sandbox Class as well as several detail reports. Default is false. | Optional |
| report_cache | Whether to enable report cache. Default is false. | Optional |
| command_line_argument | A command line argument to be passed to the sample. | Optional |
| live_interaction | Whether to enable live interaction. Default is false. | Optional |
| document_password | The document password. | Optional |
| archive_password | The archive password. | Optional |
| start_as_normal_user | Whether to start the analysis as a normal user. Default is false. | Optional |
| language_and_locale | Changes the language and locale of the analysis machine. | Optional |
| delete_after_days | The number of days after which the analysis will be deleted. Default is 30. | Optional |
| encrypt_with_password | The password to encrypt the analysis with. | Optional |
| export_to_jbxview | Whether to export the analysis to JBXView. Default is false. | Optional |
| email_notification | Send an email notification once the analysis completes. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| File.Hashes.type | String | The hash type. |
| File.Hashes.value | String | The hash value. |
| File.MD5 | String | The MD5 hash of the file. |
| File.Name | String | The full file name. |
| File.SHA1 | String | The SHA1 hash of the file. |
| File.SHA256 | String | The SHA256 hash of the file. |
| Joe.Analysis.AnalysisID | String | The analysis ID. |
| Joe.Analysis.Classification | String | The classification. |
| Joe.Analysis.Comments | String | The comments. |
| Joe.Analysis.detection | String | The detection. |
| Joe.Analysis.duration | Number | The duration. |
| Joe.Analysis.encrypted | Boolean | Whether the analysis is encrypted. |
| Joe.Analysis.filename | String | The filename. |
| Joe.Analysis.runs.detection | String | The detection. |
| Joe.Analysis.runs.error | Unknown | The error. |
| Joe.Analysis.runs.score | Number | The score. |
| Joe.Analysis.runs.sigma | Boolean | The sigma. |
| Joe.Analysis.runs.snort | Boolean | The snort. |
| Joe.Analysis.runs.system | String | The system. |
| Joe.Analysis.runs.yara | Boolean | The YARA. |
| Joe.Analysis.score | Number | The score. |
| Joe.Analysis.scriptname | String | The script name. |
| Joe.Analysis.status | String | The status. |
| Joe.Analysis.threatname | String | The threat name. |
| Joe.Analysis.time | Date | The time. |
| Joe.Analysis.webid | String | The web ID. |
| Joe.Submission.most_relevant_analysis.detection | String | The detection. |
| Joe.Submission.most_relevant_analysis.score | Number | The score. |
| Joe.Submission.most_relevant_analysis.webid | String | The web ID. |
| Joe.Submission.name | String | The name. |
| Joe.Submission.status | String | The status. |
| Joe.Submission.submission_id | String | The submission ID. |
| Joe.Submission.time | Date | The time. |
Command example
!joe-submit-sample entry_id=1111@1111111111-1111-1111-1111-1 systems=w10x64
Context Example
{
"DBotScore": [
{
"Indicator": "example.txt",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "file",
"Vendor": "JoeSecurityV2"
}
],
"File": [
{
"Hashes": [
{
"type": "MD5",
"value": "11111111111111111111111111111111"
},
{
"type": "SHA1",
"value": "1111111111111111111111111111111111111111"
},
{
"type": "SHA256",
"value": "1111111111111111111111111111111111111111111111111111111111111111"
}
],
"MD5": "11111111111111111111111111111111",
"Name": "example.txt",
"SHA1": "1111111111111111111111111111111111111111",
"SHA256": "1111111111111111111111111111111111111111111111111111111111111111"
}
],
"Joe": {
"Analysis": [
{
"analysisid": "1",
"classification": "",
"comments": "example comment",
"detection": "clean",
"duration": 500,
"encrypted": false,
"filename": "example.txt",
"md5": "11111111111111111111111111111111",
"runs": [
{
"detection": "clean",
"error": null,
"score": 1,
"sigma": false,
"snort": false,
"system": "w10x64",
"yara": false
}
],
"score": 1,
"scriptname": "example.jbs",
"sha1": "1111111111111111111111111111111111111111",
"sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"status": "finished",
"tags": [],
"threatname": "Unknown",
"time": "2022-09-15T10:57:20+02:00",
"webid": "1"
}
],
"Submission": {
"most_relevant_analysis": {
"detection": "clean",
"score": 1,
"webid": "1"
},
"name": "example.txt",
"status": "finished",
"submission_id": "1111111",
"time": "2022-09-15T10:57:14+02:00"
}
}
}
Human Readable Output
Submission Results
Submission Id Sample Name Time Status Web Id Encrypted Analysis Id Classification Threat Name Score Detection SHA256 MD5 SHA1 File Name 1 example.zip 2022-09-15T10:57:14+02:00 finished 1 false 1 Unknown 1 clean 1111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111 1111111111111111111111111111111111111111 example.txt
joe-submit-url
Notice: Submitting indicators using this command might make the indicator data publicly available. See the vendor’s documentation for more details.
Base Command
joe-submit-url
Input
| Argument Name | Description | Required |
|---|---|---|
| url | The URL to submit. | Required |
| url_reputation | The URL reputation. Possible values are: true, false. Default is false. | Optional |
| full_display | When set to true, indicators information, including their DBot Scores, will be displayed. Possible values are: true, false. Default is true. | Optional |
| timeout | The timeout for the polling in seconds. Default is 1200. | Optional |
| hide_polling_output | Hide polling output. | Optional |
| report_type | The report type. Possible values are: html, json, pcap, pdf, xml, iocjson. Default is html. | Optional |
| comments | A comment to be added to the analysis. | Optional |
| tags | A comma-separated list of tags to be added to the analysis. | Optional |
| systems | A comma-separated list of operating systems to be used for the analysis. Possible values are: w7, w7x64, w7_1, w7_2, w7_4, w7_5, w7native, android2, android3, mac1, w7l, w7x64l, w10, android4, w7x64native, w7_3, w10native, android5native_1, w10x64, w7x64_hvm, android6, iphone1, w7_sec, macvm, w7_lang_packs, w7x64native_hvm, lnxubuntu1, lnxcentos1, android7_nougat. | Optional |
| internet_access | Whether to allow internet access for the analysis. Default is true. | Optional |
| archive_no_unpack | Whether to archive the sample without unpacking it. Default is false. | Optional |
| ssl_inspection | Whether to enable SSL inspection. Default is false. | Optional |
| localized_internet_country | The localized internet anonymization country. | Optional |
| internet_simulation | Whether to enable internet simulation. Default is false. | Optional |
| hybrid_code_analysis | Whether to enable hybrid code analysis. Default is false. | Optional |
| hybrid_decompilation | Whether to enable hybrid decompilation. Default is false. | Optional |
| vba_instrumentation | Whether to enable VBA instrumentation. Default is true. | Optional |
| js_instrumentation | Whether to enable JS instrumentation. Default is true. | Optional |
| java_jar_tracing | Whether to enable Java JAR tracing. Default is true. | Optional |
| dotnet_tracing | Whether to enable .NET tracing. Default is true. | Optional |
| amsi_unpacking | Whether to enable Microsoft Antimalware Scan Interface unpacking. Default is true. | Optional |
| fast_mode | Whether to enable fast mode, focuses on fast analysis and detection versus deep forensic analysis. Default is false. | Optional |
| secondary_results | Whether to enable secondary results, such as Yara rule generation, classification via Joe Sandbox Class as well as several detail reports. Default is false. | Optional |
| report_cache | Whether to enable report cache. Default is false. | Optional |
| command_line_argument | A command line argument to be passed to the sample. | Optional |
| live_interaction | Whether to enable live interaction. Default is false. | Optional |
| document_password | The document password. | Optional |
| archive_password | The archive password. | Optional |
| start_as_normal_user | Whether to start the analysis as a normal user. Default is false. | Optional |
| language_and_locale | Changes the language and locale of the analysis machine. | Optional |
| delete_after_days | The number of days after which the analysis will be deleted. Default is 30. | Optional |
| encrypt_with_password | The password to encrypt the analysis with. | Optional |
| export_to_jbxview | Whether to export the analysis to JBXView. Default is false. | Optional |
| email_notification | Send an email notification once the analysis completes. Default is false. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| DBotScore.Indicator | String | The indicator that was tested. |
| DBotScore.Reliability | String | The reliability of the source providing the intelligence data. |
| DBotScore.Score | Number | The actual score. |
| DBotScore.Type | String | The indicator type. |
| DBotScore.Vendor | String | The vendor used to calculate the score. |
| URL.Data | String | The URL. |
| Joe.Analysis.AnalysisID | String | The analysis ID. |
| Joe.Analysis.Classification | String | The classification. |
| Joe.Analysis.Comments | String | The comments. |
| Joe.Analysis.detection | String | The detection. |
| Joe.Analysis.duration | Number | The duration. |
| Joe.Analysis.encrypted | Boolean | Whether the analysis is encrypted. |
| Joe.Analysis.filename | String | The filename. |
| Joe.Analysis.runs.detection | String | The detection. |
| Joe.Analysis.runs.error | Unknown | The error. |
| Joe.Analysis.runs.score | Number | The score. |
| Joe.Analysis.runs.sigma | Boolean | The sigma. |
| Joe.Analysis.runs.snort | Boolean | The snort. |
| Joe.Analysis.runs.system | String | The system. |
| Joe.Analysis.runs.yara | Boolean | The YARA. |
| Joe.Analysis.score | Number | The score. |
| Joe.Analysis.scriptname | String | The script name. |
| Joe.Analysis.status | String | The status. |
| Joe.Analysis.threatname | String | The threat name. |
| Joe.Analysis.time | Date | The time. |
| Joe.Analysis.webid | String | The web ID. |
| Joe.Submission.most_relevant_analysis.detection | String | The detection. |
| Joe.Submission.most_relevant_analysis.score | Number | The score. |
| Joe.Submission.most_relevant_analysis.webid | String | The web ID. |
| Joe.Submission.name | String | The name. |
| Joe.Submission.status | String | The status. |
| Joe.Submission.submission_id | String | The submission ID. |
| Joe.Submission.time | Date | The time. |
Command example
!joe-submit-url url=http://example.com
Context Example
{
"DBotScore": [
{
"Indicator": "example.txt",
"Reliability": "C - Fairly reliable",
"Score": 1,
"Type": "url",
"Vendor": "JoeSecurityV2"
}
],
"URL": [
{
"Data": "http://example.com"
}
],
"Joe": {
"Analysis": [
{
"analysisid": "1",
"classification": "",
"comments": "example comment",
"detection": "clean",
"duration": 500,
"encrypted": false,
"filename": "http://example.com",
"md5": "",
"runs": [
{
"detection": "clean",
"error": null,
"score": 0,
"sigma": false,
"snort": false,
"system": "w7",
"yara": false
}
],
"score": 1,
"scriptname": "example.jbs",
"sha1": "",
"sha256": "",
"status": "finished",
"tags": [],
"threatname": "Unknown",
"time": "2022-09-15T10:57:20+02:00",
"webid": "1"
}
],
"Submission": {
"most_relevant_analysis": {
"detection": "clean",
"score": 0,
"webid": "1"
},
"name": "http://example.com",
"status": "finished",
"submission_id": "1111111",
"time": "2022-09-15T10:57:14+02:00"
}
}
}
Human Readable Output
Submission Results
Submission Id Sample Name Time Status Web Id Encrypted Analysis Id Classification Threat Name Score Detection URL 1 http://example.com 2022-09-15T10:57:14+02:00 finished 1 false 1 Unknown 1 clean http://example.com
Breaking Changes
Commands
The following commands were removed in this version
- joe-analysis-submit-sample - this command was replaced by joe-submit-sample.
- joe-analysis-submit-url - this command was replaced by joe-submit-url.
- joe-search command, the query argument now supports comma-separated values.
Playbooks
The following playbooks were deprecated
Detonate File - JoeSecurity - Use the joe-submit-sample command instead.
Detonate File From URL - JoeSecurity - Use the joe-submit-sample command instead.
Detonate URL - JoeSecurity - Use the joe-submit-url command instead.
Configuration parameters
url— Server URL (required)credentials— (required)Reliability— Source Reliabilityonprem— On-Premisecreate_relationships— Create relationshipsinsecure— Trust any certificate (not secure)proxy— Use system proxy settings
Commands (14)
-
fileRetrieves files information from Joe Security.
-
joe-analysis-infoGet information about an analysis.
-
joe-download-reportDownload a resource belonging to a report. This can be the full report, dropped binaries, etc. See the integration README for the full list of supported report types.
-
joe-download-sampleDownload a sample.
-
joe-get-account-quotaRetrieve the account quota.
-
joe-is-onlineCheck if the Joe Sandbox analysis backend is online or in maintenance mode.
-
joe-list-analysisLists all analyses.
-
joe-list-lang-localesRetrieve a list of available language and locale combinations.
-
joe-list–lia-countriesRetrieve a list of localized internet anonymization countries.
-
joe-searchSearch through all analyses.
-
joe-submission-infoRetrieve the submission info.
-
joe-submit-sampleSubmit a sample for sandbox analysis.
-
joe-submit-urlSubmit an URL for sandbox analysis.
-
urlRetrieves URL information from Joe Security.
from collections.abc import Generator from copy import deepcopy import jbxapi import urllib3 from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import from CommonServerUserPython import * # noqa urllib3.disable_warnings() """ CONSTANTS """ DATE_FORMAT = "%Y-%m-%dT%H:%M:%SZ" # ISO8601 format with UTC, default in XSOAR API_ERRORS = { 1: "Quota", 2: "MissingParameterError", 3: "InvalidParameterError", 4: "InvalidApiKeyError", 5: "ServerOfflineError", 6: "InternalServerError", 7: "PermissionError", 8: "UnknownEndpointError", } class Client(jbxapi.JoeSandbox): def __init__( self, apikey: str = "", on_premise: bool = True, base_url: str = "", accept_tac: bool = True, verify_ssl: bool = True, proxy: bool = False, create_relationships: bool = False, reliability: str = DBotScoreReliability.C, ): proxies = {} self.reliability = reliability self.create_relationships = create_relationships self.on_premise = on_premise if not proxy: demisto.debug("Removing proxy environment variables.") else: demisto.debug("Handling proxy.") proxies = handle_proxy() super().__init__(apikey=apikey, apiurl=base_url, accept_tac=accept_tac, verify_ssl=verify_ssl, proxies=proxies) def analysis_info_list(self, web_ids: List[str]) -> List[Dict[str, Any]]: """ A wrapper function supporting a list of webids to query. Args: web_ids: List(str): List of analysis webids to query. Returns: result: List(Dict(str, any)): List of analysis info result. """ return [self.analysis_info(webid=web_id) for web_id in web_ids] """ HELPER FUNCTIONS """ def update_metrics(exception: Exception, exe_metrics: ExecutionMetrics): """ Helper function that supports the update of the execution metrics. Args: exception: Exception: The exception. exe_metrics: ExecutionMetrics: Execution metrics object. Returns: None """ if isinstance(exception, jbxapi.ApiError): match API_ERRORS.get(exception.code): case "Quota": exe_metrics.quota_error += 1 case "InvalidApiKeyError" | "PermissionError": exe_metrics.auth_error += 1 case "ServerOfflineError" | "InternalServerError": exe_metrics.connection_error += 1 case _: exe_metrics.general_error += 1 else: exe_metrics.general_error += 1 def paginate(args: Dict[str, Any], results: Generator) -> List: """ Helper function supporting paginate for results. Args: args: Dict(str, any): paginate arguments (page, page_size, limit). results: (Generator): API results for paginate. Returns: result: List: The requests pages. """ page: Optional[int] = arg_to_number(args.get("page", None)) page_size: Optional[int] = arg_to_number(args.get("page_size", None)) limit: Optional[int] = arg_to_number(args.get("limit", 50)) # paginate is available only if supplied page and page size. if (page and not page_size) or (page_size and not page): raise DemistoException("Either `page` or `page_size` was not provided.") if page and page <= 0: raise ValueError("The 'page' argument value is not valid.") if page_size and page_size <= 0: raise ValueError("The 'page_size' argument value is not valid.") if limit and limit < 0: raise ValueError("The 'limit' argument value is not valid.") number_of_entries = page * page_size if (page and page_size) else limit if limit else 0 if page and page_size: try: all_pages = [next(results) for _ in range(number_of_entries)] return all_pages[-page_size:] # pylint: disable=E1130 except StopIteration: return [] return list(results)[:limit] def build_analysis_hr(analysis: Dict[str, Any]) -> Dict[str, Any]: """ Helper function that supports the building of the human-readable output. Args: analysis: Dict(str, any): Analysis result returned by the API. Returns: result: Dict(str, any): The analysis human-readable entry. """ file_name = analysis.get("filename") sha1 = analysis.get("sha1") sha256 = analysis.get("sha256") md5 = analysis.get("md5") tags = analysis.get("tags") hr_analysis = { "Id": analysis.get("webid"), "SampleName": file_name, "Status": analysis.get("status"), "Time": analysis.get("time"), "MD5": md5, "SHA1": sha1, "SHA256": sha256, "Systems": list({run.get("system") for run in analysis.get("runs", [])}), "Result": list({run.get("detection") for run in analysis.get("runs", [])}), "Tags": tags, "Errors": list({run.get("error") for run in analysis.get("runs", [])}), "Comments": analysis.get("comments"), } return hr_analysis def build_search_hr(analysis: Dict[str, Any]) -> Dict[str, Any]: """ Helper function that supports the building of the human-readable output for search command. Args: analysis: Dict(str, any): Analysis result returned by the API. Returns: result: Dict(str, any): The analysis human-readable entry. """ file_name = analysis.get("filename") web_id = analysis.get("webid") sha1 = analysis.get("sha1") sha256 = analysis.get("sha256") md5 = analysis.get("md5") tags = analysis.get("tags") hr_analysis = {"Id": web_id, "Name": file_name, "MD5": md5, "SHA1": sha1, "SHA256": sha256, "Tags": tags} return hr_analysis def build_quota_hr(res: Dict[str, Any]) -> tuple[Dict[str, Any], List[str]]: """ Helper function that supports the building of the human-readable output for quota command. Args: res: Dict(str, any): Quota result returned by the API. Returns: result: Tuple(Dict(str,Any), List(str)): The quota human-readable entry. """ headers = [ "Quota Type", "Daily Quota Current", "Daily Quota Limit", "Daily Quote Remaining", "Monthly Quota Current", "Monthly Quota Limit", "Monthly Quota Remaining", ] hr = { "Quota Type": res.get("type"), "Daily Quota Current": res.get("quota", {}).get("daily", {}).get("current", 0), "Daily Quota Limit": res.get("quota", {}).get("daily", {}).get("limit", 0), "Daily Quote Remaining": res.get("quota", {}).get("daily", {}).get("remaining", 0), "Monthly Quota Current": res.get("quota", {}).get("monthly", {}).get("current", 0), "Monthly Quota Limit": res.get("quota", {}).get("monthly", {}).get("limit", 0), "Monthly Quota Remaining": res.get("quota", {}).get("monthly", {}).get("remaining", 0), } return hr, headers def build_submission_hr(res: Dict[str, Any], analyses: List[Dict[str, Any]]) -> tuple[Dict[str, Any], List[str]]: """ Helper function that supports the building of the human-readable output for submission command. Args: res: Dict(str, any): Submission result returned by the API. analyses: List(Dict(str, any)): List of analysis result returned by the API. Returns: result: Tuple(Dict(str,Any), List(str)): The submission human-readable entry. """ headers = [ "Submission Id", "Sample Name", "Time", "Status", "Web Id", "Encrypted", "Analysis Id", "Classification", "Threat Name", "Score", "Detection", ] hr = { "Submission Id": res.get("submission_id"), "Sample Name": res.get("name"), "Time": res.get("time"), "Status": res.get("status"), "Web Id": analyses[0].get("webid"), "Encrypted": analyses[0].get("encrypted"), "Analysis Id": analyses[0].get("analysisid"), "Classification": analyses[0].get("classification"), "Threat Name": analyses[0].get("threatname"), "Score": analyses[0].get("score"), "Detection": analyses[0].get("detection"), } if res.get("analyses", [{}])[0].get("sha256"): headers.extend(["SHA256", "MD5", "SHA1", "File Name"]) hr.update( { "SHA256": analyses[0].get("sha256"), "MD5": analyses[0].get("md5"), "SHA1": analyses[0].get("sha1"), "File Name": analyses[0].get("filename"), } ) else: headers.append("URL") hr.update({"URL": res.get("url")}) return hr, headers def build_reputation_hr(analysis: Dict[str, Any], command: str) -> Dict[str, Any]: """ Helper function that supports the building of the human-readable output. Args: analysis: (Dict(str, any)): Analysis result returned by the API. command: (str): The command url or file. Returns: result: Dict(str, any): The analysis human-readable entry. """ if command == "file": file_name = analysis.get("filename") sha1 = analysis.get("sha1") sha256 = analysis.get("sha256") md5 = analysis.get("md5") tags = analysis.get("tags") hr_analysis = {"File Name": file_name, "Sha1": sha1, "Sha256": sha256, "Md5": md5, "Tags": tags} return hr_analysis return {"Url": analysis.get("filename")} def build_relationships(threat_name: str, entity: str, entity_type: str) -> EntityRelationship: """ Helper function that creates the relationships table. Args: threat_name (str): The malware from joe security. entity: (str): The main entity value. entity_type: Union(File, URL): The main entity type. Returns: result: List(EntityRelationship): The relationship entry. """ return EntityRelationship( name=EntityRelationship.Relationships.INDICATOR_OF, entity_a=entity, entity_a_type=entity_type, entity_b=threat_name, entity_b_type=FeedIndicatorType.Malware, reverse_name=EntityRelationship.Relationships.INDICATED_BY, ) def build_indicator_object( client: Client, analysis: Dict[str, Any], analyses: List[Dict[str, Any]], is_reputation: bool = False ) -> CommandResults: """ Helper function that creates the Indicator object. Args: client (Client): The client class. analysis: Dict(str, any): Analysis result returned by the API. analyses: List(Dict(str, any)): List of analysis result returned by the API. is_reputation: (bool): If the command is reputation command. Returns: result: (CommandResults) The indicator object including its relationships """ if analysis.get("sha256"): return build_file_object(client, analysis, analyses, is_reputation) return build_url_object(client, analysis, analyses, is_reputation) def build_file_object( client: Client, analysis: Dict[str, Any], analyses: List[Dict[str, Any]], is_reputation: bool ) -> CommandResults: """ Helper function that creates the File object. Args: client (Client): The client class. analysis: Dict(str, any): Analysis result returned by the API. analyses: List(Dict(str, any)): List of analysis result returned by the API. is_reputation (bool): Whether the command is reputation command. Returns: result: (CommandResults) The indicator object including its relationships """ file_name = analysis.get("filename") sha1 = analysis.get("sha1") sha256 = analysis.get("sha256", "") md5 = analysis.get("md5") tags = analysis.get("tags") threat_name = analysis.get("threatname", "") relationships = [] headers = ["File Name", "Sha1", "Sha256", "Md5"] hr = {"File Name": file_name, "Sha1": sha1, "Sha256": sha256, "Md5": md5} score, description = max( [indicator_calculate_score(entry.get("detection", "")) for entry in analyses if entry.get("sha256") == sha256], key=lambda tup: tup[1], ) # Find the max dbot score between all the analysis results. dbot_score = Common.DBotScore( indicator=sha256, integration_name="JoeSecurityV2", indicator_type=DBotScoreType.FILE, reliability=DBotScoreReliability.get_dbot_score_reliability_from_str(client.reliability), score=score, malicious_description=description, ) if client.create_relationships and threat_name and threat_name.lower() != "unknown": relationships.append(build_relationships(threat_name, sha256, FeedIndicatorType.File)) indicator = Common.File( name=file_name, sha1=sha1, sha256=sha256, dbot_score=dbot_score, md5=md5, tags=tags, relationships=relationships ) if is_reputation: return CommandResults( outputs=hr, indicator=indicator, relationships=relationships, outputs_prefix="Joe.File", readable_output=tableToMarkdown("File Result:", hr, headers), ) return CommandResults( indicator=indicator, relationships=relationships, readable_output=tableToMarkdown("File Result:", hr, headers) ) def build_url_object( client: Client, analysis: Dict[str, Any], analyses: List[Dict[str, Any]], is_reputation: bool ) -> CommandResults: """ Helper function that creates the URL object. Args: client (Client): The client class. analysis: Dict(str, any): Analysis result returned by the API. analyses: List(Dict(str, any)): Analysis results returned by the API. is_reputation (bool): Whether the command is reputation command. Returns: result: (CommandResults) The indicator object including its relationships """ url = analysis.get("filename", "") threat_name = analysis.get("threatname", "") relationships = [] score, description = max( [indicator_calculate_score(entry.get("detection", "")) for entry in analyses if entry.get("filename") == url], key=lambda tup: tup[1], ) # Find the max dbot score between all the analysis results. dbot_score = Common.DBotScore( indicator=url, integration_name="JoeSecurityV2", indicator_type=DBotScoreType.URL, reliability=DBotScoreReliability.get_dbot_score_reliability_from_str(client.reliability), score=score, malicious_description=description, ) if client.create_relationships and threat_name and threat_name.lower() != "unknown": relationships.append(build_relationships(threat_name, url, FeedIndicatorType.URL)) indicator = Common.URL(url=url, dbot_score=dbot_score, relationships=relationships) if is_reputation: return CommandResults( outputs=url, indicator=indicator, relationships=relationships, outputs_prefix="Joe.URL", readable_output=tableToMarkdown("Url Result:", {"Url": url}), ) return CommandResults( indicator=indicator, relationships=relationships, readable_output=tableToMarkdown("Url Result:", {"Url": url}) ) def indicator_calculate_score(detection: str = "") -> tuple[int, str]: """ Calculate the DBot Score based on analysis detection. Args: detection (str): The analysis detection. Returns: dbot_score,description (tuple): The DBot Score and the description associated with it. """ if "malicious" in detection: return Common.DBotScore.BAD, "This indicator is malicious" elif "suspicious" in detection: return Common.DBotScore.SUSPICIOUS, "" elif "clean" in detection: return Common.DBotScore.GOOD, "" return Common.DBotScore.NONE, "" def build_search_command_result(analyses: List[Dict[str, Any]]) -> CommandResults: """ Helper function that parses the search result object. Args: analyses: (List(Dict(str, any))): The analyses result returned by the API. Returns: result: (CommandResults) The parsed CommandResults object. """ hr_headers = ["Id", "Name", "SHA256", "SHA1", "MD5", "Tags"] hr_analysis_ls = [] for analysis in analyses: hr_analysis_ls.append(build_search_hr(analysis)) return CommandResults( outputs=analyses, readable_output=tableToMarkdown("Analysis Result:", hr_analysis_ls, hr_headers), outputs_prefix="Joe.Analysis", outputs_key_field="Id", ) def build_analysis_command_result(client: Client, analyses: List[Dict[str, Any]], full_display: bool) -> List[CommandResults]: """ Helper function that parses the analysis result object. Args: client (Client): The client class. analyses: (List(Dict(str, any))): The analyses result returned by the API. full_display (bool): Whether to display the full analysis result or not. Returns: result: List(CommandResults) The parsed CommandResults object. """ hr_headers = ["Id", "SampleName", "Status", "Time", "MD5", "SHA1", "SHA256", "Systems", "Result", "Errors", "Comments"] command_res_ls = [] hr_analysis_ls = [] for analysis in analyses: hr_analysis_ls.append(build_analysis_hr(analysis)) if full_display: command_res = build_indicator_object(client, analysis, analyses) command_res_ls.append(command_res) command_res_ls.append( CommandResults( outputs=analyses, readable_output=tableToMarkdown("Analysis Result:", hr_analysis_ls, hr_headers), outputs_prefix="Joe.Analysis", ) ) return command_res_ls def build_reputiation_command_result(client: Client, analyses: List[Dict[str, Any]]) -> List[CommandResults]: """ Helper function that parses the file or URL result object. Args: client (Client): The client class. analyses: (List[Dict(str, any)]): The analyses file or URL returned by the API. Returns: result: List(CommandResults): The parsed CommandResults object. """ command_res_ls = [] for analysis in analyses: command_res = build_indicator_object(client, analysis, analyses, is_reputation=True) command_res_ls.append(command_res) return command_res_ls def build_submission_command_result( client: Client, res: Dict[str, Any], args: Dict[str, Any], exe_metrics: ExecutionMetrics, download_report: bool ) -> List[Union[CommandResults, Dict[str, Any]]]: """ Helper function that parses the submission result object. Args: client (Client): The client class. res: (Dict(str, any)): The submission result returned by the API. args: (Dict(str, any)): The submission arguments. download_report: (bool): Indicates either to download the report. exe_metrics: (ExecutionMetrics): The execution metrics. Returns: result: (List[Union[CommandResults, Dict[str, Any]]]): A list of CommandResults objects or fileResult data. """ command_results: List[Union[CommandResults, Dict[str, Any]]] = [] report_type = args.get("report_type") full_display = argToBoolean(args.get("full_display", True)) analyses = res.get("analyses", []) hr, headers = build_submission_hr(res, res.get("analyses", [])) res_copy = deepcopy(res) if full_display: for analysis in analyses: command_res = build_indicator_object(client, analysis, analyses) web_id = analysis.get("webid") if download_report: report = download_report_command(client, {"type": report_type, "webid": web_id}) command_results.append(report) command_results.append(command_res) context_entry = {"Joe.Submission": res, "Joe.Analysis": res.pop("analyses")} command_results.append( CommandResults( outputs=context_entry, outputs_key_field="submission_id", readable_output=tableToMarkdown("Submission Results:", hr, headers=headers), execution_metrics=exe_metrics.get_metric_list(), raw_response=res_copy, ) ) return command_results def build_submission_params(args: Dict[str, Any], on_premise: bool) -> Dict[str, Any]: """ Helper function that builds the submission parameters. Args: args: (Dict[str, Any]): The command arguments. Returns: result: (Dict[str, Any]): The submission parameters. """ params = { "comments": args.get("comments", None), "systems": argToList(args.get("systems")), "tags": argToList(args.get("tags")), "internet-access": argToBoolean(args.get("internet_access", True)), "archive-no-unpack": argToBoolean(args.get("archive_no_unpack", False)), "ssl-inspection": argToBoolean(args.get("ssl_inspection", False)), "localized-internet-country": args.get("localized_internet_country"), "internet-simulation": argToBoolean(args.get("internet_simulation", False)), "hybrid-code-analysis": argToBoolean(args.get("hybrid_code_analysis", True)), "hybrid-decompilation": argToBoolean(args.get("hybrid_decompilation", False)), "vba-instrumentation": argToBoolean(args.get("vba_instrumentation", True)), "js-instrumentation": argToBoolean(args.get("js_instrumentation", True)), "java-jar-tracing": argToBoolean(args.get("java_jar_tracing", True)), "dotnet-tracing": argToBoolean(args.get("dotnet_tracing", True)), "amsi-unpacking": argToBoolean(args.get("amsi_unpacking", True)), "fast-mode": argToBoolean(args.get("fast_mode", False)), "secondary-results": argToBoolean(args.get("secondary_results", False)), "report-cache": argToBoolean(args.get("report_cache", False)), "command-line-argument": args.get("command_line_argument"), "live-interaction": argToBoolean(args.get("live_interaction", False)), "document-password": args.get("document_password"), "archive-password": args.get("archive_password"), "start-as-normal-user": argToBoolean(args.get("start_as_normal_user", False)), "language-and-locale": args.get("language_and_locale"), "delete-after-days": arg_to_number(args.get("delete_after_days", 30)), "encrypt-with-password": args.get("encrypt_with_password"), "email-notification": argToBoolean(args.get("email_notification", False)), } if on_premise: params.pop("delete-after-days", None) return params def file_submission( client: Client, args: Dict[str, Any], params: Dict[str, Any], file: str, exe_metrics: ExecutionMetrics ) -> PollResult: """ Helper function that submits a file to Joe Sandbox. Args: client (Client): The client class. args: (Dict[str, Any]): The command arguments. params: (Dict[str, Any]): The submission parameters. file: (str): The file to submit. exe_metrics Returns: result: (PollResult): The parsed PollResult object. """ file_path = demisto.getFilePath(file) name = file_path["name"] demisto.debug(f"Trying to upload file {name=} from entry= {file_path['path']}") with open(file_path["path"], "rb") as f: file_to_send = (args.get("file_name") or name, f) res = client.submit_sample(sample=file_to_send, params=params, cookbook=args.get("cookbook")) exe_metrics.success += 1 partial_res = CommandResults(readable_output=f'Waiting for submission "{res.get("submission_id")}" to finish...') return PollResult( response=CommandResults(outputs=res, outputs_prefix="Joe.Submission", outputs_key_field="submission_id"), args_for_next_run={"submission_id": res.get("submission_id"), **args}, continue_to_poll=True, partial_result=partial_res, ) def url_submission( client: Client, args: Dict[str, Any], params: Dict[str, Any], url: str, exe_metrics: ExecutionMetrics ) -> PollResult: """ Helper function that submits a URL to Joe Sandbox. Args: client (Client): The client class. args: (Dict[str, Any]): The command arguments. params: (Dict[str, Any]): The submission parameters. url: (str): The URL to submit. exe_metrics: (ExecutionMetrics): The execution metrics. Returns: result: (PollResult): The parsed PollResult object. """ res = client.submit_url(url=url, params=params) exe_metrics.success += 1 partial_res = CommandResults(readable_output=f'Waiting for submission "{res.get("submission_id")}" to finish...') return PollResult( response=CommandResults(outputs=res, outputs_prefix="Joe.Submission", outputs_key_field="submission_id"), args_for_next_run={"submission_id": res.get("submission_id"), **args}, continue_to_poll=True, partial_result=partial_res, ) # The interval timeout should be set between 30 and 60 seconds for optimal server usage. @polling_function( name=demisto.command(), timeout=arg_to_number(demisto.args().get("timeout", 1200)), interval=arg_to_number(demisto.args().get("interval_in_seconds", 45)), requires_polling_arg=False, ) def polling_submit_command( args: Dict[str, Any], client: Client, params: Dict[str, Any], exe_metrics: ExecutionMetrics ) -> PollResult: """ Helper function that polls the analysis result. Args: args: (Dict[str, Any]): The command arguments. client (Client): The client class. params: (Dict[str, Any]): The submission parameters. exe_metrics: (ExecutionMetrics): The execution metrics. Returns: result: (Dict[str, Any]): The analysis result. """ if submission_id := args.get("submission_id"): res = client.submission_info(submission_id=submission_id) status = res.get("status") if status == "finished": command_results = build_submission_command_result(client, res, args, exe_metrics, True) return PollResult(command_results) return PollResult( response=None, partial_result=CommandResults( outputs=res, # this is what the response will be in case job has finished outputs_prefix="Joe.Submission", outputs_key_field="submission_id", readable_output=f'Waiting for submission "{res.get("submission_id")}" to finish...', ), continue_to_poll=True, args_for_next_run={"submission_id": args.get("submission_id"), **args}, ) else: if file := args.get("entry_id"): return file_submission(client, args, params, file, exe_metrics) elif url := args.get("url"): return url_submission(client, args, params, url, exe_metrics) else: raise DemistoException("No file or URL was provided.") """ COMMAND FUNCTIONS """ def test_module(client: Client) -> str: # pragma: no cover """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. :type client: ``JoeSandbox`` :param JoeSandbox: client to use :return: 'ok' if test passed, anything else will fail the test. :rtype: ``str`` """ try: demisto.debug(f"sending request with url: {client.apiurl + '/v2/server/online'}") client.server_online() except Exception as e: if isinstance(e, jbxapi.ApiError): match API_ERRORS.get(e.code): case "InvalidApiKeyError": return "Invalid Api Key" case "PermissionError": return "Permission Error" case "ServerOfflineError" | "InternalServerError": return "Server error, please verify the Server URL or check if the server is offline" else: return f"Server error, please verify the server url or check if the server is online, exact error: {e}" return "ok" def is_online_command(client: Client) -> CommandResults: """ Check if the Joe Sandbox analysis back end is online or in maintenance mode. Args: client: (Client) The client class. Returns: result: (CommandResults) The CommandResults object . """ result = client.server_online() status = "online" if result.get("online") else "offline" return CommandResults( outputs_prefix="Joe.ServerStatus.Online", outputs=result.get("online"), readable_output=f"Joe server is {status}" ) def analysis_info_command(client: Client, args: Dict[str, Any]) -> Union[CommandResults, List[CommandResults]]: """ Get information about a specific analysis. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. Returns: result: Union[CommandResults, List[CommandResults]] The CommandResults object. """ try: res = client.analysis_info(webid=args.get("webid")) command_results = build_analysis_command_result(client, [res], argToBoolean(args.get("full_display"))) if command_results: return command_results except jbxapi.InvalidParameterError: pass return CommandResults(readable_output="No Results were found.") def list_analysis_command(client: Client, args: Dict[str, Any]) -> Union[CommandResults, List[CommandResults]]: """ List all analyses in descending order, starting with the most recent. The result may be sliced by page and page size or by limit. (default 50) Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. Returns: result: Union(CommandResults, List(CommandResults)): The CommandResults object. """ filtered_pages = paginate(args, client.analysis_list_paged()) analysis_result_ls = client.analysis_info_list(web_ids=[entry.get("webid") for entry in filtered_pages]) command_results = build_analysis_command_result(client, analysis_result_ls, argToBoolean(args.get("full_display"))) if command_results: return command_results return CommandResults(readable_output="No Results were found.") def download_report_command(client: Client, args: Dict[str, Any]) -> Dict[str, Any]: """ Download a resource belonging to a report. This can be the full report, dropped binaries, etc. Args: client: (Client): The client class. args: (Dict(str, any)): The commands arguments. Returns: result: (Dict(str, Any)): The fileResult object. """ web_id = args.get("webid") report_type = args.get("type") result = client.analysis_download(webid=web_id, type=report_type)[1] return fileResult(f"{web_id}_report.{report_type}", result, EntryType.ENTRY_INFO_FILE) def download_sample_command(client: Client, args: Dict[str, Any]) -> Dict[str, Any]: """ Download a sample. Args: client: (Client): The client class. args: (Dict(str, any)): The commands arguments. Returns: result: (Dict(str, Any)): The fileResult object. """ web_id = args.get("webid") result = client.analysis_download(webid=web_id, type="sample")[1] return fileResult(f"{web_id}.dontrun", result) def search_command(client: Client, args: Dict[str, Any]) -> Union[CommandResults, List[CommandResults]]: """ Search through all analyses. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. Returns: result: (CommandResults) The CommandResults object. """ query = args.get("query") result = client.analysis_search(query=query) if result: return build_analysis_command_result(client, result, argToBoolean(args.get("full_display", False))) return CommandResults(readable_output="No Results were found.") def file_command(client: Client, args: Dict[str, Any]) -> Union[CommandResults, List[CommandResults]]: """ The file reputation command. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. Returns: result: (CommandResults) The CommandResults object. """ analyses = [] files = set(argToList(args.get("file", ""))) for file in files: res = client.analysis_search(query=file) if res: analyses.append(res[0]) if analyses: return build_reputiation_command_result(client, analyses) return CommandResults(readable_output="No Results were found.") def url_command(client: Client, args: Dict[str, Any]) -> Union[CommandResults, List[CommandResults]]: """ The url reputation command. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. Returns: result: (CommandResults) The CommandResults object. """ analyses = [] urls = set(argToList(args.get("url", ""))) for url in urls: res = client.analysis_search(query=url) if res: analyses.append(res[0]) if analyses: return build_reputiation_command_result(client, analyses) return CommandResults(readable_output="No Results were found.") def list_lia_countries_command(client: Client) -> CommandResults: """ Retrieve a list of localized internet anonymization countries. Args: client: (Client) The client class. Returns: result: (CommandResults) The CommandResults object. """ res = client.server_lia_countries() if res: data = [country.get("name") for country in res] return CommandResults( outputs_prefix="Joe.LIACountry", outputs=data, readable_output=tableToMarkdown("Results:", {"Name": data}) ) return CommandResults(readable_output="No Results were found.") def list_lang_locales_command(client: Client) -> CommandResults: """ Retrieve a list of available language and locale combinations. Args: client: (Client) The client class. Returns: result: (CommandResults) The CommandResults object. """ res = client.server_languages_and_locales() if res: data = [lang.get("name") for lang in res] return CommandResults( outputs_prefix="Joe.LangLocale", outputs=data, readable_output=tableToMarkdown("Results:", {"Name": data}) ) return CommandResults(readable_output="No Results were found.") def get_account_quota_command(client: Client) -> CommandResults: """ Retrieve the quota for the current account. Args: client: (Client) The client class. Returns: result: (CommandResults) The CommandResults object. """ res = client.account_info() if res: hr, headers = build_quota_hr(res) return CommandResults( outputs_prefix="Joe.AccountQuota", outputs=res, readable_output=tableToMarkdown("Results:", hr, headers=headers) ) return CommandResults(readable_output="No Results were found.") def submission_info_command( client: Client, args: Dict[str, Any], exe_metrics: ExecutionMetrics ) -> List[Union[CommandResults, Dict[str, Any]]]: """ Retrieve information about a submission. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. exe_metrics: (ExecutionMetrics) The execution metrics object. Returns: result: (CommandResults) The CommandResults object. """ submission_ids = argToList(args.get("submission_ids")) command_results = [] for submission_id in submission_ids: res = client.submission_info(submission_id=submission_id) if res: command_results.extend(build_submission_command_result(client, res, args, exe_metrics, False)) else: command_results.append(CommandResults(readable_output=f"No Results were found for submission {submission_id}.")) return command_results def submit_sample_command(client: Client, args: Dict[str, Any], exe_metrics: ExecutionMetrics) -> PollResult: """ Upload a sample to Joe server. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. exe_metrics: (ExecutionMetrics) The execution metrics. Returns: result: (CommandResults) The CommandResults object. """ params = build_submission_params(args, client.on_premise) try: return polling_submit_command(args, client, params, exe_metrics) except jbxapi.InvalidParameterError as e: if e.message == "Unknown parameter delete-after-days.": raw = { "code": 3, "message": ( "The parameter delete-after-days is only available in the cloud version.\n" 'Check the "On-Premise" option in the integration settings for on-premise setups to avoid this error' ), } raise jbxapi.ApiError(raw) else: raise def submit_url_command(client: Client, args: Dict[str, Any], exe_metrics: ExecutionMetrics) -> PollResult: """ Upload a URL to Joe server. Args: client: (Client) The client class. args: (Dict(str, any)) The commands arguments. exe_metrics: (ExecutionMetrics) The execution metrics. Returns: result: (CommandResults) The CommandResults object. """ params = build_submission_params(args, client.on_premise) params.update({"url-reputation": argToBoolean(args.get("url_reputation", False))}) return polling_submit_command(args, client, params, exe_metrics) """ MAIN FUNCTION """ def main() -> None: # pragma: no cover """main function, parses params and runs command functions :return: :rtype: """ api_key = demisto.get(demisto.params(), "credentials.password") base_url = demisto.params().get("url") demisto.debug(f"base url before handling it: {base_url}") if "api" not in base_url: base_url = urljoin(base_url, "api/") demisto.debug(f"base url after handling it: {base_url}") verify_certificate = not demisto.params().get("insecure", False) proxy = demisto.params().get("proxy", False) reliability = demisto.params().get("Reliability", DBotScoreReliability.C) create_relationships = demisto.params().get("create_relationships", False) on_premise = demisto.params().get("onprem", False) command = demisto.command() args = demisto.args() exe_metrics = ExecutionMetrics() demisto.debug(f"Command being called is {demisto.command()}") try: client = Client( apikey=api_key, on_premise=on_premise, base_url=base_url, accept_tac=True, verify_ssl=verify_certificate, proxy=proxy, reliability=reliability, create_relationships=create_relationships, ) if command == "test-module": return_results(test_module(client)) elif command == "joe-is-online": return_results(is_online_command(client)) elif command == "joe-analysis-info": return_results(analysis_info_command(client, args)) elif command == "joe-list-analysis": return_results(list_analysis_command(client, args)) elif command == "joe-download-report": demisto.results(download_report_command(client, args)) elif command == "joe-download-sample": demisto.results(download_sample_command(client, args)) elif command == "joe-search": return_results(search_command(client, args)) elif command == "file": return_results(file_command(client, args)) elif command == "url": return_results(url_command(client, args)) elif command == "joe-list–lia-countries": # noqa: RUF001 (backwards compatibility) return_results(list_lia_countries_command(client)) elif command == "joe-list-lang-locales": return_results(list_lang_locales_command(client)) elif command == "joe-get-account-quota": return_results(get_account_quota_command(client)) elif command == "joe-submission-info": return_results(submission_info_command(client, args, exe_metrics)) elif command == "joe-submit-sample": return_results(submit_sample_command(client, args, exe_metrics)) elif command == "joe-submit-url": return_results(submit_url_command(client, args, exe_metrics)) else: raise NotImplementedError(f"{command} command is not implemented.") except Exception as e: update_metrics(e, exe_metrics) return_results(CommandResults(execution_metrics=exe_metrics.get_metric_list())) return_error(f"Failed to execute {command} command.\nError:\n{e!s}") """ ENTRY POINT """ if __name__ in ("__main__", "__builtin__", "builtins"): main()