Last updated at Mon, 04 Dec 2017 19:16:33 GMT

Our integrations team recently attended BroCon at the National Center for Supercomputing Applications in Urbana, IL. BroCon is an annual network security monitoring conference for users and developers of the Bro network security monitoring platform. They got excited about the interesting research going on, and set out to whip up a new proof of concept integration to help fellow Bro users utilize Komand in interesting and novel ways.


A little background on me first. I was a former security engineer at the NCSA which used Bro at scale. In addition, I was briefly a member of the Bro team where I worked on training materials and developed the Bro sandbox training tool which later become ISLET.

Given my background with the tool, an understanding of how powerful it really is, and its growth in enterprise and government environments, it only makes sense to enhance its use cases through automation. We already have a basic Bro integration for Try Bro to perform testing and analysis on small PCAP files, like those sample captures that come from a malware analysis system. We also have customers who pull Bro logs into Komand for additional enrichment and action using our Splunk and ElasticSearch plugins.


Let's set the bar a little a higher this time and get Bro to talk to Komand when it find something interesting. We can do this by leveraging the Bro scripting language to work with data extracted from the network. Once we obtain data of interest we can send it to the Komand API trigger to kick off a workflow which opens up many possibilities for automation.

In this tutorial, we will begin with a simple use case to send the MD5 hashes calculated for files Bro has seen on the wire to Komand for enrichment. You can customize this example to send any data that you please such as URLs, IP addresses, certificates, notices, etc.

First, we'll need to configure an API trigger to listen for events from Bro. Let's add an API Trigger to the canvas and tell it to accept a single input of type string for the MD5 hash.

Next, we need to proceed with the API Trigger step and obtain the URL and authorization key to authenticate to this endpoint. We'll use this in our Bro script to authenticate and send data to Komand.

Now, we can add a bunch of steps to the workflow. Any of your choosing for the workflow you have in mind. We have an existing MD5 hash lookup workflow available for you to try called Malicious MD5 Hash Detection which verifies the submitted hash against VirusTotal and Team Cymru's MHR. Hashes that are verified from two sources of truth are blocked with Carbon Black Response. Results are posted to Slack and an artifact is created with details.

The Bro script posted below uses ActiveHTTP::request to make web requests via cURL to Komand. To use this script in your environment, set authorization to your token and set $url in the request Record to your API trigger's URL.

Further adjustments can be made to customize the mime_types in match_file_types to reduce the amount of activity to those file types you care about.

module Komand;

export {
    global authorization = "-H 'Authorization: 0d9cfce8-a3d4-42e3-99bf-e50eb8294c5b'" &redef;

    global request: ActiveHTTP::Request = [

    const match_file_types = /application\/x-dosexec/ |
                                     /application\/ |
                                     /application\/pdf/ |
                                     /application\/x-shockwave-flash/ |
                                     /application\/x-java-applet/ |
                                     /application\/jar/ &redef;

    # For keeping track of past hash submissions
    global hash_history: set[string] &redef;

event file_hash(f: fa_file, kind: string, hash: string) {
    if ( kind == "md5" && f?$info && f$info?$mime_type && match_file_types in f$info$mime_type ) {
        local body = fmt("{\"md5\": \"%s\"}", f$info$md5);
        request$client_data = body;

        if ( f$info$md5 in hash_history )

        when ( local resp = ActiveHTTP::request(request) ) {
            print fmt("New MD5 hash found, request made ===> %s", request);

        add hash_history[f$info$md5];

event bro_done(){
    print "Hash History: ", hash_history;
    print fmt("History Count: %d", |hash_history|);

We can place this code in a file called komand.bro and run it through Bro.

$ bro -C -r nitroba.pcap komand.bro
New MD5 hash found, request made ===> [url=, method=POST, client_data={"md5": "84840356108553ed9aca60b5fa99d331"}, max_time=1.0 min, addl_curl_args=-H 'Authorization: 0d9cfce8-a3d4-42e3-99bf-e50eb8294c5b']
New MD5 hash found, request made ===> [url=, method=POST, client_data={"md5": "d56f1aafab8ec06221e8ab65861525a8"}, max_time=1.0 min, addl_curl_args=-H 'Authorization: 0d9cfce8-a3d4-42e3-99bf-e50eb8294c5b']
Hash History, {
History Count: 45

Next, we can check our Komand jobs page for new jobs. Notice that we have a bunch of new jobs. For each hash that was sent by Bro a new job was created with the details for that instance of the workflow.

We can take a sample look at a malicious hash displayed in an Artifact from one of the jobs on the Jobs page for the Malicious MD5 Hash Detection workflow.

Wrapping Up

The Bro script can be used in live mode as well as on a cluster. It should be tuned and modified to your use cases and provides plenty of structure and logic to get you excited about sending IP addresses, URLs, and all sorts of other things to Komand for additional actions.

We will be coming up with more ways to integrate with Bro so be on the look out for those.

If you found this Bro use case helpful, check out a few other security orchestration and automation use cases that Komand handles: