Outwardly, Red Canary appears to focus heavily on the “Detection” in Endpoint Detection and Response. Much of what we share addresses the need to understand the platforms that we defend, and techniques that can be applied to detect threats to those platforms in a manner that lends to both accuracy and scale. But this is not to say that we don’t focus as much, if not more, of our time thinking about and building systems for response.
In fact, when Chris Rothe, our Chief Technology Officer and co-founder, first suggested the concept of response bandwidth, it resonated heavily with all of us. Building detections systems, criteria, and our suppression-driven analysis platform are significant and critical to our work. And that work, as it turns out, is actually 90% response. Triage, investigation, piecing together a detection timeline, remediation, and recovery—these are all response activities of differing types. Some are undertaken by us, some by our customers.
This article will focus on a few specific response activities: isolation, investigation, and remediation. Specifically, we’re going to outline a basic response playbook and then show (with code) how to use the Carbon Black Response platform to very quickly automate the steps.
The examples we’ll show assume you have:
- a Carbon Black Response environment available
- an account with privileges sufficient to exercise Live Response
- the cbapi-python client libraries installed and properly configured
We can test this setup by creating a simple script that sets up our imports, logging, and makes a connection to the Response server:
import argparse import logging from cbapi.response import BannedHash from cbapi.response.models import Process, Sensor from cbapi.response.rest_api import CbEnterpriseResponseAPI logging.basicConfig(level=logging.INFO) def main(): cb = CbEnterpriseResponseAPI() if __name__ == '__main__': main()
Save this as playbook.py
and execute via python playbook.py
and you should get…nothing in return. The lack of an error means that the client was able to successfully connect to the server.
What’s in a response playbook?
A response playbook is a set of steps that the incident response team will take when presented with a given threat. These can range from very simple to very complex, depending on a number of factors including the nature and scope of the threat, as well as the organizational elements involved in response. Within financial services, for instance, it may be common for cybersecurity threats to have both technical and physical security response actions. When dealing with critical infrastructure the same may be true, with added requirements that safety personnel be in the loop.
Here we’re going to assume a realized threat that is very limited in scope. A standalone binary on a single system. I think you’ll see that, once a framework for response is in place, adding capabilities is relatively simple.
The scenario
One of our endpoints is infected with an evil version of the venerable Sticky Note application. Our playbook for this event is to:
- Isolate the endpoint on the network
- Kill any process associated with the unauthorized software
- Ban the binary
We’re not trying to perform a remote forensic investigation. Instead, we want a fast and confirmed kill.
The setup
We’ll start by adding some input handling. Specifically, we need to be able to provide the script with a hostname and a process name.
parser = argparse.ArgumentParser() parser.add_argument("--hostname", type=str, action="store", help="Target a specific hostname.") parser.add_argument("--process-name", type=str, action="store", help="Name of the process to kill.") args = parser.parse_args()
Then, below the existing code that connects to the API, we’ll actually query Response to get the sensor object that we need, and at the same time stage the query that will seek out the process to kill.
sensor = cb.select(Sensor).where("hostname:{0}".format(args.hostname))[0] target_process = args.process_name
Now we start to make things happen! The first step in our playbook is to protect the rest of the enterprise by isolating the endpoint on the network:
sensor.network_isolation_enabled = True sensor.save()
Once that’s done, we can kill the running process. Note that we’re actually doing a few things here: First, we list all processes on the endpoint. Next we iterate through the process list and store the PIDs of processes associated with the offending process name (there may be more than one). Finally, we kill each of the stored PIDs.
process_list = cblr.list_processes() target_pids = [proc['pid'] for proc in process_list if target_process in proc['path']] for pid in target_pids: cblr.kill_process(pid)
The last step is to ban the binary. To accomplish this, we first need to find the MD5 hash of any process matching the provided name. And to get the hash, we’ll query Response using the query API as opposed to the Live Response API (which doesn’t expose all of the process metadata that is stored server-side).
process_list = cb.select(Process).where("process_name:{0}".format(args.process_name)) target_md5s = set() for process in process_list: target_md5s.add(process.process_md5) for md5 in target_md5s: banned_hash = cb.create(BannedHash) banned_hash.md5hash = md5 banned_hash.text = "Banned by Joe Dirt" banned_hash.enabled = True banned_hash.save()
And that’s it! To run our playbook, we execute this:
python playbook.py --hostname win7pro64 --process-name vnc.exe
And we should see something like this!
Grab this example from GitHub!
More Carbon Black Resources
Red Canary’s Security Operations Center is comprised of threat researchers and analysts who are skilled at leveraging Carbon Black Response (CbR) data to quickly and accurately identify threats on customers’ endpoints. Browse our most popular CbR resources and tools.
*Image courtesy of Warner Bros.