@@ -15,6 +15,7 @@ from pydantic import (
|
||||
constr,
|
||||
field_serializer,
|
||||
field_validator,
|
||||
model_validator,
|
||||
)
|
||||
from pydantic_core import PydanticCustomError
|
||||
from pydantic_core.core_schema import ValidationInfo
|
||||
@@ -179,6 +180,28 @@ class Atomic(BaseModel):
|
||||
)
|
||||
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):
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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: |
|
||||
|
||||
@@ -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: |
|
||||
|
||||
Reference in New Issue
Block a user