Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
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
224 changes: 153 additions & 71 deletions .github/workflows/Release.yml
Original file line number Diff line number Diff line change
@@ -1,84 +1,166 @@
name: Release
name: CD

on:
on:
workflow_dispatch:
inputs:
release_tag:
description: "Git tag to publish when running manually. Leave empty to build and validate only."
required: false
type: string
c2implant_release_tag:
description: "C2Implant release tag to import. Leave empty to use latest."
required: false
type: string
c2linuximplant_release_tag:
description: "C2LinuxImplant release tag to import. Leave empty to use latest."
required: false
type: string
push:
tags:
- '*'

- "*"

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_DIR: build-release
BUILD_TYPE: Release
RELEASE_TARBALL: Release.tar.gz
RELEASE_ARTIFACT: C2TeamServer-Release

permissions:
contents: write
contents: read

jobs:
build-test-package:
name: Build, test, package, and validate release
runs-on: ubuntu-22.04

steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
C2Client/pyproject.toml
C2Client/requirements.txt

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
golang-cfssl \
libegl1 \
libgl1 \
libsmbclient-dev \
libxkbcommon-x11-0 \
libxcb-cursor0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-render-util0 \
libxcb-xinerama0

- name: Install Conan
run: python -m pip install --upgrade pip "conan==2.24.0"

- name: Cache Conan packages
uses: actions/cache@v4
with:
path: ~/.conan2
key: conan-${{ runner.os }}-${{ hashFiles('conanfile.txt', 'conan.lock', 'conan/profiles/linux-gcc13') }}
restore-keys: |
conan-${{ runner.os }}-

- name: Configure CMake
run: >
cmake -S "${{ github.workspace }}"
-B "${{ github.workspace }}/${{ env.BUILD_DIR }}"
-DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}"
-DWITH_TESTS=ON
-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="${{ github.workspace }}/conan_provider.cmake"
-DCONAN_HOST_PROFILE="${{ github.workspace }}/conan/profiles/linux-gcc13"
-DCONAN_BUILD_PROFILE="${{ github.workspace }}/conan/profiles/linux-gcc13"
-DCONAN_LOCKFILE="${{ github.workspace }}/conan.lock"

- name: Build
run: cmake --build "${{ env.BUILD_DIR }}" --config "${{ env.BUILD_TYPE }}" --parallel "$(nproc)"

jobs:
buildAndRelease:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
- name: Run CTest
run: ctest --test-dir "${{ env.BUILD_DIR }}" --build-config "${{ env.BUILD_TYPE }}" --output-on-failure --timeout 120

- name: Install client test dependencies
run: python -m pip install -e "${{ github.workspace }}/C2Client[test]"

- name: Run client tests
env:
C2_PROTOCOL_PYTHON_ROOT: ${{ github.workspace }}/${{ env.BUILD_DIR }}/generated/python_protocol
QT_QPA_PLATFORM: offscreen
run: timeout 180 python -m pytest "${{ github.workspace }}/C2Client/tests" -vv -s

- name: Stage TeamServer release bundle
run: cmake --build "${{ env.BUILD_DIR }}" --target validate_release_bundle --config "${{ env.BUILD_TYPE }}"

- name: Import implant release assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
C2IMPLANT_RELEASE_TAG: ${{ inputs.c2implant_release_tag || '' }}
C2LINUXIMPLANT_RELEASE_TAG: ${{ inputs.c2linuximplant_release_tag || '' }}
run: |
set -euo pipefail

args=()
if [ -n "${C2IMPLANT_RELEASE_TAG}" ]; then
args+=(--windows-tag "${C2IMPLANT_RELEASE_TAG}")
fi
if [ -n "${C2LINUXIMPLANT_RELEASE_TAG}" ]; then
args+=(--linux-tag "${C2LINUXIMPLANT_RELEASE_TAG}")
fi

python "${{ github.workspace }}/packaging/import_implant_releases.py" \
--stage-root "${{ github.workspace }}/${{ env.BUILD_DIR }}/release-staging/Release" \
--import-root "${{ github.workspace }}/${{ env.BUILD_DIR }}/release-imports" \
"${args[@]}"

