Creating a Plugin for Netflix Security Monkey

Posted by Alan Barr on Thu 19 July 2018

Image of Security Monkey

Enhancing Security Automagically

Security is a super hard concept for me to work with. It feels like keeping track of many many details and seems easy to be overwhelmed by it. Enter Security Monkey a tool that my colleague Paul introduced me to. One of the cool things about moving towards the cloud is the variety of offerings that cloud providers enable through security setting vetting. Unfortunately its super hard to keep track of all the different things. Security Monkey takes care of all that for you by monitoring different endpoints for changes and presenting json diffs of those changes using Watchers for the monitoring. Auditors to run business rules against the findings of the watchers and notifiers to alert those who need to know. It provides a unified places to obtain and vet changes in cloud environments.

Writing a plugin

Documentation writing is super hard and trying to augment other people's software is not so easy especially when its easier to do it in any old way. Digging through the documentation I found references to a couple different ways of adding a custom plugin. One using the /custom folder and two using the plugin system using entry_points in python. I did not want my changes to be part of the bigger system since most of the items thus using entry_points would work best. There was a lot of trial and error and due to my current computer situation I did not want to bother with using docker. I ended up creating a vm in azure in order to run security monkey and develop the plugin simultaneously. Luckily the documentation provided was phenomenal. Even writing the plugin was straight forward. I ended up confusing myself because I assumed that by dropping in my folder of plugins that I would somehow be using the security.monkey namespace but ended up only using my own plugin namespace. I've never professionally worked in Python only doing my own machine learning on the side or other projects. I also learned that init.py was required for python to know that this would be part of a package to install.

Getting to know the concepts

The installation on my vm worked great and running most of the software was pretty easy. Understanding the roles of Watchers, Auditors, and Notifiers was a little more complex. There was not as much information as to the intricacies of how these pieces work and I mostly cribbed what I could learn from the GitHub implementation of these concepts. The first item I created was a new Account Manager. I wanted to see how I could start introducing Security Monkey to Azure. The account manager was the most simple to implement.

    from security_monkey.account_manager import AccountManager, CustomFieldConfig

    class AzureAccountManager(AccountManager):
        account_type = 'Azure'
        identifier_label = 'Organization Name'
        identifier_tool_tip = 'Enter the Azure AD Tenant ID'
        access_token_tool_tip = "Enter the path to the file that contains the Azure personal access token."
        custom_field_configs = [
            CustomFieldConfig('access_token_file', "Personal Access Token", True, access_token_tool_tip),
        ]

        def __init__(self):
            super(AccountManager, self).__init__()

I mostly copied the GitHub version for the most part I want to define for the Security Monkey UI how to add this new type and indicate for it where to find its credentials. In this case I'm going to assume it is json stored on disk somewhere.

In order to create a custom Watcher the new watcher needs to inherit from the base and override some of its functionality. A slurp function and a separate class to inherit from ChangeItem also some properties with unique values to the SecurityMonkey keeps things separate. One thing that confused me quite a bit was that so much of SM assumed things like AWS it feels very AWS focused and I was worried I might be doing things wrong but it didn't seem to be an issue. The documents indicated using a particular file for connection logic but based on the GitHub version this appeared to be placed in a util file. Basically the Watchers are a scheduled job that will hit various endpoints for accounts and grab lists of the data and save it in the SM database to display to the security user or for Auditors to run rules against.

The Auditor and Watcher keep a reference to a shared index so they cna work in tandem. All plugins are dynamically loaded so this made iterating on the functionality pretty easy and not too hard to debug when things broke in an obvious way.

    from security_monkey import app
    from security_monkey.auditor import Auditor
    from vusmplugins.watchers.azure.security_center import AzureSecurityCenter
    import jmespath

    class AzureSecurityCenterAuditor(Auditor):
        index = AzureSecurityCenter.index
        i_am_singular = AzureSecurityCenter.i_am_singular
        i_am_plural = AzureSecurityCenter.i_am_plural

        def __init__(self, accounts=None, debug=False):
            super(AzureSecurityCenterAuditor, self).__init__(accounts=accounts, debug=debug)

        def check_for_provisioning_monitoring_agent(self, item):
            """
            Check that security agent is collecting data 
            :param security_details:
            :return:
            """
            tag = "Account contains policy with security monitoring agent off."
            result = [match for match in jmespath.compile('value[*].properties.logCollection').search(item.config)]

            if "Off" in result:
                self.add_issue(10, tag, item, notes="Account contains unprovisioned monitoring agents")

I ended up with this and I wasn't fully able to see it work in my VM likely because I did not setup the workers to run off redis and celery but the pattern stays the same. Auditors hold business rules for security issues. One problem with this could be that a lot of your rules end up in code and it may be something that may need to be more ui editable? Overall it was an interesting experience. The main challenge now is integrating with Azure because the authentication methods vary especially on accounts. For my personal testing I used the azure cli to generate my account token. For an enterprise solution it appears that service principals would be the way to go. The rest of my time I spent integrating SM with our on premise utilities such as rabbitmq and getting the autorunning to work. A little linux ops work is a nice change of pace.

Wrapping Up

If you deal with multiple cloud vendors and an everexpanding suite of new apis, tools, and systems to work with Security Monkey is going to be your best friend. Having something to run on a schedule and audit your environment is a dream. Even if you do not use Security Monkey in the future using automated tooling to enforce quality or enable it is a great step in being more proactive about managing your systems.