How to Create Easy and Open Integrations with VMRay’s REST API

Jan 14th 2020

With the recent release of VMRay Analyzer Version 3.2, we have repackaged and enhanced our already robust REST API. These enhancements add more automation and scalability to malware analysis, detection, and result-sharing across heterogeneous environments.

VMRay’s portfolio of out-of-the-box integrations and connectors built with our REST API, enables partners to leverage selected aspects of VMRay’s analysis and detection results for focused use cases, such as endpoint protection, security operations (SOAR) and big data (e.g., SIEM).

However, there’s wider utility and value to be gained in custom integrations. A key reason is that virtually all the features and functions of VMRay Analyzer are mapped to our REST API, something few, if any, other solutions can match. As a result, security teams can leverage highly accurate and noise-free results to consistently enhance the security profile of multiple legacy systems and diverse security tools across the enterprise.

Here’s how to get started:

 

Accessing REST API documentation & VMRay WEB UI

VMRay Analyzer v3.2 includes comprehensive documentation on using the VMRay REST API Package for Python to build custom integrations. The documentation is available in HTML and PDF formats. There’s also a downloadable Zip archive, which contains a Python library and examples.

 

VMRay - REST API Documentation

Figure 1: VMRay Customers can access the REST API Documentation in the “Documentation” section in their account

 

In addition, the highly intuitive web interface for VMRay Analyzer is a great visual reference when building custom integrations. Designed for SOC analysts and DFIR teams doing in-depth analysis and investigation, the web UI encompasses all the features, functionality and data that can be automated via the REST API. We have included some representative screen grabs in this post.

 

Setting up the REST API client

The setup is slightly different for cloud customers vs. on-premises deployments. With VMRay’s cloud service, the administrator will need the customer organization’s API Key to import the VMRay REST API, as shown below.

from rest_api import VMRayRESTAPI

server = "cloud.vmray.com"
api_key = ""

api_client = VMRayRESTAPI(server=server, api_key=api_key)

Figure 2: Importing VMRay REST API to set up the API client

As mentioned in our recent blog post, VMRay Analyzer Version v3.2, we’ve enhanced support for multiple API keys, enabling each key to have different settings and quotas. This gives security organizations more flexibility in defining how a given API key will be used to achieve the right balance between performance and analysis depth. Available settings include the ability to pre-filter known malicious or benign samples, limit the number of dynamic analyses per sample, and limit the number of samples that can be submitted recursively.

 

Defining how samples are submitted & results are accessed

Once the API client is set up, you’re ready to define how samples are submitted for analysis and results are accessed so they can be shared with other systems. Throughout, you’ll use variations of the same basic format:

 

Endpoint Action
/rest/sample/submit endpoint to submit a sample
/rest/submission endpoint to check whether the analysis of the sample has been completed
/rest/sample endpoint to retrieve high-level results: the sample’s severity score and VMRay Threat Indicator (VTI) scores
/rest/analysis endpoint to retrieve the full analysis results

 

Submitting a sample

In this example, we’re creating a submission for a suspect file (‘Sample.exe’)—that will be sent to the VMRay cloud for analysis. The file—which is locally available—is opened, and parameters are applied for how it will be analyzed.

with open('Sample.exe', 'rb') as f_obj:
    params = {
        "reanalyze": False,
        "sample_file": f_obj
        }

    response = api_client.call("POST", "/rest/sample/submit", params=params)

error = response["errors"]
jobs = response["jobs"]
submissions = response["submissions"]
samples = response["samples"]

 

Figure 3: Creating a submission and receiving a response

For example, “reanalyze” applies if the sample was previously seen and analyzed in the customer’s environment. It is currently set at False, indicating the sample would not be reanalyzed; a True setting would trigger a reanalysis. Responses contain information about errors, jobs, submissions and samples.

Once the file is submitted, a job is created and a response is returned. It includes a unique identifier (submission_id) which is tied to the submission and can be used to query the analysis results.

 

Checking whether the analysis is complete

For submissions that only require reputation and static analysis, results may be returned in seconds, ready to be shared with other systems. When the dynamic analysis is also required, the wait may be longer.

By including the submission identifier in the format, the API can query at regular intervals to determine at the earliest moment when the analysis is finished and the results are available to be shared.

