Skip to content

Commit

Permalink
Debug powershell
Browse files Browse the repository at this point in the history
  • Loading branch information
cgranleese-r7 committed Aug 21, 2024
1 parent dd04557 commit 79bc241
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 99 deletions.
131 changes: 46 additions & 85 deletions .github/workflows/acceptance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ on:
metasploitPayloadsCommit:
description: 'metasploit-payloads branch would like to test'
required: true
default: '0b77a961b2f10fa1bee670ca49673801a70fa1e8'
default: 'master'
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'
default: 'master'
push:
branches-ignore:
- gh-pages
Expand Down Expand Up @@ -64,52 +62,52 @@ jobs:
fail-fast: false
matrix:
os:
# - macos-12
- macos-12
- windows-2019
# - ubuntu-20.04
- 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 }
- { meterpreter: { name: linux }, os: ubuntu-20.04 }

# CMD
# - { meterpreter: { name: cmd }, os: windows-2019 }
# - { meterpreter: { name: cmd }, os: windows-2022 }
- { 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: 50

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

- uses: shivammathur/setup-php@6d7209f44a25a59e904b1ee9f3b0c33ab2cd888d
- uses: shivammathur/setup-php@fc14643b0a99ee9db10a3c025a33d76544fa3761
if: ${{ matrix.meterpreter.name == 'php' }}
with:
php-version: ${{ matrix.meterpreter.runtime_version }}
Expand Down Expand Up @@ -157,24 +155,20 @@ jobs:
# The job checkout structure is:
# .
# ├── metasploit-framework
# └── metasploit-payloads (Only if metasploit-payloads-label is applied)
# └── mettle (Only if mettle-label is applied)
# └── metasploit-payloads (Only if the "payload-testing-branch" GitHub label is applied)
# └── mettle (Only if the "payload-testing-mettle-branch" GitHub 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')
# if: ${{ ( matrix.meterpreter.name == 'java') && (runner.os == 'macos' ) && (contains(github.event.issue.labels.*.name, 'payload-testing-mettle-branch')) }}
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')
# if: ${{ matrix.meterpreter.name == 'mettle' && (contains(github.event.issue.labels.*.name, 'payload-testing-mettle-branch')) }}
uses: actions/checkout@v4
with:
repository: rapid7/mettle
Expand All @@ -183,49 +177,35 @@ jobs:

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

- name: Use mettle version
- name: Prerequisite mettle gem setup
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')
# if: ${{ matrix.meterpreter.name == 'mettle' && (contains(github.event.issue.labels.*.name, 'payload-testing-mettle-branch')) }}
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')
# if: ${{ matrix.meterpreter.name == 'mettle' && runner.os != 'macos' && (contains(github.event.issue.labels.*.name, 'payload-testing-mettle-branch')) }}
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')
# if: ${{ matrix.meterpreter.name == 'mettle' && runner.os == 'macos' && (contains(github.event.issue.labels.*.name, 'payload-testing-mettle-branch')) }}
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:
Expand All @@ -238,66 +218,48 @@ 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

# 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')
- name: Move mettle gem into framework
if: ${{ matrix.meterpreter.name == 'mettle' && (contains(github.event.issue.labels.*.name, 'mettle-testing-branch')) }}
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
cp ./mettle/pkg/metasploit_payloads-mettle-${{ env.METTLE_VERSION }}.pre.dev.gem ./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')
# if: ${{ matrix.meterpreter.name == 'mettle' && (contains(github.event.issue.labels.*.name, 'payload-testing-mettle-branch')) }}
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
ruby -pi.bak -e "gsub(/'metasploit_payloads-mettle', '${{ env.METTLE_VERSION }}'/, '\'metasploit_payloads-mettle\', \'${{ env.METTLE_VERSION }}.pre.dev\'')" metasploit-framework.gemspec
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')
# if: contains(github.event.issue.labels.*.name, 'payload-testing-branch')
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
- name: Build Java and Android payloads
if: ${{ (matrix.meterpreter.name == 'java') && (runner.os != 'Windows') }}
# if: contains(github.event.issue.labels.*.name, 'metasploit-payloads-label')
# if: ${{ (matrix.meterpreter.name == 'java') && (runner.os != 'Windows') && (contains(github.event.issue.labels.*.name, 'payload-testing-branch')) }}
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') ) }}
# if: ${{ (runner.os == 'Windows') && (matrix.os == 'windows-2019') && (contains(github.event.issue.labels.*.name, 'payload-testing-branch')) }}
run: |
cd c/meterpreter
git submodule init && git submodule update
Expand All @@ -307,17 +269,16 @@ jobs:
- 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') ) }}
# if: ${{ (runner.os == 'Windows') && (matrix.os == 'windows-2022') && (contains(github.event.issue.labels.*.name, 'payload-testing-branch')) }}
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')
if: ${{ ((matrix.meterpreter.name == 'php') || (matrix.meterpreter.name == 'python') || (runner.os == 'Windows')) }}
# if: ${{ ((matrix.meterpreter.name == 'php') || (matrix.meterpreter.name == 'python') || (runner.os == 'Windows')) && (contains(github.event.issue.labels.*.name, 'payload-testing-branch'))}}
run: |
make install-php install-python install-windows
working-directory: metasploit-payloads
Expand Down
16 changes: 12 additions & 4 deletions data/cmd_exec/README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@

## Setup

This contains setup steps used for acceptance testing of the `cmd_exec` API. We will make use of the gcc docker image to build out the C binaries to
then be uploaded to the host machine, so they can be used as part of the `cmd_exec` create process API.
This contains setup steps used for acceptance testing of the `cmd_exec` API. We will make use of the gcc docker image to
build out the C binaries to then be uploaded to the host machine, so they can be used as part of the `cmd_exec`
create process API.

This directory contains:
- C executable `show_args.c`
This file is used as part of the `cmd_exec` testing as it requires a file to take args loop over them and output those args back to the user.
This file is used as part of the `cmd_exec` testing as it requires a file to take args, then loop over them and output
those args back to the user.

- Makefile to build the binaries `makefile.mk`
This file is used to create the binaries for both Windows and Linux that the docker command below will make use of.
This file is used to create the binaries for both Windows and Linux that the docker command below will make use of.

- Precompiled binaries for Windows
- `show_args.exe`

- Precompiled binaries for Linux and Mettle
- `show_args`

- Precompiled binaries for macOS
- `show_args_macos`

## Compile binaries locally

We make use of gcc for this: https://hub.docker.com/_/gcc
Expand All @@ -24,3 +30,5 @@ We make use of gcc for this: https://hub.docker.com/_/gcc
```shell
docker run --rm -v "$PWD":/usr/src/myapp -w /usr/src/myapp gcc:11.4.0 /bin/bash -c "apt update && apt install -y gcc-mingw-w64 && make all -f makefile.mk"
```

You will need to compile the OSX payload separately on an OSX machine, Docker is not supported.
2 changes: 1 addition & 1 deletion data/cmd_exec/makefile.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
all: show_args_linux show_args_windows
show_args_linux: show_args.c
cc show_args.c -o show_args
cc show_args.c -o show_args_linux
show_args_windows: show_args.c
x86_64-w64-mingw32-gcc show_args.c -o show_args.exe
1 change: 0 additions & 1 deletion data/cmd_exec/show_args.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
int printf(const char *format, ...);

int main(int argc, char *argv[]) {

for (int i = 0; i < argc; i++) {
printf("%s\n", argv[i]);
}
Expand Down
5 changes: 3 additions & 2 deletions spec/acceptance/non_meterpreter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,15 @@ def initialize(path)
session_id = nil

# Wait for the session to open, or break early if the payload is detected as dead
wait_for_expect do
larger_retry_count_for_powershell = 600
wait_for_expect(larger_retry_count_for_powershell) do
unless payload_process.alive?
break
end

# TODO: Was strictly for Meterpreter sessions, now more generic
# - can be reverted if we decide to move these new tests
session_opened_matcher = /\w.* session (\d+) opened[^\n]*\n/
session_opened_matcher = /session (\d+) opened[^\n]*\n/
session_message = ''
begin
session_message = console.recvuntil(session_opened_matcher, timeout: 1)
Expand Down
8 changes: 4 additions & 4 deletions spec/support/acceptance/non_meterpreter/powershell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ module Acceptance::NonMeterpreter
POWERSHELL = {
payloads: [
{
name: 'windows/x64/powershell_reverse_tcp',
extension: '.exe',
name: 'cmd/windows/powershell_reverse_tcp',
extension: '.ps1',
platforms: [:windows],
execute_cmd: ['${payload_path}'],
execute_cmd: ['powershell ${payload_path}'],
executable: true,
generate_options: {
'-f': 'exe'
'-f': 'raw'
},
datastore: {
global: {},
Expand Down
11 changes: 9 additions & 2 deletions test/lib/module_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,15 @@ def push_test_directory
@directory_stack.push(_file_system.pwd)

# Find the temp directory
tmp = _file_system.get_env("TMP").strip.presence || _file_system.get_env("TMPDIR").strip.presence
# tmp = _file_system.get_env("TMP") || _file_system.get_env("TMPDIR")

# TODO: This caused issue with random jobs, will add some logic below to unblock for now
# tmp = _file_system.get_env("TMP")&.strip&.presence || _file_system&.get_env("TMPDIR").strip&.presence
if session.platform == 'unix'
tmp = _file_system.get_env("TMP").strip.presence || _file_system.get_env("TMPDIR").strip.presence
else
tmp = _file_system.get_env("TMP") || _file_system.get_env("TMPDIR")
end

# mettle fallback
tmp = '/tmp' if tmp.nil? && _file_system.directory?('/tmp')
raise "Could not find tmp directory" if tmp == nil || !_file_system.directory?(tmp)
Expand Down

0 comments on commit 79bc241

Please sign in to comment.