Check application against Virus Total (VT)

When a new application is discovered on an asset, call Virus Totals API. If the application hash (sha256) has a hit as a malicious application then email someone.

Setup

This workflow uses the ASSET_APPLICATION event hook. Every time a new application is found on an asset. Or the risk for a given asset changes. The ASSET_APPLICATION event is triggered.

Event

You can use this event to test the workflow.

{
  "uuid": "5c15f50e-432f-43fa-b169-40ea0b2957d1",
  "timestamp": "2020-03-04T14:18:14+00:00",
  "level": "INFO",
  "action": "ASSET_APPLICATION",
  "meta": null,
  "changes": null,
  "item": {
    "id": "b2ece742a0dd16bef93b9fe7e3e763ec0a6c49e533eb76764baa295683206513",
    "name": "com.apple.ncplugin.weather"
  },
  "company": {
    "uuid": "f50dfca1-c8b0-40ca-80cd-984d2d6dce10",
    "name": "Zercurity"
  },
  "user": null,
  "team": {
    "uuid": "53d27c4a-41f5-4d37-83ab-93532dbfeab6",
    "name": "Zercurity"
  },
  "asset": {
    "uuid": "4e8924a8-31ff-4895-8956-92879b8c617e",
    "name": "James (laptop)"
  }
}

States

check_vt

This state uses the type task to call the zercurity resource zrn:zercurity:core:request. This lets you request external resources using a HTTP REST request. The result is then passed to: process_vt_result.

process_vt_result

Once we’ve got a response from check_vt we want to check if the result from Virus Total decides that the application is malicious. We can do this by looking in the response for $.positives. This will contain the number of positive hits. We can then check if the value in $.positives is greater than or equal to 2. We can set this condition using numericGreaterThanEquals. In the event this statement is true the next state will be triggered. Which will be to send an email. In the event the condition is not met the state will fall back to the default state. Which will be to end the workflow by calling the end state.

email_post

This final state will email a pre-defined user. Zercurity lets map data from the response into the content of the email using the mapping parameter.

Full example

{
  "states": {
    "end": {
      "end": true,
      "type": "Pass"
    },
    "check_vt": {
      "resource": "zrn:zercurity:core:request",
      "type": "task",
      "parameters": {
        "url": "https://www.virustotal.com/vtapi/v2/file/report",
        "params": {
          "apikey": "VIRUS_TOTAL_API_KEY",
          "resource": "$.item.id"
        },
        "method": "GET"
      },
      "next": "process_vt_result"
    },
    "process_vt_result": {
      "default": "end",
      "type": "choice",
      "description": "Check the result of the request",
      "choices": [
        {
          "variable": "$.positives",
          "numericGreaterThanEquals": 2,
          "next": "email_post"
        }
      ]
    },
    "start": {
      "type": "Pass",
      "description": "Start",
      "next": "check_vt"
    },
    "email_post": {
      "resource": "zrn:zercurity:core:email",
      "type": "Task",
      "description": "Send information about malware",
      "parameters": {
        "body": {
          "text": "We've detected a malicious application running {{sha1}} click {{link}}",
          "html": "We've detected a malicious application running click <a href=\"{{link}}\">{{sha1}}</a>"
        },
        "from": "support@zercurity.com",
        "cc": [],
        "mapping": {
          "sha1": "$.sha1",
          "link": "$.permalink"
        },
        "bcc": [],
        "to": [
          "your@email.com"
        ],
        "subject": "Hello"
      },
      "next": "end"
    },
    "yes": {
      "type": "pass",
      "end": true
    }
  },
  "entry": "start",
  "description": "Post a message on slack if a risky application is found"
}