- name: Validate complete release staging
run: >
python "${{ github.workspace }}/packaging/validate_release.py"
--release-root "${{ github.workspace }}/${{ env.BUILD_DIR }}/release-staging/Release"
--require-implants

- name: Create release archive
run: tar -C "${{ env.BUILD_DIR }}/release-staging" -czf "${{ env.RELEASE_TARBALL }}" Release

- name: Upload validated release artifact
uses: actions/upload-artifact@v4
with:
name: ${{ env.RELEASE_ARTIFACT }}
path: ${{ env.RELEASE_TARBALL }}
if-no-files-found: error

publish:
name: Publish GitHub release
runs-on: ubuntu-22.04
needs: build-test-package
if: startsWith(github.ref, 'refs/tags/') || (github.event_name == 'workflow_dispatch' && inputs.release_tag != '')
permissions:
contents: write

steps:
- uses: actions/checkout@v4

- name: Install Samba client dev headers
run: |
sudo apt-get update
sudo apt-get install -y libsmbclient-dev

# Update references
- name: Git Sumbodule Update
run: |
git submodule update --init

# Needed to generate certificates
- uses: ConorMacBride/install-package@v1
with:
apt: golang-cfssl

- name: Get Conan
# You may pin to the exact commit or the version.
# uses: turtlebrowser/get-conan@c171f295f3f507360ee018736a6608731aa2109d
uses: turtlebrowser/get-conan@v1.2

- name: Create default profile
run: conan profile detect

- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DWITH_TESTS=OFF -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=${{github.workspace}}/conan_provider.cmake

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 18

- name: Prep release
run: |
rm -rf Release/Beacons
rm -f Release/Client/.gitignore
rm -f Release/Client/logs/.gitignore
rm -f Release/Client/libGrpcMessages/build/py/.gitignore
rm -f Release/Modules/.gitignore
mv ./Release/Modules/ ./Release/TeamServerModules/
rm -f Release/Scripts/.gitignore
rm -f Release/TeamServer/.gitignore
rm -f Release/Tools/.gitignore
rm -f Release/www/.gitignore
wget -q $(wget -q -O - 'https://api.github.com/repos/maxDcb/C2Implant/releases/latest' | jq -r '.assets[] | select(.name=="Release.zip").browser_download_url') -O ./C2Implant.zip
unzip -o C2Implant.zip
rm -f C2Implant.zip
wget -q $(wget -q -O - 'https://api.github.com/repos/maxDcb/C2LinuxImplant/releases/latest' | jq -r '.assets[] | select(.name=="Release.tar.gz").browser_download_url') -O ./C2LinuxImplant.tar.gz
tar -zxvf C2LinuxImplant.tar.gz
rm -f C2LinuxImplant.tar.gz
tar -zcvf Release.tar.gz Release

- name: Upload release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: Release.tar.gz
asset_name: Release.tar.gz
tag: ${{ github.ref }}
overwrite: true
body: "C2TeamServer client and server, include the release of C2Implant with the windows beacons and modules"
- name: Download validated release artifact
uses: actions/download-artifact@v4
with:
name: ${{ env.RELEASE_ARTIFACT }}

- name: Upload release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: ${{ env.RELEASE_TARBALL }}
asset_name: ${{ env.RELEASE_TARBALL }}
tag: ${{ inputs.release_tag || github.ref }}
overwrite: true
body: "C2TeamServer client, server, TeamServer modules, and validated C2Implant/C2LinuxImplant beacons and modules."
137 changes: 90 additions & 47 deletions .github/workflows/Tests.yml
Original file line number Diff line number Diff line change
@@ -1,55 +1,98 @@
name: Tests
name: CI

on: workflow_dispatch
on:
workflow_dispatch:
pull_request:
push:
branches:
- "**"

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_DIR: build-ci
BUILD_TYPE: Release

jobs:
buildAndTest:
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
# You can convert this to a matrix build if you need cross-platform coverage.
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
permissions:
contents: read

jobs:
build-test:
name: Build, test, and validate staging
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4

- name: Install Samba client dev headers
run: |
sudo apt-get update
sudo apt-get install -y libsmbclient-dev

# Update references
- name: Git Sumbodule Update
run: |
git submodule update --init

