ReversingLabs TitaniumScale

ReversingLabs advanced file decomposition appliance.

Forensics & Malware Analysis · ReversingLabs TitaniumScale

Details

IDReversingLabs TitaniumScale
ProviderReversingLabs
CategoryForensics & Malware Analysis
From Version5.5.0
Docker Imagedemisto/reversinglabs-sdk-py3:2.0.0.10170191
Supported ModulesAgentix XSIAM

README

Overview

This integration supports using ReversingLabs Advanced File Analysis to ‘detonate file’ on the TitaniumScale Advanced Malware
Analysis Appliance.

The ReversingLabs TitaniumScale Appliance is powered by TitaniumCore, the malware analysis engine that performs
automated static analysis using the Active File Decomposition technology.

TitaniumCore unpacks and recursively analyzes files without executing them, and extracts internal threat indicators to
classify files and determine their threat level. TitaniumCore is capable of identifying thousands of file format
families. It recursively unpacks hundreds of file format families, and fully repairs extracted files to enable further
analysis.


Prerequisites

You need to obtain the following:

  • TitaniumScale instance
  • TitaniumScale API Token

Configure ReversingLabs TitaniumScale in Cortex

Parameter Required
ReversingLabs TitaniumScale instance URL True
API Token True
Verify host certificates False
Reliability False
Wait time between report fetching retries (seconds). Deafult is 2 seconds. False
Number of report fetching retries. Default is 30. False
HTTP proxy address with the protocol and port number False
HTTP proxy username False
HTTP proxy password False
HTTPS proxy address with the protocol and port number False
HTTPS proxy username False
HTTPS proxy password False

Commands

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

reversinglabs-titaniumscale-upload-sample-and-get-results


Upload sample to TitaniumScale and retrieve analysis report.

Base Command

reversinglabs-titaniumscale-upload-sample-and-get-results

Input

Argument Name Description Required
entryId The file entry to upload. Required
custom_token A custom token for filtering processing tasks. Optional
user_data User-defined data in the form of a JSON string. This data is NOT included in file analysis reports. Optional
custom_data User-defined data in the form of a JSON string. This data is included in file analysis reports. Optional

Context Output

Path Type Description
File.SHA256 String The SHA256 hash of the file.
File.SHA1 String The SHA1 hash of the file.
File.SHA512 String The SHA512 hash of the file.
File.Name String The name of the file.
File.EntryID String The Entry ID.
File.Info String Information about the file.
File.Type String The type of the file.
File.MD5 String MD5 hash of the file.
DBotScore.Score Number The actual score.
DBotScore.Type String The indicator type.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Vendor String The vendor used to calculate the score.
ReversingLabs.tc_report String Full report.

Command example

!reversinglabs-titaniumscale-upload-sample-and-get-results entryId="371@b26c8c3a-8d0e-459f-8f2c-c0b8783a8422" custom_token="a-custom-token"

Context Example

