facebookincubator / TTPForge

The TTPForge is a Cybersecurity Framework for developing, automating, and executing attacker Tactics, Techniques, and Procedures (TTPs).
MIT License
344 stars 34 forks source link

🚨 [BUG] - CreateFile Step Fails when Directory in Path Does Not Exist #506

Closed d0n601 closed 3 months ago

d0n601 commented 4 months ago

What happened?

Executing the create_file step fails when the path contains a directory or subdirectory that does not exist.

Steps to Reproduce

  1. Modify the basic.yaml example to include a subdirectory in /tmp that does not exist.
---
api_version: 2.0
uuid: df306aab-5824-4e32-bd04-76fb49da6b17
name: create_file_and_subdirectories
description: |
  This TTP shows you how to use the create_file action type
  to create files on disk
steps:
  - name: create-first-tmp-file
    create_file: /tmp/folder_does_not_exist/ttpforge_create_file_{{randAlphaNum 10}}
    contents: |
      Using create_file is a convenient to simulate TTPs that
      drop files to disk. We can control the permission mode
      with which the file is created using `mode:`
    cleanup: default
  1. Execute the TTP on Linux, see that the step fails to execute /tmp/folder_does_not_exist/ttpforge_create_file_GMAdvgIrzT: no such file or directory.

Expected Behavior

  1. The createfile_test.go indicates on Lines 54-60 that this functionality should not fail, and instead should create the necessary subdirectories.

Any suggestions for fixing this bug?

This seems like an issue between how Afero works, and how the OS file system is working here.

More TBD

Relevant log output

ttpforge run examples//actions/create-file/basic.yaml
INFO    RUNNING TTP: create_file_and_subdirectories
INFO    ----------------------------------------
INFO    Executing Step #1: "create-first-tmp-file"
INFO    Creating file /tmp/folder_does_not_exist/ttpforge_create_file_GMAdvgIrzT
ERROR   Failed to execute step create-first-tmp-file: open /tmp/folder_does_not_exist/ttpforge_create_file_GMAdvgIrzT: no such file or directory
INFO    ----------------------------------------
ERROR   [*] Error executing TTP: open /tmp/folder_does_not_exist/ttpforge_create_file_GMAdvgIrzT: no such file or directory
INFO    ========================================
INFO    CLEANING UP 0 steps of TTP: "create_file_and_subdirectories"
INFO    ----------------------------------------
INFO    Finished Cleanup Successfully ✅
ERROR   failed to run command:
        failed to run TTP at ....../ttpforge/example-ttps/actions/create-file/basic.yaml: <nil>


### Details about your environment

* OS: Red Hat
* Go Version: `1.22.4`:
inesusvet commented 3 months ago

From the golang 1.23 os/file.go

// Flags to OpenFile wrapping those of the underlying system. Not all
// flags may be implemented on a given system.
const (
    // Exactly one of O_RDONLY, O_WRONLY, or O_RDWR must be specified.
    O_RDONLY int = syscall.O_RDONLY // open the file read-only.
    O_WRONLY int = syscall.O_WRONLY // open the file write-only.
    O_RDWR   int = syscall.O_RDWR   // open the file read-write.
    // The remaining values may be or'ed in to control behavior.
    O_APPEND int = syscall.O_APPEND // append data to the file when writing.
    O_CREATE int = syscall.O_CREAT  // create a new file if none exists.
    O_EXCL   int = syscall.O_EXCL   // used with O_CREATE, file must not exist.
    O_SYNC   int = syscall.O_SYNC   // open for synchronous I/O.
    O_TRUNC  int = syscall.O_TRUNC  // truncate regular writable file when opened.
)

Which makes me think that we might want to call MkdirAll function before creating a file