Skip to content

💡 [REQUEST] - TTP Setup Steps  #359

@d3sch41n

Description

@d3sch41n

Implementation PR

No response

Reference Issues

No response

Summary

TL;DR

We need the following features:

  • mark certain steps as "setup steps"
  • have these steps run only when required (e.g. when an attacker tool must be compiled for the first time), not on every TTP execution

ART has this functionality in their dependencies blocks:

  dependency_executor_name: command_prompt
  dependencies:
  - description: |
      Computer must have python 3 installed
    prereq_command: |
      py -3 --version >nul 2>&1
      exit /b %errorlevel%
    get_prereq_command: |
      echo "Python 3 must be installed manually"

Background: Reasons to Separate Setup Steps and Regular Steps

Setup Step Execution Can Require Specialized Tooling

For example, it may require specialized kernel headers or a C compiler to build a kernel module TTP,
but deploying that TTP should just require copying the resulting .ko file

Setup Steps May Require Specific Network Connectivity

A setup step that requires downloading mimikatz from github probably can’t even run in a network-locked-domain environment like a domain controller. However, that doesn't mean one shouldn't necessarily "assume breach"
and still run mimikatz TTPs that reference an already-downloaded binary.

Setup Steps May Take a Long Time to Run

You shouldn’t be building a giant executable from source every time you want to run it.

Setup Steps May be Shared Across TTPs

Suppose that you have a given TTP that uses the ttp: syntax to start multiple kubernetes pods from the same base docker image. That docker image shouldn’t get rebuilt every time.

Proposed Solution

We should reuse many of our existing steps for this purpose:

setup:
  steps:
    - name: download_mimikatz 
       fetch_uri: ...
       download_path: mimikatz.exe
       success_criteria:
         file_exists:
           path: mimikatz.exe 
           hash: ...

The steps: used in setup: can have the following custom behavior applied to them when invoked by ttpforge run:

  • the success_criteria checks will be run PRIOR to the execution of the step itself
  • if the success criteria is met, that step will be skipped (don't need to download mimikatz again if it is already there)
  • one can run ttpforge run --setup-only to run the setup steps without running the TTP - useful for situations where you want to package the TTP in a tar file and deploy it elsewhere

Basic Example

Example links:

https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1003.002/T1003.002.yaml
https://github.com/redcanaryco/atomic-red-team/blob/0fbf08855e8955420672cb5e55db2f0e5f0e8588/atomics/T1609/T1609.yaml

Drawbacks

Sometimes you'll just want the "setup_step" to be part of the regular "steps:" array and have it get run
every time the TTP is executed. For example, dropping mimikatz might be part of the TTP and you may wish to explicitly measure the associated telemetry/EDR response.

Unresolved questions

No response

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions