ReversingLabs A1000 Deprecated
Deprecated. Use the ReversingLabs A1000 v2 integration instead.
Forensics & Malware Analysis · ReversingLabs A1000
Details
| ID | ReversingLabs A1000 |
|---|---|
| Provider | ReversingLabs |
| Category | Forensics & Malware Analysis |
| From Version | 5.0.0 |
| Docker Image | demisto/python:2.7.18.20958 |
| Supported Modules | Agentix XSIAM |
README
Overview
Use the A1000 Malware Analysis Platform to support advanced hunting and investigations through high-speed automated static analysis. A1000 Malware Analysis Platform is integrated with file reputation services to provide in-depth rich context and threat classification on over 6B files and across all file types.
This integration was integrated and tested with ReversingLabs A1000 Malware Analysis Platform™, 3.7.1.4.
Use Cases
- Supports automated analysis processes (Static Analysis) that includes unpacking and identifying the families of archives, installers, packers and compressors.
- Extracts over 3,000 PTIs from extracted files for PE/Windows, ELF/Linux, Mac OS, iOS, Android, firmware, and documents.
- Calculates file threat level using extracted information.
Helps in regulating the investigation process by uploading and downloading samples to A1000 cloud platform at any point in time. (File reputation data can also be retrieved from an A1000 appliance.)
Prerequisites
You need to obtain the following ReversingLabs A1000 platform information.
- Base URL of the A1000 box (https://a1000.reversinglabs.com)
- Authentication Token
Get Your ReversingLabs A1000 Authentication Token
- Log in to the ReversingLabs A1000 platform.
- Navigate to Administration and click the Tokens icon.
- On the Authentication Tokens page, click the red plus button to create a new token key.
- Select the necessary user, and click the Save button.
The new key is listed on the token table. - Copy the key (authentication token), which you will paste when you configure the integration on Cortex XSOAR.
Configure ReversingLabs A1000 Cortex XSOAR
- Navigate to Settings > Integrations > Servers & Services.
- Search for ReversingLabs A1000.
- Click Add instance to create and configure a new integration instance.
- Name: a textual name for the integration instance.
- Base URL of the A1000 box : https://a1000.reversinglabs.com
- Authentication Token: paste the token that you copied.
- Click Test to validate the URLs 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.
- Upload a sample to A1000 for analysis: reversinglabs-upload
- Re-analyze sample set: reversinglabs-analyze
- Download a sample to the investigation: reversinglabs-download
- Download samples obtained through the unpacking process: reversinglabs-download-unpacked
- List extracted files from a sample: reversinglabs-extracted-files
- Delete an uploaded sample: reversinglabs-delete
- Retrieve file reputation data from an A1000 appliance: file
Upload a sample to A1000 for analysis : reversinglabs-upload
Upload a sample to A1000 for analysis.
Command Example
!reversinglabs-upload entryId="126@331388d4-d045-4e89-843f-28569f05556e" cloud_analyze="true"
Input
|
Parameter |
Description |
|
entryId |
Entry ID of the file to be uploaded. (Once you upload a file on Cortex XSOAR’s platform, click on the link(chain) icon to get the entry ID of that file) |
|
comment |
A comment for the file to be uploaded. |
|
tags |
A comma separated list of tags for the file. |
|
cloud_analyze |
Specifies if the sample is sent to TiCloud for scanning. By default the value is true.
|
Human Readable Output
Raw Output
{
"code": 201,
"message": "Done.",
"detail": {
"id": 604883,
"sha1": "2fb56606463867310bbe853501d662cc21a7f6d9",
"user": 585,
"created": "2018-05-27T22:32:06.830474Z",
"filename": "2018-05-24-Trickbot-malspam-1140-UTC.eml",
"href": "/?q=2fb56606463867310bbe853501d662cc21a7f6d9"
}
}
Reanalyze sample set: reversinglabs-analyze
Schedule a set of samples that were previously updated to the A1000 appliance to be reanalyzed.
Command Example
!reversinglabs-analyze hash="2fb56606463867310bbe853501d662cc21a7f6d9"
Input
|
Parameter |
Description |
|
hash |
The hash of a previously uploaded sample. Hexadecimal representation of SHA-1, SHA-256, SHA-512, or MD5 digest. |
Human Readable Output
Raw Output
{
"code": 200,
"message": "Sample is already queued for analysis.",
"detail": {
"sha1": "f3be1fe7a01b73f0a6eaef9b62945433fcf53d3c",
"Sha256": "f474543f4dace1e830df2dcbed83aecd89a24069c99952f5d24cf0379c116195",
"md5": "fdd22060f2680b46f2783b3b579e82d5"
}
}
Download a sample to the investigation: reversinglabs-download
Download a sample that resides on A1000 to the investigation.
Command Example
!reversinglabs-download hash="fdd22060f2680b46f2783b3b579e82d5"
Input
|
Parameter |
Description |
|
hash |
The hash of a sample that resides on A1000. Hexadecimal representation of SHA-1, SHA-256, SHA-512, or MD5 digest. |
Human Readable Output

Raw Output
There is no raw output for this command.
When the command runs successfully, you get a downloadable file.
When the command fails, you receive a notification with one of the following error codes.
- 404 - Sample not found.
- 401 - Unable to retrieve sample content.
Download samples obtained through the unpacking process : reversinglabs-download-unpacked
Download samples obtained through the unpacking process.
Command Example
!reversinglabs-download-unpacked hash="6bb767e20c25e4d37e73fc0733c7ef2fce4ac8c6"
Input
|
Parameter |
Description |
|
hash |
The hash of a sample that resides on A1000. Hexadecimal representation of SHA-1, SHA-256, SHA-512, or MD5 digest |
Human Readable Output
Raw Output
There is no raw output for this command.
When the command runs successfully, you get a downloadable file.
When the command fails, you are receive a notification with one of the following error codes.
- 404 - Sample not found.
- 401 - Unable to retrieve sample content.
List extracted files from a sample : reversinglabs-extracted-files
List extracted files from a sample
Command Example
!reversinglabs-extracted-files hash="f3be1fe7a01b73f0a6eaef9b62945433fcf53d3c"
Input
|
Parameter |
Description |
|
hash |
The hash of an already uploaded sample. Hexadecimal representation of SHA-1, SHA-256, SHA-512, or MD5 digest |
Human Readable Output

Raw Output
{
"count": 5,
"next": null,
"previous": null,
"results": [
{
"id": 197,
"parent_relationship": null,
"sample": {
"id": 192,
"sha1": "e906fa3d51e86a61741b3499145a114e9bfb7c56",
"type_display": "PE/Exe",
"category": "application",
"file_type": "PE",
"file_subtype": "Exe",
"identification_name": "",
"identification_version": "",
"file_size": 267278,
"extracted_file_count": 2,
"local_first_seen": "2016-05-05T09:57:50.910412Z",
"local_last_seen": "2016-05-05T13:43:21.282072Z",
"threat_status": "malicious",
"trust_factor": 5,
"threat_level": 5,
"threat_name": "Win32.Trojan.Bitman"
},
"filename": "DeVuongHoi.exe",
"path": "DeVuongHoi.exe"
},
{
"id": 198,
"parent_relationship": null,
"sample": {
"id": 198,
"sha1": "e654d39cd13414b5151e8cf0d8f5b166dddd45cb",
"type_display": "PE/Exe",
"category": "application",
"file_type": "PE",
"file_subtype": "Exe",
"identification_name": "",
"identification_version": "",
"file_size": 290816,
ReversingLabs
123
"extracted_file_count": 1,
"local_first_seen": "2016-05-05T09:58:27.096525Z",
"local_last_seen": "2016-05-05T09:58:27.096525Z",
"threat_status": "malicious",
"trust_factor": 5,
"threat_level": 5,
"threat_name": "Win32.Malware.YARA"
},
"filename": "DieGroupv8.exe",
"path": "DieGroupv8.exe"
},
...
Delete an uploaded sample : reversinglabs-delete
Delete an uploaded sample for the specified hash value that resides A1000. All related data, including extracted samples and metadata, will be deleted.
Command Example
!reversinglabs-delete hash="942d85abb2e94a4e5205eae7efdc5677ee6a0881"
Input
|
Parameter |
Description |
|
hash |
The hash of a sample that resides on A1000. Hexadecimal representation of SHA-1, SHA-256, SHA-512, or MD5 digest |
Human Readable Output

Raw Output
{
"code": 200,
"message": "Sample deleted successfully.",
"detail": {
"sha1": "f3be1fe7a01b73f0a6eaef9b62945433fcf53d3c",
"Sha256": "f474543f4dace1e830df2dcbed83aecd89a24069c99952f5d24cf0379c116195",
"Sha512": "68d32e15df33735173ac457c948ed411e2f5aac1dc0d48feaafe5e38f1cd86fe5d67053dca7de36206beed4c9c6274d605a9dfcb19a6c48c8ceb2ffb0bc530d5"
"md5": "fdd22060f2680b46f2783b3b579e82d5"
}
}
Retrieve file reputation data from an A1000 appliance : file
Retrieve file reputation data from an A1000 appliance.
Command Example
!file file="8437682e44a764d0c0f610f6cb262a98"
Input
|
Parameter |
Description |
|
file |
The hash that you want to retrieve reputation data for. Hexadecimal representation of SHA-1, SHA-256, SHA-512, or MD5 digest. |
Human Readable Output

Context Output
|
Parameter |
Description |
|
File.MD5 |
Bad hash detected. |
|
File.SHA1 |
Bad hash SHA-1. |
|
File.Malicious.Vendor |
For malicious files, the vendor that made the decision. |
|
File.Malicious.Detections |
For malicious files, the total number of detections. |
|
File.Malicious.TotalEngines |
For malicious files, the total number of engines. |
|
DBotScore.Indicator |
The indicator that is being tested. |
|
DBotScore.Type |
Indicator type. |
|
DBotScore.Vendor |
Vendor used to calculate the score. |
|
DBotScore.Score |
The actual score |
Raw Output
"results": [
{
"category": "archive",
"aliases": {
"0": "2017-12-04-artifacts-from-Dridex-malspam-infection.zip"
},
"classification_origin":{
"imphash": "33259202a22c25d002be697749eb957e",
"md5": "dbf96ab40b728c12951d317642fbd9da",
"sha1": "38687e06f4f66a6a661b94aaf4e73d0012dfb8e3",
"sha256": "daab430bb5771eaa7af0fbd3417604e8af5f4693099a6393a4dc3b440863bced",
"sha512": "a49cc96651d01da5d6cbb833df36b7987eafb4f09cc9c516c10d0d812002d06ae8edee4e7256c84e300dc2eadad90f7bb37c797bccdee4bad16fcaf88277b381"
}
"classification_reason": "cloud",
"extracted_file_count": 79,
"file_size": 1525222,
"file_subtype": "Archive",
"file_type": "Binary",
"identification_name": "ZIP",
"identification_version": "Generic",
"local_first_seen": "2018-05-27T22:50:27.414449Z",
"local_last_seen": "2018-05-27T22:50:27.414449Z",
"md5": "fdd22060f2680b46f2783b3b579e82d5",
"sha1": "f3be1fe7a01b73f0a6eaef9b62945433fcf53d3c",
"sha256": "f474543f4dace1e830df2dcbed83aecd89a24069c99952f5d24cf0379c116195",
"sha512": "68d32e15df33735173ac457c948ed411e2f5aac1dc0d48feaafe5e38f1cd86fe5d67053dca7de36206beed4c9c6274d605a9dcb19a6c48c8ceb2ffb0bc530d5",
"summary":{
"id": 8306112,
"indicators": []
}
"sha1": "f3be1fe7a01b73f0a6eaef9b62945433fcf53d3c",
"threat_level": 5,
"threat_name": Win32.Trojan.Dridex,
"threat_status": malicious,
"ticloud": {
"first_seen": "2018-05-27T22:50:32Z",
"last_seen": "2018-05-27T22:55:00Z",
"threat_level": 0,
"threat_name": null,
"threat_status": "known",
"trust_factor": 5,
"Trust_factor" 5
}
}
Configuration parameters
base— Base URL of the A1000 box (required)token— Token to use for authentication (required)extended— Provide extended information when availableproxy— Use system proxy settingsverify— Verify host certificates
Commands (7)
-
fileDeprecatedRetrieve file reputation data from an A1000 appliance
-
reversinglabs-analyzeDeprecatedRe-analyze sample
-
reversinglabs-deleteDeprecatedDelete an uploaded sample
-
reversinglabs-downloadDeprecatedDownload a sample to the investigation
-
reversinglabs-download-unpackedDeprecatedDownload samples obtained through the unpacking process
-
reversinglabs-extracted-filesDeprecatedList extracted files from a sample
-
reversinglabs-uploadDeprecatedUpload a sample to A1000 for analysis
import demistomock as demisto # noqa: F401 from CommonServerPython import * # noqa: F401 import os import re import shutil import requests from urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) VERSION = "v1.0.1" USER_AGENT = "ReversingLabs XSOAR A1000 {version}".format(version=VERSION) BASE_URL = demisto.getParam('base') if BASE_URL[-1] == '/': BASE_URL = BASE_URL[0:-1] HEADERS = { 'Authorization': 'Token ' + demisto.getParam('token'), "User-Agent": USER_AGENT } EXTENDED = demisto.getParam('extended') VERIFY_CERT = demisto.getParam('verify') A1000_FIELDS = ('sha1', 'sha256', 'sha512', 'md5', 'category', 'file_type', 'file_subtype', 'identification_name', 'identification_version', 'file_size', 'extracted_file_count', 'local_first_seen', 'local_last_seen', 'classification_origin', 'classification_reason', 'threat_status', 'trust_factor', 'threat_level', 'threat_name', 'summary', 'ticloud', 'aliases') if not demisto.getParam('proxy'): del os.environ['HTTP_PROXY'] del os.environ['HTTPS_PROXY'] del os.environ['http_proxy'] del os.environ['https_proxy'] class NoReferenceFoundError(Exception): def __init__(self, message="No reference was found for this input"): super(NoReferenceFoundError, self).__init__(message) no_rerence_object = NoReferenceFoundError() no_reference_message = "{original_message} - {added_message}".format( original_message=str(no_rerence_object), added_message="Reply does not contain results" ) # pylint: disable=function-redefined def return_error(data): # type: ignore """ Return error as result and exit - filter 404 as non-errors """ if '404' in data or 'Reply does not contain results' in data: demisto.results( { 'Type': entryTypes['note'], 'ContentsFormat': formats['text'], 'Contents': data } ) else: demisto.results( { 'Type': entryTypes['error'], 'ContentsFormat': formats['text'], 'Contents': data } ) sys.exit(0) def validate_hash(hash_value): """ Validate that the given hash is valid and return the type """ type_dict = { 32: { 'type': 'md5', 'regex': r'([a-fA-F\d]{32})' }, 40: { 'type': 'sha1', 'regex': r'([a-fA-F\d]{40})' }, 64: { 'type': 'sha256', 'regex': r'([a-fA-F\d]{64})' } } if len(hash_value) not in type_dict.keys(): return_error('Provided input string length does not match any hash type') if not re.match(type_dict[len(hash_value)]['regex'], hash_value): return_error('Provided input string is not as hash due to containing invalid characters') return type_dict[len(hash_value)]['type'] def validate_http(r): """ Make sure that the HTTP response is valid and return relevant data if yes """ if 299 >= r.status_code >= 200: try: return True, r.json() except Exception as e: return False, 'HTTP response is not JSON [{error}] - {body}'.format(error=e, body=r.text) elif r.status_code in (401, 403): return False, 'Credential error - The provided A1000 credentials/token are either incorrect or lack ' \ 'API roles [{code}] - {body}'.format(code=r.status_code, body=r.text) elif r.status_code == 404: return False, 'No reference found - There were no results found for the provided input ' \ '[{code}] - {body}'.format(code=r.status_code, body=r.text) else: return False, 'An error has occurred [{code}] - {body}'.format( code=r.status_code, body=r.text ) def file(hash_type, hash_value): """ Get the summary data from A1000 with most of the fields except TICORE """ ok, r = validate_http(requests.post( url=BASE_URL + '/api/samples/list/', headers=HEADERS, data={ 'hash_values': hash_value, 'fields': A1000_FIELDS }, verify=VERIFY_CERT )) if not ok: return_error(r) results = r.get('results') if not results: return_error(no_reference_message) res = results[0] status = res['threat_status'] score = {'unknown': 0, 'known': 1, 'suspicious': 2, 'malicious': 3}[status] prop = status.title() file_data = { prop: { 'Vendor': 'ReversingLabs A1000', 'Status': status }, 'properties_to_append': prop } md = '## ReversingLabs A1000 reputation for: {}\n'.format(hash_value) ec = {'DBotScore': []} # type: ignore md5 = res.get('md5') sha1 = res.get('sha1') sha256 = res.get('sha256') sha512 = res.get('sha512') file_type = res.get('file_type') file_info = res.get('file_subtype') file_size = res.get('file_size') if md5: file_data['MD5'] = md5 md += 'MD5: **' + md5 + '**\n' ec['DBotScore'].append({'Indicator': md5, 'Type': 'hash', 'Vendor': 'ReversingLabs A1000', 'Score': score}) if sha1: file_data['SHA1'] = sha1 md += 'SHA1: **' + sha1 + '**\n' ec['DBotScore'].append({'Indicator': sha1, 'Type': 'hash', 'Vendor': 'ReversingLabs A1000', 'Score': score}) if sha256: file_data['SHA256'] = sha256 md += 'SHA256: **' + sha256 + '**\n' ec['DBotScore'].append({'Indicator': sha256, 'Type': 'hash', 'Vendor': 'ReversingLabs A1000', 'Score': score}) if sha512: file_data['SHA512'] = sha512 md += 'SHA512: **' + sha512 + '**\n' if file_type: file_data['Type'] = file_type if file_info: file_data['Info'] = file_info if file_size: file_data['Size'] = file_size ec[outputPaths['file']] = file_data # type: ignore md += 'ID: **{}**\n'.format(demisto.get(res, 'summary.id')) md += 'Malware status: **{}**\n'.format(status) md += 'Local first seen: **{}**\n'.format(res.get('local_first_seen')) md += 'Local last seen: **{}**\n'.format(res.get('local_last_seen')) md += 'First seen: **{}**\n'.format(demisto.gets(res, 'ticloud.first_seen')) md += 'Last seen: **{}**\n'.format(demisto.gets(res, 'ticloud.last_seen')) md += 'Trust factor: **{}**\n'.format(res.get('trust_factor')) if status == 'malicious': md += 'Threat name: **{}**\n'.format(res.get('threat_name')) md += 'Threat level: **{}**\n'.format(res.get('threat_level')) md += 'Category: **{}**\n'.format(res.get('category')) md += 'Classification origin: **{}**\n'.format(res.get('classification_origin')) md += 'Classification reason: **{}**\n'.format(res.get('classification_reason')) md += 'Aliases: **{}**\n'.format(','.join(res.get('aliases'))) md += 'Extracted file count: **{}**\n'.format(res.get('extracted_file_count')) md += 'File type: **{}/{}**\n'.format(file_type, file_info) md += 'File size: **{}**\n'.format(file_size) md += 'Identification name: **{}**\n'.format(res.get('identification_name')) md += 'Identification version: **{}**\n'.format(res.get('identification_version')) indicators = demisto.get(res, 'summary.indicators') if indicators: md += tableToMarkdown('Indicators', indicators) demisto.results({'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': r, 'EntryContext': ec, 'HumanReadable': md}) def extracted_files(): """ Get the list of extracted files for a given sample """ parent = demisto.getArg('hash') endpoint = '/api/samples/{}/extracted-files/'.format(parent) ok, r = validate_http( requests.get( url=BASE_URL + endpoint, headers=HEADERS, verify=VERIFY_CERT )) if not ok: return_error(r) results = r.get('results') if not results: return_error(no_reference_message) ec = {'DBotScore': []} # type: ignore file_list = [] file_context_list = [] for res in results: sha1 = demisto.get(res, 'sample.sha1') status = demisto.get(res, 'sample.threat_status') score = {'unknown': 0, 'known': 1, 'suspicious': 2, 'malicious': 3}[status] prop = status.title() file_data = { 'SHA1': sha1, 'Name': res.get('filename'), 'Info': demisto.get(res, 'sample.type_display'), 'Size': demisto.get(res, 'sample.file_size'), 'Path': res.get('path'), 'Local First': demisto.get(res, 'sample.local_first_seen'), 'Local Last': demisto.get(res, 'sample.local_last_seen'), 'Malware Status': status, 'Trust': demisto.get(res, 'sample.trust_factor'), 'Threat Name': demisto.get(res, 'sample.threat_name'), 'Threat Level': demisto.get(res, 'sample.threat_level') } file_context = { 'SHA1': sha1, 'Type': demisto.get(res, 'sample.file_type'), 'Name': res.get('filename'), 'Info': demisto.get(res, 'sample.type_display'), 'Size': demisto.get(res, 'sample.file_size'), prop: { 'Vendor': 'ReversingLabs A1000', 'Status': status }, 'properties_to_append': prop } file_list.append(file_data) file_context_list.append(file_context) ec['DBotScore'].append({'Indicator': sha1, 'Type': 'hash', 'Vendor': 'ReversingLabs A1000', 'Score': score}) md = tableToMarkdown('ReversingLabs A1000 extracted files for: {}\n'.format(parent), file_data, ['SHA1', 'Name', 'Path', 'Info', 'Size', 'Local First', 'Local Last', 'Malware Status', 'Trust', 'Threat Name', 'Threat Level']) ec[outputPaths['file']] = file_context_list demisto.results({'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': r, 'EntryContext': ec, 'HumanReadable': md}) def upload(): """ Upload a file to A1000 for analysis """ data = {} if demisto.getArg('comment'): data['comment'] = demisto.getArg('comment') if demisto.getArg('tags'): data['tags'] = demisto.getArg('tags') cloud = demisto.getArg('cloud_analyze') if cloud and cloud.lower() == 'true': data['analysis'] = 'cloud' try: file_entry = demisto.getFilePath(demisto.getArg('entryId')) data['filename'] = file_entry['name'] with open(file_entry['path'], 'rb') as f: ok, r = validate_http(requests.post( url=BASE_URL + '/api/uploads/', data=data, files={'file': f}, headers=HEADERS, verify=VERIFY_CERT )) if not ok: return_error(r) md = '## ReversingLabs A1000 file upload\n' md += 'Message: **{}**\n'.format(r.get('message')) md += 'ID: **{}**\n'.format(demisto.get(r, 'detail.id')) md += 'SHA1: **{}**\n'.format(demisto.get(r, 'detail.sha1')) md += 'Created: **{}**\n'.format(demisto.get(r, 'detail.created')) demisto.results( {'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': r, 'HumanReadable': md}) except Exception: return_error('Entry ID {} is not a file'.format(demisto.getArg('entryId'))) def delete_sample(): """ Delete a file from A1000 """ ok, r = validate_http(requests.delete( url=BASE_URL + '/api/samples/{}/'.format(demisto.getArg('hash')), headers=HEADERS, verify=VERIFY_CERT )) if not ok: return_error(r) res = r.get('results') if not res: return_error('Deleted successfully but got wrong JSON reply') md = '## ReversingLabs A1000 file delete\n' md += 'Message: **{}**\n'.format(res.get('message')) md += 'MD5: **{}**\n'.format(demisto.get(res, 'detail.md5')) md += 'SHA1: **{}**\n'.format(demisto.get(res, 'detail.sha1')) md += 'SHA256: **{}**\n'.format(demisto.get(res, 'detail.sha256')) demisto.results({'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': r, 'HumanReadable': md}) def download(): """ Download a sample from A1000 """ hash_value = demisto.getArg('hash') r = requests.get( url=BASE_URL + '/api/samples/{}/download/'.format(hash_value), headers=HEADERS, stream=True, verify=VERIFY_CERT ) if r.status_code < 200 or r.status_code > 299: return_error('Bad HTTP response [{code}] - {body}'.format(code=r.status_code, body=r.text)) filename = hash_value + '.bin' with open(filename, 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) demisto.results(file_result_existing_file(filename)) def reanalyze(): """ Re-Analyze a sample already existing on A1000 """ ok, r = validate_http(requests.post( url=BASE_URL + '/api/samples/{}/analyze/'.format(demisto.getArg('hash')), headers=HEADERS, data={'analysis': 'cloud'}, verify=VERIFY_CERT )) if not ok: return_error(r) md = '## ReversingLabs A1000 file re-analyze\n' md += 'Message: **{}**\n'.format(r.get('message')) md += 'MD5: **{}**\n'.format(demisto.get(r, 'detail.md5')) md += 'SHA1: **{}**\n'.format(demisto.get(r, 'detail.sha1')) md += 'SHA256: **{}**\n'.format(demisto.get(r, 'detail.sha256')) demisto.results({'Type': entryTypes['note'], 'ContentsFormat': formats['json'], 'Contents': r, 'HumanReadable': md}) def unpacked(): """ Download samples obtained through the unpacking process """ hash_value = demisto.getArg('hash') r = requests.get( url=BASE_URL + '/api/samples/{}/unpacked/'.format(hash_value), headers=HEADERS, stream=True, verify=VERIFY_CERT ) if r.status_code < 200 or r.status_code > 299: return_error('Bad HTTP response [{code}] - {body}'.format(code=r.status_code, body=r.text)) filename = hash_value + '.zip' with open(filename, 'wb') as f: r.raw.decode_content = True shutil.copyfileobj(r.raw, f) demisto.results(file_result_existing_file(filename)) if __name__ in ('__main__', '__builtin__', 'builtins'): if demisto.command() == 'test-module': ok, r = validate_http(requests.get( url=BASE_URL + '/api/samples/21841b32c6165b27dddbd4d6eb3a672defe54271/ticloud/', headers=HEADERS, verify=VERIFY_CERT )) if ok: demisto.results('ok') else: return_error(r) elif demisto.command() == 'file': hash_value = demisto.args()['file'] hash_type = validate_hash(hash_value) file(hash_type, hash_value) elif demisto.command() == 'reversinglabs-upload': upload() elif demisto.command() == 'reversinglabs-delete': delete_sample() elif demisto.command() == 'reversinglabs-extracted-files': extracted_files() elif demisto.command() == 'reversinglabs-download': download() elif demisto.command() == 'reversinglabs-analyze': reanalyze() elif demisto.command() == 'reversinglabs-download-unpacked': unpacked() else: return_error('Command [{}] not implemented'.format(demisto.command()))
