In cybersecurity, there has been a shift to adopt more software development principles in order to create security solutions quickly and reliably. Utilization of tools like Git and Continuous Integration/Continuous Deployment (CICD) pipelines have become more common to achieve reliable deployments. At Tines, while we strive to make automation accessible to anyone without development skills, our platform is also highly flexible to accommodate developer-centric uses.
"Detection-as-code” is one such introduction of development principles into cybersecurity. Detection-as-code is a means of managing detection rules and other content for SIEM or XDR in a more structured fashion. Generally, to create a new detection rule or improve an existing one, an analyst would go into the tool's console and utilize that tool's capabilities to make the changes. The changes in the user interface are usually difficult to keep track of and provide little in the way of peer review compared to how software developers update an application. As a result, Detection-as-code has begun utilizing APIs and deployment pipelines to provide the desired auditing capabilities moving security operations closer to software development.
Ideas for detection rules are more prevalent than ever and are shared pervasively on platforms like GitHub. Companies and communities such as Sigma, SOC Prime, Microsoft, and Elastic are all contributing to the public good by sharing their research and rules for use by anyone. The platforms they use to share this content fit nicely into the GitHub Flow model for software development.
Now that more resources are available in platforms that adhere to current software development models, the open-ended question is how to go about actually utilizing all of these resources for security tooling. Of course, it depends on the platforms your organization utilizes, but a major hurdle to getting started is having access to a working example to reference. This article and associated resources aim to be that reference to get started.
Environment overview
We’ve chosen some widely used and very accessible platforms for you to be able to utilize some of the examples provided.
Elastic: SIEM
GitHub: detection content development
GitHub Actions: CI/CD
GitHub Issues: SIEM alert management
Tines: alert and response handling
Many other platforms for SIEM or CICD could be used in place of these, but the concepts outlined to start with detection-as-code should not change significantly. Code examples and references mentioned here are contained in this repository unless otherwise noted.
Elastic SIEM configuration
Using Elastic Cloud is the fastest way to get started with Elastic SIEM. After signing up for an account and creating a new deployment, Elastic SIEM will be available for use.
Using any of the rules listed, we’ll create an Action that will send any detections to a Tines webhook so we can handle alerts that are produced. By doing this, we can also use this webhook destination in other rules we’ll create.
This is the configuration used for the Action:
[{{#context.alerts}}{{{.}}},{{/context.alerts}}null]
Additionally, set a custom header of content-type: text/plain
.Once the Action is created, we export the rule to get the raw configuration of the Action, like the Action ID, that we will use later when we’re writing our rule as code.
The Elastic detection rules repository
Elastic provides its detection rules and takes contributions in a GitHub repository. Every time a new rule is added to their repository, a number of checks and tests are run to ensure that the rules will be deployed successfully to Elastic SIEM. These checks form a starting point for our uses as well.
Fork or clone Elastic's repository to create a new version to modify. This will enable all changes, such as new rules, to the upstream repository owned by Elastic to be added to the new repository. Cloning the repository will remove that upstream link, and any new rules will need to be brought over via another process.
With this new repository, in the rules
directory, create a new directory named custom
that will contain newly created rules for our purposes. For this example, the rule located at /rules/windows/discovery_whoami_command_activity.toml
is copied to the custom
directory as /rules/custom/discovery_whoami_command_activity_tines.toml
and modified to create the first custom rule that will be added to Elastic SIEM.
When we edit the new rule, we’ll update the name of the rule as it will appear in Elastic SIEM and add to the TOML file the alert configuration that was set above and exported to the JSON file containing the rule action configuration.
Next is configuring the testing and deployment of the new rule that was created using GitHub Actions.
GitHub Actions CICD setup
GitHub Actions are defined in each repository as YAML files in the .github/workflows
directory. In this instance, some of what Elastic provides will be used as inspiration but it will be mostly reconfigured for the detection-as-code use. The file that will be kept is lock-versions.yml, and two new files will be created called pull-request.yml for pull request testing and deploy.yml to deploy to Elastic SIEM after rule changes are approved.
In the workflow file for pull requests, GitHub will utilize a Python script provided by Elastic in the repository to validate and test that the added rules meet a high configuration standard and won't produce errors when deployed to Elastic SIEM.
The workflow file for deploying changes includes a slightly modified script, update_rules.py, provided by Stijn Holzhauer of the Elastic community that will create or update the rules in Elastic SIEM. This script handles the connection to Elastic SIEM using environment variables for the Kibana URL, Kibana user, and Kibana password to interact with the Kibana API.
The environment variables are set using GitHub repository secrets and are local to the repository and GitHub Actions running the workflows.
Making rule changes
At this point, rule changes can be made following the Github Flow in order to update Elastic SIEM from our code repository. A new code branch is first created. The custom rule can be edited in that code branch with a new matching query for detection purposes.
For my “whoami” rule, it was made to match against Windows hosts, which use the executable “whoami.exe”, but if it should match against Mac hosts, it could be changed to just “whoami”.
process where event.type in ("start", "process_started") and process.name : "whoami.exe"
changed to
process where event.type in ("start", "process_started") and process.name : "whoami"
After committing and making a pull request, the pull request workflow testing the rule and its required components will run.
Once the tests run successfully, the pull request can be merged into the main code branch and the rules will be deployed via the deploy workflow.
Handling alerts in Tines
With the detection rule deployed and the Tines webhook ready to receive alerts, we can begin building out the Tines Story to handle the alerts. Instead of tra