Skip to content

Commit

Permalink
Add automated acceptance tests for cmd_exec
Browse files Browse the repository at this point in the history
  • Loading branch information
cgranleese-r7 committed Aug 20, 2024
1 parent 3589f54 commit 1e5a878
Show file tree
Hide file tree
Showing 19 changed files with 2,224 additions and 146 deletions.
222 changes: 201 additions & 21 deletions .github/workflows/acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ permissions:
statuses: none

on:
workflow_dispatch:
inputs:
metasploitPayloadsCommit:
description: 'metasploit-payloads branch would like to test'
required: true
default: '0b77a961b2f10fa1bee670ca49673801a70fa1e8'
mettleCommit:
description: 'mettle branch you would like to test'
required: true
# default: '375434396ff9a80880f9901f1dfd5b0226b9b4d9' # Master
# default: '08c2fb772ea48961909f19c832e3ec078e448637' # Smashery
default: 'new_cmd_exec_rebased_against_latest_master'
push:
branches-ignore:
- gh-pages
Expand Down Expand Up @@ -52,39 +64,52 @@ jobs:
fail-fast: false
matrix:
os:
- macos-12
- windows-2019
# - macos-12
# - windows-2019
- ubuntu-20.04
ruby:
- 3.0.2
meterpreter:
# Python
- { name: python, runtime_version: 3.6 }
- { name: python, runtime_version: 3.11 }
# meterpreter:
# Python
# - { name: python, runtime_version: 3.6 }
# - { name: python, runtime_version: 3.11 }

# Java
- { name: java, runtime_version: 8 }
- { name: java, runtime_version: 21 }
# - { name: java, runtime_version: 8 }
# - { name: java, runtime_version: 21 }

# PHP
- { name: php, runtime_version: 5.3 }
- { name: php, runtime_version: 7.4 }
- { name: php, runtime_version: 8.3 }
# - { name: php, runtime_version: 5.3 }
# - { name: php, runtime_version: 7.4 }
# - { name: php, runtime_version: 8.3 }
include:
# Windows Meterpreter
- { meterpreter: { name: windows_meterpreter }, os: windows-2019 }
- { meterpreter: { name: windows_meterpreter }, os: windows-2022 }
# - { meterpreter: { name: windows_meterpreter }, os: windows-2019 }
# - { meterpreter: { name: windows_meterpreter }, os: windows-2022 }

# Powershell
- { meterpreter: { name: powershell }, os: windows-2019 }
- { meterpreter: { name: powershell }, os: windows-2022 }

# Linux
- { meterpreter: { name: linux }, os: ubuntu-20.04 }

# CMD
- { meterpreter: { name: cmd }, os: windows-2019 }
- { meterpreter: { name: cmd }, os: windows-2022 }

# Mettle
- { meterpreter: { name: mettle }, os: macos-12 }
- { meterpreter: { name: mettle }, os: ubuntu-20.04 }
# - { meterpreter: { name: mettle }, os: macos-12 }
# - { meterpreter: { name: mettle }, os: ubuntu-20.04 }

runs-on: ${{ matrix.os }}

timeout-minutes: 25
timeout-minutes: 50

env:
RAILS_ENV: test
metasploitPayloadsCommit: ${{ github.event.inputs.metasploitPayloadsCommit || '0b77a961b2f10fa1bee670ca49673801a70fa1e8' }}
mettleCommit: ${{ github.event.inputs.mettleCommit|| 'new_cmd_exec_rebased_against_latest_master' }}
HOST_RUNNER_IMAGE: ${{ matrix.os }}
METERPRETER: ${{ matrix.meterpreter.name }}
METERPRETER_RUNTIME_VERSION: ${{ matrix.meterpreter.runtime_version }}
Expand All @@ -96,7 +121,7 @@ jobs:
if: runner.os == 'Linux'
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz

- uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761
- uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d
if: ${{ matrix.meterpreter.name == 'php' }}
with:
php-version: ${{ matrix.meterpreter.runtime_version }}
Expand Down Expand Up @@ -129,8 +154,82 @@ jobs:
dir %WINDIR%
type %WINDIR%\\system32\\drivers\\etc\\hosts
- name: Checkout code
# The job checkout structure is:
# .
# ├── metasploit-framework
# └── metasploit-payloads (Only if metasploit-payloads-label is applied)
# └── mettle (Only if mettle-label is applied)