submission_id = submissions[0]["submission_id"]
data = api_client.call("GET", "/rest/submission/{}".format(submission_id))
 if data["submission_finished"]: 
     do_work()

 

Figure 4: “Are we there yet?” Automatically checking if the analysis is complete
 

 

Getting top-level analysis results

Many automation use cases (email, for example) only require access to top-level analysis results. With VMRay custom integrations, this takes the form of a sample severity score—a score of 0/100 or above would be rated Malicious—plus VMRay Threat Identifier (VTI) scores detected during the analysis. The many types of VTIs include Defense Evasion, Hide Tracks, Network Connection, Persistence, and so on. This top-level “verdict” data can be accessed using the /rest/sample/endpoint format and the sample identifier, as shown here.

sample_id = samples[0]['sample_id']
sample = api_client.call("GET", "/rest/sample/{}".format(sample_id))

sample_severity = sample["sample_severity"]
sample_vti_score = sample["sample_vti_score"]

 

Figure 5: In many use cases, top-level analysis results are all that’s needed
Everything that is shown on the Sample Overview page of the web interface (Figure 6) will also be available via the “sample” API endpoint.

 

Figure 5: Results, displayed in the web UI - VMRay REST API

Figure 6: Top-level analysis results, displayed in the web UI

 

Note that for anyone submission, VMRay Analyzer will go beyond these top-level results and generate one or more in-depth analyses, with each analysis being assigned an identifier. Figure 6 shows that three analyses were created for this submission, scrutinizing the sample’s impact on three different environments: Windows 7/64-bit, Windows 7/32-bit and Windows 10/64-bit with MS Office. For illustrative purposes, we’ll only be drilling down on the first analysis.

 

Gaining deeper insight

In more complex scenarios, like DFIR and threat hunting, high-level detection results are not enough. Access to the most relevant, in-depth analysis results returned by VMRay will also be required. Access can be automated using the format/rest/analysis/endpoint including submission_id and analysis_id, per below.

analyses = api_client.call("GET", "/rest/analysis/submission/{}".format(submission_id))
analysis_id = analyses[0]["analysis_id"]

summary = api_client.call("GET", "/rest/analysis/{}/archive/logs%2fsummary.json".format(analysis_id), raw_data=True)
summary_dict = json.loads(summary.read())

 

Figure 7: Accessing in-depth results for one analysis
The full results are captured as structured data in a Summary .json file to facilitate standardized data exchange (Figure 7). Note

 