{
    "DBotScore": {
        "Indicator": "0000a0a381d31e0dafcaa22343d2d7e40ff76e06",
        "Reliability": "C - Fairly reliable",
        "Score": 3,
        "Type": "file",
        "Vendor": "ReversingLabs TitaniumScale"
    },
    "File": {
        "Hashes": [
            {
                "type": "MD5",
                "value": "a984de0ce47a8d5337ef569c812b57d0"
            },
            {
                "type": "SHA1",
                "value": "0000a0a381d31e0dafcaa22343d2d7e40ff76e06"
            },
            {
                "type": "SHA256",
                "value": "b25e707a78a472d92a99b08be5d0e55072f695275a7408d1e841a5344ca85dc3"
            }
        ],
        "MD5": "a984de0ce47a8d5337ef569c812b57d0",
        "Malicious": {
            "Description": "\n **Antivirus (based on the RCA Classify):** Win32.Downloader.Unruy",
            "Vendor": "ReversingLabs TitaniumScale"
        },
        "SHA1": "0000a0a381d31e0dafcaa22343d2d7e40ff76e06",
        "SHA256": "b25e707a78a472d92a99b08be5d0e55072f695275a7408d1e841a5344ca85dc3"
    },
    "InfoFile": {
        "EntryID": "398@b26c8c3a-8d0e-459f-8f2c-c0b8783a8422",
        "Info": "text/plain",
        "Name": "Full report in JSON",
        "Size": 19763,
        "Type": "ASCII text"
    },
    "ReversingLabs": {
        "tc_report": [
            {
                "classification": {
                    "classification": 3,
                    "factor": 3,
                    "propagated": false,
                    "rca_factor": 8,
                    "result": "Win32.Downloader.Unruy",
                    "scan_results": [
                        {
                            "classification": 3,
                            "factor": 3,
                            "ignored": false,
                            "name": "Antivirus (based on the RCA Classify)",
                            "rca_factor": 8,
                            "result": "Win32.Downloader.Unruy",
                            "type": "av",
                            "version": "2.91"
                        },
                        {
                            "classification": 3,
                            "factor": 3,
                            "ignored": false,
                            "name": "TitaniumCore RHA1",
                            "rca_factor": 8,
                            "result": "Win32.Downloader.Unruy",
                            "type": "internal",
                            "version": "5.0.1.26"
                        },
                        {
                            "classification": 3,
                            "factor": 1,
                            "ignored": false,
                            "name": "TitaniumCore Machine Learning",
                            "rca_factor": 6,
                            "result": "Win32.Malware.Heuristic",
                            "type": "internal",
                            "version": "5.0.1.26"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "drweb",
                            "rca_factor": 0,
                            "result": "Win32.HLLC.Asdas.7",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "vba32",
                            "rca_factor": 0,
                            "result": "SScope.TrojanInjector.MY",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "endgame",
                            "rca_factor": 0,
                            "result": "malicious (high confidence)",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "ahnlab",
                            "rca_factor": 0,
                            "result": "Trojan/Win32.Kazy.R3559",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "antivir",
                            "rca_factor": 0,
                            "result": "detected",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "avast",
                            "rca_factor": 0,
                            "result": "Win32:Unruy-Z [Trj]",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "bitdefender",
                            "rca_factor": 0,
                            "result": "Gen:Trojan.ProcessHijack.cqX@aaG5Soe",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "carbonblack",
                            "rca_factor": 0,
                            "result": "trojan",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "clamav",
                            "rca_factor": 0,
                            "result": "Win.Trojan.Powp-13",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "crowdstrike",
                            "rca_factor": 0,
                            "result": "win/malicious_confidence_100",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "mcafee_online",
                            "rca_factor": 0,
                            "result": "Downloader-CIS.c (trojan)",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "ffri",
                            "rca_factor": 0,
                            "result": "Detected",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "fireeye_online",
                            "rca_factor": 0,
                            "result": "Generic.mg.a984de0ce47a8d53",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "fortinet",
                            "rca_factor": 0,
                            "result": "W32/Powp.gen!tr",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "gdata",
                            "rca_factor": 0,
                            "result": "Gen:Trojan.ProcessHijack.cqX@aaG5Soe",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "ikarus",
                            "rca_factor": 0,
                            "result": "Trojan.Injector",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "k7computing",
                            "rca_factor": 0,
                            "result": "Riskware (0040eff71)",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "malwarebytes",
                            "rca_factor": 0,
                            "result": "Malware.AI.4098645872",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "mcafeegwedition_online",
                            "rca_factor": 0,
                            "result": "BehavesLike.Win32.VirRansom.pc",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "varist",
                            "rca_factor": 0,
                            "result": "W32/CeeInject.L.gen!Eldorado",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "mcafee_beta",
                            "rca_factor": 0,
                            "result": "Downloader-CIS.c (trojan)",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "sentinelone_online",
                            "rca_factor": 0,
                            "result": "DFI - Malicious PE",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "ahnlab_online",
                            "rca_factor": 0,
                            "result": "Trojan/Win32.Kazy.R3559",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "microsoft",
                            "rca_factor": 0,
                            "result": "TrojanDownloader:Win32/Unruy.H",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "microsoft_online",
                            "rca_factor": 0,
                            "result": "TrojanDownloader:Win32/Unruy.H",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "panda",
                            "rca_factor": 0,
                            "result": "Generic Suspicious",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "panda_online",
                            "rca_factor": 0,
                            "result": "Generic Malware",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "quickheal",
                            "rca_factor": 0,
                            "result": "VirTool.CeeInject.G",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "rising",
                            "rca_factor": 0,
                            "result": "Downloader.Unruy!1.679D",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "rising_online",
                            "rca_factor": 0,
                            "result": "Downloader.Unruy!1.679D",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "sonicwall",
                            "rca_factor": 0,
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "sophos_susi",
                            "rca_factor": 0,
                            "result": "Mal/EncPk-ZC",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "symantec",
                            "rca_factor": 0,
                            "result": "Trojan.Gen",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "symantec_beta",
                            "rca_factor": 0,
                            "result": "Trojan.Gen",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "symantec_online",
                            "rca_factor": 0,
                            "result": "Trojan.Gen",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "trendmicro",
                            "rca_factor": 0,
                            "result": "TROJ_UNRUY.SMJF",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "trendmicro_consumer",
                            "rca_factor": 0,
                            "result": "TROJ_UNRUY.SMJF",
                            "type": "av"
                        },
                        {
                            "classification": 0,
                            "factor": 0,
                            "ignored": false,
                            "name": "mcafee",
                            "rca_factor": 0,
                            "result": "Downloader-CIS.c (trojan)",
                            "type": "av"
                        },
                        {
                            "classification": 3,
                            "factor": 2,
                            "ignored": false,
                            "name": "Next-Generation Antivirus",
                            "rca_factor": 7,
                            "result": "Win32.Malware.Heuristic",
                            "type": "ng_av",
                            "version": "1.0"
                        }
                    ]
                },
                "index": 0,
                "indicators": [
                    {
                        "category": 4,
                        "description": "Allocates additional memory in the calling process.",
                        "id": 17985,
                        "priority": 3,
                        "reasons": [
                            {
                                "category": "Imported API Name",
                                "description": "Imports the following function: HeapAlloc",
                                "propagated": false
                            }
                        ],
                        "relevance": 0
                    },
                    {
                        "category": 10,
                        "description": "Loads additional libraries.",
                        "id": 69,
                        "priority": 2,
                        "reasons": [
                            {
                                "category": "Imported API Name",
                                "description": "Imports the following function: LoadLibraryA",
                                "propagated": false
                            }
                        ],
                        "relevance": 1
                    },
                    {
                        "category": 10,
                        "description": "Loads additional APIs.",
                        "id": 70,
                        "priority": 2,
                        "reasons": [
                            {
                                "category": "Imported API Name",
                                "description": "Imports the following function: GetProcAddress",
                                "propagated": false
                            },
                            {
                                "category": "Indicator Match",
                                "description": "Matched another indicator that describes the following: Loads additional libraries.",
                                "propagated": false
                            }
                        ],
                        "relevance": 0
                    },
                    {
                        "category": 16,
                        "description": "Uses string related methods.",
                        "id": 18050,
                        "priority": 1,
                        "reasons": [
                            {
                                "category": "Imported API Name",
                                "description": "Imports the following function: lstrcatA",
                                "propagated": false
                            }
                        ],
                        "relevance": 0
                    }
                ],
                "info": {
                    "file": {
                        "entropy": 7.222407502197507,
                        "file_name": "b26c8c3a-8d0e-459f-8f2c-c0b8783a8422_371@b26c8c3a-8d0e-459f-8f2c-c0b8783a8422",
                        "file_path": "b26c8c3a-8d0e-459f-8f2c-c0b8783a8422_371@b26c8c3a-8d0e-459f-8f2c-c0b8783a8422",
                        "file_subtype": "Exe",
                        "file_type": "PE",
                        "hashes": [
                            {
                                "name": "imphash",
                                "value": "054e4e5c28d6533b44ae24cbf3e08a15"
                            },
                            {
                                "name": "md5",
                                "value": "a984de0ce47a8d5337ef569c812b57d0"
                            },
                            {
                                "name": "rha0",
                                "value": "6e60e6783d0e5104dab2311c93d6f9b42cebbf03"
                            },
                            {
                                "name": "sha1",
                                "value": "0000a0a381d31e0dafcaa22343d2d7e40ff76e06"
                            },
                            {
                                "name": "sha256",
                                "value": "b25e707a78a472d92a99b08be5d0e55072f695275a7408d1e841a5344ca85dc3"
                            }
                        ],
                        "size": 42544
                    }
                },
                "metadata": {
                    "application": {
                        "capabilities": 4255756
                    }
                }
            }
        ]
    }
}

