Package: atomic-operator
atomic-operatorThis python package is used to execute Atomic Red Team tests (Atomics) across multiple operating system environments.(What's new?)Why?atomic-operatorenables security professionals to test their detection and defensive capabilities against prescribed techniques defined withinatomic-red-team. By utilizing a testing framework such asatomic-operator, you can identify both your defensive capabilities as well as gaps in defensive coverage.Additionally,atomic-operatorcan be used in many other situations like:Generating alerts to test productsTesting EDR and other security toolsIdentifying way to perform defensive evasion from an adversary perspectivePlus more.FeaturesSupport local and remote execution of Atomic Red Teams tests on Windows, macOS, and Linux systemsSupports running atomic-tests againstiaas:awsCan prompt for input arguments but not requiredAssist with downloading the atomic-red-team repositoryCan be automated further based on a configuration fileA command-line and importable Python packageSelect specific tests when one or more techniques are specifiedSearch across all atomics for that perfect testPass input_arguments as input for tests via command linePlus moreGetting Startedatomic-operatoris a Python-only package hosted onPyPiand works with Python 3.6 and greater.If you are wanting a PowerShell version, please checkoutInvoke-AtomicRedTeam.pipinstallatomic-operatorThe next steps will guide you through setting up and runningatomic-operator.Get AtomicsInstall / clone Atomic Red Team repositoryatomic-operatorUnderstand the options availble in atomic-operatorRunning Test on Command LineorRunning Tests within a ScriptRunning Tests via Configuration FileInstallationYou can installatomic-operatoron OS X, Linux, or Windows. You can also install it directly from the source. To install, see the commands under the relevant operating system heading, below.PrerequisitesThe following libraries are required and installed by atomic-operator:pyyaml==5.4.1
fire==0.4.0
requests==2.26.0
attrs==21.2.0
pick==1.2.0macOS, Linux and Windows:pipinstallatomic-operatormacOS using M1 processorgitclonehttps://github.com/swimlane/atomic-operator.gitcdatomic-operator# Satisfy ModuleNotFoundError: No module named 'setuptools_rust'brewinstallrust
pip3install--upgradepip
pip3installsetuptools_rust# Back to our regularly scheduled programming . . .pipinstall-rrequirements.txt
pythonsetup.pyinstallInstalling from sourcegitclonehttps://github.com/swimlane/atomic-operator.gitcdatomic-operator
pipinstall-rrequirements.txt
pythonsetup.pyinstallUsage example (command line)You can runatomic-operatorfrom the command line or within your own Python scripts. To useatomic-operatorat the command line simply enter the following in your terminal:atomic-operator--help
atomic-operatorrun----helpPlease note that to see details about the run command runatomic-operator run -- --helpand NOTatomic-operator run --helpRetrieving Atomic TestsIn order to useatomic-operatoryou must have one or moreatomic-red-teamtests (Atomics) on your local system.atomic-operatorprovides you with the ability to download the Atomic Red Team repository. You can do so by running the following at the command line:atomic-operatorget_atomics# You can specify the destination directory by using the --destination flagatomic-operatorget_atomics--destination"/tmp/some_directory"Running Tests LocallyIn order to run a test you must provide some additional properties (and options if desired). The main method to run tests is namedrun.# This will run ALL tests compatiable with your local operating systematomic-operatorrun--atomics-path"/tmp/some_directory/redcanaryco-atomic-red-team-3700624"You can select individual tests when you provide one or more specific techniques. For example running the following on the command line:atomic-operatorrun--techniquesT1564.001--select_testsWill prompt the user with a selection list of tests associated with that technique. A user can select one or more tests by using the space bar to highlight the desired test:Select Test(s) for Technique T1564.001 (Hide Artifacts: Hidden Files and Directories)

 * Create a hidden file in a hidden directory (61a782e5-9a19-40b5-8ba4-69a4b9f3d7be)
   Mac Hidden file (cddb9098-3b47-4e01-9d3b-6f5f323288a9)
   Create Windows System File with Attrib (f70974c8-c094-4574-b542-2c545af95a32)
   Create Windows Hidden File with Attrib (dadb792e-4358-4d8d-9207-b771faa0daa5)
   Hidden files (3b7015f2-3144-4205-b799-b05580621379)
   Hide a Directory (b115ecaf-3b24-4ed2-aefe-2fcb9db913d3)
   Show all hidden files (9a1ec7da-b892-449f-ad68-67066d04380c)The following will allow you to provide custom input arguments for tests. You do this providing a dictionary of keys and values as a dictionary to theinput_argumentsparameter on the run method.atomic-operatorrun--techniquesT1564.001--input_arguments'{"project-id": "some_value", "another_key": "another value"}'# Please include single quotes around the input_arguments value.Running Tests RemotelyIn order to run a test remotely you must provide some additional properties (and options if desired). The main method to run tests is namedrun.# This will run ALL tests compatiable with your local operating systematomic-operatorrun--atomics-path"/tmp/some_directory/redcanaryco-atomic-red-team-3700624"--hosts"10.32.1.0"--username"my_username"--password"my_password"When running commands remotely against Windows hosts you may need to configure PSRemoting. See details here:Windows RemotingAdditional parametersYou can see additional parameters by running the following command:atomic-operatorrun----helpParameter NameTypeDefaultDescriptiontechniqueslistallOne or more defined techniques by attack_technique ID.test_guidslistNoneOne or more Atomic test GUIDs.select_testsboolFalseSelect one or more atomic tests to run when a techniques are specified.atomics_pathstros.getcwd()The path of Atomic tests.input_argumentsdict{}A dictionary of input arguments to pass to the test.check_prereqsboolFalseWhether or not to check for prereq dependencies (prereq_comand).get_prereqsboolFalseWhether or not you want to retrieve prerequisites.cleanupboolFalseWhether or not you want to run cleanup command(s).copy_source_filesboolTrueWhether or not you want to copy any related source (src, bin, etc.) files to a remote host.command_timeoutint20Time duration for each command before timeout.debugboolFalseWhether or not you want to output details about tests being ran.prompt_for_input_argsboolFalseWhether you want to prompt for input arguments for each test.return_atomicsboolFalseWhether or not you want to return atomics instead of running them.config_filestrNoneA path to a conifg_file which is used to automate atomic-operator in environments.config_file_onlyboolFalseWhether or not you want to run tests based on the provided config_file only.hostslistNoneA list of one or more remote hosts to run a test on.usernamestrNoneUsername for authentication of remote connections.passwordstrNonePassword for authentication of remote connections.ssh_key_pathstrNonePath to a SSH Key for authentication of remote connections.private_key_stringstrNoneA private SSH Key string used for authentication of remote connections.verify_sslboolFalseWhether or not to verify ssl when connecting over RDP (windows).ssh_portint22SSH port for authentication of remote connections.ssh_timeoutint5SSH timeout for authentication of remote connections.**kwargsdictNoneIf additional flags are passed into the run command then we will attempt to match them with defined inputs within Atomic tests and replace their value with the provided value.You should see a similar output to the following:NAME
    atomic-operator run - The main method in which we run Atomic Red Team tests.

SYNOPSIS
    atomic-operator run <flags>

DESCRIPTION
    The main method in which we run Atomic Red Team tests.

FLAGS
    --techniques=TECHNIQUES
        Type: list
        Default: ['all']
        One or more defined techniques by attack_technique ID. Defaults to 'all'.
    --test_guids=TEST_GUIDS
        Type: list
        Default: []
        One or more Atomic test GUIDs. Defaults to None.
    --select_tests=SELECT_TESTS
        Type: bool
        Default: False
        Select one or more tests from provided techniques. Defaults to False.
    --atomics_path=ATOMICS_PATH
        Default: '/U...
        The path of Atomic tests. Defaults to os.getcwd().
    --input_arguments={}
        Default: {}
        A dictionary of input arguments to pass to the test.
    --check_prereqs=CHECK_PREREQS
        Default: False
        Whether or not to check for prereq dependencies (prereq_comand). Defaults to False.
    --get_prereqs=GET_PREREQS
        Default: False
        Whether or not you want to retrieve prerequisites. Defaults to False.
    --cleanup=CLEANUP
        Default: False
        Whether or not you want to run cleanup command(s). Defaults to False.
    --copy_source_files=COPY_SOURCE_FILES
        Default: True
        Whether or not you want to copy any related source (src, bin, etc.) files to a remote host. Defaults to True.
    --command_timeout=COMMAND_TIMEOUT
        Default: 20
        Timeout duration for each command. Defaults to 20.
    --debug=DEBUG
        Default: False
        Whether or not you want to output details about tests being ran. Defaults to False.
    --prompt_for_input_args=PROMPT_FOR_INPUT_ARGS
        Default: False
        Whether you want to prompt for input arguments for each test. Defaults to False.
    --return_atomics=RETURN_ATOMICS
        Default: False
        Whether or not you want to return atomics instead of running them. Defaults to False.
    --config_file=CONFIG_FILE
        Type: Optional[]
        Default: None
        A path to a conifg_file which is used to automate atomic-operator in environments. Default to None.
    --config_file_only=CONFIG_FILE_ONLY
        Default: False
        Whether or not you want to run tests based on the provided config_file only. Defaults to False.
    --hosts=HOSTS
        Default: []
        A list of one or more remote hosts to run a test on. Defaults to [].
    --username=USERNAME
        Type: Optional[]
        Default: None
        Username for authentication of remote connections. Defaults to None.
    --password=PASSWORD
        Type: Optional[]
        Default: None
        Password for authentication of remote connections. Defaults to None.
    --ssh_key_path=SSH_KEY_PATH
        Type: Optional[]
        Default: None
        Path to a SSH Key for authentication of remote connections. Defaults to None.
    --private_key_string=PRIVATE_KEY_STRING
        Type: Optional[]
        Default: None
        A private SSH Key string used for authentication of remote connections. Defaults to None.
    --verify_ssl=VERIFY_SSL
        Default: False
        Whether or not to verify ssl when connecting over RDP (windows). Defaults to False.
    --ssh_port=SSH_PORT
        Default: 22
        SSH port for authentication of remote connections. Defaults to 22.
    --ssh_timeout=SSH_TIMEOUT
        Default: 5
        SSH timeout for authentication of remote connections. Defaults to 5.
    Additional flags are accepted.
        If provided, keys matching inputs for a test will be replaced. Default is None.Running atomic-operator using a config_fileIn addition to the ability to pass in parameters withatomic-operatoryou can also pass in a path to aconfig_filethat contains all the atomic tests and their potential inputs. You can see an example of this config_file here:atomic_tests:-guid:f7e6ec05-c19e-4a80-a7e7-241027992fdbinput_arguments:output_file:value:custom_output.txtinput_file:value:custom_input.txt-guid:3ff64f0b-3af2-3866-339d-38d9791407c3input_arguments:second_arg:value:SWAPPPED argument-guid:32f90516-4bc9-43bd-b18d-2cbe0b7ca9b2Usage example (scripts)To useatomic-operatoryou must instantiate anAtomicOperatorobject.fromatomic_operatorimportAtomicOperatoroperator=AtomicOperator()# This will download a local copy of the atomic-red-team repositoryprint(operator.get_atomics('/tmp/some_directory'))# this will run tests on your local systemoperator.run(technique:str='All',atomics_path=os.getcwd(),check_dependencies=False,get_prereqs=False,cleanup=False,command_timeout=20,debug=False,prompt_for_input_args=False,**kwargs)Getting HelpPlease create anissueif you have questions or run into any issues.Built Withcarcass- Python packaging templateContributingPlease readCONTRIBUTING.mdfor details on our code of conduct, and the process for submitting pull requests to us.VersioningWe useSemVerfor versioning.AuthorsJosh Rickard -Initial work-MSAdministratorSee also the list ofcontributorswho participated in this project.LicenseThis project is licensed under the MIT License - see theLICENSEfile for detailsShoutoutThanks tokeithmccammonfor helping identify issues with macOS M1 based proccesssor and providing a fix