Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Molecule tests for atomic-red-team role #3

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,7 @@ banned_tids_windows:
art_tids_linux: []
art_tids_macos: []
art_tids_windows: []

# PowerShell version to install (if needed)
atomic_red_team_pwsh_version: "7.4.1"
atomic_red_team_nix_pwsh_path: "/opt/microsoft/powershell/7"
2 changes: 1 addition & 1 deletion example-playbook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
art_tids_windows:
# https://thedfirreport.com/2022/08/08/bumblebee-roasts-its-way-to-domain-admin/
- T1553.005:c2587b8d-743d-4985-aa50-c83394eaeb68 # download and mount iso, run lnk
- T1016 # System Network Configurration Discovery - 8 tests
- T1016 # System Network Configuration Discovery - 8 tests
- T1057 # Process Discovery - 5 tests
- T1219-2 # Install Anydesk
- T1087.002-5,6,7,8 # Account Discovery(domain)
Expand Down
13 changes: 13 additions & 0 deletions molecule/default/converge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name: Converge
hosts: all
tasks:
- name: Include default variables
ansible.builtin.include_vars:
file: "../../defaults/main.yml"
- name: Include variables
ansible.builtin.include_vars:
file: "../../vars/main.yml"
roles:
- name: Run the atomic-red-team role
role: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}"
1 change: 1 addition & 0 deletions molecule/default/inventory
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
localhost
41 changes: 41 additions & 0 deletions molecule/default/molecule.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
# Run molecule inside of a docker container
driver:
name: docker

platforms:
- name: ubuntu-atomic-red-team
image: "geerlingguy/docker-ubuntu2204-ansible:latest"
# Setting the command to this is necessary for systemd containers
command: ""
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true

- name: kali-atomic-red-team
image: cisagov/docker-kali-ansible:latest
# Setting the command to this is necessary for systemd containers
command: ""
pre_build_image: true
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true

- name: redhat-atomic-red-team
image: "geerlingguy/docker-rockylinux9-ansible:latest"
# Setting the command to this is necessary for systemd containers
command: ""
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:rw
cgroupns_mode: host
privileged: true

provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}

verifier:
name: ansible
34 changes: 34 additions & 0 deletions molecule/default/verify.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
- name: Verify
hosts: all
gather_facts: true
tasks:
- name: Include default variables
ansible.builtin.include_vars:
file: "../../defaults/main.yml"

- name: Include variables
ansible.builtin.include_vars:
file: "../../vars/main.yml"

- name: Check if PowerShell is installed
ansible.builtin.shell:
cmd: "pwsh -NoProfile -v"
register: pwsh_version
ignore_errors: true

- name: Assert that PowerShell is installed
ansible.builtin.assert:
that:
- pwsh_version.rc == 0
- "'PowerShell' in pwsh_version.stdout"

- name: Check if /usr/local/bin is in $PATH
ansible.builtin.shell:
cmd: "echo $PATH"
register: system_path

- name: Assert that /usr/local/bin is in $PATH
ansible.builtin.assert:
that:
- "'/usr/local/bin' in system_path.stdout"
4 changes: 4 additions & 0 deletions requirements.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
collections:
- name: ansible.windows
- name: cowdogmoo.workstation
26 changes: 15 additions & 11 deletions tasks/invoke-atomictest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
cmd: |
Invoke-AtomicTest {{ testarg }} -CheckPrereqs
args:
executable: /usr/bin/pwsh
executable: pwsh
register: check_prereqs
failed_when: '"Prerequisites not met:" in check_prereqs.stdout'
changed_when: false
Expand All @@ -55,23 +55,25 @@
cmd: |
Invoke-AtomicTest {{ testarg }} -GetPrereqs
args:
executable: /usr/bin/pwsh
executable: pwsh
register: get_prereqs
ignore_errors: true
changed_when: true

- name: "Debug prereqs {{ item }}"
- name: Debug prereqs {{ item }}
ansible.builtin.debug:
var: get_prereqs.stdout
when: get_prereqs.changed
var: "{{ item }}"
loop: "{{ prereqs }}"

