oasis-tcs / openc2-ap-er

OASIS Open Command and Control (OpenC2) TC: An OpenC2 Actuator Profile defining the Actions, Targets, Specifiers and Options that are consistent with version 1.0 of the OpenC2 Language Specification. https://github.com/oasis-tcs/openc2-ap-edr
Other
5 stars 4 forks source link

Action/Target pairs and Actuator specifiers not granular enough #30

Open MartinEvandt opened 2 years ago

MartinEvandt commented 2 years ago

Certain Commands require a further level of granularity in order to specify which exact endpoint the Command is to be performed. For example running a "Stop process" action entails that the Target field is already populated with the process in question, and so the endpoint (which would usally be a "device" Target) is not specified.

In other words we need a way to say e.g. "Contain file on this endpoint via this Actuator".

A similar concern is that of tenants/segments on cloud-based EDR solutions such as Carbon Black Cloud (CBC) and Microsoft Defender for Endpoint (MDE). Where an organizations' tenant is denoted using some sort of unique identifier.

Meaning we also need a way to say e.g. "Stop process on this endpoint on this tenant via this Actuator".

Currently, the most pressing part of this is to find a consistent way to tell the Actuator to execute Commands/Action-Target pairs where the Target is something other than "device" to a specific endpoint.

I'll post some examples from the MDE/CBC API as well as some suggestions in this thread.

MartinEvandt commented 2 years ago

Here is an example from MDE on how to quarantine a file via their API: https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/stop-and-quarantine-file?view=o365-worldwide

"Contain file on this endpoint via this Actuator"

Request:
https://api.securitycenter.microsoft.com/api/machines/{machine_id}/StopAndQuarantineFile

Body:
{
  "Sha1": {file.sha1}
}

Where

MartinEvandt commented 2 years ago

Here is an example of how to quarantine an endpoint on a specific CBC tenant via their API: https://developer.carbonblack.com/reference/carbon-black-cloud/platform/latest/devices-api/#quarantine

"Contain device on this tenant via this Actuator"
Request:
{cbc-hostname}/appservices/v6/orgs/{org_key}/device_actions

Body:
{
    "action_type": "QUARANTINE",
    "device_id": ["12131"],
}

Where

MartinEvandt commented 2 years ago

To even further complicate things, MDE handles the issue of tenants within the Authentication token itself, meaning you have to include your tenant ID when generating a token: https://docs.microsoft.com/en-us/microsoft-365/security/defender-endpoint/api-hello-world?view=o365-worldwide

How would this work with the way that OpenC2 does authentication? (I think I might have to open a separate issue regarding this, as it feels like quite an edge-case).

MartinEvandt commented 2 years ago

Ignoring the issue with MDE specifying tenants in the auth token, we can address the lack of tenant specifiers (such as it is in the CBC example) by adding a tenant_id optional field in the Actuator Specifiers map:

Type: Specifiers (Map)

ID Name Type # Description
1 hostname Hostname 1 The hostname of a machine with ER Actuator capabilities. MUST be formatted as an internet host name as specified in [RFC1123]
2 tenant_id string 0..1 Unique identifier for an Actuator which resides on a tenant or similar form of logical segment within a host. E.g., a cloud-based EDR solution where multiple tenants share the same hostname.

When wanting to specify a particular endpoint it becomes trickier, as the endpoint is not an actuator. It is however the target of an Action/Target pair consumed by the Actuator. One solution would then be to add it to the specifier list anyways, and then add some sort of usage requirement to the section explaining the purpose of it being in the specifiers map.

ID Name Type # Description
1 hostname Hostname 1 The hostname of a machine with ER Actuator capabilities. MUST be formatted as an internet host name as specified in [RFC1123]
2 tenant_id string 0..1 Unique identifier for an Actuator which resides on a tenant or similar form of logical segment within a host. E.g., a cloud-based EDR solution where multiple tenants share the same hostname.
3 endpoint_id string 0..1 Unique identifier for a particular device on which the Actuator is to execute a Command.

Sample command

{
  "action": "contain",
  "target":{
    "file": {
       "hashes":"..."
    }
  },
  "actuator": {
    "edr": {
       "hostname":"edr.organization.tld",
       "endpoint_id":"Host123ABC"
    }
  }
}

Another solution to the endpoint issue would be to add a "target_endpoint" Command Argument.

*_Type: Actuator-target (Map{1..})_**

ID Name Type # Description
1 endpoint_id string 0..1 Unique identifier for a particular device on which the Actuator is to execute a Command

An added benefit here would be that we can denote which Commands this argument can be paired with in the Command Arguments matrix.

Table 2.3-2. Command Arguments Matrix

response_requested [...] Actuator-target
contain device valid [...]
contain file valid [...] valid
restart process valid [...] valid

[...]

Sample command

{
  "action": "contain",
  "target":{
    "file": {
       "hashes":"..."
    }
  },
  "args": {
    "edr": {
      "actuator_target":{
        "endpoint_id":"Host123ABC"
      }
    }
   },
  "actuator": {
    "edr": {
       "hostname":"edr.organization.tld",
    }
  }
}
dlemire60 commented 2 years ago

Overall, I think you've done a nice job of laying out the problem here. I wish I'd looked at these sooner, but we're now hitting a very similar issue with Posture Attribute Collection so my interest level has definitely increased. :-) And I think as the population of APs grows it seems likely we'll see more cases like this. The PF AP handles at least some aspects of this via the Actuator Specifiers. I'm still learning about the use cases PAC cares about and whether the PF AP approach is sufficient.

Regarding the CBC example:

  • Leaving orgs/{org_key} as the part we are missing

For this example I'm still a bit uncertain what information is conveyed by orgs/{org_key}. Meanwhile, I'm still studying the other examples and concerns.

davaya commented 2 years ago

Looking at the CBC Quarantine example, their API says:

Permission (.notation name) Operation(s) Action Type
device.quarantine EXECUTE QUARANTINE
device.bypass EXECUTE BYPASS
device.bg-scan EXECUTE BACKGROUND_SCAN
device.policy UPDATE UPDATE_POLICY
org.kits EXECUTE UPDATE_SENSOR_VERSION
device.uninstall EXECUTE UNINSTALL_SENSOR
device.deregistered DELETE DELETE_SENSOR

Request; POST {cbc-hostname}/appservices/v6/orgs/{org_key}/device_actions

Example: POST https://defense-prod05.conferdeploy.net/appservices/v6/orgs/ABCD1234/device_actions

That's a REST endpoint, where hostname is the destination consumer and appservices/.../device_actions is the API route. OpenC2 over HTTP is a single-endpoint API, so the command body has to contain the information from the API route in addition to the JSON body. CBC conveniently has a body schema - I'll give this some more thought and come up with a CBC-only AP that does exactly what their API does. The first weirdness is that their actions include verb and noun {UPDATEPOLICY, or QUARANTINE\<implicit DEVICE>).