Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
output/*
.vscode/*
.idea/*
.obsidian/*

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down Expand Up @@ -148,6 +150,7 @@ cython_debug/
# .tfstate files
*.tfstate
*.tfstate.*
*lock.hcl

# Crash log files
crash.log
Expand Down Expand Up @@ -175,3 +178,5 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc

test-files/
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ This is the repository containing Leonidas, a framework for executing attacker a
* Sigma rules (https://github.com/Neo23x0/sigma) for detection
* Documentation - see http://detectioninthe.cloud/ for an example

![Leonidas Architecture](./docs/architecture.png?raw=true "Leonidas Architecture")
The project was originally designed for use in AWS environments, with the following architecture:

![Leonidas Architecture](./docs/architecture.png)
In 2024, Leonidas was extended to support Kubernetes environments. Its resources can be deployed within the target cluster, as per the following architecture:
![Leonidas K8S Architecture](./docs/k8s-architecture.png)

## Deploying the API

The API is deployed via an AWS-native CI/CD pipeline. Instructions for this can be found at [Deploying Leonidas](./docs/deploying-leonidas.md).
The API is deployed into an AWS account via an AWS-native CI/CD pipeline, and into a Kubernetes cluster using auto-generated YAML manifests.
Instructions for both environments can be found at [Deploying Leonidas](./docs/deploying-leonidas.md).

## Using the API

Expand Down Expand Up @@ -39,10 +44,10 @@ The documentation is generated as follows:

This will produce markdown versions of the documentation available at `output/docs`. This can be uploaded to an existing markdown-based documentation system, or the following can be used to create a prettified HTML version of the docs:

* `cd output`
* `cd ../output`
* `mkdocs build`

This will create a `output/site` folder containing the HTML site. It is also possible to view this locally by running `mkdocs serve` in the same folder.
This will create an `output/site` folder containing the HTML site. It is also possible to view this locally by running `mkdocs serve` in the same folder.

## Writing Definitions

Expand Down Expand Up @@ -86,6 +91,10 @@ detection:

Project built and maintained by Nick Jones ( [NJonesUK](https://github.com/NJonesUK) / [@nojonesuk](https://twitter.com/nojonesuk)).

Kubernetes support added by Leo Tsaousis ( [@laripping](https://github.com/LAripping) ).

Special thanks also to Mohit Gupta ( @[Skybound1](https://github.com/Skybound1) ) for his invaluable contribution.

This project drew ideas and inspiration from a range of sources, including:

* [Pacu](https://github.com/RhinoSecurityLabs/pacu)
Expand Down
2 changes: 1 addition & 1 deletion aws-pipeline/codepipeline.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ resource "aws_iam_role" "codepipeline_role" {

# CodePipeline policy needed to use CodeCommit and CodeBuild
resource "aws_iam_role_policy" "attach_codepipeline_policy" {
name = "odepipeline-policy"
name = "codepipeline-policy"
role = aws_iam_role.codepipeline_role.id

policy = <<EOF
Expand Down
38 changes: 38 additions & 0 deletions definitions/credential_access/access-secrets-api-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Access Secrets from API Server
author: Leo Tsaousis
category: "Credential Access"
description: |
Enumerate cluster secrets by querying the API server

This test case only simulates a standard "list" verb, although the same result can also be achieved with a "watch" operation. The associated detection shall therefore not be considered complete, but only a 1-to-1 match of this particular test case.
mitre_ids:
- T1552.007
platform: kubernetes
permissions:
- namespaced: true
apiGroups: [""]
resources:
- secrets
verbs:
- list
input_arguments:
executors:
sh:
code: |
kubectl get secrets -o json
leonidas_kube:
implemented: True
detection:
sigma_id: eeb3e9e1-b685-44e4-9232-6bb701f925b5
status: experimental
level: low
sources:
- name: audit
attributes:
apiGroup: ""
resource: secrets
verb:
- list
references:
- https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/List%20K8S%20secrets/
33 changes: 33 additions & 0 deletions definitions/credential_access/access-secrets-pod-filesystem.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
name: Access Secrets from Pod
author: Leo Tsaousis
category: "Credential Access"
description: |
Access secrets within our own pod's filesystem

This test case simulates an adversary within a pod e.g. in the case of a compromised workload. As this operation would not go through the API server, no Audit event will be recorded and therefore no detection signature can be authored with the log sources currently available to Sigmahq. Instead, the detection's log source is set to the non-existent "Falco" source, should equivalent functionality be onboarded in the future.
mitre_ids:
- T1552.001
platform: kubernetes
permissions:
- namespaced: true
apiGroups: [""]
resources: [""]
verbs: [""]
input_arguments:
executors:
sh:
code: |
find /var/run/secrets/ -type f -exec cat {} \;
leonidas_kube:
implemented: True
detection: # Action not detectable via Audit logs. Present signature using an indicative alternative log source
sigma_id: 98a31be4-f1b6-47ed-9a7c-c564e4c7687b
status: unsupported # to ensure this does not find its way in production systems
level: low
sources:
- name: falco # indicative hypothetical log source
attributes:
filepathAccessed: /var/run/secrets # indicative filter for that hypothetical log source


39 changes: 39 additions & 0 deletions definitions/credential_access/app-creds-configmaps.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
name: Access Application Credentials from ConfigMaps
author: Leo Tsaousis
category: "Credential Access"
description: |
Attempt to Access Application Credentials by listing ConfigMaps

Despite this being a bad practice, Developers sometimes store secrets in the Kubernetes configuration files, such as environment variables in the pod configuration. Access to those configurations can be obtained by querying the API server.

This test case only simulates a standard "list" operation, although the same result can also be achieved with a "watch" operation. The associated detection shall therefore not be considered complete, but only a 1-to-1 match of this particular test case.
mitre_ids:
- T1552.007
platform: kubernetes
permissions:
- namespaced: true
apiGroups: [""]
resources:
- configmaps
verbs:
- list
input_arguments:
executors:
sh:
code: |
kubectl get configmaps
leonidas_kube:
implemented: True
detection:
sigma_id: 8235adde-cbe2-4cc0-a34d-1e8f0f068e48
status: experimental
level: low
sources:
- name: audit
attributes:
apiGroup: ""
resource: configmaps
verb: list
references:
- https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Application%20credentials%20in%20configuration%20files/
41 changes: 41 additions & 0 deletions definitions/credential_access/app-creds-env.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
name: Application Credentials from Environment Variables
author: Leo Tsaousis
category: "Credential Access"
description: |
Attempt to Access Application Credentials in Environmemt Variables

Developers store secrets in the Kubernetes configuration files, such as environment variables in the pod configuration. These variables can be listed within the description of pods.

This test case only simulates a standard "list" operation, although the same result can also be achieved with a "watch" operation. The associated detection shall therefore not be considered complete, but only a 1-to-1 match of this particular test case.
mitre_ids:
- T1552.007
platform: kubernetes
permissions:
- namespaced: true
apiGroups: [""]
resources:
- pods
verbs:
- list
input_arguments:
executors:
sh:
code: |
kubectl get pods -o=jsonpath="{.items[*].spec.containers[*].env}"
leonidas_kube:
implemented: True
detection:
sigma_id: ec8ec8b1-c696-4e9a-ae20-8e1c1f056b09
status: experimental
level: low
sources:
- name: audit
attributes:
apiGroup: ""
resource: pods
verb: list
falsepositives:
- get pods might be performed for various legitimate reasons. Stronger detections could be based on a correlation search for subsequent activity making use of environment variables
references:
- https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Application%20credentials%20in%20configuration%20files/
36 changes: 36 additions & 0 deletions definitions/defense_evasion/delete-kubernetes-events.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Delete Events
author: Leo Tsaousis
category: "Defense Evasion"
description: |
Delete all Kubernetes events within a namespace
mitre_ids:
- T1070
platform: kubernetes
permissions:
- namespaced: true
apiGroups: [""]
resources:
- events
verbs:
- delete
- list
input_arguments:
executors:
sh:
code: |
kubectl delete events --all
leonidas_kube:
implemented: True
detection:
sigma_id: 3132570d-cab2-4561-9ea6-1743644b2290
status: experimental
level: medium
sources:
- name: audit
attributes:
apiGroup: ""
resource: events
verb: delete
references:
- https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Delete%20K8S%20events/
40 changes: 40 additions & 0 deletions definitions/defense_evasion/pod-name-similarity.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
name: Pod Name Similarity
author: Leo Tsaousis
category: "Defense Evasion"
description: |
Deploy a backdoor container named to imitate system pods.

System pods, created by controllers such as Deployments or DaemonSets have random suffixes in their names. Attackers can use this fact and name their backdoor pods as if they were created by the existing controllers to avoid detection. This can be attempted in the kube-system namespace alongside the other administrative containers.

This test case creates pod imitating kube-proxy within the kube-system namespace, which is however based on a public image.
mitre_ids:
- T1036.005
platform: kubernetes
permissions:
- namespaced: false
apiGroups: [""]
resources:
- pods
verbs:
- create
input_arguments:
executors:
sh:
code: |
kubectl -n kube-system run kube-proxy-bv61v --image ubuntu --command -- sleep infinity
leonidas_kube:
implemented: True
detection:
sigma_id: a80d927d-ac6e-443f-a867-e8d6e3897318
status: experimental
level: medium
sources:
- name: audit
attributes:
apiGroup: ""
resource: pods
verb: create
namespace: kube-system
references:
- https://microsoft.github.io/Threat-Matrix-for-Kubernetes/techniques/Pod%20or%20container%20name%20similarily/
38 changes: 38 additions & 0 deletions definitions/discovery/enumerate-nodes.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Enumerate nodes
author: Leo Tsaousis
category: "Discovery"
description: |
Enumerate nodes within a cluster

This test case only simulates a standard "list" verb, although the same result can also be achieved with a "watch" operation. The associated detection shall therefore not be considered complete, but only a 1-to-1 match of this particular test case.
mitre_ids:
- T1580
- T1613
platform: kubernetes
permissions:
- namespaced: false
apiGroups: [""] # "" indicates the core API group
resources:
- nodes
verbs:
- list
input_arguments:
executors:
sh:
code: |
kubectl get nodes
leonidas_kube:
implemented: True
detection:
sigma_id: 7609f875-66d0-445e-ab16-8b3e53b1edc9
status: experimental
level: low
sources:
- name: audit
attributes:
apiGroup: ""
resource: nodes
verb: list
falsepositives:
- Legitimate administrative activity. Investigate for similar activity from the same identity that could indicate enumeration attempts
35 changes: 35 additions & 0 deletions definitions/discovery/enumerate-pods.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
name: Enumerate pods
author: Leo Tsaousis
category: "Discovery"
description: |
Enumerate pods within the Leonidas namepsace
mitre_ids:
- T1580
- T1613
platform: kubernetes
permissions:
- namespaced: true
apiGroups: [""] # "" indicates the core API group
resources:
- pods
verbs:
- list
input_arguments:
executors:
sh:
code: |
kubectl get pods
leonidas_kube:
implemented: True
detection:
sigma_id: 18490e7b-f1f3-484a-806b-4cb16aa225ce
status: experimental
level: low
sources:
- name: audit
attributes:
resource: pods
verb: list
falsepositives:
- Legitimate administrative activity. Investigate for similar activity from the same identity that could indicate enumeration attempts
Loading