# Needed to generate certificates
- uses: ConorMacBride/install-package@v1
with:
apt: golang-cfssl

- name: Get Conan
# You may pin to the exact commit or the version.
# uses: turtlebrowser/get-conan@c171f295f3f507360ee018736a6608731aa2109d
uses: turtlebrowser/get-conan@v1.2

- name: Create default profile
run: conan profile detect

- name: Configure CMake for tests
run: cmake -B ${{github.workspace}}/build -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=${{github.workspace}}/conan_provider.cmake

- name: Build for test
run: cmake --build ${{github.workspace}}/build -j 18

- name: Run unit tests
run: ctest --test-dir build

- name: Configure CMake like the release
run: cmake -B ${{github.workspace}}/buildRelease -DWITH_TESTS=OFF -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=${{github.workspace}}/conan_provider.cmake

- name: Build like the release
run: cmake --build ${{github.workspace}}/buildRelease -j 18
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
cache-dependency-path: |
C2Client/pyproject.toml
C2Client/requirements.txt

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
golang-cfssl \
libegl1 \
libgl1 \
libsmbclient-dev \
libxkbcommon-x11-0 \
libxcb-cursor0 \
libxcb-icccm4 \
libxcb-image0 \
libxcb-keysyms1 \
libxcb-render-util0 \
libxcb-xinerama0

- name: Install Conan
run: python -m pip install --upgrade pip "conan==2.24.0"

- name: Cache Conan packages
uses: actions/cache@v4
with:
path: ~/.conan2
key: conan-${{ runner.os }}-${{ hashFiles('conanfile.txt', 'conan.lock', 'conan/profiles/linux-gcc13') }}
restore-keys: |
conan-${{ runner.os }}-

- name: Configure CMake
run: >
cmake -S "${{ github.workspace }}"
-B "${{ github.workspace }}/${{ env.BUILD_DIR }}"
-DCMAKE_BUILD_TYPE="${{ env.BUILD_TYPE }}"
-DWITH_TESTS=ON
-DCMAKE_PROJECT_TOP_LEVEL_INCLUDES="${{ github.workspace }}/conan_provider.cmake"
-DCONAN_HOST_PROFILE="${{ github.workspace }}/conan/profiles/linux-gcc13"
-DCONAN_BUILD_PROFILE="${{ github.workspace }}/conan/profiles/linux-gcc13"
-DCONAN_LOCKFILE="${{ github.workspace }}/conan.lock"

- name: Build
run: cmake --build "${{ env.BUILD_DIR }}" --config "${{ env.BUILD_TYPE }}" --parallel "$(nproc)"

- name: Run CTest
run: ctest --test-dir "${{ env.BUILD_DIR }}" --build-config "${{ env.BUILD_TYPE }}" --output-on-failure --timeout 120

- name: Install client test dependencies
run: python -m pip install -e "${{ github.workspace }}/C2Client[test]"

- name: Run client tests
env:
C2_PROTOCOL_PYTHON_ROOT: ${{ github.workspace }}/${{ env.BUILD_DIR }}/generated/python_protocol
QT_QPA_PLATFORM: offscreen
run: timeout 180 python -m pytest "${{ github.workspace }}/C2Client/tests" -vv -s

- name: Validate release staging
run: |
cmake --build "${{ env.BUILD_DIR }}" --target validate_release_bundle --config "${{ env.BUILD_TYPE }}"

- name: Validate integration runtime staging
run: |
cmake --build "${{ env.BUILD_DIR }}" --target stage_integration_runtime --config "${{ env.BUILD_TYPE }}"
test -x "${{ github.workspace }}/${{ env.BUILD_DIR }}/integration-staging/runtime/Release/TeamServer/TeamServer"
test -f "${{ github.workspace }}/${{ env.BUILD_DIR }}/integration-staging/runtime/Release/Client/c2client_protocol/TeamServerApi_pb2.py"
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@ Tests
C2Client/build/
.vscode
build/
build-*/
C2Client/.cmdHistory
C2Client/.termHistory
C2Client/.venv/
__pycache__/
.pytest_cache/
C2Client/Beacon.exe
C2Client/C2Client/Scripts/__init__.py
C2Client/C2Client/TerminalModules/__pycache__/
Expand Down
Loading
Loading