{
  "analysis_details": {
    "cmdline_parameters": null,
    "creation_time": "2020-01-07 08:39 (UTC+1)",
    "execution_successful": true,
    "job_id": 1010139,
    "local_av_enabled": true,
    "number_of_processes": 4,
    "prescript_filename": null,
    "reputation_enabled": true,
    "result_code": 1,
    "result_str": "Operation completed successfully",
    "termination_reason": "timeout",
    "type": "analysis_details",
    "url": null,
    "version": 5,
    "vm_analysis_duration_time": "00:04:00",
    "whois_enabled": false
  },
  "artifacts": {
    "domains": [],
    "files": [
      {
        "filename": "\\\\?\\C:\\$GetCurrent\\Logs\\downlevel_2017_09_07_02_02_39_766.log.id[B4197730-2574].[decrypt4data@protonmail.com].devil",
        "hashes": [
          {
            "imp_hash": null,
            "md5_hash": "7edcae2df83ed96625ed177cc0f206ab",
            "sha1_hash": "fe6b4c9bcbec66b6a56f8986497ad4006934fe6a",
            "sha256_hash": "d67be4df2ff2b27f074284d294f77d321fd84270bfa5bb80437997c65977e062",
            "ssdeep_hash": "768:w7EmX83F8xXKKk9A5rDnn38nUOsEmGwX5Q6fKarEohFuZZSkiRZ449:w7EmM3F89TxOnDOFrZ7kUB9",
            "type": "file_hash",
            "version": 2
          }
        ],
        "norm_filename": "c:\\$getcurrent\\logs\\downlevel_2017_09_07_02_02_39_766.log.id[b4197730-2574].[decrypt4data@protonmail.com].devil",
        "operations": [
          "access",
          "write",
          "create"
        ],
        "type": "file_artifact",
        "version": 1
      },
      {
        "filename": "\\\\?\\C:\\$GetCurrent\\Logs\\oobe_2017_09_07_03_08_57_737.log.id[B4197730-2574].[decrypt4data@protonmail.com].devil",
        "hashes": [
          {
            "imp_hash": null,
            "md5_hash": "2668c5e517ec5bf3f64a5c3112e7dc03",
            "sha1_hash": "dbbd244855ad3eb01eadae163f971da8bb9bd259",
            "sha256_hash": "5be76c9ecca43c32a5bf0503336c3cac3b874de8f7388b42c3c25caf3a222381",
            "ssdeep_hash": "192:KOde/YOAH4OhEd1bxrmKKHVJmUBExgphGdR8cyP:3QXDHvbwKKewExgphGdRi",
            "type": "file_hash",
            "version": 2
          }
        ],
        "norm_filename": "c:\\$getcurrent\\logs\\oobe_2017_09_07_03_08_57_737.log.id[b4197730-2574].[decrypt4data@protonmail.com].devil",
        "operations": [
          "access",
          "write",
          "create"
        ],
        "type": "file_artifact",
        "version": 1
      },
      {
        "filename": "\\\\?\\C:\\$GetCurrent\\SafeOS\\GetCurrentOOBE.dll.id[B4197730-2574].[decrypt4data@protonmail.com].devil",
        "hashes": [
          {
            "imp_hash": null,
            "md5_hash": "ef14b26ee1b22ae1bab4fe2c03dd2cb1",
            "sha1_hash": "02fd8d248952e63aff6efcc4fa400b074bafe8d8",
            "sha256_hash": "f4cb4387e3f1d728fd6fb838d2574a2ed6188701632bfe3d8c66e5ba6daf2fd9",
            "ssdeep_hash": "3072:LkOcvU7r0M+XitzzPgCbPWGdGY5m0lSYWGjI6XyUC3XfnZEF7n4Js:LkPvUnn+XSwA1MYs+SY7FyLvnZEZ7",
            "type": "file_hash",
            "version": 2
          }
        ],
        "norm_filename": "c:\\$getcurrent\\safeos\\getcurrentoobe.dll.id[b4197730-2574].[decrypt4data@protonmail.com].devil",
        "operations": [
          "access",
          "write",
          "create"
        ],
        "type": "file_artifact",
        "version": 1
      },
      {
        "filename": "\\\\?\\C:\\$GetCurrent\\Logs\\PartnerSetupCompleteResult.log.id[B4197730-2574].[decrypt4data@protonmail.com].devil",
        "hashes": [
          {
            "imp_hash": null,
            "md5_hash": "5c75259ca27d96912de4d1bc71b5dc5f",
            "sha1_hash": "29022492439fd45e32a030b25a95c9ce751cb574",
            "sha256_hash": "2f13fc9ecd7e4b5fd2550880b7795201fc7351e8768a0d571fdbbbf865bb5794",
            "ssdeep_hash": "6:rrIOIuhWYXGmuYhz2NBQx0ixwKyt+o87JVQ2EBx64VFHAENlvR:3IXuhWY2lYhsBQx0ixwR+o8742mvgE3J",
            "type": "file_hash",
            "version": 2
          }

 

Figure 8: Our one analysis generates a large Summary .json file (1.5 MB)
The summary .json is an open-standard file format for which the details of the analysis can neatly fit into other technologies’ data structures. To pull additional elements, the full results can be retrieved from the analysis archive. This is similar to how a DFIR analyst would manually drill down on the various tabs (Network, Behavior, Files, IOCs) to find the required information. The .json file contents will closely match the corresponding analysis that would be displayed in the web UI below (Figure 9).

 

In-depth results for this one analysis

Figure 9: Each tab contains in-depth results for this one analysis

 

The summary .json file -or any portion of it- can be accessed in two ways: by using the UI’s drop-down menu, shown above in Figure 9, or by making an API call to an archive containing the file (Figure 6).

 

Get hands-on with VMRay’s REST API

Existing customers can access our documentation and API right now within their account.

Interested in integrating VMRay into your security ecosystem? Start your trial today.