diff --git a/example-ttps/cleanup/basic.yaml b/example-ttps/cleanup/basic.yaml new file mode 100644 index 00000000..76e7efb9 --- /dev/null +++ b/example-ttps/cleanup/basic.yaml @@ -0,0 +1,24 @@ +--- +name: Basic Cleanup Demonstration +description: | + Every time a step completes successfully, its cleanup action is enqueued. + Then, the enqueued cleanup steps are run in reverse order + ("last in, first out") whenever: + 1. The TTP Completes Successfully, or... + 2. A Step Fails +steps: + - name: first_step + print_str: | + This step completes successfully, so its cleanup action will be enqueued. + cleanup: + print_str: "Cleaning up first_step" + - name: second_step + print_str: | + This step has no cleanup action defined, so it will be skipped during cleanup + - name: third_step + print_str: | + This step uses an `inline:` action instead of a `print_str:` action + as its cleanup action - you may use any of TTPForge's supported action types + as a cleanup action. + cleanup: + inline: echo "Cleaning up third_step" diff --git a/example-ttps/cleanup/default.yaml b/example-ttps/cleanup/default.yaml new file mode 100644 index 00000000..bf4b3c8a --- /dev/null +++ b/example-ttps/cleanup/default.yaml @@ -0,0 +1,12 @@ +--- +name: Default Cleanup Actions Demo +description: | + Certain types of actions, such as `create_file`, have a default cleanup + action that you can enable by specifying `cleanup: default` in the relevant + step. This TTP shows how the `create_file` default cleanup action deletes + the created file. +steps: + - name: create_file_cleanup_demo + create_file: /tmp/ttpforge-default-cleanup-demo-{{randAlphaNum 10}} + contents: this will be automatically deleted... + cleanup: default diff --git a/example-ttps/cleanup/failure.yaml b/example-ttps/cleanup/failure.yaml new file mode 100644 index 00000000..4c0ef8ef --- /dev/null +++ b/example-ttps/cleanup/failure.yaml @@ -0,0 +1,27 @@ +--- +name: Basic Cleanup Demonstration +description: | + If a step fails, we stop executing new steps, and begin + cleaning up the prior steps in reverse order starting from the last + successful step. +steps: + - name: first_step + print_str: | + This step completes successfully, so its cleanup action will be enqueued. + cleanup: + print_str: Cleaning up first_step + - name: second_step + print_str: So does this step. + cleanup: + print_str: Cleaning up second_step + - name: third_step + inline: | + echo "This step fails, so it will not have its cleanup action run..." + notarealcommandwillcauseafailure + cleanup: + print_str: This won't run! + - name: fourth_step + print_str: | + Since the previous step failed, this step won't run at all... + cleanup: + print_str: ...and therefore its cleanup action won't run either. diff --git a/pkg/blocks/basicstep.go b/pkg/blocks/basicstep.go index 808c4acf..f9b124be 100755 --- a/pkg/blocks/basicstep.go +++ b/pkg/blocks/basicstep.go @@ -105,8 +105,6 @@ func (b *BasicStep) Execute(execCtx TTPExecutionContext) (*ActResult, error) { ctx, cancel := context.WithTimeout(context.Background(), 100*time.Minute) defer cancel() - logging.L().Info("========= Executing ==========") - if b.Inline == "" { return nil, fmt.Errorf("empty inline value in Execute(...)") } @@ -115,9 +113,6 @@ func (b *BasicStep) Execute(execCtx TTPExecutionContext) (*ActResult, error) { if err != nil { return nil, err } - - logging.L().Info("========= Done ==========") - return result, nil } diff --git a/pkg/blocks/ttps.go b/pkg/blocks/ttps.go index 224fc2da..721c6225 100755 --- a/pkg/blocks/ttps.go +++ b/pkg/blocks/ttps.go @@ -207,6 +207,7 @@ func (t *TTP) chdir() (func(), error) { // *StepResultsRecord: A StepResultsRecord containing the results of each step. // error: An error if any of the steps fail to execute. func (t *TTP) Execute(execCtx *TTPExecutionContext) (*StepResultsRecord, error) { + logging.L().Infof("RUNNING TTP: %v", t.Name) stepResults, firstStepToCleanupIdx, runErr := t.RunSteps(execCtx) if runErr != nil { // we need to run cleanup so we don't return here @@ -258,13 +259,12 @@ func (t *TTP) RunSteps(execCtx *TTPExecutionContext) (*StepResultsRecord, int, e } // actually run all the steps - logging.L().Infof("[+] Running current TTP: %s", t.Name) stepResults := NewStepResultsRecord() execCtx.StepResults = stepResults firstStepToCleanupIdx := -1 - for _, step := range t.Steps { + for stepIdx, step := range t.Steps { stepCopy := step - logging.L().Infof("[+] Running current step: %s", step.Name) + logging.L().Infof("Executing Step #%d: %s", stepIdx+1, step.Name) // core execution - run the step action stepResult, err := stepCopy.Execute(*execCtx) @@ -304,9 +304,6 @@ func (t *TTP) RunSteps(execCtx *TTPExecutionContext) (*StepResultsRecord, int, e } stepResults.ByName[step.Name] = execResult stepResults.ByIndex = append(stepResults.ByIndex, execResult) - - // Enters in reverse order - logging.L().Infof("[+] Finished running step: %s", step.Name) } return stepResults, firstStepToCleanupIdx, nil }