Human Readable Output

ReversingLabs TitaniumScale upload sample and get results

Type: PE/Exe
Size: 42544 bytes

IMPHASH: 054e4e5c28d6533b44ae24cbf3e08a15
MD5: a984de0ce47a8d5337ef569c812b57d0
RHA0: 6e60e6783d0e5104dab2311c93d6f9b42cebbf03
SHA1: 0000a0a381d31e0dafcaa22343d2d7e40ff76e06
SHA256: b25e707a78a472d92a99b08be5d0e55072f695275a7408d1e841a5344ca85dc3

Status: malicious
Antivirus (based on the RCA Classify): Win32.Downloader.Unruy
DBot score: 3

reversinglabs-titaniumscale-upload-sample


Upload sample to TitaniumScale for analysis.

Base Command

reversinglabs-titaniumscale-upload-sample

Input

Argument Name Description Required
entryId The file entry to upload. Required
custom_token A custom token for filtering processing tasks. Optional
user_data User-defined data in the form of a JSON string. This data is NOT included in file analysis reports. Optional
custom_data User-defined data in the form of a JSON string. This data is included in file analysis reports. Optional

Context Output

Path Type Description
ReversingLabs.task_Url Unknown url to get report from.

Command example

!reversinglabs-titaniumscale-upload-sample entryId="371@b26c8c3a-8d0e-459f-8f2c-c0b8783a8422" custom_token="a-custom-token"