- name: "Execute {{ item }}"
ansible.builtin.shell:
cmd: |
Invoke-AtomicTest {{ testarg }} -Confirm:$false -TimeoutSeconds 300 -ExecutionLogPath /root/atc_execution.csv
args:
executable: /usr/bin/pwsh
executable: pwsh
register: execute_test
ignore_errors: true
changed_when: false

- name: "Execute {{ item }}"
ansible.builtin.debug:
Expand All @@ -82,9 +84,10 @@
cmd: |
Invoke-AtomicTest {{ testarg }} -Cleanup
args:
executable: /usr/bin/pwsh
executable: pwsh
register: cleanup_test
ignore_errors: true
changed_when: false

- name: "Cleanup {{ item }}"
ansible.builtin.debug:
Expand All @@ -108,11 +111,12 @@
Invoke-AtomicTest {{ testarg }} -GetPrereqs
register: get_prereqs
ignore_errors: true
changed_when: false
notify: debug_prereqs

- name: "Debug prereqs {{ item }}"
ansible.builtin.debug:
var: get_prereqs.stdout
when: get_prereqs.changed
- name: Debug prereqs {{ item }}
ansible.builtin.meta: debug
with_items: "{{ prereqs }}"

- name: "Execute {{ item }}"
ansible.windows.win_shell: |
Expand Down
137 changes: 58 additions & 79 deletions tasks/setup-linux.yml
Original file line number Diff line number Diff line change
@@ -1,90 +1,69 @@
---
- name: Powershell
- name: Install PowerShell on Linux
block:
- name: Check for powershell
ansible.builtin.shell:
cmd: pwsh -c '$true'
changed_when: false
rescue:
- name: Install dependencies
ansible.builtin.include_role:
name: cowdogmoo.workstation.package_management
vars:
package_management_common_install_packages: "{{ atomic_red_team_common_install_packages }}"
package_management_debian_specific_packages: "{{ atomic_red_team_debian_specific_packages }}"
package_management_redhat_specific_packages: "{{ atomic_red_team_redhat_specific_packages }}"
when: ansible_os_family in ['Debian', 'RedHat']

# ------- Ubuntu
- name: Set architecture mapping for PowerShell tar.gz packages
ansible.builtin.set_fact:
ps_arch_map:
x86_64: "x64"
aarch64: "arm64"

- name: Ensure powershell is installed (prereq)
ansible.builtin.package:
name:
- wget
- apt-transport-https
- software-properties-common
state: present
when: ansible_facts['distribution'] == 'Ubuntu'
- name: Set PowerShell package name based on architecture
ansible.builtin.set_fact:
ps_pkg_name: "powershell-{{ atomic_red_team_pwsh_version }}-linux-{{ ps_arch_map[ansible_architecture] }}.tar.gz"
when: ansible_architecture in ps_arch_map

- name: Ensure powershell is installed (repo keys)
ansible.builtin.apt:
deb: "https://packages.microsoft.com/config/ubuntu/{{ ansible_distribution_version }}/packages-microsoft-prod.deb"
when: ansible_facts['distribution'] == 'Ubuntu'
- name: Set PowerShell package download URL
ansible.builtin.set_fact:
ps_download_url: "https://github.com/PowerShell/PowerShell/releases/download/v{{ atomic_red_team_pwsh_version }}/{{ ps_pkg_name }}"
when: ansible_architecture in ps_arch_map

- name: Ensure powershell is installed (deb)
ansible.builtin.apt:
name: powershell
update_cache: yes
when: >-
ansible_facts['distribution'] == 'Ubuntu'

# ------- Amazon / CentOS

- name: Add Microsoft Repo (Amazon Linux 2)
- name: Download PowerShell package
ansible.builtin.get_url:
url: https://packages.microsoft.com/config/rhel/8/prod.repo
dest: /etc/yum.repos.d/microsoft.repo
mode: '0644'
owner: root
when: ansible_facts['distribution'] == 'Amazon'

- name: Add Microsoft Repo (CentOS)
ansible.builtin.get_url:
url: https://packages.microsoft.com/config/rhel/{{ ansible_distribution_major_version }}/prod.repo
dest: /etc/yum.repos.d/microsoft.repo
mode: '0644'
owner: root
when: ansible_facts['distribution'] == 'CentOS'

