CACAO Playbooks 102: Building Workflows
If you are reading this blog post via a 3rd party source it is very likely that many parts of it will not render correctly. Please view the post on signalscorps.com for the full interactive viewing experience. In this post I will show you how workflows inside a playbook can be created so you can start to construct your own.
Workflows contain a series of steps to be performed. Think of the workflow as the logic of a playbook; it describes the actions and order of the actions that should be taken.
Steps can be performed sequentially, in parallel, or both depending on the type of steps required by the playbook.
Each work step can also contain conditional operations to control the steps executed (e.g. if true; do this, if false, do that).
As I introduced last week, each step in a playbook is built from various json objects…
Every playbook must have a start step to define when a playbook workflow should start. For example, the start step might be receive an Indicator of Compromise.
You will quickly see how each action is defined with a type and UUID (e.g.
In this case we have a
"type": "start" step to kick of this workflow. The
on_completion step defines (by ID) the next step when the workflow starts.
A single workflow step is to be processed sequentially in the workflow.
In the example above, you will see workflow step contains the a
manual command to be executed (i.e. to be run manually by humans). In this case, "Get IOC from threat feed".
Commands can have a other few types, many more suited to automation in the playbook (but can also be run manually).
For example, Sigma and Kestrel hunting commands are supported (as are entire Jupyter notebooks).
For Sigma and Kestrel, the rule should be encoded as base64 and the
command_b64 property should be used.
Of course, if automating this, the place where this Sigma rule (or any command
type) must be defined.
target object contains detailed information about the entities or devices that accept, receive, process, or execute one or more
commands as defined in a workflow step. Targets contain the information needed to send commands as defined in steps to devices or humans.
(e.g. firewalls, IPS, Switch, Router, Threat Intelligence Platform, etc.)
For increased automation, the
target object can contain full information. For example, complete information to initiate an SSH connection;
So what’s the difference between a
target and a
A command defines WHAT command should be run. e.g.
A target defines WHERE the command should run/
So if the last command and target example were in a step,
last; netstat -n; ls -l -a /root would be run on
As you progress into more advanced use-cases like this the commands to be run (and other property values in each step) will require variables that are the result of outcomes from previous steps (e.g. a value generated from a lookup step) or defined globally in the playbook (e.g. username / password).
Playbook (global) / Workflow (local) Variables
A variable may be defined globally for the entire playbook or locally within a workflow step.
Here is a definition of a variable at playbook level, meaning it can be used by every workflow step;
Which can be referenced in the step;
If I wanted to define a workflow step specific variable, I could do so inside the step itself using the
Once this step has been executed, data will be returned as a result of the step (a response from the threat intel feed). Once complete, the
"on_completion" value defines the next step, in this case a
parallel type step (
The Parallel Step is a playbook step type that allows playbook authors to define two or more steps that can be executed at the same time (e.g. perform two single steps in parallel).
In the example below, two single steps should be conducted in parallel.
Now, in many cases the suspicious IP that triggered the start of the playbook might not be malicious at all. In this playbook, a benign IOC could be described as an IOC that returned no information from the threat intelligence provider.
This is where you would want to introduce conditional logic into your workflow.
Conditional Steps (if, while, switch)
CACAO offers three types of conditional steps:
conditions are defined in the step itself.
In my example, I could create new step defining how the response of the threat intel lookup should be handled if the response matches (
on_true) or does not match (
on_false) the condition.
Playbook workflow Step
Chaining playbooks can also prove incredibly useful.
Instead of referencing a step in an existing playbook, an
on_completion step can also start another playbook using a Playbook workflow Step.
When a step references an external playbook as above it can take
in_args, an optional list of arguments passed to the target(s) as input to the referenced playbook and
out_args, variables taken from the completion of the referenced playbook for use in the next step of this playbook (in this case
Putting it all together
You can see a basic example of how json objects can be put together to create an entire playbook flow.
In the next tutorial in this series I will show you how to write even more complex playbooks.
CACAO Certification (Virtual and In Person)
The content used in this post is a small subset of our full training material used in our CACAO training.
If you want to join a select group of certified CACAO professionals, subscribe to our newsletter below to be notified of new course dates.
Similar Posts You Will Enjoy Reading…
Originally published at https://www.signalscorps.com on November 14, 2022.