Context Example

{
    "InfoFile": {
        "EntryID": "403@b26c8c3a-8d0e-459f-8f2c-c0b8783a8422",
        "Info": "text/plain",
        "Name": "Full report in JSON",
        "Size": 95,
        "Type": "ASCII text"
    },
    "ReversingLabs": {
        "tc_task_url": "https://tiscale-worker-integrations-demo-01.rl.lan/api/tiscale/v1/task/42"
    }
}

Human Readable Output

ReversingLabs TitaniumScale upload sample

Titanium Scale task URL: https://tiscale-worker-integrations-demo-01.rl.lan/api/tiscale/v1/task/42

reversinglabs-titaniumscale-get-results


Retrieve report of a previously uploaded file from TitaniumScale.

Base Command

reversinglabs-titaniumscale-get-results

Input

Argument Name Description Required
taskUrl The file entry to upload. Required

Context Output

Path Type Description
File.SHA256 String The SHA256 hash of the file.
File.SHA1 String The SHA1 hash of the file.
File.SHA512 String The SHA512 hash of the file.
File.Name String The name of the file.
File.EntryID String The Entry ID.
File.Info String Information about the file.
File.Type String The type of the file.
File.MD5 String MD5 hash of the file.
DBotScore.Score Number The actual score.
DBotScore.Type String The indicator type.
DBotScore.Indicator String The indicator that was tested.
DBotScore.Vendor String The vendor used to calculate the score.
ReversingLabs.tc_report String Full report.

reversinglabs-titaniumscale-list-processing-tasks


List active processing tasks.

Base Command

reversinglabs-titaniumscale-list-processing-tasks

Input

Argument Name Description Required
age Task age in seconds. Optional
custom_token A custom token for filtering processing tasks. Optional

Context Output

Path Type Description
ReversingLabs.list_processing_tasks Unknown Processing tasks.

Command example

!reversinglabs-titaniumscale-list-processing-tasks age="60" custom_token="a-custom-token"

Context Example

{
    "ReversingLabs": {
        "list_processing_tasks": []
    }
}

Human Readable Output

ReversingLabs TitaniumScale List processing tasks

Processing tasks

No entries.

