From 23aa86035aa9ebb61455e6468e30436386902a87 Mon Sep 17 00:00:00 2001 From: Jayson Grace Date: Sat, 6 Apr 2024 02:14:39 -0600 Subject: [PATCH] Fixed linux install; refactored PowerShell installation and execution paths for Atomic Red Team **Added:** - Added variables for PowerShell version and installation path. - Included common, Debian-specific, and RedHat-specific package lists for installation. **Changed:** - Refactored PowerShell installation to use a generic approach with architecture mapping. - Updated `invoke-atomictest.yml` to use the `pwsh` command without absolute paths. - Simplified `setup-linux.yml` to streamline PowerShell setup and remove old installation methods. **Removed:** - Removed old PowerShell installation tasks specific to Ubuntu, Amazon Linux, and CentOS. --- defaults/main.yml | 4 ++ example-playbook.yml | 2 +- tasks/invoke-atomictest.yml | 26 ++++--- tasks/setup-linux.yml | 137 +++++++++++++++--------------------- vars/main.yml | 13 ++++ vars/update-art-tids.sh | 16 ++--- 6 files changed, 99 insertions(+), 99 deletions(-) diff --git a/defaults/main.yml b/defaults/main.yml index dd2c428..9aeb3c3 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -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" diff --git a/example-playbook.yml b/example-playbook.yml index 2ceadeb..ea2d21c 100644 --- a/example-playbook.yml +++ b/example-playbook.yml @@ -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) diff --git a/tasks/invoke-atomictest.yml b/tasks/invoke-atomictest.yml index 717edda..6a7c1f1 100644 --- a/tasks/invoke-atomictest.yml +++ b/tasks/invoke-atomictest.yml @@ -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 @@ -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: @@ -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: @@ -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: | diff --git a/tasks/setup-linux.yml b/tasks/setup-linux.yml index 3352834..e037783 100644 --- a/tasks/setup-linux.yml +++ b/tasks/setup-linux.yml @@ -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 diff --git a/vars/main.yml b/vars/main.yml index ed97d53..9d2efb3 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -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 diff --git a/vars/update-art-tids.sh b/vars/update-art-tids.sh index eb3f0b2..3e1ea5c 100755 --- a/vars/update-art-tids.sh +++ b/vars/update-art-tids.sh @@ -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