dxlmarclient.client module

class dxlmarclient.client.MarClient(dxl_client)

Bases: dxlbootstrap.client.Client

This client provides a high level wrapper for communicating with the McAfee Active Response (MAR) DXL service.

The purpose of this client is to allow the user to perform MAR searches without having to focus on lower-level details such as MAR-specific DXL topics and message formats.

Constructor parameters:

Parameters:dxl_client -- The DXL client to use for communication with the MAR DXL service
poll_interval

The amount of time to wait (in seconds) before polling the MAR server for results

search(projections, conditions=None, context=None)

Executes a search via McAfee Active Response.

Once the search has completed a ResultsContext object is returned which is used to access the search results.

Note

Client Authorization

The OpenDXL Python client invoking this method must have permission to send messages to the /mcafee/mar/service/api/search topic.

See the following page for details on authorizing a client to perform MAR searches:

https://opendxl.github.io/opendxl-client-python/pydoc/marsendauth.html

Execution of a MAR search requires a list of projections and an optional dictionary containing the search conditions.

Projections

Projections are used to describe the information to collect in the search. Each projection consists of a collector name and a list of output names from the collector. For example, the Processes collector includes output names such as name, sha1, md5, etc.

For a complete list of collectors and their associated output names refer to the McAfee Active Response Product Guide.

Each projection specified must contain the following fields:

  • name: The name of the collector to project
  • outputs: An array of output names of the collector to project

The python list below is equivalent to the projections within the following textual search:

Processes name, id where Processes name equals "csrss" and Processes name contains "exe" or Processes size not greater than 200

projections=[{
    "name": "Processes",
    "outputs": ["name", "id"]
}]

Conditions

Conditions are used to restrict which items are included in the search results. For example, a search that collects process-related information could be limited to those processes which match a specified name.

A condition has a fixed structure starting with an or conditional operator and allowing only one level of and conditions.

The python dictionary below is equivalent to the conditions within the following textual search:

Processes name, id where Processes name equals "csrss" and Processes name contains "exe" or Processes size not greater than 200

conditions={
    "or": [{
        "and": [{
            "name": "Processes",
            "output": "name",
            "op": "EQUALS",
            "value": "csrss"
        }, {
            "name": "Processes",
            "output": "name",
            "op": "CONTAINS",
            "value": "exe"
        }]
    }, {
        "and": [{
            "name": "Processes",
            "output": "size",
            "op": "GREATER_THAN",
            "value": "200",
            "negated": "true"
        }]
    }]
}

The following fields are used for each condition:

  • name: The name of the collector from which to retrieve a
    value for comparison
  • output: The output name from the collector that selects
    the specific value to use for comparison
  • op: The comparison operator
  • value: The value to compare with the value from the collector
  • negated: (optional) Indicates if the comparison is negated

The operators available for each value data type are as follows:

Operator NUMBER STRING BOOLEAN DATE IPV4IPV6 REG_STR
GREATER_EQUAL_THAN x          
GREATER_THAN x          
LESS_EQUAL_THAN x          
LESS_THAN x          
EQUALS x x x x x x (*)
CONTAINS   x     x x (*)
STARTS_WITH   x       x (*)
ENDS_WITH   x       x (*)
BEFORE       x    
AFTER       x    

(*) Negated field is not supported in those cases.

Example Usage

# Create the client
with DxlClient(config) as client:

    # Connect to the fabric
    client.connect()

    # Create the McAfee Active Response (MAR) client
    marclient = MarClient(client)

    # Execute the search
    results_context = marclient.search(
            projections=[{
                "name": "Processes",
                "outputs": ["name", "id"]
            }],
            conditions={
                "or": [{
                    "and": [{
                        "name": "Processes",
                        "output": "name",
                        "op": "EQUALS",
                        "value": "csrss"
                    }, {
                        "name": "Processes",
                        "output": "name",
                        "op": "CONTAINS",
                        "value": "exe"
                    }]
                }, {
                    "and": [{
                        "name": "Processes",
                        "output": "size",
                        "op": "GREATER_THAN",
                        "value": "200",
                        "negated": "true"
                    }]
                }]
            }
        )

Context

Context is used to restrict the search query. For example, a search that only contains results for specific Agent UUID/s.

Note

Context requires Agent UUID/s (MA GUIDs) to be lower case

Note

Context requires McAfee Active Response 2.3 or greater

Example Usage

results_context = marclient.search(
        projections=[{
            "name": "HostInfo",
            "outputs": ["hostname","ip_address"]
        }, {
            "name": "Files",
            "outputs": ["md5","status"]
        }],
        conditions={
            "or": [{
                "and": [{
                "name": "Files",
                "output": "md5",
                "op": "EQUALS",
                "value": "daac6ba6967893ddea06ed132b781529"
                }]
            }]
        },
        context={
            "maGuids": [
                "{A53CB87C-37F4-11E8-3671-00000007327C}".lower()
            ]
        }
    )
Parameters:
  • projections -- A list containing the projections for the search
  • conditions -- (optional) A dictionary containing the conditions for the search
  • context -- (optional) A dictionary containing the context for the search
Returns:

A ResultsContext object which is used to access the search results.

class dxlmarclient.client.ResultsContext(mar_client, search_id, result_count, error_count, host_count, subscribed_host_count)

Bases: object

This object is used to access to the results of a MAR search (see MarClient.search()).

error_count

The count of errors that were reported during the search

get_results(offset=0, limit=20, text_filter='', sort_by='count', sort_direction='desc')

This method is used to retrieve a particular set of results from a MAR search.

Results

Each search result item has the following fields:

  • id: The identifier of the item within the search results
  • count: The number of times that the search result was reported
  • created_at: The item timestamp
  • output: The search result data where each key is composed of <CollectorName>|<OutputName> and the value that correspond to that collector and output name.

The python dictionary below is an example of a result that would be returned from the following textual search:

Processes name, id where Processes name equals "csrss" and Processes name contains "exe" or Processes size not greater than 200

{
    "startIndex": 0,
    "totalItems": 2,
    "currentItemCount": 2,
    "itemsPerPage": 20,
    "items": [
        {
            "id": "{1=[[System Process], 0]}",
            "count": 2,
            "created_at": "2016-11-16T22:50:04.650Z",
            "output": {
                "Processes|id": 0,
                "Processes|name": "[System Process]"
            }
        },
        {
            "id": "{1=[System, 4]}",
            "count": 1,
            "created_at": "2016-11-16T22:50:04.650Z",
            "output": {
                "Processes|id": 4,
                "Processes|name": "System"
            }
        }
    ]
}

Example Usage

results = results_context.get_results(sort_by="Processes|name",
    sort_direction="asc")

# Display items
for item in results["items"]:
    print "    " + item["output"]["Processes|name"]
Parameters:
  • offset -- (optional) Index of the first result item to be returned. This value is 0 based. Default value: 0
  • limit -- (optional) The maximum number of items to return in the results. Default value: 20
  • text_filter -- (optional) A text based filter to limit the results (this can be any string)
  • sort_by -- (optional) The field that will be used to sort the results. Default value: count
  • sort_direction -- (optional) values: ascending asc or descending desc (String). Default value: desc
Returns:

A dictionary containing the specified results from the search.

has_results

Whether the search has results

host_count

The count of endpoints that responded to the search

result_count

The total count of items available in the search results

subscribed_host_count

The count of endpoints that were connected to the DXL fabric when the search started