- name: Ensure powershell is installed (rpm)
ansible.builtin.yum:
name: powershell
update_cache: yes
when: >-
ansible_facts['distribution'] == 'CentOS' or
ansible_facts['distribution'] == 'Amazon'
url: "{{ ps_download_url }}"
dest: "/tmp/{{ ps_pkg_name }}"
mode: "0755"
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_id }}"
when: ps_pkg_name is defined

- name: Install Invoke-ART
ansible.builtin.shell:
cmd: |
IEX (IWR 'https://raw.githubusercontent.com/redcanaryco/invoke-atomicredteam/master/install-atomicredteam.ps1' -UseBasicParsing); Install-AtomicRedTeam -getAtomics -Force
args:
executable: /usr/bin/pwsh
creates: /root/AtomicRedTeam/atomics/Indexes/index.yaml
- name: Create PowerShell directory
become: true
ansible.builtin.file:
path: "{{ atomic_red_team_nix_pwsh_path }}"
state: directory
mode: "0755"
owner: "{{ ansible_user_id }}"
group: "{{ ansible_user_id }}"
when: ps_pkg_name is defined

- name: Find the path to the system powershell profile
ansible.builtin.shell:
cmd: |
$PROFILE.AllUsersAllHosts
changed_when: false
args:
executable: /usr/bin/pwsh
register: pwshprofile
- name: Extract PowerShell tar.gz
become: true
ansible.builtin.unarchive:
src: "/tmp/{{ ps_pkg_name }}"
dest: "{{ atomic_red_team_nix_pwsh_path }}"
remote_src: true
when: ps_pkg_name is defined

- name: Powershell Profile (debug)
ansible.builtin.debug:
var: pwshprofile.stdout
- name: Set execute permissions for pwsh
become: true
ansible.builtin.file:
path: "{{ atomic_red_team_nix_pwsh_path }}/pwsh"
mode: "+x"
when: ps_pkg_name is defined

- name: Add Invoke-AtomicRedTeam to the powershell profile
ansible.builtin.lineinfile:
path: "{{ pwshprofile.stdout }}"
state: present
regex: '.*Inovke-AtomicRedTeam.*'
line: |-
Import-Module "/root/AtomicRedTeam/invoke-atomicredteam/Invoke-AtomicRedTeam.psd1" -Force
owner: root
group: root
mode: '0644'
create: yes
- name: Create symlink for pwsh
become: true
ansible.builtin.file:
src: "{{ atomic_red_team_nix_pwsh_path }}/pwsh"
dest: "/usr/bin/pwsh"
state: link
when: ps_pkg_name is defined
13 changes: 13 additions & 0 deletions vars/main.yml
Original file line number Diff line number Diff line change
@@ -1 +1,14 @@
---
atomic_red_team_common_install_packages:
- wget

atomic_red_team_debian_specific_packages:
- apt-transport-https
- ca-certificates
- curl
- libunwind8
- software-properties-common
- wget

atomic_red_team_redhat_specific_packages:
- libicu
16 changes: 8 additions & 8 deletions vars/update-art-tids.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ branch="master"

echo "---" | tee art-tids.yml

function fetch-art-index-to-yml () {
url="https://github.com/${ghuser}/atomic-red-team/raw/${branch}/atomics/Indexes/Indexes-CSV/${1}-index.csv"
tidlist=( $(curl -sL $url | awk -F, '/T1/{print $2}' | sort -u) )
echo "art_tids_${1}:" | tee -a art-tids.yml
for tid in ${tidlist[*]}; do
echo " - ${tid}"
done | tee -a art-tids.yml
function fetch-art-index-to-yml() {
url="https://github.com/${ghuser}/atomic-red-team/raw/${branch}/atomics/Indexes/Indexes-CSV/${1}-index.csv"
tidlist=($(curl -sL $url | awk -F, '/T1/{print $2}' | sort -u))
echo "art_tids_${1}:" | tee -a art-tids.yml
for tid in ${tidlist[*]}; do
echo " - ${tid}"
done | tee -a art-tids.yml
}

for os in linux macos windows; do
fetch-art-index-to-yml ${os}
fetch-art-index-to-yml ${os}
done