From ca82c112881fbfc6617f38b3549827749c79f75f Mon Sep 17 00:00:00 2001 From: Hare Sudhan Date: Fri, 12 Jul 2024 17:54:28 -0500 Subject: [PATCH] fix atomics --- atomic_red_team/models.py | 23 +++++++++++++++++++ .../elevation_required_but_not_provided.yaml | 13 +++++++++++ atomic_red_team/validator.py | 4 ++++ atomics/T1070.003/T1070.003.yaml | 2 +- atomics/T1082/T1082.yaml | 1 + 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 atomic_red_team/test_data/elevation_required_but_not_provided.yaml diff --git a/atomic_red_team/models.py b/atomic_red_team/models.py index 003f0da8c9..4a3f82d160 100644 --- a/atomic_red_team/models.py +++ b/atomic_red_team/models.py @@ -15,6 +15,7 @@ constr, field_serializer, field_validator, + model_validator, ) from pydantic_core import PydanticCustomError from pydantic_core.core_schema import ValidationInfo @@ -179,6 +180,28 @@ def validate_dep_executor(cls, v, info: ValidationInfo): ) return v + @model_validator(mode="after") + def validate_elevation_required(self): + if ( + ("linux" in self.supported_platforms or "macos" in self.supported_platforms) + and not self.executor.elevation_required + and isinstance(self.executor, CommandExecutor) + ): + commands = [self.executor.command] + if self.executor.cleanup_command: + commands.append(self.executor.cleanup_command) + + if any(["sudo" in cmd for cmd in commands]): + raise PydanticCustomError( + "elevation_required_but_not_provided", + "'elevation_required' shouldn't be empty/false. Since `sudo` is used, set `elevation_required` to true`", + { + "loc": ["executor", "elevation_required"], + "input": self.executor.elevation_required, + }, + ) + return self + @field_validator("input_arguments", mode="before") # noqa @classmethod def validate(cls, v, info: ValidationInfo): diff --git a/atomic_red_team/test_data/elevation_required_but_not_provided.yaml b/atomic_red_team/test_data/elevation_required_but_not_provided.yaml new file mode 100644 index 0000000000..12a84b4dec --- /dev/null +++ b/atomic_red_team/test_data/elevation_required_but_not_provided.yaml @@ -0,0 +1,13 @@ +attack_technique: T1003 +display_name: OS Credential Dumping +atomic_tests: +- name: Root login + auto_generated_guid: + description: | + Login as root. + supported_platforms: + - linux + executor: + command: | + sudo -i + name: bash \ No newline at end of file diff --git a/atomic_red_team/validator.py b/atomic_red_team/validator.py index 6db1a5e8bc..66e14a8eb6 100644 --- a/atomic_red_team/validator.py +++ b/atomic_red_team/validator.py @@ -16,11 +16,15 @@ def format_validation_error(error: ValidationError): if len(error.errors()) == 1: err = error.errors()[0] message = "" + if err["type"] == "elevation_required_but_not_provided": + return {err["msg"]: list(err.get("loc")) + err.get("ctx").get("loc")} if err["input"] and err["type"] != "unused_input_argument": message += f"{err['input']} - " return {message + err["msg"]: err.get("loc")} inputs = collections.defaultdict(set) for e in error.errors(): + if e["type"] == "elevation_required_but_not_provided": + return {e["msg"]: e.get("loc") + e.get("ctx").get("loc")} # If it's a union type, then it generates multiple errors for the same input arguments. # Here we collect only the common paths. For example, # [( input_arguments, url_parsing),(input_arguments, string_mismatch)] => (input_arguments) diff --git a/atomics/T1070.003/T1070.003.yaml b/atomics/T1070.003/T1070.003.yaml index 4f1c38db60..5395698002 100644 --- a/atomics/T1070.003/T1070.003.yaml +++ b/atomics/T1070.003/T1070.003.yaml @@ -155,7 +155,7 @@ atomic_tests: name: bash command: | docker container prune -f && sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log - + elevation_required: true - name: Prevent Powershell History Logging auto_generated_guid: 2f898b81-3e97-4abb-bc3f-a95138988370 description: | diff --git a/atomics/T1082/T1082.yaml b/atomics/T1082/T1082.yaml index 954993050f..d9d3908d38 100644 --- a/atomics/T1082/T1082.yaml +++ b/atomics/T1082/T1082.yaml @@ -79,6 +79,7 @@ atomic_tests: sudo lsmod | grep -i "virtio_pci\|virtio_net" sudo lsmod | grep -i "hv_vmbus\|hv_blkvsc\|hv_netvsc\|hv_utils\|hv_storvsc" name: bash + elevation_required: true - name: FreeBSD VM Check via Kernel Modules auto_generated_guid: eefe6a49-d88b-41d8-8fc2-b46822da90d3 description: |