reversinglabs-titaniumscale-get-processing-task-info


Retrieves information about a completed file processing task.

Base Command

reversinglabs-titaniumscale-get-processing-task-info

Input

Argument Name Description Required
task_id Task ID. Required

Context Output

Path Type Description
ReversingLabs.tc_report Unknown Full report.

reversinglabs-titaniumscale-delete-processing-task


Deletes a processing task.

Base Command

reversinglabs-titaniumscale-delete-processing-task

Input

Argument Name Description Required
task_id Task ID. Required

Context Output

There is no context output for this command.

Command example

!reversinglabs-titaniumscale-delete-processing-task task_id="100"

Human Readable Output

ReversingLabs TitaniumScale delete processing task

Task 100 deleted successfully.

reversinglabs-titaniumscale-delete-multiple-tasks


Deletes multiple processing tasks.

Base Command

reversinglabs-titaniumscale-delete-multiple-tasks

Input

Argument Name Description Required
age Task age in seconds. Required

Context Output

There is no context output for this command.

Command example

!reversinglabs-titaniumscale-delete-multiple-tasks age="20"

Human Readable Output

ReversingLabs TitaniumScale delete multiple tasks

Tasks of age 20 seconds or less deleted successfully.

reversinglabs-titaniumscale-get-yara-id


Retrieves the identifier of the current set of YARA rules on the TitaniumScale Worker instance.

Base Command

reversinglabs-titaniumscale-get-yara-id

Input

There are no input arguments for this command.

Context Output

Path Type Description
ReversingLabs.yara_id Unknown Identifier of the current set of YARA rules on the TitaniumScale Worker instance.

Command example


#### Context Example