# Install Docker if on MACOS
- name: Install Docker - macOS
# if: ${{ ( matrix.meterpreter.name == 'java') && (runner.os == 'macos' ) || ( runner.os == 'linux') && (matrix.meterpreter.name == 'mettle') }}
if: ${{ ( matrix.meterpreter.name == 'java') && (runner.os == 'macos' ) }}
# if: contains(github.event.issue.labels.*.name, 'metasploit-payloads-label')
run: |
brew install docker
colima delete
colima start --arch x86_64
# Checkout mettle
# TODO: Mettle and Metasploit payloads labels
- name: Checkout mettle
if: ${{ matrix.meterpreter.name == 'mettle' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
uses: actions/checkout@v4
with:
repository: rapid7/mettle
path: mettle
ref: ${{ env.mettleCommit }}

- name: Get mettle version
if: ${{ matrix.meterpreter.name == 'mettle' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
echo "METTLE_VERSION=$(grep -oh '[0-9].[0-9].[0-9]*' lib/metasploit_payloads/mettle/version.rb)" >> $GITHUB_ENV
working-directory: mettle

- name: Use mettle version
if: ${{ matrix.meterpreter.name == 'mettle' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
echo "${{ env.METTLE_VERSION }}"
working-directory: mettle

# Prerequisite mettle gem setup
# TODO: Will need to figure out how to get the current version for later commands
- name: Build mettle payloads
if: ${{ matrix.meterpreter.name == 'mettle' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
set -x
ruby -pi.bak -e "gsub(/${{ env.METTLE_VERSION }}/, '${{ env.METTLE_VERSION }}-dev')" lib/metasploit_payloads/mettle/version.rb
working-directory: mettle

# Compile mettle payload
# TODO: Will need to figure out how to get the current version for later commands
- name: Compile mettle payloads
if: ${{ matrix.meterpreter.name == 'mettle' && runner.os != 'macos' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
docker run --rm=true --tty --volume=$(pwd):/mettle --workdir=/mettle rapid7/build:mettle rake mettle:build mettle:check
rake build
working-directory: mettle

# Compile mettle payload - macOS
# TODO: Will need to figure out how to get the current version for later commands
- name: Compile mettle payloads - macOS
if: ${{ matrix.meterpreter.name == 'mettle' && runner.os == 'macos' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
make TARGET=x86_64-apple-darwin
rake build
working-directory: mettle

# Checkout metasploit-framework
- name: Checkout metasploit-framework code
uses: actions/checkout@v4
with:
path: metasploit-framework

- name: Setup Ruby
env:
Expand All @@ -139,12 +238,91 @@ jobs:
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true
cache-version: 4
working-directory: metasploit-framework
cache-version: 5
# Github actions with Ruby requires Bundler 2.2.18+
# https://github.com/ruby/setup-ruby/tree/d2b39ad0b52eca07d23f3aa14fdf2a3fcc1f411c#windows
bundler: 2.2.33

- name: acceptance
# Copying mettle gem into framework - macOS
- name: Move mettle gem - macOS
if: ${{ matrix.meterpreter.name == 'mettle' && runner.os == 'macos' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
cp /Users/runner/work/metasploit-framework/metasploit-framework/mettle/pkg/metasploit_payloads-mettle-${{ env.METTLE_VERSION }}.pre.dev.gem /Users/runner/work/metasploit-framework/metasploit-framework/metasploit-framework
working-directory: metasploit-framework

# Copying mettle gem into framework - macOS
- name: Move mettle gem
if: ${{ matrix.meterpreter.name == 'mettle' && runner.os != 'macos' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
cp /home/runner/work/metasploit-framework/metasploit-framework/mettle/pkg/metasploit_payloads-mettle-${{ env.METTLE_VERSION }}.pre.dev.gem /home/runner/work/metasploit-framework/metasploit-framework/metasploit-framework
working-directory: metasploit-framework

# Copying mettle gem into framework
- name: Install mettle gem
if: ${{ matrix.meterpreter.name == 'mettle' }}
# if: contains(github.event.issue.labels.*.name, 'mettle-label')
run: |
set -x
bundle exec gem install metasploit_payloads-mettle-${{ env.METTLE_VERSION }}.pre.dev.gem
gem list metasploit_payloads-mettle
ruby -pi.bak -e "gsub(/'metasploit_payloads-mettle', '1.0.31'/, '\'metasploit_payloads-mettle\', \'${{ env.METTLE_VERSION }}.pre.dev\'')" metasploit-framework.gemspec
cat Gemfile.lock
bundle config
bundle config unset deployment
bundle update metasploit_payloads-mettle
bundle install
working-directory: metasploit-framework

# Checkout metasploit-payloads
- name: Checkout metasploit-payloads
# if: contains(github.event.issue.labels.*.name, 'metasploit-payloads-label')
uses: actions/checkout@v4
with:
repository: rapid7/metasploit-payloads
path: metasploit-payloads
ref: ${{ env.metasploitPayloadsCommit }}

# Build Java and Android payloads, Docker command needs to be ran from the directory up from metasploit-payloads
- name: Build Java & Android payloads
if: ${{ (matrix.meterpreter.name == 'java') && (runner.os != 'Windows') }}
# if: contains(github.event.issue.labels.*.name, 'metasploit-payloads-label')
run: |
cd ..
docker run --rm -w "$(pwd)" -v "$(pwd):$(pwd)" rapid7/msf-ubuntu-x64-meterpreter:latest /bin/bash -c "cd metasploit-payloads/java && make clean && make android && mvn -P deploy package"
working-directory: metasploit-payloads

- name: Build Windows payloads via Visual Studio 2019 Build (Windows)
shell: cmd
if: ${{ (runner.os == 'Windows') && (matrix.os == 'windows-2019') }}
# if: ${{ (runner.os == 'Windows') && (contains(github.event.issue.labels.*.name, 'metasploit-payloads-label') ) }}
run: |
cd c/meterpreter
git submodule init && git submodule update
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat" && make.bat
working-directory: metasploit-payloads

- name: Build Windows payloads via Visual Studio 2022 Build (Windows)
shell: cmd
if: ${{ (runner.os == 'Windows') && (matrix.os == 'windows-2022') }}
# if: ${{ (runner.os == 'Windows') && (contains(github.event.issue.labels.*.name, 'metasploit-payloads-label') ) }}
run: |
cd c/meterpreter
git submodule init && git submodule update
make.bat
working-directory: metasploit-payloads

# Run makefile within metasploit-payloads
- name: Build PHP, Python and Windows payloads
if: ${{ (matrix.meterpreter.name == 'php') || (matrix.meterpreter.name == 'python') || (runner.os == 'Windows') }}
# if: contains(github.event.issue.labels.*.name, 'metasploit-payloads-label')
run: |
make install-php install-python install-windows
working-directory: metasploit-payloads

- name: Acceptance
env:
SPEC_HELPER_LOAD_METASPLOIT: false
SPEC_OPTS: "--tag acceptance --require acceptance_spec_helper.rb --color --format documentation --format AllureRspec::RSpecFormatter"
Expand All @@ -157,14 +335,16 @@ jobs:
# Additionally - flakey tests should be fixed or marked as flakey instead of silently retried
run: |
bundle exec rspec spec/acceptance/meterpreter_spec.rb
bundle exec rspec spec/acceptance/non_meterpreter_spec.rb
working-directory: metasploit-framework

- name: Archive results
if: always()
uses: actions/upload-artifact@v4
with:
# Provide a unique artifact for each matrix os, otherwise race conditions can lead to corrupt zips
name: raw-data-${{ matrix.meterpreter.name }}-${{ matrix.meterpreter.runtime_version }}-${{ matrix.os }}
path: tmp/allure-raw-data
path: metasploit-framework/tmp/allure-raw-data

# Generate a final report from the previous test results
report:
Expand Down
Loading

0 comments on commit 1e5a878

Please sign in to comment.