{"id":18483222,"url":"https://github.com/swimlane/atomic-operator","last_synced_at":"2025-04-06T23:16:46.329Z","repository":{"id":37587219,"uuid":"387910925","full_name":"swimlane/atomic-operator","owner":"swimlane","description":"A Python package is used to execute Atomic Red Team tests (Atomics) across multiple operating system environments.","archived":false,"fork":false,"pushed_at":"2023-12-24T06:21:15.000Z","size":979,"stargazers_count":139,"open_issues_count":10,"forks_count":23,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-04-14T06:41:19.466Z","etag":null,"topics":["deepdive","hacktoberfest"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swimlane.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"GitHub":["MSAdministrator"]}},"created_at":"2021-07-20T20:50:22.000Z","updated_at":"2024-06-20T23:28:52.852Z","dependencies_parsed_at":"2023-12-24T07:27:51.085Z","dependency_job_id":null,"html_url":"https://github.com/swimlane/atomic-operator","commit_stats":{"total_commits":485,"total_committers":6,"mean_commits":80.83333333333333,"dds":0.06391752577319587,"last_synced_commit":"58486f1099e230e08b791779026e2fa217e39a01"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimlane%2Fatomic-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimlane%2Fatomic-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimlane%2Fatomic-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swimlane%2Fatomic-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swimlane","download_url":"https://codeload.github.com/swimlane/atomic-operator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247563935,"owners_count":20958971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deepdive","hacktoberfest"],"created_at":"2024-11-06T12:34:54.543Z","updated_at":"2025-04-06T23:16:46.301Z","avatar_url":"https://github.com/swimlane.png","language":"Python","funding_links":["MSAdministrator"],"categories":[],"sub_categories":[],"readme":"[![PyPI](https://img.shields.io/pypi/v/atomic-operator.svg)][pypi status]\n[![Status](https://img.shields.io/pypi/status/atomic-operator.svg)][pypi status]\n[![Python Version](https://img.shields.io/pypi/pyversions/atomic-operator)][pypi status]\n[![License](https://img.shields.io/pypi/l/atomic-operator)][license]\n\n[![Read the documentation at https://atomic-operator.com/](https://img.shields.io/readthedocs/czds/latest.svg?label=Read%20the%20Docs)][read the docs]\n[![Code Quality \u0026 Tests](https://github.com/Swimlane/atomic-operator/actions/workflows/quality.yml/badge.svg)](https://github.com/Swimlane/atomic-operator/actions/workflows/quality.yml)\n\n[![Black](https://img.shields.io/badge/code%20style-black-000000.svg)][black]\n\n[pypi status]: https://pypi.org/project/atomic-operator/\n[read the docs]: https://atomic-operator.com\n[tests]: https://github.com/Swimlane/atomic-operator/actions?workflow=Quality\n[codecov]: https://app.codecov.io/gh/Swimlane/atomic-operator\n[pre-commit]: https://github.com/pre-commit/pre-commit\n[black]: https://github.com/psf/black\n\n# atomic-operator\n\n![](images/atomic-operator-logo.svg)\n\nThis python package is used to execute Atomic Red Team tests (Atomics) across multiple operating system environments.\n\n\u003e ([What's new?](CHANGELOG.md))\n\n## Why?\n\n`atomic-operator` enables security professionals to test their detection and defensive capabilities against prescribed techniques defined within [atomic-red-team](https://github.com/redcanaryco/atomic-red-team). By utilizing a testing framework such as `atomic-operator`, you can identify both your defensive capabilities as well as gaps in defensive coverage.\n\nAdditionally, `atomic-operator` can be used in many other situations like:\n\n- Generating alerts to test products\n- Testing EDR and other security tools\n- Identifying way to perform defensive evasion from an adversary perspective\n- Plus more.\n\n## Features\n\n* Support local and remote execution of Atomic Red Teams tests on Windows, macOS, and Linux systems\n* Supports running atomic-tests against `iaas:aws`\n* Can prompt for input arguments but not required\n* Assist with downloading the atomic-red-team repository\n* Can be automated further based on a configuration file\n* A command-line and importable Python package\n* Select specific tests when one or more techniques are specified\n* Search across all atomics for that perfect test\n* Pass input_arguments as input for tests via command line\n* Plus more\n\n## Getting Started\n\n`atomic-operator` is a Python-only package hosted on [PyPi](https://pypi.org/project/atomic-operator/) and works with Python 3.6 and greater.\n\nIf you are wanting a PowerShell version, please checkout [Invoke-AtomicRedTeam](https://github.com/redcanaryco/invoke-atomicredteam).\n\n```bash\npip install atomic-operator\n```\n\nThe next steps will guide you through setting up and running `atomic-operator`.\n\n* [Get Atomics](docs/atomics.md) Install / clone Atomic Red Team repository\n* [atomic-operator](docs/atomic-operator.md) Understand the options availble in atomic-operator\n* [Running Test on Command Line](docs/running-tests-command-line.md) or [Running Tests within a Script](docs/running-tests-script.md)\n* [Running Tests via Configuration File](atomic-operator-config.md)\n\n## Installation\n\nYou can install **atomic-operator** on 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.\n\n### Prerequisites\n\nThe following libraries are required and installed by atomic-operator:\n\n```\npyyaml==5.4.1\nfire==0.4.0\nrequests==2.26.0\nattrs==21.2.0\npick==1.2.0\n```\n\n### macOS, Linux and Windows:\n\n```bash\npip install atomic-operator\n```\n\n### macOS using M1 processor\n\n```bash\ngit clone https://github.com/swimlane/atomic-operator.git\ncd atomic-operator\n\n# Satisfy ModuleNotFoundError: No module named 'setuptools_rust'\nbrew install rust\npip3 install --upgrade pip\npip3 install setuptools_rust\n\n# Back to our regularly scheduled programming . . .  \npip install -r requirements.txt\npython setup.py install\n```\n\n### Installing from source\n\n```bash\ngit clone https://github.com/swimlane/atomic-operator.git\ncd atomic-operator\npip install -r requirements.txt\npython setup.py install\n```\n\n## Usage example (command line)\n\nYou can run `atomic-operator` from the command line or within your own Python scripts. To use `atomic-operator` at the command line simply enter the following in your terminal:\n\n```bash\natomic-operator --help\natomic-operator run -- --help\n```\n\n\u003e Please note that to see details about the run command run `atomic-operator run -- --help` and NOT `atomic-operator run --help`\n\n### Retrieving Atomic Tests\n\nIn order to use `atomic-operator` you must have one or more [atomic-red-team](https://github.com/redcanaryco/atomic-red-team) tests (Atomics) on your local system. `atomic-operator` provides you with the ability to download the Atomic Red Team repository. You can do so by running the following at the command line:\n\n```bash\natomic-operator get_atomics \n# You can specify the destination directory by using the --destination flag\natomic-operator get_atomics --destination \"/tmp/some_directory\"\n```\n\n### Running Tests Locally\n\nIn order to run a test you must provide some additional properties (and options if desired). The main method to run tests is named `run`.\n\n```bash\n# This will run ALL tests compatiable with your local operating system\natomic-operator run --atomics-path \"/tmp/some_directory/redcanaryco-atomic-red-team-3700624\"\n```\n\nYou can select individual tests when you provide one or more specific techniques. For example running the following on the command line:\n\n```bash\natomic-operator run --techniques T1564.001 --select_tests\n```\n\nWill 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:\n\n```text\n Select Test(s) for Technique T1564.001 (Hide Artifacts: Hidden Files and Directories)\n\n * Create a hidden file in a hidden directory (61a782e5-9a19-40b5-8ba4-69a4b9f3d7be)\n   Mac Hidden file (cddb9098-3b47-4e01-9d3b-6f5f323288a9)\n   Create Windows System File with Attrib (f70974c8-c094-4574-b542-2c545af95a32)\n   Create Windows Hidden File with Attrib (dadb792e-4358-4d8d-9207-b771faa0daa5)\n   Hidden files (3b7015f2-3144-4205-b799-b05580621379)\n   Hide a Directory (b115ecaf-3b24-4ed2-aefe-2fcb9db913d3)\n   Show all hidden files (9a1ec7da-b892-449f-ad68-67066d04380c)\n```\n\nThe 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 the `input_arguments` parameter on the run method.\n\n```bash\natomic-operator run --techniques T1564.001 --input_arguments '{\"project-id\": \"some_value\", \"another_key\": \"another value\"}'\n# Please include single quotes around the input_arguments value.\n```\n\n### Running Tests Remotely\n\nIn order to run a test remotely you must provide some additional properties (and options if desired). The main method to run tests is named `run`.\n\n```bash\n# This will run ALL tests compatiable with your local operating system\natomic-operator run --atomics-path \"/tmp/some_directory/redcanaryco-atomic-red-team-3700624\" --hosts \"10.32.1.0\" --username \"my_username\" --password \"my_password\"\n```\n\n\u003e When running commands remotely against Windows hosts you may need to configure PSRemoting. See details here: [Windows Remoting](docs/windows-remote.md)\n\n### Additional parameters\n\nYou can see additional parameters by running the following command:\n\n```bash\natomic-operator run -- --help\n```\n\n\n\n|Parameter Name|Type|Default|Description|\n|--------------|----|-------|-----------|\n|techniques|list|all|One or more defined techniques by attack_technique ID.|\n|test_guids|list|None|One or more Atomic test GUIDs.|\n|select_tests|bool|False|Select one or more atomic tests to run when a techniques are specified.|\n|atomics_path|str|os.getcwd()|The path of Atomic tests.|\n|input_arguments|dict|{}|A dictionary of input arguments to pass to the test.|\n|check_prereqs|bool|False|Whether or not to check for prereq dependencies (prereq_comand).|\n|get_prereqs|bool|False|Whether or not you want to retrieve prerequisites.|\n|cleanup|bool|False|Whether or not you want to run cleanup command(s).|\n|copy_source_files|bool|True|Whether or not you want to copy any related source (src, bin, etc.) files to a remote host.|\n|command_timeout|int|20|Time duration for each command before timeout.|\n|debug|bool|False|Whether or not you want to output details about tests being ran.|\n|prompt_for_input_args|bool|False|Whether you want to prompt for input arguments for each test.|\n|return_atomics|bool|False|Whether or not you want to return atomics instead of running them.|\n|config_file|str|None|A path to a conifg_file which is used to automate atomic-operator in environments.|\n|config_file_only|bool|False|Whether or not you want to run tests based on the provided config_file only.|\n|hosts|list|None|A list of one or more remote hosts to run a test on.|\n|username|str|None|Username for authentication of remote connections.|\n|password|str|None|Password for authentication of remote connections.|\n|ssh_key_path|str|None|Path to a SSH Key for authentication of remote connections.|\n|private_key_string|str|None|A private SSH Key string used for authentication of remote connections.|\n|verify_ssl|bool|False|Whether or not to verify ssl when connecting over RDP (windows).|\n|ssh_port|int|22|SSH port for authentication of remote connections.|\n|ssh_timeout|int|5|SSH timeout for authentication of remote connections.|\n|**kwargs|dict|None|If 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.|\n\n\nYou should see a similar output to the following:\n\n```text\nNAME\n    atomic-operator run - The main method in which we run Atomic Red Team tests.\n\nSYNOPSIS\n    atomic-operator run \u003cflags\u003e\n\nDESCRIPTION\n    The main method in which we run Atomic Red Team tests.\n\nFLAGS\n    --techniques=TECHNIQUES\n        Type: list\n        Default: ['all']\n        One or more defined techniques by attack_technique ID. Defaults to 'all'.\n    --test_guids=TEST_GUIDS\n        Type: list\n        Default: []\n        One or more Atomic test GUIDs. Defaults to None.\n    --select_tests=SELECT_TESTS\n        Type: bool\n        Default: False\n        Select one or more tests from provided techniques. Defaults to False.\n    --atomics_path=ATOMICS_PATH\n        Default: '/U...\n        The path of Atomic tests. Defaults to os.getcwd().\n    --input_arguments={}\n        Default: {}\n        A dictionary of input arguments to pass to the test.\n    --check_prereqs=CHECK_PREREQS\n        Default: False\n        Whether or not to check for prereq dependencies (prereq_comand). Defaults to False.\n    --get_prereqs=GET_PREREQS\n        Default: False\n        Whether or not you want to retrieve prerequisites. Defaults to False.\n    --cleanup=CLEANUP\n        Default: False\n        Whether or not you want to run cleanup command(s). Defaults to False.\n    --copy_source_files=COPY_SOURCE_FILES\n        Default: True\n        Whether or not you want to copy any related source (src, bin, etc.) files to a remote host. Defaults to True.\n    --command_timeout=COMMAND_TIMEOUT\n        Default: 20\n        Timeout duration for each command. Defaults to 20.\n    --debug=DEBUG\n        Default: False\n        Whether or not you want to output details about tests being ran. Defaults to False.\n    --prompt_for_input_args=PROMPT_FOR_INPUT_ARGS\n        Default: False\n        Whether you want to prompt for input arguments for each test. Defaults to False.\n    --return_atomics=RETURN_ATOMICS\n        Default: False\n        Whether or not you want to return atomics instead of running them. Defaults to False.\n    --config_file=CONFIG_FILE\n        Type: Optional[]\n        Default: None\n        A path to a conifg_file which is used to automate atomic-operator in environments. Default to None.\n    --config_file_only=CONFIG_FILE_ONLY\n        Default: False\n        Whether or not you want to run tests based on the provided config_file only. Defaults to False.\n    --hosts=HOSTS\n        Default: []\n        A list of one or more remote hosts to run a test on. Defaults to [].\n    --username=USERNAME\n        Type: Optional[]\n        Default: None\n        Username for authentication of remote connections. Defaults to None.\n    --password=PASSWORD\n        Type: Optional[]\n        Default: None\n        Password for authentication of remote connections. Defaults to None.\n    --ssh_key_path=SSH_KEY_PATH\n        Type: Optional[]\n        Default: None\n        Path to a SSH Key for authentication of remote connections. Defaults to None.\n    --private_key_string=PRIVATE_KEY_STRING\n        Type: Optional[]\n        Default: None\n        A private SSH Key string used for authentication of remote connections. Defaults to None.\n    --verify_ssl=VERIFY_SSL\n        Default: False\n        Whether or not to verify ssl when connecting over RDP (windows). Defaults to False.\n    --ssh_port=SSH_PORT\n        Default: 22\n        SSH port for authentication of remote connections. Defaults to 22.\n    --ssh_timeout=SSH_TIMEOUT\n        Default: 5\n        SSH timeout for authentication of remote connections. Defaults to 5.\n    Additional flags are accepted.\n        If provided, keys matching inputs for a test will be replaced. Default is None.\n```\n\n### Running atomic-operator using a config_file\n\nIn addition to the ability to pass in parameters with `atomic-operator` you can also pass in a path to a `config_file` that contains all the atomic tests and their potential inputs. You can see an example of this config_file here:\n\n```yaml\natomic_tests:\n  - guid: f7e6ec05-c19e-4a80-a7e7-241027992fdb\n    input_arguments:\n      output_file:\n        value: custom_output.txt\n      input_file:\n        value: custom_input.txt\n  - guid: 3ff64f0b-3af2-3866-339d-38d9791407c3\n    input_arguments:\n        second_arg:\n          value: SWAPPPED argument\n  - guid: 32f90516-4bc9-43bd-b18d-2cbe0b7ca9b2\n```\n\n## Usage example (scripts)\n\nTo use **atomic-operator** you must instantiate an **AtomicOperator** object.\n\n```python\nfrom atomic_operator import AtomicOperator\n\noperator = AtomicOperator()\n\n# This will download a local copy of the atomic-red-team repository\n\nprint(operator.get_atomics('/tmp/some_directory'))\n\n# this will run tests on your local system\noperator.run(\n    technique: str='All', \n    atomics_path=os.getcwd(), \n    check_dependencies=False, \n    get_prereqs=False, \n    cleanup=False, \n    command_timeout=20, \n    debug=False,\n    prompt_for_input_args=False,\n    **kwargs\n)\n```\n\n## Getting Help\n\nPlease create an [issue](https://github.com/swimlane/atomic-operator/pulls) if you have questions or run into any issues.\n\n## Built With\n\n* [carcass](https://github.com/MSAdministrator/carcass) - Python packaging template\n\n## Contributing\n\nPlease read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us.\n\n## Versioning\n\nWe use [SemVer](http://semver.org/) for versioning. \n\n## Authors\n\n* Josh Rickard - *Initial work* - [MSAdministrator](https://github.com/MSAdministrator)\n\nSee also the list of [contributors](https://github.com/swimlane/atomic-operator/contributors) who participated in this project.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE.md) file for details\n\n## Shoutout\n\n- Thanks to [keithmccammon](https://github.com/keithmccammon) for helping identify issues with macOS M1 based proccesssor and providing a fix\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswimlane%2Fatomic-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswimlane%2Fatomic-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswimlane%2Fatomic-operator/lists"}