```json
{
    "ReversingLabs": {
        "yara_id": {
            "id": "f0a151ce303ae9b9e46b236492ac9196f3f72490"
        }
    }
}

Human Readable Output

ReversingLabs TitaniumScale YARA ruleset ID

ID: f0a151ce303ae9b9e46b236492ac9196f3f72490

Configuration parameters

  • host — ReversingLabs TitaniumScale instance URL (required)
  • token — API Token (required)
  • verify — Verify host certificates
  • reliability — Reliability
  • wait_time_seconds — Wait time between report fetching retries (seconds). Deafult is 2 seconds.
  • num_of_retries — Number of report fetching retries. Default is 30.
  • http_proxy — HTTP proxy address with the protocol and port number
  • http_credentials — HTTP proxy username
  • https_proxy — HTTPS proxy address with the protocol and port number
  • https_credentials — HTTPS proxy username

Commands (8)

  • reversinglabs-titaniumscale-delete-multiple-tasks

    Deletes multiple processing tasks.

  • reversinglabs-titaniumscale-delete-processing-task

    Deletes a processing task.

  • reversinglabs-titaniumscale-get-processing-task-info

    Retrieves information about a completed file processing task.

  • reversinglabs-titaniumscale-get-results

    Retrieve report of a previously uploaded file from TitaniumScale.

  • reversinglabs-titaniumscale-get-yara-id

    Retrieves the identifier of the current set of YARA rules on the TitaniumScale Worker instance.

  • reversinglabs-titaniumscale-list-processing-tasks

    List active processing tasks.

  • reversinglabs-titaniumscale-upload-sample

    Upload sample to TitaniumScale for analysis.

  • reversinglabs-titaniumscale-upload-sample-and-get-results

    Upload sample to TitaniumScale and retrieve analysis report.

import json

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401
from ReversingLabs.SDK.tiscale import TitaniumScale

# pragma: no cover

VERSION = "v1.2.0"
USER_AGENT = f"ReversingLabs XSOAR TitaniumScale {VERSION}"
HOST = demisto.params().get("host")
TOKEN = demisto.params().get("token")
VERIFY_CERT = demisto.params().get("verify")
RELIABILITY = demisto.params().get("reliability", "C - Fairly reliable")
WAIT_TIME_SECONDS = demisto.params().get("wait_time_seconds")
NUM_OF_RETRIES = demisto.params().get("num_of_retries")

HTTP_PROXY = demisto.params().get("http_proxy", None)
HTTP_PROXY_USERNAME = demisto.params().get("http_credentials", {}).get("identifier", None)
HTTP_PROXY_PASSWORD = demisto.params().get("http_credentials", {}).get("password", None)

HTTPS_PROXY = demisto.params().get("https_proxy", None)
HTTPS_PROXY_USERNAME = demisto.params().get("https_credentials", {}).get("identifier", None)
HTTPS_PROXY_PASSWORD = demisto.params().get("https_credentials", {}).get("password", None)


def format_proxy(addr, username=None, password=None):
    protocol = ""
    proxy_name = ""
    if addr.startswith("http://"):
        protocol = addr[:7]
        proxy_name = addr[7:]
    elif addr.startswith("https://"):
        protocol = addr[:8]
        proxy_name = addr[8:]
    else:
        return_error("Proxy address needs to start with either 'http://' or 'https://'")

    if username:
        if password:
            proxy = f"{protocol}{username}:{password}@{proxy_name}"
        else:
            proxy = f"{protocol}{username}@{proxy_name}"
    else:
        proxy = f"{protocol}{proxy_name}"

    return proxy


def return_proxies():
    proxies = {}

    if HTTP_PROXY:
        http_proxy = format_proxy(addr=HTTP_PROXY, username=HTTP_PROXY_USERNAME, password=HTTP_PROXY_PASSWORD)

        proxies["http"] = http_proxy

    if HTTPS_PROXY:
        https_proxy = format_proxy(addr=HTTPS_PROXY, username=HTTPS_PROXY_USERNAME, password=HTTPS_PROXY_PASSWORD)

        proxies["https"] = https_proxy

    if proxies:
        return proxies
    else:
        return None


def classification_to_score(classification):
    score_dict = {"UNKNOWN": 0, "KNOWN": 1, "SUSPICIOUS": 2, "MALICIOUS": 3}
    return score_dict.get(classification, 0)


def test(tiscale):
    """
    Test credentials and connectivity
    """
    try:
        tiscale.test_connection()
        return "ok"
    except Exception as e:
        return_error(str(e))


def get_status_from_classification(classification_int):
    status_mapping = {3: "malicious", 2: "suspicious", 1: "known"}

    return status_mapping.get(classification_int, "unknown")


def parse_upload_report_and_return_results(response_json):
    task_url = response_json.get("task_url")
    md = f"## ReversingLabs TitaniumScale upload sample\n **Titanium Scale task URL**: {task_url}"

    command_result = CommandResults(
        outputs_prefix="ReversingLabs",
        outputs={"tc_task_url": task_url},
        readable_output=md,
    )

    return command_result


def upload_file(tiscale: TitaniumScale):
    """
    Upload a file and return task url
    """
    try:
        file_entry = demisto.getFilePath(demisto.getArg("entryId"))
        custom_token = demisto.getArg("custom_token")
        user_data = demisto.getArg("user_data")
        custom_data = demisto.getArg("custom_data")

        with open(file_entry["path"], "rb") as file:
            response_json = tiscale.upload_sample_from_file(
                file_source=file, custom_token=custom_token, user_data=user_data, custom_data=custom_data
            ).json()
    except Exception as e:
        return_error(str(e))

    command_result = parse_upload_report_and_return_results(response_json)

    file_result = fileResult("Full report in JSON", json.dumps(response_json, indent=4), file_type=EntryType.ENTRY_INFO_FILE)

    return [command_result, file_result]


def parse_report_and_return_results(title, response_json):
    """
    Parse the report, return human-readable info, and the whole report as a file
    """
    md = title
    tc_report = response_json.get("tc_report")
    if tc_report:
        info = tc_report[0].get("info")
        if info:
            file = info.get("file")
            if file:
                file_type = file.get("file_type")
                file_subtype = file.get("file_subtype")
                file_size = file.get("size")
                md += f"""\n **Type:** {file_type}/{file_subtype}
                             **Size:** {file_size} bytes \n"""

                for h in file.get("hashes"):
                    name = h.get("name").upper()
                    value = h.get("value")

                    md += f"\n **{name}:** {value}"

        classification_obj = tc_report[0].get("classification")
        if classification_obj.get("scan_results"):
            scan_result = classification_obj.get("scan_results")[0]
            if "classification" in scan_result:
                classification = scan_result.get("classification")
                status = get_status_from_classification(classification)
                md += f"\n\n **Status:** {status}"

                name = scan_result.get("name")
                result = scan_result.get("result")

                desc = ""
                if result:
                    desc = f"\n **{name}:** {result}"
                    md += desc

                d_bot_score = classification_to_score(status.upper())

                md += f"\n **DBot score:** {d_bot_score}\n"

                if "indicators" in tc_report:
                    md += tableToMarkdown("Indicators", tc_report.get("indicators"))

                dbot_score = Common.DBotScore(
                    indicator=list(filter(lambda elem: elem.get("name") == "sha1", file.get("hashes")))[0].get("value"),
                    indicator_type=DBotScoreType.FILE,
                    integration_name="ReversingLabs TitaniumScale",
                    score=d_bot_score,
                    malicious_description=desc,
                    reliability=RELIABILITY,
                )

                common_file = Common.File(
                    md5=list(filter(lambda elem: elem.get("name") == "md5", file.get("hashes")))[0].get("value"),
                    sha1=list(filter(lambda elem: elem.get("name") == "sha1", file.get("hashes")))[0].get("value"),
                    sha256=list(filter(lambda elem: elem.get("name") == "sha256", file.get("hashes")))[0].get("value"),
                    dbot_score=dbot_score,
                )

                command_result = CommandResults(
                    outputs_prefix="ReversingLabs", outputs={"tc_report": tc_report}, readable_output=md, indicator=common_file
                )

                return command_result

            else:
                return_error("Scan result does not contain classifications")
                return None
        else:
            return_error("Report does not contain scan results")
            return None
    else:
        return_error("Response does not contain report")
        return None


def get_report(tiscale):
    """
    Get report by the task url
    """
    try:
        task_url = demisto.getArg("taskUrl")
        response = tiscale.get_results(task_url)
        if not response:
            raise Exception("No report could be obtained or maximum number of retries was exceeded.")
        response_json = response.json()
    except Exception as e:
        return_error(str(e))

    command_result = parse_report_and_return_results(
        title="## ReversingLabs TitaniumScale get results\n", response_json=response_json
    )

    file_result = fileResult("Full report in JSON", json.dumps(response_json, indent=4), file_type=EntryType.ENTRY_INFO_FILE)

    return [command_result, file_result]


def upload_file_and_get_results(tiscale: TitaniumScale):
    """
    Upload a file and get report
    """
    try:
        file_entry = demisto.getFilePath(demisto.getArg("entryId"))
        custom_token = demisto.getArg("custom_token")
        user_data = demisto.getArg("user_data")
        custom_data = demisto.getArg("custom_data")

        with open(file_entry["path"], "rb") as f:
            response_json = tiscale.upload_sample_and_get_results(
                file_source=f, custom_token=custom_token, user_data=user_data, custom_data=custom_data
            ).json()
    except Exception as e:
        return_error(str(e))

    command_result = parse_report_and_return_results(
        title="## ReversingLabs TitaniumScale upload sample and get results\n", response_json=response_json
    )

    file_result = fileResult("Full report in JSON", json.dumps(response_json, indent=4), file_type=EntryType.ENTRY_INFO_FILE)

    return [command_result, file_result]


def list_processing_tasks_command(tiscale: TitaniumScale):
    age = demisto.getArg("age")
    if age:
        age = int(age)
    custom_token = demisto.getArg("custom_token")

    try:
        resp = tiscale.list_processing_tasks(age=age, custom_token=custom_token)
    except Exception as e:
        if hasattr(e, "response_object"):
            return_error(e.response_object.text)  # type: ignore[attr-defined]
        else:
            raise

    results = list_processing_tasks_output(resp_json=resp.json())
    return results


def list_processing_tasks_output(resp_json):
    task_table = tableToMarkdown("Processing tasks", resp_json)

    markdown = f"""## ReversingLabs TitaniumScale List processing tasks\n {task_table}"""

    results = CommandResults(
        outputs_prefix="ReversingLabs", outputs={"list_processing_tasks": resp_json}, readable_output=markdown
    )

    return results


def get_processing_task_info_command(tiscale: TitaniumScale):
    task_id = int(demisto.getArg("task_id"))

    try:
        resp = tiscale.get_processing_task_info(task_id=task_id, full=False)
    except Exception as e:
        if hasattr(e, "response_object"):
            return_error(e.response_object.text)  # type: ignore[attr-defined]
        else:
            raise

    command_result = parse_report_and_return_results(
        title="## ReversingLabs TitaniumScale get processing task info\n", response_json=resp.json()
    )

    file_result = fileResult("Full report in JSON", json.dumps(resp.json(), indent=4), file_type=EntryType.ENTRY_INFO_FILE)

    return [command_result, file_result]


def delete_processing_task_command(tiscale: TitaniumScale):
    task_id = int(demisto.getArg("task_id"))

    try:
        tiscale.delete_processing_task(task_id=task_id)
    except Exception as e:
        if hasattr(e, "response_object"):
            return_error(e.response_object.text)  # type: ignore[attr-defined]
        else:
            raise

    results = CommandResults(
        readable_output=f"""## ReversingLabs TitaniumScale delete processing task\n Task {task_id} deleted successfully."""
    )

    return results


def delete_multiple_tasks_command(tiscale: TitaniumScale):
    age = int(demisto.getArg("age"))

    try:
        tiscale.delete_multiple_tasks(age=age)
    except Exception as e:
        if hasattr(e, "response_object"):
            return_error(e.response_object.text)  # type: ignore[attr-defined]
        else:
            raise

    results = CommandResults(
        readable_output=f"## ReversingLabs TitaniumScale delete multiple tasks\n Tasks "
        f"of age {age} seconds or less deleted successfully."
    )

    return results


def get_yara_id_command(tiscale: TitaniumScale):
    try:
        resp = tiscale.get_yara_id()
    except Exception as e:
        if hasattr(e, "response_object"):
            return_error(e.response_object.text)  # type: ignore[attr-defined]
        else:
            raise

    results = get_yara_id_output(resp_json=resp.json())
    return results


def get_yara_id_output(resp_json):
    markdown = f"""## ReversingLabs TitaniumScale YARA ruleset ID\n **ID**: {resp_json.get("id")}"""

    results = CommandResults(outputs_prefix="ReversingLabs", outputs={"yara_id": resp_json}, readable_output=markdown)

    return results


def main():
    try:
        wait_time_seconds = int(WAIT_TIME_SECONDS)
    except ValueError:
        return_error("Integration parameter <Wait between retries> has to be of type integer.")

    try:
        num_of_retries = int(NUM_OF_RETRIES)
    except ValueError:
        return_error("Integration parameter <Number of retries> has to be of type integer.")

    proxies = return_proxies()

    tiscale = TitaniumScale(
        host=HOST,
        token=TOKEN,
        verify=VERIFY_CERT,
        user_agent=USER_AGENT,
        wait_time_seconds=wait_time_seconds,
        retries=num_of_retries,
        proxies=proxies,
    )

    demisto.info(f"Command being called is {demisto.command()}")

    try:
        if demisto.command() == "test-module":
            return_results(test(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-upload-sample-and-get-results":
            return_results(upload_file_and_get_results(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-upload-sample":
            return_results(upload_file(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-get-results":
            return_results(get_report(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-list-processing-tasks":
            return_results(list_processing_tasks_command(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-get-processing-task-info":
            return_results(get_processing_task_info_command(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-delete-processing-task":
            return_results(delete_processing_task_command(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-delete-multiple-tasks":
            return_results(delete_multiple_tasks_command(tiscale))
        elif demisto.command() == "reversinglabs-titaniumscale-get-yara-id":
            return_results(get_yara_id_command(tiscale))
        else:
            return_error(f"Command [{demisto.command()}] not implemented")
    except Exception as e:
        return_error(f"Failed to execute {demisto.command()} command. Error: {e!s}")


if __name__ in ("__main__", "__builtin__", "builtins"):
    main()