From 7e0537fdc7b8264dafd089abc921bed0dcb2535c Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 12:50:01 -0600 Subject: [PATCH 001/117] v0.0.1 --- .github/docker.yml | 140 +++++++++++++++++++++++++++++++ Mythic_CLI/.docker/Dockerfile | 20 +++++ Mythic_CLI/Dockerfile | 17 +--- mythic-docker/.docker/Dockerfile | 21 +++++ mythic-docker/Dockerfile | 22 +---- 5 files changed, 183 insertions(+), 37 deletions(-) create mode 100644 .github/docker.yml create mode 100644 Mythic_CLI/.docker/Dockerfile create mode 100644 mythic-docker/.docker/Dockerfile diff --git a/.github/docker.yml b/.github/docker.yml new file mode 100644 index 000000000..8f50a7137 --- /dev/null +++ b/.github/docker.yml @@ -0,0 +1,140 @@ +# Pulled from Thanatos (https://github.com/MythicAgents/thanatos/blob/rewrite/.github/workflows/image.yml) +# MEhrn00 + +# Name for the Github actions workflow +name: Build and push container images + +on: + # Only run workflow when there is a new release published in Github + #release: + # types: [published] + push: + branches: + - 'docker_updates' + +# Variables holding configuration settings +env: + # Container registry the built container image will be pushed to + REGISTRY: ghcr.io + + # Set the container image name to the Github repository name. (its-a-feature/Mythic) + SERVER_IMAGE_NAME: ${{ github.repository }}_server + MYTHIC_CLI_IMAGE_NAME: ${{ github.repository }}_cli + + # Description label for the package in Github + IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" + + # Source URL for the package in Github. This links the Github repository packages list + # to this container image + SERVER_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} + MYTHIC_CLI_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} + + # License for the container image + IMAGE_LICENSE: BSD-3-Clause + + # Set the container image version to the Github release tag + #VERSION: ${{ github.event.release.tag_name }} + VERSION: ${{ github.event.head_commit.message }} + + # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) + #RELEASE_BRANCH: rewrite + +jobs: + # Builds the base container image and pushes it to the container registry + build-and-push-image: + runs-on: ubuntu-latest + + # Provision an ephemeral Github token for the workflow which is capable of pushing + # Github packages and pushing code + permissions: + contents: write + packages: write + + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + + # Log in to the configured container registry using the ephemeral Github token + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + # Container image names need to be lowercased. This changes the 'IMAGE_NAME' + # variable to all lowercase letters + - name: Lowercase the server container image name + run: echo "SERVER_IMAGE_NAME=${SERVER_IMAGE_NAME,,}" >> ${GITHUB_ENV} + + - name: Lowercase the cli container image name + run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} + + # Build and push the server container image with the specified tag and labels + - name: Build and push the server container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: mythic-docker + file: mythic-docker/.docker/Dockerfile + tags: ${{ env.REGISTRY }}/${{ env.SERVER_IMAGE_NAME }}:${{ env.VERSION }} + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.SERVER_IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + + - name: Build and push the cli container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: Mythic_CLI + file: Mythic_CLI/.docker/Dockerfile + tags: ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:${{ env.VERSION }} + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.MYTHIC_CLI_IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + + # The Dockerfile which Mythic uses to pull in the base container image needs to be + # updated to reference the newly built container image + - name: Fix the server Dockerfile reference to reference the new release tag + working-directory: mythic-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${SERVER_IMAGE_NAME}:${VERSION}|" Dockerfile + + - name: Fix the cli Dockerfile reference to reference the new release tag + working-directory: Mythic_CLI + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Dockerfile + + # Push the changes to the Dockerfile + - name: Push the updated base Dockerfile image reference changes + uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit + with: + # Only add the Dockerfile changes. Nothing else should have been modified + add: + - mythic-docker/Dockerfile + - Mythic_CLI/Dockerfile + # Use the Github actions bot for the commit author + default_author: github_actions + committer_email: github-actions[bot]@users.noreply.github.com + + # Set the commit message + message: "Bump Mythic Dockerfile tag to match release '${{ env.VERSION }}'" + + # Overwrite the current git tag with the new changes + #tag: '${{ env.VERSION }} --force' + + # Push the new changes with the tag overwriting the current one + #tag_push: '--force' + + # Push the commits to the branch marked as the release branch + push: origin HEAD:${{ env.RELEASE_BRANCH }} --set-upstream + + # Have the workflow fail in case there are pathspec issues + pathspec_error_handling: exitImmediately \ No newline at end of file diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile new file mode 100644 index 000000000..076c9cddf --- /dev/null +++ b/Mythic_CLI/.docker/Dockerfile @@ -0,0 +1,20 @@ +FROM itsafeaturemythic/mythic_go_base:latest + +WORKDIR /usr/src/app + +ARG GOPROXY=proxy.golang.org +ARG GO111MODULE + +RUN go env -w GOPROXY=${GOPROXY} +RUN go env -w GO111MODULE=${GO111MODULE} + +COPY ["src/", "."] + +RUN go mod download +RUN go mod tidy + +CMD ["/bin/bash", "-c", "make", "build"] + +FROM alpine + +COPY --from=0 /mythic-cli /mythic-cli \ No newline at end of file diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 6ba2fcb93..412fdd599 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1,16 +1 @@ -FROM itsafeaturemythic/mythic_go_base:latest - -WORKDIR /usr/src/app - -ARG GOPROXY=proxy.golang.org -ARG GO111MODULE - -RUN go env -w GOPROXY=${GOPROXY} -RUN go env -w GO111MODULE=${GO111MODULE} - -COPY ["src/", "."] - -RUN go mod download -RUN go mod tidy - -CMD ["/bin/bash", "-c", "make", "build"] \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.0 \ No newline at end of file diff --git a/mythic-docker/.docker/Dockerfile b/mythic-docker/.docker/Dockerfile new file mode 100644 index 000000000..a97df24ef --- /dev/null +++ b/mythic-docker/.docker/Dockerfile @@ -0,0 +1,21 @@ +FROM itsafeaturemythic/mythic_go_base:latest + +WORKDIR /usr/src/app + +ARG GOPROXY=proxy.golang.org +ARG GO111MODULE + +RUN go env -w GOPROXY=${GOPROXY} +RUN go env -w GO111MODULE=${GO111MODULE} + +COPY ["src/", "."] + +RUN make build_final + +FROM alpine + +COPY --from=0 /mythic_server /mythic_server + +WORKDIR /usr/src/app + +CMD ["/bin/sh", "-c", "cp /mythic_server . && ./mythic_server" ] \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index a97df24ef..81cd4f5a2 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1,21 +1 @@ -FROM itsafeaturemythic/mythic_go_base:latest - -WORKDIR /usr/src/app - -ARG GOPROXY=proxy.golang.org -ARG GO111MODULE - -RUN go env -w GOPROXY=${GOPROXY} -RUN go env -w GO111MODULE=${GO111MODULE} - -COPY ["src/", "."] - -RUN make build_final - -FROM alpine - -COPY --from=0 /mythic_server /mythic_server - -WORKDIR /usr/src/app - -CMD ["/bin/sh", "-c", "cp /mythic_server . && ./mythic_server" ] \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.0 \ No newline at end of file From a780f0ead394e85fb17d716e18cffe42b910e3e0 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 12:52:33 -0600 Subject: [PATCH 002/117] v0.0.2 --- .github/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/docker.yml b/.github/docker.yml index 8f50a7137..38c831e07 100644 --- a/.github/docker.yml +++ b/.github/docker.yml @@ -37,7 +37,7 @@ env: VERSION: ${{ github.event.head_commit.message }} # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) - #RELEASE_BRANCH: rewrite + RELEASE_BRANCH: docker_updates jobs: # Builds the base container image and pushes it to the container registry From 35c43975c317955e53277cfd34029902f5313ecb Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 12:53:21 -0600 Subject: [PATCH 003/117] v0.0.1 --- .github/{ => workflows}/docker.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/docker.yml (100%) diff --git a/.github/docker.yml b/.github/workflows/docker.yml similarity index 100% rename from .github/docker.yml rename to .github/workflows/docker.yml From be4a09d6bfd2aca5b72dfe871842f0d6eb2c8678 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 12:57:16 -0600 Subject: [PATCH 004/117] v0.0.1 --- .github/workflows/docker.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 38c831e07..93aa6c7bc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,5 +1,4 @@ -# Pulled from Thanatos (https://github.com/MythicAgents/thanatos/blob/rewrite/.github/workflows/image.yml) -# MEhrn00 +# Pulled from Thanatos (https://github.com/MythicAgents/thanatos/blob/rewrite/.github/workflows/image.yml) - MEhrn00 # Name for the Github actions workflow name: Build and push container images From 1f9e9b729592cd6abc36201edf3a193552b8ce36 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 13:01:57 -0600 Subject: [PATCH 005/117] v0.0.1 fixing git add workflow --- .github/workflows/docker.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 93aa6c7bc..35698a165 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -116,9 +116,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: - - mythic-docker/Dockerfile - - Mythic_CLI/Dockerfile + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com From 23ce0972abe2d4f30d5421100d35c6b8007d3473 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 13:05:07 -0600 Subject: [PATCH 006/117] v0.0.1 fixing version to use summary instead of message --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 35698a165..788b4ea59 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ env: # Set the container image version to the Github release tag #VERSION: ${{ github.event.release.tag_name }} - VERSION: ${{ github.event.head_commit.message }} + VERSION: ${{ github.event.head_commit.message }} # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) RELEASE_BRANCH: docker_updates From 4ee5418ab8fa4e01aaaae3d6f98f254b792fd438 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 13:13:39 -0600 Subject: [PATCH 007/117] changing back to message v0.0.1 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 788b4ea59..35698a165 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ env: # Set the container image version to the Github release tag #VERSION: ${{ github.event.release.tag_name }} - VERSION: ${{ github.event.head_commit.message }} + VERSION: ${{ github.event.head_commit.message }} # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) RELEASE_BRANCH: docker_updates From c8e32f403513223a3c5bfa87962ce9c3c44dcfb6 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 13:17:07 -0600 Subject: [PATCH 008/117] v0.0.1 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 35698a165..788b4ea59 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ env: # Set the container image version to the Github release tag #VERSION: ${{ github.event.release.tag_name }} - VERSION: ${{ github.event.head_commit.message }} + VERSION: ${{ github.event.head_commit.message }} # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) RELEASE_BRANCH: docker_updates From fa7889ee2a0d8ba6fd4ac30b10ee361b9096c0c2 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 13:22:00 -0600 Subject: [PATCH 009/117] v0.0.2 --- Mythic_CLI/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index 076c9cddf..ea222050d 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -17,4 +17,4 @@ CMD ["/bin/bash", "-c", "make", "build"] FROM alpine -COPY --from=0 /mythic-cli /mythic-cli \ No newline at end of file +COPY --from=0 /usr/src/app /mythic-cli \ No newline at end of file From 3fc60bef2fd956a15cb4e64afacc99eadd6dcd3a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 19:23:21 +0000 Subject: [PATCH 010/117] Bump Mythic Dockerfile tag to match release 'v0.0.2' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 412fdd599..9d3834826 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.0 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 81cd4f5a2..75fa35165 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.0 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2 \ No newline at end of file From e5be3ed78bc89f5d9cb2074d97d44a4304e2a38b Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 14:20:11 -0600 Subject: [PATCH 011/117] v0.0.2.1 --- .github/workflows/docker.yml | 2 +- Mythic_CLI/.docker/Dockerfile | 2 +- Mythic_CLI/Makefile | 19 +++++++++++-------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 788b4ea59..35698a165 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -33,7 +33,7 @@ env: # Set the container image version to the Github release tag #VERSION: ${{ github.event.release.tag_name }} - VERSION: ${{ github.event.head_commit.message }} + VERSION: ${{ github.event.head_commit.message }} # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) RELEASE_BRANCH: docker_updates diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index ea222050d..fdc66a9d5 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -17,4 +17,4 @@ CMD ["/bin/bash", "-c", "make", "build"] FROM alpine -COPY --from=0 /usr/src/app /mythic-cli \ No newline at end of file +COPY --from=0 /usr/src/app/mythic-cli /mythic-cli \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 16eef8ea6..433181345 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,5 +1,6 @@ BINARY_NAME=mythic-cli -LOCAL_PATH=$(shell pwd)/src +LOCAL_PATH=$(shell pwd) +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2 .PHONY: default default: build_all_linux ; @@ -10,17 +11,19 @@ default: build_all_linux ; export build_container: - docker build -t mythic-cli --build-arg GOPROXY --build-arg GO111MODULE . + #docker build -t mythic-cli --build-arg GOPROXY --build-arg GO111MODULE . build_binary: - docker run --env GOPROXY --env GO111MODULE --name mythic-cli-builder --rm -v ${LOCAL_PATH}:/usr/src/app mythic-cli make build_linux - mv src/${BINARY_NAME} . - chmod +x ${BINARY_NAME} + #docker run --env GOPROXY --env GO111MODULE --name mythic-cli-builder --rm -v ${LOCAL_PATH}:/usr/src/app mythic-cli make build_linux + #mv src/${BINARY_NAME} . + docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli /copy_file/mythic-cli" + mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} build_binary_macos: - docker run --env GOPROXY --env GO111MODULE --name mythic-cli-builder --rm -v ${LOCAL_PATH}:/usr/src/app mythic-cli make build_macos - mv src/${BINARY_NAME} . - chmod +x ${BINARY_NAME} + #docker run --env GOPROXY --env GO111MODULE --name mythic-cli-builder --rm -v ${LOCAL_PATH}:/usr/src/app mythic-cli make build_macos + #mv src/${BINARY_NAME} . + docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli /copy_file/mythic-cli" + mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} build_binary_macos_local: cd src && go build -o ../../mythic-cli . From f3f3da6434c27731ad1301943855499f38fdec76 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 14:22:44 -0600 Subject: [PATCH 012/117] v0.0.2.2 latest --- Mythic_CLI/.docker/Dockerfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index fdc66a9d5..13a1a0d6f 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -10,10 +10,11 @@ RUN go env -w GO111MODULE=${GO111MODULE} COPY ["src/", "."] -RUN go mod download -RUN go mod tidy +RUN go mod download && go mod tidy && make build +#RUN go mod tidy -CMD ["/bin/bash", "-c", "make", "build"] + +#CMD ["/bin/bash", "-c", "make", "build"] FROM alpine From 70050b6156e6c8775d431834e844a5690585e391 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 14:25:47 -0600 Subject: [PATCH 013/117] v0.0.2.3 --- Mythic_CLI/.docker/Dockerfile | 2 +- Mythic_CLI/src/Makefile | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index 13a1a0d6f..a1d98fc0a 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -10,7 +10,7 @@ RUN go env -w GO111MODULE=${GO111MODULE} COPY ["src/", "."] -RUN go mod download && go mod tidy && make build +RUN make build #RUN go mod tidy diff --git a/Mythic_CLI/src/Makefile b/Mythic_CLI/src/Makefile index 076291052..20294e4ec 100644 --- a/Mythic_CLI/src/Makefile +++ b/Mythic_CLI/src/Makefile @@ -3,6 +3,8 @@ BINARY_NAME=mythic-cli export build: + go mod download + go mod tidy go build -o ${BINARY_NAME} . build_linux: From 13fd3eac98690d953cbfbb2c25a83343f77aa898 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 20:27:18 +0000 Subject: [PATCH 014/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.3' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 9d3834826..63adca106 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.3 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 75fa35165..ca62a32c4 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.3 \ No newline at end of file From 78c6f049479a58e79ca34f12b9c72b344761b2fc Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 14:37:44 -0600 Subject: [PATCH 015/117] v0.0.2.4 --- .github/workflows/docker.yml | 8 + Mythic_CLI/Changelog.md | 6 + Mythic_CLI/Makefile | 15 +- Mythic_CLI/src/cmd/config/vars.go | 2 +- Mythic_CLI/src/cmd/internal/dockercompose.go | 234 ++++++++++--------- 5 files changed, 144 insertions(+), 121 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 35698a165..35a4b76ec 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -84,6 +84,9 @@ jobs: org.opencontainers.image.source=${{ env.SERVER_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: |- + linux/amd64 + linux/arm64 - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -98,6 +101,11 @@ jobs: org.opencontainers.image.source=${{ env.MYTHIC_CLI_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: |- + linux/amd64 + linux/arm64 + darwin/amd64 + darwin/arm64 # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image diff --git a/Mythic_CLI/Changelog.md b/Mythic_CLI/Changelog.md index 9a2aba0ad..dac352c20 100644 --- a/Mythic_CLI/Changelog.md +++ b/Mythic_CLI/Changelog.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.2.3 - 2023-12-27 + +### Changed + +- Updated the 3rd party service additions to respect existing volume mounts + ## 0.2.2 - 2023-09-07 ### Changed diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 433181345..4e34d51ad 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.3 .PHONY: default default: build_all_linux ; @@ -10,23 +10,16 @@ default: build_all_linux ; export -build_container: - #docker build -t mythic-cli --build-arg GOPROXY --build-arg GO111MODULE . - build_binary: - #docker run --env GOPROXY --env GO111MODULE --name mythic-cli-builder --rm -v ${LOCAL_PATH}:/usr/src/app mythic-cli make build_linux - #mv src/${BINARY_NAME} . docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli /copy_file/mythic-cli" mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} build_binary_macos: - #docker run --env GOPROXY --env GO111MODULE --name mythic-cli-builder --rm -v ${LOCAL_PATH}:/usr/src/app mythic-cli make build_macos - #mv src/${BINARY_NAME} . docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli /copy_file/mythic-cli" - mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} + mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} build_binary_macos_local: cd src && go build -o ../../mythic-cli . -build_all_linux: build_container build_binary -build_all_macos: build_container build_binary_macos \ No newline at end of file +build_all_linux: build_binary +build_all_macos: build_binary_macos \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/vars.go b/Mythic_CLI/src/cmd/config/vars.go index 81aaf307b..22c14da72 100644 --- a/Mythic_CLI/src/cmd/config/vars.go +++ b/Mythic_CLI/src/cmd/config/vars.go @@ -4,5 +4,5 @@ package config var ( // Version Mythic CLI version - Version = "v0.2.2" + Version = "v0.2.3" ) diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 657cdcaf5..dfd04ec6f 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -10,6 +10,7 @@ import ( "path/filepath" "sort" "strings" + "sync" "github.com/docker/docker/api/types" "github.com/docker/docker/client" @@ -670,87 +671,89 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac "com.docker.network.bridge.name": "mythic_if", }) } - if absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)); err != nil { + absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)) + if err != nil { fmt.Printf("[-] Failed to get the absolute path to the %s folder, does the folder exist?\n", InstalledServicesFolder) fmt.Printf("[*] If the service doesn't exist, you might need to install with 'mythic-cli install'\n") os.Exit(1) - } else if !dirExists(absPath) { + } + if !dirExists(absPath) { fmt.Printf("[-] %s does not exist, not adding to Mythic\n", absPath) os.Exit(1) - } else { - pStruct := map[string]interface{}{ - "labels": map[string]string{ - "name": service, - }, - "image": strings.ToLower(service), - "hostname": service, - "logging": map[string]interface{}{ - "driver": "json-file", - "options": map[string]string{ - "max-file": "1", - "max-size": "10m", - }, - }, - "restart": "always", - "volumes": []string{ - absPath + ":/Mythic/", + } + pStruct := map[string]interface{}{ + "labels": map[string]string{ + "name": service, + }, + "image": strings.ToLower(service), + "hostname": service, + "logging": map[string]interface{}{ + "driver": "json-file", + "options": map[string]string{ + "max-file": "1", + "max-size": "10m", }, - "container_name": strings.ToLower(service), - //"networks": []string{ - // "default_network", - //}, - "cpus": mythicEnv.GetInt("INSTALLED_SERVICE_CPUS"), - } - if mythicEnv.GetString("installed_service_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("installed_service_mem_limit") - } - for key, element := range additionalConfigs { - pStruct[key] = element - } - pStruct["build"] = map[string]interface{}{ - "context": absPath, - "args": buildArguments, - } - pStruct["network_mode"] = "host" - pStruct["extra_hosts"] = []string{ - "mythic_server:127.0.0.1", - "mythic_rabbitmq:127.0.0.1", - } - environment := []string{ - "MYTHIC_ADDRESS=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/agent_message", - "MYTHIC_WEBSOCKET=ws://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/ws/agent_message", - "RABBITMQ_USER=${RABBITMQ_USER}", - "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", - "RABBITMQ_PORT=${RABBITMQ_PORT}", - "RABBITMQ_HOST=${RABBITMQ_HOST}", - "MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}", - "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", - "MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT}", - "WEBHOOK_DEFAULT_URL=${WEBHOOK_DEFAULT_URL}", - "WEBHOOK_DEFAULT_CALLBACK_CHANNEL=${WEBHOOK_DEFAULT_CALLBACK_CHANNEL}", - "WEBHOOK_DEFAULT_FEEDBACK_CHANNEL=${WEBHOOK_DEFAULT_FEEDBACK_CHANNEL}", - "WEBHOOK_DEFAULT_STARTUP_CHANNEL=${WEBHOOK_DEFAULT_STARTUP_CHANNEL}", - "WEBHOOK_DEFAULT_ALERT_CHANNEL=${WEBHOOK_DEFAULT_ALERT_CHANNEL}", - "WEBHOOK_DEFAULT_CUSTOM_CHANNEL=${WEBHOOK_DEFAULT_CUSTOM_CHANNEL}", - "DEBUG_LEVEL=${DEBUG_LEVEL}", - } - if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } else { - pStruct["environment"] = environment - } - curConfig.Set("services."+strings.ToLower(service), pStruct) - if !curConfig.IsSet("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) + }, + "restart": "always", + "container_name": strings.ToLower(service), + "cpus": mythicEnv.GetInt("INSTALLED_SERVICE_CPUS"), + } + if mythicEnv.GetString("installed_service_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("installed_service_mem_limit") + } + for key, element := range additionalConfigs { + pStruct[key] = element + } + pStruct["build"] = map[string]interface{}{ + "context": absPath, + "args": buildArguments, + } + pStruct["network_mode"] = "host" + pStruct["extra_hosts"] = []string{ + "mythic_server:127.0.0.1", + "mythic_rabbitmq:127.0.0.1", + } + environment := []string{ + "MYTHIC_ADDRESS=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/agent_message", + "MYTHIC_WEBSOCKET=ws://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/ws/agent_message", + "RABBITMQ_USER=${RABBITMQ_USER}", + "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", + "RABBITMQ_PORT=${RABBITMQ_PORT}", + "RABBITMQ_HOST=${RABBITMQ_HOST}", + "MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}", + "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", + "MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT}", + "WEBHOOK_DEFAULT_URL=${WEBHOOK_DEFAULT_URL}", + "WEBHOOK_DEFAULT_CALLBACK_CHANNEL=${WEBHOOK_DEFAULT_CALLBACK_CHANNEL}", + "WEBHOOK_DEFAULT_FEEDBACK_CHANNEL=${WEBHOOK_DEFAULT_FEEDBACK_CHANNEL}", + "WEBHOOK_DEFAULT_STARTUP_CHANNEL=${WEBHOOK_DEFAULT_STARTUP_CHANNEL}", + "WEBHOOK_DEFAULT_ALERT_CHANNEL=${WEBHOOK_DEFAULT_ALERT_CHANNEL}", + "WEBHOOK_DEFAULT_CUSTOM_CHANNEL=${WEBHOOK_DEFAULT_CUSTOM_CHANNEL}", + "DEBUG_LEVEL=${DEBUG_LEVEL}", + } + if _, ok := pStruct["environment"]; ok { + pStruct["environment"] = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) + } else { + pStruct["environment"] = environment + } + // only add in volumes if some aren't already listed + if _, ok := pStruct["volumes"]; !ok { + pStruct["volumes"] = []string{ + absPath + ":/Mythic/", } - curConfig.Set("version", "2.4") - curConfig.WriteConfig() - fmt.Println("[+] Successfully updated docker-compose.yml") } + curConfig.Set("services."+strings.ToLower(service), pStruct) + if !curConfig.IsSet("networks") { + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + curConfig.Set("version", "2.4") + curConfig.WriteConfig() + fmt.Println("[+] Successfully updated docker-compose.yml") + return nil } func RemoveDockerComposeEntry(service string) error { @@ -831,20 +834,25 @@ func runDockerCompose(args []string) error { stdoutScanner := bufio.NewScanner(stdout) stderrScanner := bufio.NewScanner(stderr) + wg := sync.WaitGroup{} + wg.Add(2) go func() { for stdoutScanner.Scan() { fmt.Printf("%s\n", stdoutScanner.Text()) } + wg.Done() }() go func() { for stderrScanner.Scan() { fmt.Printf("%s\n", stderrScanner.Text()) } + wg.Done() }() err = command.Start() if err != nil { log.Fatalf("[-] Error trying to start docker-compose: %v\n", err) } + wg.Wait() err = command.Wait() if err != nil { fmt.Printf("[-] Error from docker-compose: %v\n", err) @@ -854,47 +862,55 @@ func runDockerCompose(args []string) error { return nil } func runDocker(args []string) (string, error) { - if lookPath, err := exec.LookPath("docker"); err != nil { + lookPath, err := exec.LookPath("docker") + if err != nil { log.Fatalf("[-] docker is not installed or available in the current PATH\n") - } else if exe, err := os.Executable(); err != nil { + } + exe, err := os.Executable() + if err != nil { log.Fatalf("[-] Failed to get lookPath to current executable\n") - } else { - exePath := filepath.Dir(exe) - command := exec.Command(lookPath, args...) - command.Dir = exePath - command.Env = getMythicEnvList() - stdout, err := command.StdoutPipe() - if err != nil { - log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") + } + exePath := filepath.Dir(exe) + command := exec.Command(lookPath, args...) + command.Dir = exePath + command.Env = getMythicEnvList() + stdout, err := command.StdoutPipe() + if err != nil { + log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") + } + stderr, err := command.StderrPipe() + if err != nil { + log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") + } + stdoutScanner := bufio.NewScanner(stdout) + stderrScanner := bufio.NewScanner(stderr) + outputString := "" + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + for stdoutScanner.Scan() { + outputString += stdoutScanner.Text() } - stderr, err := command.StderrPipe() - if err != nil { - log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") - } - stdoutScanner := bufio.NewScanner(stdout) - stderrScanner := bufio.NewScanner(stderr) - outputString := "" - go func() { - for stdoutScanner.Scan() { - outputString += stdoutScanner.Text() - } - }() - go func() { - for stderrScanner.Scan() { - fmt.Printf("%s\n", stderrScanner.Text()) - } - }() - if err = command.Start(); err != nil { - log.Fatalf("[-] Error trying to start docker: %v\n", err) - } else if err = command.Wait(); err != nil { - fmt.Printf("[-] Error from docker: %v\n", err) - fmt.Printf("[*] Docker command: %v\n", args) - return "", err - } else { - return outputString, nil + wg.Done() + }() + go func() { + for stderrScanner.Scan() { + fmt.Printf("%s\n", stderrScanner.Text()) } + wg.Done() + }() + err = command.Start() + if err != nil { + log.Fatalf("[-] Error trying to start docker: %v\n", err) + } + wg.Wait() + err = command.Wait() + if err != nil { + fmt.Printf("[-] Error from docker: %v\n", err) + fmt.Printf("[*] Docker command: %v\n", args) + return "", err } - return "", nil + return outputString, nil } func GetAllExistingNonMythicServiceNames() ([]string, error) { // get all services that exist within the loaded config From 69f6da1a308ea02d69007af6ac4d700cd6fc776f Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 14:49:57 -0600 Subject: [PATCH 016/117] v0.0.2.5 --- .github/workflows/docker.yml | 12 ++++++++++-- Makefile | 2 +- Mythic_CLI/.docker/Dockerfile | 9 +++------ Mythic_CLI/Makefile | 12 ++++++------ Mythic_CLI/src/Makefile | 6 ++++-- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 35a4b76ec..1e3b89378 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -62,6 +62,16 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + # setup Docker build action + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + # Container image names need to be lowercased. This changes the 'IMAGE_NAME' # variable to all lowercase letters - name: Lowercase the server container image name @@ -104,8 +114,6 @@ jobs: platforms: |- linux/amd64 linux/arm64 - darwin/amd64 - darwin/arm64 # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image diff --git a/Makefile b/Makefile index d2d962453..706f9aeb3 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ linux: cd Mythic_CLI && make && mv mythic-cli ../ macos: - cd Mythic_CLI && make build_all_macos && mv mythic-cli ../ + cd Mythic_CLI && make build_macos && mv mythic-cli ../ macos_local: cd Mythic_CLI && make build_binary_macos_local diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index a1d98fc0a..0e6486a8b 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -10,12 +10,9 @@ RUN go env -w GO111MODULE=${GO111MODULE} COPY ["src/", "."] -RUN make build -#RUN go mod tidy - - -#CMD ["/bin/bash", "-c", "make", "build"] +RUN make build_all FROM alpine -COPY --from=0 /usr/src/app/mythic-cli /mythic-cli \ No newline at end of file +COPY --from=0 /usr/src/app/mythic-cli_linux /mythic-cli_linux +COPY --from=0 /usr/src/app/mythic-cli_macos /mythic-cli_macos \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 4e34d51ad..2921fbbdb 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -2,7 +2,7 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.3 .PHONY: default -default: build_all_linux ; +default: build_linux ; # pull in build and env options from global settings -include ../build.env @@ -10,16 +10,16 @@ default: build_all_linux ; export -build_binary: - docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli /copy_file/mythic-cli" +build_binary_linux: + docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli_linux /copy_file/mythic-cli" mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} build_binary_macos: - docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli /copy_file/mythic-cli" + docker run -v ${LOCAL_PATH}/copy_file/:/copy_file/ --rm -ti ${BUILDER_IMAGE} sh -c "cp /mythic-cli_macos /copy_file/mythic-cli" mv ./copy_file/${BINARY_NAME} . && rm -rf ./copy_file && chmod +x ${BINARY_NAME} build_binary_macos_local: cd src && go build -o ../../mythic-cli . -build_all_linux: build_binary -build_all_macos: build_binary_macos \ No newline at end of file +build_linux: build_binary_linux +build_macos: build_binary_macos \ No newline at end of file diff --git a/Mythic_CLI/src/Makefile b/Mythic_CLI/src/Makefile index 20294e4ec..928bd6537 100644 --- a/Mythic_CLI/src/Makefile +++ b/Mythic_CLI/src/Makefile @@ -8,10 +8,12 @@ build: go build -o ${BINARY_NAME} . build_linux: - GOOS=linux go build -o ${BINARY_NAME} . + GOOS=linux go build -o ${BINARY_NAME}_linux . build_macos: - GOOS=darwin go build -o ${BINARY_NAME} . + GOOS=darwin go build -o ${BINARY_NAME}_macos . + +build_all: build_linux build_macos run: ./${BINARY_NAME} From 191e278496b4bdd812fbdbf132de61ea1aa1cc15 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 20:59:24 +0000 Subject: [PATCH 017/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.5' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 63adca106..c3c230e74 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.5 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index ca62a32c4..df7c3d023 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.5 \ No newline at end of file From efa58591e9d745bc44a899a427558c22d284adb1 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 15:12:02 -0600 Subject: [PATCH 018/117] v0.0.2.6 --- .github/workflows/docker.yml | 12 ++++++++---- Mythic_CLI/Makefile | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1e3b89378..32e89009a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -86,7 +86,9 @@ jobs: with: context: mythic-docker file: mythic-docker/.docker/Dockerfile - tags: ${{ env.REGISTRY }}/${{ env.SERVER_IMAGE_NAME }}:${{ env.VERSION }} + tags: | + ${{ env.REGISTRY }}/${{ env.SERVER_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.SERVER_IMAGE_NAME }}:latest push: true # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository @@ -94,7 +96,7 @@ jobs: org.opencontainers.image.source=${{ env.SERVER_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} - platforms: |- + platforms: | linux/amd64 linux/arm64 @@ -103,7 +105,9 @@ jobs: with: context: Mythic_CLI file: Mythic_CLI/.docker/Dockerfile - tags: ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:${{ env.VERSION }} + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:latest push: true # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository @@ -111,7 +115,7 @@ jobs: org.opencontainers.image.source=${{ env.MYTHIC_CLI_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} - platforms: |- + platforms: | linux/amd64 linux/arm64 diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 2921fbbdb..f22f965b5 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.3 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.5 .PHONY: default default: build_linux ; From 96b5db2c5800b751be2b83e170fb60ab30dbbccd Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 21:21:27 +0000 Subject: [PATCH 019/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.6' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index c3c230e74..9af8fbb1b 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.5 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.6 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index df7c3d023..a98803ad9 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.5 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.6 \ No newline at end of file From 8167a9654d49b0438945aee184b36c4a80a11b28 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 16:40:52 -0600 Subject: [PATCH 020/117] v0.0.2.7 --- .github/workflows/docker.yml | 45 ++++++++++++++++---- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/internal/dockercompose.go | 22 ++++++++-- Mythic_CLI/src/cmd/internal/env.go | 14 +++++- postgres-docker/.docker/Dockerfile | 4 ++ postgres-docker/Dockerfile | 4 +- 6 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 postgres-docker/.docker/Dockerfile diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 32e89009a..0743352e5 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -17,16 +17,18 @@ env: REGISTRY: ghcr.io # Set the container image name to the Github repository name. (its-a-feature/Mythic) - SERVER_IMAGE_NAME: ${{ github.repository }}_server + MYTHIC_SERVER_IMAGE_NAME: ${{ github.repository }}_server MYTHIC_CLI_IMAGE_NAME: ${{ github.repository }}_cli + MYTHIC_POSTGRES_IMAGE_NAME: ${{ github.repository }}_postgres # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" # Source URL for the package in Github. This links the Github repository packages list # to this container image - SERVER_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} + MYTHIC_SERVER_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} MYTHIC_CLI_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} + MYTHIC_POSTGRES_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} # License for the container image IMAGE_LICENSE: BSD-3-Clause @@ -75,11 +77,14 @@ jobs: # Container image names need to be lowercased. This changes the 'IMAGE_NAME' # variable to all lowercase letters - name: Lowercase the server container image name - run: echo "SERVER_IMAGE_NAME=${SERVER_IMAGE_NAME,,}" >> ${GITHUB_ENV} + run: echo "MYTHIC_SERVER_IMAGE_NAME=${MYTHIC_SERVER_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Lowercase the cli container image name run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the postgres container image name + run: echo "MYTHIC_POSTGRES_IMAGE_NAME=${MYTHIC_POSTGRES_IMAGE_NAME,,}" >> ${GITHUB_ENV} + # Build and push the server container image with the specified tag and labels - name: Build and push the server container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -87,13 +92,13 @@ jobs: context: mythic-docker file: mythic-docker/.docker/Dockerfile tags: | - ${{ env.REGISTRY }}/${{ env.SERVER_IMAGE_NAME }}:${{ env.VERSION }} - ${{ env.REGISTRY }}/${{ env.SERVER_IMAGE_NAME }}:latest + ${{ env.REGISTRY }}/${{ env.MYTHIC_SERVER_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_SERVER_IMAGE_NAME }}:latest push: true # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | - org.opencontainers.image.source=${{ env.SERVER_IMAGE_SOURCE }} + org.opencontainers.image.source=${{ env.MYTHIC_SERVER_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: | @@ -119,24 +124,48 @@ jobs: linux/amd64 linux/arm64 + - name: Build and push the postgres container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: postgres-docker + file: postgres-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_POSTGRES_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_POSTGRES_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.MYTHIC_POSTGRES_IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: | + linux/amd64 + linux/arm64 + # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag working-directory: mythic-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${SERVER_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the cli Dockerfile reference to reference the new release tag working-directory: Mythic_CLI run: | sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the postgres Dockerfile reference to reference the new release tag + working-directory: postgres-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_POSTGRES_IMAGE_NAME}:${VERSION}|" Dockerfile + # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile]" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index f22f965b5..2a72a36c4 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.5 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:latest .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index dfd04ec6f..ec8cb8d6f 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -69,6 +69,10 @@ func addMythicServiceDockerComposeEntry(service string) { "com.docker.network.bridge.name": "mythic_if", }) } + volumes := map[string]interface{}{} + if curConfig.IsSet("volumes") { + volumes = curConfig.GetStringMap("volumes") + } // adding or setting services in the docker-compose file var pStruct map[string]interface{} @@ -116,10 +120,19 @@ func addMythicServiceDockerComposeEntry(service string) { "start_period": "20s", } pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgresql.conf" - pStruct["volumes"] = []string{ - "./postgres-docker/database:/var/lib/postgresql/data", - "./postgres-docker/postgres.conf:/etc/postgresql.conf", + if mythicEnv.GetBool("postgres_bind_local_mount") { + pStruct["volumes"] = []string{ + "./postgres-docker/database:/var/lib/postgresql/data", + "./postgres-docker/postgres.conf:/etc/postgresql.conf", + } + } else { + pStruct["volumes"] = []string{ + "mythic_postgres/database:/var/lib/postgresql/data", + "mythic_postgres/postgres.conf:/etc/postgresql.conf", + } + } + if imageExists("mythic_postgres") { if mythicEnv.GetBool("postgres_debug") { pStruct["volumes"] = []string{ @@ -151,6 +164,9 @@ func addMythicServiceDockerComposeEntry(service string) { } else { pStruct["environment"] = environment } + if _, ok := volumes["mythic_postgres"]; !ok { + volumes["mythic_postgres"] = "" + } case "mythic_documentation": pStruct["build"] = "./documentation-docker" pStruct["build"] = map[string]interface{}{ diff --git a/Mythic_CLI/src/cmd/internal/env.go b/Mythic_CLI/src/cmd/internal/env.go index 67409e8d8..8b898eb54 100644 --- a/Mythic_CLI/src/cmd/internal/env.go +++ b/Mythic_CLI/src/cmd/internal/env.go @@ -14,6 +14,8 @@ import ( var mythicEnv = viper.New() func setMythicConfigDefaultValues() { + // global configuration + mythicEnv.SetDefault("debug_level", "warning") // nginx configuration mythicEnv.SetDefault("nginx_port", 7443) mythicEnv.SetDefault("nginx_host", "mythic_nginx") @@ -21,15 +23,18 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("nginx_use_ssl", true) mythicEnv.SetDefault("nginx_use_ipv4", true) mythicEnv.SetDefault("nginx_use_ipv6", true) + mythicEnv.SetDefault("nginx_bind_local_mount", true) // mythic react UI configuration mythicEnv.SetDefault("mythic_react_host", "mythic_react") mythicEnv.SetDefault("mythic_react_port", 3000) mythicEnv.SetDefault("mythic_react_bind_localhost_only", true) - // mythic server configuration + mythicEnv.SetDefault("mythic_react_local_mount", true) + // documentation configuration mythicEnv.SetDefault("documentation_host", "mythic_documentation") mythicEnv.SetDefault("documentation_port", 8090) mythicEnv.SetDefault("documentation_bind_localhost_only", true) - mythicEnv.SetDefault("debug_level", "warning") + mythicEnv.SetDefault("documentation_bind_local_mount", true) + // mythic server configuration mythicEnv.SetDefault("mythic_debug_agent_message", false) mythicEnv.SetDefault("mythic_server_port", 17443) mythicEnv.SetDefault("mythic_server_grpc_port", 17444) @@ -39,6 +44,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("mythic_server_mem_limit", "") mythicEnv.SetDefault("mythic_server_dynamic_ports", "7000-7010") mythicEnv.SetDefault("mythic_server_dynamic_ports_bind_localhost_only", false) + mythicEnv.SetDefault("mythic_server_bind_local_mount", true) mythicEnv.SetDefault("mythic_server_command", "") mythicEnv.SetDefault("mythic_sync_cpus", "2") mythicEnv.SetDefault("mythic_sync_mem_limit", "") @@ -51,6 +57,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("postgres_password", generateRandomPassword(30)) mythicEnv.SetDefault("postgres_cpus", "2") mythicEnv.SetDefault("postgres_mem_limit", "") + mythicEnv.SetDefault("postgres_bind_local_mount", true) // rabbitmq configuration mythicEnv.SetDefault("rabbitmq_host", "mythic_rabbitmq") mythicEnv.SetDefault("rabbitmq_port", 5672) @@ -60,6 +67,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("rabbitmq_vhost", "mythic_vhost") mythicEnv.SetDefault("rabbitmq_cpus", "2") mythicEnv.SetDefault("rabbitmq_mem_limit", "") + mythicEnv.SetDefault("rabbitmq_bind_local_mount", true) // jwt configuration mythicEnv.SetDefault("jwt_secret", generateRandomPassword(30)) // hasura configuration @@ -69,6 +77,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("hasura_secret", generateRandomPassword(30)) mythicEnv.SetDefault("hasura_cpus", "2") mythicEnv.SetDefault("hasura_mem_limit", "2gb") + mythicEnv.SetDefault("hasura_bind_local_mount", true) // docker-compose configuration mythicEnv.SetDefault("COMPOSE_PROJECT_NAME", "mythic") mythicEnv.SetDefault("REBUILD_ON_START", true) @@ -86,6 +95,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("jupyter_cpus", "2") mythicEnv.SetDefault("jupyter_mem_limit", "") mythicEnv.SetDefault("jupyter_bind_localhost_only", true) + mythicEnv.SetDefault("jupyter_bind_local_mount", true) // debugging help mythicEnv.SetDefault("postgres_debug", false) mythicEnv.SetDefault("mythic_react_debug", false) diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile new file mode 100644 index 000000000..7f29d32f5 --- /dev/null +++ b/postgres-docker/.docker/Dockerfile @@ -0,0 +1,4 @@ +FROM postgres:15-alpine +COPY ["pg_hba.conf", "/var/lib/postgresql/pg_hba.conf"] +COPY ["configuration.sh", "/docker-entrypoint-initdb.d/configuration.sh"] +COPY ["postgres.conf", "/etc/postgres.confg"] \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index c18305e5a..c85669db4 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1,3 +1 @@ -FROM postgres:15-alpine -COPY ["pg_hba.conf", "/var/lib/postgresql/pg_hba.conf"] -COPY ["configuration.sh", "/docker-entrypoint-initdb.d/configuration.sh"] \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.6 \ No newline at end of file From 3379ad38b75a5b53f2a0b808a616b7e047007230 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 16:55:53 -0600 Subject: [PATCH 021/117] v0.0.2.8 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 0743352e5..3867e39ab 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -165,7 +165,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile]" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com From d53291394fcdebce5b7b30ff4eac79148678d25b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 23:05:32 +0000 Subject: [PATCH 022/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.8' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 9af8fbb1b..f1774335e 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.6 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.8 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index a98803ad9..b2d2f4290 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.6 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.8 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index c85669db4..71ae63263 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.6 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.8 \ No newline at end of file From 6e2a2608b2943a93a83e3de36bf0e339b8848dd4 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 29 Dec 2023 22:07:53 -0600 Subject: [PATCH 023/117] v0.0.2.9 --- .github/workflows/docker.yml | 12 +--- Mythic_CLI/src/cmd/config/vars.go | 2 +- Mythic_CLI/src/cmd/internal/dockercompose.go | 73 +++++++++++++------- postgres-docker/.docker/Dockerfile | 2 +- 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 3867e39ab..8dbfd30a7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -101,9 +101,7 @@ jobs: org.opencontainers.image.source=${{ env.MYTHIC_SERVER_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} - platforms: | - linux/amd64 - linux/arm64 + platforms: linux/amd64,linux/arm64 - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -120,9 +118,7 @@ jobs: org.opencontainers.image.source=${{ env.MYTHIC_CLI_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} - platforms: | - linux/amd64 - linux/arm64 + platforms: linux/amd64,linux/arm64 - name: Build and push the postgres container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -139,9 +135,7 @@ jobs: org.opencontainers.image.source=${{ env.MYTHIC_POSTGRES_IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} - platforms: | - linux/amd64 - linux/arm64 + platforms: linux/amd64,linux/arm64 # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image diff --git a/Mythic_CLI/src/cmd/config/vars.go b/Mythic_CLI/src/cmd/config/vars.go index 22c14da72..8c01d12c1 100644 --- a/Mythic_CLI/src/cmd/config/vars.go +++ b/Mythic_CLI/src/cmd/config/vars.go @@ -4,5 +4,5 @@ package config var ( // Version Mythic CLI version - Version = "v0.2.3" + Version = "v0.2.4" ) diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index ec8cb8d6f..c0caad0c3 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -61,7 +61,7 @@ func addMythicServiceDockerComposeEntry(service string) { }, }, } - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { // don't blow away changes to the network configuration curConfig.Set("networks", networkInfo) } else { @@ -70,14 +70,14 @@ func addMythicServiceDockerComposeEntry(service string) { }) } volumes := map[string]interface{}{} - if curConfig.IsSet("volumes") { + if curConfig.InConfig("volumes") { volumes = curConfig.GetStringMap("volumes") } // adding or setting services in the docker-compose file var pStruct map[string]interface{} - if curConfig.IsSet("services." + strings.ToLower(service)) { + if curConfig.InConfig("services." + strings.ToLower(service)) { pStruct = curConfig.GetStringMap("services." + strings.ToLower(service)) delete(pStruct, "network_mode") delete(pStruct, "extra_hosts") @@ -127,8 +127,7 @@ func addMythicServiceDockerComposeEntry(service string) { } } else { pStruct["volumes"] = []string{ - "mythic_postgres/database:/var/lib/postgresql/data", - "mythic_postgres/postgres.conf:/etc/postgresql.conf", + "mythic_postgres_volume:/var/lib/postgresql/data", } } @@ -165,7 +164,9 @@ func addMythicServiceDockerComposeEntry(service string) { pStruct["environment"] = environment } if _, ok := volumes["mythic_postgres"]; !ok { - volumes["mythic_postgres"] = "" + volumes["mythic_postgres_volume"] = map[string]interface{}{ + "name": "mythic_postgres_volume", + } } case "mythic_documentation": pStruct["build"] = "./documentation-docker" @@ -425,7 +426,7 @@ func addMythicServiceDockerComposeEntry(service string) { pStruct["environment"] = []string{ "JUPYTER_TOKEN=${JUPYTER_TOKEN}", } - if curConfig.IsSet("services.mythic_jupyter.deploy") { + if curConfig.InConfig("services.mythic_jupyter.deploy") { pStruct["deploy"] = curConfig.Get("services.mythic_jupyter.deploy") } case "mythic_server": @@ -519,19 +520,19 @@ func addMythicServiceDockerComposeEntry(service string) { "GHOSTWRITER_URL=${GHOSTWRITER_URL}", "GHOSTWRITER_OPLOG_ID=${GHOSTWRITER_OPLOG_ID}", } - if !mythicEnv.IsSet("GHOSTWRITER_API_KEY") { + if !mythicEnv.InConfig("GHOSTWRITER_API_KEY") { key := askVariable("Please enter your GhostWriter API Key") mythicEnv.Set("GHOSTWRITER_API_KEY", key) } - if !mythicEnv.IsSet("GHOSTWRITER_URL") { + if !mythicEnv.InConfig("GHOSTWRITER_URL") { url := askVariable("Please enter your GhostWriter URL") mythicEnv.Set("GHOSTWRITER_URL", url) } - if !mythicEnv.IsSet("GHOSTWRITER_OPLOG_ID") { + if !mythicEnv.InConfig("GHOSTWRITER_OPLOG_ID") { gwID := askVariable("Please enter your GhostWriter OpLog ID") mythicEnv.Set("GHOSTWRITER_OPLOG_ID", gwID) } - if !mythicEnv.IsSet("MYTHIC_API_KEY") { + if !mythicEnv.InConfig("MYTHIC_API_KEY") { mythicID := askVariable("Please enter your Mythic API Key (optional)") mythicEnv.Set("MYTHIC_API_KEY", mythicID) } @@ -582,22 +583,28 @@ func addMythicServiceDockerComposeEntry(service string) { } pStruct["command"] = "--extend.query-path=/queries.yaml" } - if !curConfig.IsSet("services." + strings.ToLower(service)) { + if !curConfig.InConfig("services." + strings.ToLower(service)) { curConfig.Set("services."+strings.ToLower(service), pStruct) fmt.Printf("[+] Added %s to docker-compose\n", strings.ToLower(service)) } else { curConfig.Set("services."+strings.ToLower(service), pStruct) } - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { curConfig.Set("networks", networkInfo) } else { curConfig.Set("networks.default_network.driver_opts", map[string]string{ "com.docker.network.bridge.name": "mythic_if", }) } + curConfig.Set("volumes", volumes) curConfig.Set("version", "2.4") - curConfig.WriteConfig() + err := curConfig.WriteConfig() + if err != nil { + fmt.Printf("[-] Failed to update config: %v\n", err) + } else { + fmt.Println("[+] Successfully updated docker-compose.yml") + } } func removeMythicServiceDockerComposeEntry(service string) { var curConfig = viper.New() @@ -623,7 +630,7 @@ func removeMythicServiceDockerComposeEntry(service string) { }, }, } - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { // don't blow away changes to the network configuration curConfig.Set("networks", networkInfo) } else { @@ -635,7 +642,7 @@ func removeMythicServiceDockerComposeEntry(service string) { if isServiceRunning(service) { DockerStop([]string{strings.ToLower(service)}) } - if curConfig.IsSet("services." + strings.ToLower(service)) { + if curConfig.InConfig("services." + strings.ToLower(service)) { delete(curConfig.Get("services").(map[string]interface{}), strings.ToLower(service)) if stringInSlice(service, []string{"mythic_grafana", "mythic_prometheus", "mythic_postgres_exporter"}) { fmt.Printf("[+] Removed %s from docker-compose because postgres_debug is set to false\n", strings.ToLower(service)) @@ -644,7 +651,7 @@ func removeMythicServiceDockerComposeEntry(service string) { } } - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { curConfig.Set("networks", networkInfo) } else { curConfig.Set("networks.default_network.driver_opts", map[string]string{ @@ -652,7 +659,13 @@ func removeMythicServiceDockerComposeEntry(service string) { }) } curConfig.Set("version", "2.4") - curConfig.WriteConfig() + fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) + err := curConfig.WriteConfig() + if err != nil { + fmt.Printf("[-] Failed to update config: %v\n", err) + } else { + fmt.Println("[+] Successfully updated docker-compose.yml") + } } func AddDockerComposeEntry(service string, additionalConfigs map[string]interface{}) error { @@ -680,7 +693,7 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac }, }, } - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { curConfig.Set("networks", networkInfo) } else { curConfig.Set("networks.default_network.driver_opts", map[string]string{ @@ -759,7 +772,7 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac } } curConfig.Set("services."+strings.ToLower(service), pStruct) - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { curConfig.Set("networks", networkInfo) } else { curConfig.Set("networks.default_network.driver_opts", map[string]string{ @@ -767,8 +780,13 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac }) } curConfig.Set("version", "2.4") - curConfig.WriteConfig() - fmt.Println("[+] Successfully updated docker-compose.yml") + fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) + err = curConfig.WriteConfig() + if err != nil { + fmt.Printf("[-] Failed to update config: %v\n", err) + } else { + fmt.Println("[+] Successfully updated docker-compose.yml") + } return nil } @@ -806,7 +824,7 @@ func RemoveDockerComposeEntry(service string) error { fmt.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) } - if !curConfig.IsSet("networks") { + if !curConfig.InConfig("networks") { curConfig.Set("networks", networkInfo) } else { curConfig.Set("networks.default_network.driver_opts", map[string]string{ @@ -814,8 +832,13 @@ func RemoveDockerComposeEntry(service string) error { }) } curConfig.Set("version", "2.4") - curConfig.WriteConfig() - fmt.Println("[+] Successfully updated docker-compose.yml") + fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) + err := curConfig.WriteConfig() + if err != nil { + fmt.Printf("[-] Failed to update config: %v\n", err) + } else { + fmt.Println("[+] Successfully updated docker-compose.yml") + } return nil } diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index 7f29d32f5..f1892f867 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -1,4 +1,4 @@ FROM postgres:15-alpine COPY ["pg_hba.conf", "/var/lib/postgresql/pg_hba.conf"] COPY ["configuration.sh", "/docker-entrypoint-initdb.d/configuration.sh"] -COPY ["postgres.conf", "/etc/postgres.confg"] \ No newline at end of file +COPY ["postgres.conf", "/etc/postgres.conf"] \ No newline at end of file From 63b0901c05215176cc955a319dba8dbb0e7ad60a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 04:17:52 +0000 Subject: [PATCH 024/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.9' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index f1774335e..d95d9fcf0 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.8 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.9 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index b2d2f4290..8f8231f7f 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.8 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.9 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 71ae63263..740e53b08 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.8 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.9 \ No newline at end of file From eb2f9bd7ee783652f2fdddb3b4f677cb7fae9260 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 11:16:32 -0600 Subject: [PATCH 025/117] v0.0.2.10 --- .github/workflows/docker.yml | 26 ++ Mythic_CLI/src/cmd/internal/docker.go | 38 ++- Mythic_CLI/src/cmd/internal/dockercompose.go | 254 +++++++++++-------- Mythic_CLI/src/cmd/internal/reset.go | 17 +- rabbitmq-docker/.docker/Dockerfile | 4 + rabbitmq-docker/Dockerfile | 5 +- 6 files changed, 228 insertions(+), 116 deletions(-) create mode 100755 rabbitmq-docker/.docker/Dockerfile diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 8dbfd30a7..5461fecd4 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,6 +20,7 @@ env: MYTHIC_SERVER_IMAGE_NAME: ${{ github.repository }}_server MYTHIC_CLI_IMAGE_NAME: ${{ github.repository }}_cli MYTHIC_POSTGRES_IMAGE_NAME: ${{ github.repository }}_postgres + MYTHIC_RABBITMQ_IMAGE_NAME: ${{ github.repository }}_postgres # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" @@ -29,6 +30,7 @@ env: MYTHIC_SERVER_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} MYTHIC_CLI_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} MYTHIC_POSTGRES_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} + MYTHIC_RABBITMQ_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} # License for the container image IMAGE_LICENSE: BSD-3-Clause @@ -85,6 +87,9 @@ jobs: - name: Lowercase the postgres container image name run: echo "MYTHIC_POSTGRES_IMAGE_NAME=${MYTHIC_POSTGRES_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the rabbitmq container image name + run: echo "MYTHIC_RABBITMQ_IMAGE_NAME=${MYTHIC_RABBITMQ_IMAGE_NAME,,}" >> ${GITHUB_ENV} + # Build and push the server container image with the specified tag and labels - name: Build and push the server container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -137,6 +142,22 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + - name: Build and push the rabbitmq container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: rabbitmq-docker + file: rabbitmq-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_RABBITMQ_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_RABBITMQ_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.MYTHIC_RABBITMQ_IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag @@ -154,6 +175,11 @@ jobs: run: | sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_POSTGRES_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the rabbitmq Dockerfile reference to reference the new release tag + working-directory: rabbitmq-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_RABBITMQ_IMAGE_NAME}:${VERSION}|" Dockerfile + # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit diff --git a/Mythic_CLI/src/cmd/internal/docker.go b/Mythic_CLI/src/cmd/internal/docker.go index 54af4b35d..8402af880 100644 --- a/Mythic_CLI/src/cmd/internal/docker.go +++ b/Mythic_CLI/src/cmd/internal/docker.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" "io" "log" @@ -231,7 +232,11 @@ func DockerStart(containers []string) error { } } } - DockerRemoveImages() + err = DockerRemoveImages() + if err != nil { + fmt.Printf("[-] Failed to remove images\n%v\n", err) + return err + } TestMythicRabbitmqConnection() TestMythicConnection() Status(false) @@ -275,10 +280,14 @@ func DockerBuild(containers []string) error { } if err := runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, containers...)); err != nil { return err - } else if err := runDockerCompose(append([]string{"up", "--build", "-d"}, containers...)); err != nil { + } else if err = runDockerCompose(append([]string{"up", "--build", "-d"}, containers...)); err != nil { + return err + } + err := DockerRemoveImages() + if err != nil { + fmt.Printf("[-] Failed to remove images\n%v\n", err) return err } - DockerRemoveImages() return nil } } @@ -286,7 +295,7 @@ func DockerRemoveImages() error { ctx := context.Background() cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { - panic(err) + return err } defer cli.Close() @@ -306,6 +315,27 @@ func DockerRemoveImages() error { } return nil } +func DockerRemoveVolume(volumeName string) error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + err = cli.VolumeRemove(ctx, currentVolume.Name, true) + if err != nil { + return err + } + } + } + return nil +} func DockerRemoveContainers(containers []string) error { if err := runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, containers...)); err != nil { return err diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index c0caad0c3..0baf99208 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -49,26 +49,29 @@ func addMythicServiceDockerComposeEntry(service string) { log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) } } - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", + /* + networkInfo := map[string]interface{}{ + "default_network": map[string]interface{}{ + "driver": "bridge", + "driver_opts": map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }, + "labels": []string{ + "mythic_network", + "default_network", + }, }, - }, - } - if !curConfig.InConfig("networks") { - // don't blow away changes to the network configuration - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + } + if !curConfig.InConfig("networks") { + // don't blow away changes to the network configuration + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + + */ volumes := map[string]interface{}{} if curConfig.InConfig("volumes") { volumes = curConfig.GetStringMap("volumes") @@ -82,9 +85,13 @@ func addMythicServiceDockerComposeEntry(service string) { delete(pStruct, "network_mode") delete(pStruct, "extra_hosts") delete(pStruct, "build") - pStruct["networks"] = []string{ - "default_network", - } + delete(pStruct, "networks") + /* + pStruct["networks"] = []string{ + "default_network", + } + + */ } else { pStruct = map[string]interface{}{ "logging": map[string]interface{}{ @@ -100,9 +107,12 @@ func addMythicServiceDockerComposeEntry(service string) { }, "container_name": service, "image": service, - "networks": []string{ - "default_network", - }, + /* + "networks": []string{ + "default_network", + }, + + */ } } @@ -119,7 +129,7 @@ func addMythicServiceDockerComposeEntry(service string) { "retries": 5, "start_period": "20s", } - pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgresql.conf" + pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf" if mythicEnv.GetBool("postgres_bind_local_mount") { pStruct["volumes"] = []string{ "./postgres-docker/database:/var/lib/postgresql/data", @@ -354,11 +364,23 @@ func addMythicServiceDockerComposeEntry(service string) { } } pStruct["environment"] = finalRabbitEnv - pStruct["volumes"] = []string{ - "./rabbitmq-docker/storage:/var/lib/rabbitmq", - "./rabbitmq-docker/generate_config.sh:/generate_config.sh", - "./rabbitmq-docker/rabbitmq.conf:/tmp/base_rabbitmq.conf", + if mythicEnv.GetBool("rabbitmq_bind_local_mount") { + pStruct["volumes"] = []string{ + "./rabbitmq-docker/storage:/var/lib/rabbitmq", + "./rabbitmq-docker/generate_config.sh:/generate_config.sh", + "./rabbitmq-docker/rabbitmq.conf:/tmp/base_rabbitmq.conf", + } + } else { + pStruct["volumes"] = []string{ + "mythic_rabbitmq_volume:/var/lib/rabbitmq", + } + } + if _, ok := volumes["mythic_rabbitmq"]; !ok { + volumes["mythic_rabbitmq_volume"] = map[string]interface{}{ + "name": "mythic_rabbitmq_volume", + } } + case "mythic_react": if mythicEnv.GetBool("mythic_react_debug") { pStruct["build"] = map[string]interface{}{ @@ -589,14 +611,16 @@ func addMythicServiceDockerComposeEntry(service string) { } else { curConfig.Set("services."+strings.ToLower(service), pStruct) } + /* + if !curConfig.InConfig("networks") { + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + */ curConfig.Set("volumes", volumes) curConfig.Set("version", "2.4") err := curConfig.WriteConfig() @@ -618,26 +642,29 @@ func removeMythicServiceDockerComposeEntry(service string) { log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) } } - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", + /* + networkInfo := map[string]interface{}{ + "default_network": map[string]interface{}{ + "driver": "bridge", + "driver_opts": map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }, + "labels": []string{ + "mythic_network", + "default_network", + }, }, - }, - } - if !curConfig.InConfig("networks") { - // don't blow away changes to the network configuration - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + } + if !curConfig.InConfig("networks") { + // don't blow away changes to the network configuration + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + + */ if isServiceRunning(service) { DockerStop([]string{strings.ToLower(service)}) @@ -651,13 +678,16 @@ func removeMythicServiceDockerComposeEntry(service string) { } } - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + /* + if !curConfig.InConfig("networks") { + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + + */ curConfig.Set("version", "2.4") fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) err := curConfig.WriteConfig() @@ -681,25 +711,28 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) } } - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", + /* + networkInfo := map[string]interface{}{ + "default_network": map[string]interface{}{ + "driver": "bridge", + "driver_opts": map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }, + "labels": []string{ + "mythic_network", + "default_network", + }, }, - }, - } - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + } + if !curConfig.InConfig("networks") { + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + + */ absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)) if err != nil { fmt.Printf("[-] Failed to get the absolute path to the %s folder, does the folder exist?\n", InstalledServicesFolder) @@ -772,13 +805,16 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac } } curConfig.Set("services."+strings.ToLower(service), pStruct) - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + /* + if !curConfig.InConfig("networks") { + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + + */ curConfig.Set("version", "2.4") fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) err = curConfig.WriteConfig() @@ -803,18 +839,21 @@ func RemoveDockerComposeEntry(service string) error { log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) } } - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", + /* + networkInfo := map[string]interface{}{ + "default_network": map[string]interface{}{ + "driver": "bridge", + "driver_opts": map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }, + "labels": []string{ + "mythic_network", + "default_network", + }, }, - }, - } + } + + */ if !stringInSlice(service, MythicPossibleServices) { if isServiceRunning(service) { @@ -824,13 +863,16 @@ func RemoveDockerComposeEntry(service string) error { fmt.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) } - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + /* + if !curConfig.InConfig("networks") { + curConfig.Set("networks", networkInfo) + } else { + curConfig.Set("networks.default_network.driver_opts", map[string]string{ + "com.docker.network.bridge.name": "mythic_if", + }) + } + + */ curConfig.Set("version", "2.4") fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) err := curConfig.WriteConfig() diff --git a/Mythic_CLI/src/cmd/internal/reset.go b/Mythic_CLI/src/cmd/internal/reset.go index 81925b71d..dc3fe0148 100644 --- a/Mythic_CLI/src/cmd/internal/reset.go +++ b/Mythic_CLI/src/cmd/internal/reset.go @@ -10,14 +10,23 @@ import ( func DatabaseReset() { fmt.Printf("[*] Stopping Mythic\n") DockerStop([]string{}) + DockerRemoveContainers([]string{"mythic_postgres"}) workingPath := getCwdFromExe() fmt.Printf("[*] Removing database files\n") - err := os.RemoveAll(filepath.Join(workingPath, "postgres-docker", "database")) - if err != nil { - fmt.Printf("[-] Failed to remove database files\n") + if mythicEnv.GetBool("postgres_bind_local_mount") { + err := os.RemoveAll(filepath.Join(workingPath, "postgres-docker", "database")) + if err != nil { + fmt.Printf("[-] Failed to remove database files\n%v\n", err) + } else { + fmt.Printf("[+] Successfully reset datbase files\n") + } } else { - fmt.Printf("[+] Successfully reset datbase files\n") + err := DockerRemoveVolume("mythic_postgres_volume") + if err != nil { + fmt.Printf("[-] Failed to remove database:\n%v\n", err) + } } + } func RabbitmqReset(explicitCall bool) { if explicitCall { diff --git a/rabbitmq-docker/.docker/Dockerfile b/rabbitmq-docker/.docker/Dockerfile new file mode 100755 index 000000000..3f0da07d8 --- /dev/null +++ b/rabbitmq-docker/.docker/Dockerfile @@ -0,0 +1,4 @@ +FROM rabbitmq:3-management-alpine +ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf +ADD generate_config.sh /generate_config.sh +ADD rabbitmq.conf /tmp/base_rabbitmq.conf \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 1552af9fe..794711eae 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,3 +1,4 @@ #FROM rabbitmq:3-alpine -FROM rabbitmq:3-management-alpine -ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf \ No newline at end of file +#FROM rabbitmq:3-management-alpine +#ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.9 \ No newline at end of file From 3336181bf96223ccfcba7259249b3b4539504ddb Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 17:25:54 +0000 Subject: [PATCH 026/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.10' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index d95d9fcf0..dec6828fe 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.9 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.10 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 8f8231f7f..50723903c 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.9 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.10 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 740e53b08..e410d8e87 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.9 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.10 \ No newline at end of file From 145f311d061041d33bccddadc20297133c949853 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 11:42:25 -0600 Subject: [PATCH 027/117] v0.0.2.11 --- .github/workflows/docker.yml | 2 +- rabbitmq-docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5461fecd4..ebe06d65e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -20,7 +20,7 @@ env: MYTHIC_SERVER_IMAGE_NAME: ${{ github.repository }}_server MYTHIC_CLI_IMAGE_NAME: ${{ github.repository }}_cli MYTHIC_POSTGRES_IMAGE_NAME: ${{ github.repository }}_postgres - MYTHIC_RABBITMQ_IMAGE_NAME: ${{ github.repository }}_postgres + MYTHIC_RABBITMQ_IMAGE_NAME: ${{ github.repository }}_rabbitmq # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 794711eae..ffdbedb79 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.9 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.10 \ No newline at end of file From 40f4af62fd5028c16754a33036ffb9c6f7cbae40 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 17:52:26 +0000 Subject: [PATCH 028/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.11' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index dec6828fe..fd22e6206 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.10 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.11 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 50723903c..d78bf9b89 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.10 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.11 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index e410d8e87..7cbc73021 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.10 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.11 \ No newline at end of file From dfef6d7773ed5cca7d494557663ca59744528678 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 12:19:08 -0600 Subject: [PATCH 029/117] v0.0.2.12 --- .github/workflows/docker.yml | 2 +- Mythic_CLI/src/cmd/internal/dockercompose.go | 18 +++++++++++++--- Mythic_CLI/src/cmd/internal/reset.go | 22 +++++++++++++------- mythic-docker/.docker/Dockerfile | 1 + rabbitmq-docker/Dockerfile | 2 +- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ebe06d65e..789014973 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -185,7 +185,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 0baf99208..bcb78fd8b 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -460,9 +460,7 @@ func addMythicServiceDockerComposeEntry(service string) { if mythicEnv.GetString("mythic_server_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("mythic_server_mem_limit") } - pStruct["volumes"] = []string{ - "./mythic-docker/src:/usr/src/app", - } + pStruct["healthcheck"] = map[string]interface{}{ "test": "wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT}/health", "interval": "60s", @@ -519,6 +517,20 @@ func addMythicServiceDockerComposeEntry(service string) { } else { pStruct["environment"] = environment } + if mythicEnv.GetBool("mythic_server_bind_local_mount") { + pStruct["volumes"] = []string{ + "./mythic-docker/src:/usr/src/app", + } + } else { + pStruct["volumes"] = []string{ + "mythic_server_volume:/usr/src/app", + } + } + if _, ok := volumes["mythic_server"]; !ok { + volumes["mythic_server_volume"] = map[string]interface{}{ + "name": "mythic_server_volume", + } + } case "mythic_sync": if absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)); err != nil { fmt.Printf("[-] Failed to get abs path for mythic_sync\n") diff --git a/Mythic_CLI/src/cmd/internal/reset.go b/Mythic_CLI/src/cmd/internal/reset.go index dc3fe0148..9c441f9ac 100644 --- a/Mythic_CLI/src/cmd/internal/reset.go +++ b/Mythic_CLI/src/cmd/internal/reset.go @@ -10,7 +10,6 @@ import ( func DatabaseReset() { fmt.Printf("[*] Stopping Mythic\n") DockerStop([]string{}) - DockerRemoveContainers([]string{"mythic_postgres"}) workingPath := getCwdFromExe() fmt.Printf("[*] Removing database files\n") if mythicEnv.GetBool("postgres_bind_local_mount") { @@ -21,6 +20,7 @@ func DatabaseReset() { fmt.Printf("[+] Successfully reset datbase files\n") } } else { + DockerRemoveContainers([]string{"mythic_postgres"}) err := DockerRemoveVolume("mythic_postgres_volume") if err != nil { fmt.Printf("[-] Failed to remove database:\n%v\n", err) @@ -34,13 +34,21 @@ func RabbitmqReset(explicitCall bool) { DockerStop([]string{}) fmt.Printf("[*] Removing rabbitmq files\n") } - workingPath := getCwdFromExe() - err := os.RemoveAll(filepath.Join(workingPath, "rabbitmq-docker", "storage")) - if err != nil { - log.Fatalf("[-] Failed to reset rabbitmq files: %v\n", err) + if mythicEnv.GetBool("rabbitmq_bind_local_mount") { + workingPath := getCwdFromExe() + err := os.RemoveAll(filepath.Join(workingPath, "rabbitmq-docker", "storage")) + if err != nil { + log.Fatalf("[-] Failed to reset rabbitmq files: %v\n", err) + } else { + if explicitCall { + fmt.Printf("[+] Successfully reset rabbitmq files\n") + } + } } else { - if explicitCall { - fmt.Printf("[+] Successfully reset rabbitmq files\n") + DockerRemoveContainers([]string{"mythic_rabbitmq"}) + err := DockerRemoveVolume("mythic_rabbitmq_volume") + if err != nil { + fmt.Printf("[-] Failed to remove rabbitmq files:\n%v\n", err) } } } diff --git a/mythic-docker/.docker/Dockerfile b/mythic-docker/.docker/Dockerfile index a97df24ef..43692cc3a 100644 --- a/mythic-docker/.docker/Dockerfile +++ b/mythic-docker/.docker/Dockerfile @@ -15,6 +15,7 @@ RUN make build_final FROM alpine COPY --from=0 /mythic_server /mythic_server +COPY --from=0 /usr/src/app /usr/src/app WORKDIR /usr/src/app diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index ffdbedb79..467f70704 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.10 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.11 \ No newline at end of file From 6943a32d689900d1e390de13880a605c0fb20695 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 Dec 2023 18:28:58 +0000 Subject: [PATCH 030/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.12' --- Mythic_CLI/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index fd22e6206..3a7a4c7e3 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.11 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.12 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index d78bf9b89..2300d3442 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.11 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.12 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 7cbc73021..b616d16ce 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.11 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.12 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 467f70704..9b722987f 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.11 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.12 \ No newline at end of file From 92cc0f93aa6b5fa411951f888d02afb9d0d9219a Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 19:24:32 -0600 Subject: [PATCH 031/117] v0.0.2.13 --- .github/workflows/docker.yml | 40 ++++++++--- Mythic_CLI/src/cmd/internal/dockercompose.go | 73 +++++++++++--------- Mythic_CLI/src/cmd/internal/testServices.go | 41 +++++++---- documentation-docker/.docker/Dockerfile | 7 ++ documentation-docker/Dockerfile | 4 +- mythic-docker/.docker/Dockerfile | 3 + postgres-docker/.docker/Dockerfile | 7 +- rabbitmq-docker/.docker/Dockerfile | 7 +- 8 files changed, 122 insertions(+), 60 deletions(-) create mode 100644 documentation-docker/.docker/Dockerfile diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 789014973..43bf382ef 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -21,16 +21,14 @@ env: MYTHIC_CLI_IMAGE_NAME: ${{ github.repository }}_cli MYTHIC_POSTGRES_IMAGE_NAME: ${{ github.repository }}_postgres MYTHIC_RABBITMQ_IMAGE_NAME: ${{ github.repository }}_rabbitmq + MYTHIC_DOCUMENTATION_IMAGE_NAME: ${{ github.repository }}_documentation # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" # Source URL for the package in Github. This links the Github repository packages list # to this container image - MYTHIC_SERVER_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} - MYTHIC_CLI_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} - MYTHIC_POSTGRES_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} - MYTHIC_RABBITMQ_IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} + IMAGE_SOURCE: ${{ github.server_url }}/${{ github.repository }} # License for the container image IMAGE_LICENSE: BSD-3-Clause @@ -90,6 +88,8 @@ jobs: - name: Lowercase the rabbitmq container image name run: echo "MYTHIC_RABBITMQ_IMAGE_NAME=${MYTHIC_RABBITMQ_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the documentation container image name + run: echo "MYTHIC_DOCUMENTATION_IMAGE_NAME=${MYTHIC_DOCUMENTATION_IMAGE_NAME,,}" >> ${GITHUB_ENV} # Build and push the server container image with the specified tag and labels - name: Build and push the server container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -103,7 +103,7 @@ jobs: # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | - org.opencontainers.image.source=${{ env.MYTHIC_SERVER_IMAGE_SOURCE }} + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 @@ -120,7 +120,7 @@ jobs: # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | - org.opencontainers.image.source=${{ env.MYTHIC_CLI_IMAGE_SOURCE }} + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 @@ -137,7 +137,7 @@ jobs: # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | - org.opencontainers.image.source=${{ env.MYTHIC_POSTGRES_IMAGE_SOURCE }} + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 @@ -154,7 +154,24 @@ jobs: # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | - org.opencontainers.image.source=${{ env.MYTHIC_RABBITMQ_IMAGE_SOURCE }} + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 + + - name: Build and push the documentation container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: documentation-docker + file: documentation-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_DOCUMENTATION_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_DOCUMENTATION_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 @@ -180,12 +197,17 @@ jobs: run: | sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_RABBITMQ_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the documentation Dockerfile reference to reference the new release tag + working-directory: documentation-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_DOCUMENTATION_IMAGE_NAME}:${VERSION}|" Dockerfile + # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index bcb78fd8b..6949a60ce 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -122,14 +122,17 @@ func addMythicServiceDockerComposeEntry(service string) { "context": "./postgres-docker", "args": buildArguments, } - pStruct["healthcheck"] = map[string]interface{}{ - "test": "pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user", - "interval": "30s", - "timeout": "60s", - "retries": 5, - "start_period": "20s", - } - pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf" + /* + pStruct["healthcheck"] = map[string]interface{}{ + "test": "pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user", + "interval": "30s", + "timeout": "60s", + "retries": 5, + "start_period": "20s", + } + + */ + //pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf" if mythicEnv.GetBool("postgres_bind_local_mount") { pStruct["volumes"] = []string{ "./postgres-docker/database:/var/lib/postgresql/data", @@ -194,13 +197,16 @@ func addMythicServiceDockerComposeEntry(service string) { "${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", } } - pStruct["healthcheck"] = map[string]interface{}{ - "test": "wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT}/docs/", - "interval": "10s", - "timeout": "10s", - "retries": 5, - "start_period": "10s", - } + /* + pStruct["healthcheck"] = map[string]interface{}{ + "test": "wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT}/docs/", + "interval": "10s", + "timeout": "10s", + "retries": 5, + "start_period": "10s", + } + + */ pStruct["environment"] = []string{ "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", } @@ -322,18 +328,21 @@ func addMythicServiceDockerComposeEntry(service string) { "context": "./rabbitmq-docker", "args": buildArguments, } - pStruct["healthcheck"] = map[string]interface{}{ - "test": "rabbitmq-diagnostics -q check_port_connectivity", - "interval": "60s", - "timeout": "30s", - "retries": 5, - "start_period": "15s", - } + /* + pStruct["healthcheck"] = map[string]interface{}{ + "test": "rabbitmq-diagnostics -q check_port_connectivity", + "interval": "60s", + "timeout": "30s", + "retries": 5, + "start_period": "15s", + } + + */ pStruct["cpus"] = mythicEnv.GetInt("RABBITMQ_CPUS") if mythicEnv.GetString("rabbitmq_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("rabbitmq_mem_limit") } - pStruct["command"] = "/bin/sh -c \"chmod +x /generate_config.sh && /generate_config.sh && rabbitmq-server\"" + //pStruct["command"] = "/bin/sh -c \"chmod +x /generate_config.sh && /generate_config.sh && rabbitmq-server\"" if mythicEnv.GetBool("rabbitmq_bind_localhost_only") { pStruct["ports"] = []string{ "127.0.0.1:${RABBITMQ_PORT}:${RABBITMQ_PORT}", @@ -460,15 +469,17 @@ func addMythicServiceDockerComposeEntry(service string) { if mythicEnv.GetString("mythic_server_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("mythic_server_mem_limit") } + /* + pStruct["healthcheck"] = map[string]interface{}{ + "test": "wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT}/health", + "interval": "60s", + "timeout": "10s", + "retries": 5, + "start_period": "20s", + } - pStruct["healthcheck"] = map[string]interface{}{ - "test": "wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT}/health", - "interval": "60s", - "timeout": "10s", - "retries": 5, - "start_period": "20s", - } - pStruct["command"] = "${MYTHIC_SERVER_COMMAND}" + */ + //pStruct["command"] = "${MYTHIC_SERVER_COMMAND}" environment := []string{ "POSTGRES_HOST=${POSTGRES_HOST}", "POSTGRES_PORT=${POSTGRES_PORT}", diff --git a/Mythic_CLI/src/cmd/internal/testServices.go b/Mythic_CLI/src/cmd/internal/testServices.go index 44c4ab18b..5de89ff92 100644 --- a/Mythic_CLI/src/cmd/internal/testServices.go +++ b/Mythic_CLI/src/cmd/internal/testServices.go @@ -108,7 +108,7 @@ func TestMythicRabbitmqConnection() { fmt.Printf("[-] Failed to connect to RabbitMQ, retrying in %ds\n", sleepTime) time.Sleep(10 * time.Second) } else { - defer conn.Close() + conn.Close() fmt.Printf("[+] Successfully connected to RabbitMQ at amqp://%s:***@%s:%s/mythic_vhost\n\n", mythicEnv.GetString("RABBITMQ_USER"), rabbitmqAddress, rabbitmqPort) return } @@ -285,6 +285,7 @@ func Status(verbose bool) { } var portRanges []uint16 var portRangeMaps []string + portString := "" info := fmt.Sprintf("%s\t%s\t%s\t", container.Labels["name"], container.State, container.Status) if len(container.Ports) > 0 { sort.Slice(container.Ports[:], func(i, j int) bool { @@ -303,7 +304,7 @@ func Status(verbose bool) { if len(portRanges) > 0 { sort.Slice(portRanges, func(i, j int) bool { return portRanges[i] < portRanges[j] }) } - portString := strings.Join(portRangeMaps[:], ", ") + portString = strings.Join(portRangeMaps[:], ", ") var stringPortRanges []string for _, val := range portRanges { stringPortRanges = append(stringPortRanges, fmt.Sprintf("%d", val)) @@ -312,10 +313,19 @@ func Status(verbose bool) { portString = portString + ", " } portString = portString + strings.Join(stringPortRanges[:], ", ") - - info = info + portString } if stringInSlice(container.Image, MythicPossibleServices) { + found := false + for _, mnt := range container.Mounts { + if mnt.Name == container.Image+"_volume" { + info += mnt.Name + "\t" + found = true + } + } + if !found { + info += "local\t" + } + info = info + portString mythicLocalServices = append(mythicLocalServices, info) } else { installedServicesAbsPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder)) @@ -332,41 +342,42 @@ func Status(verbose bool) { } } } + } fmt.Fprintln(w, "Mythic Main Services") - fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tPORTS") + fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tMOUNT\tPORTS") for _, line := range mythicLocalServices { fmt.Fprintln(w, line) } - fmt.Fprintln(w, "\t\t\t\t") + fmt.Fprintln(w, "\t\t\t\t\t") w.Flush() fmt.Fprintln(w, "Installed Services") - fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tPORTS") + fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS") for _, line := range installedServices { fmt.Fprintln(w, line) } - fmt.Fprintln(w, "\t\t\t\t") + fmt.Fprintln(w, "\t\t\t") // remove all elementsInCompose from elementsOnDisk for _, container := range elementsInCompose { elementsOnDisk = RemoveStringFromSliceNoOrder(elementsOnDisk, container) } if len(elementsInCompose) > 0 && verbose { fmt.Fprintln(w, "Docker Compose services not running, start with: ./mythic-cli start [name]") - fmt.Fprintln(w, "NAME\t\t\t") + fmt.Fprintln(w, "NAME\t") sort.Strings(elementsInCompose) for _, container := range elementsInCompose { - fmt.Fprintln(w, fmt.Sprintf("%s\t\t\t", container)) + fmt.Fprintln(w, fmt.Sprintf("%s\t", container)) } - fmt.Fprintln(w, "\t\t\t\t") + fmt.Fprintln(w, "\t") } if len(elementsOnDisk) > 0 && verbose { fmt.Fprintln(w, "Extra Services, add to docker compose with: ./mythic-cli add [name]") - fmt.Fprintln(w, "NAME\t\t\t") + fmt.Fprintln(w, "NAME\t") sort.Strings(elementsOnDisk) for _, container := range elementsOnDisk { - fmt.Fprintln(w, fmt.Sprintf("%s\t\t\t", container)) + fmt.Fprintln(w, fmt.Sprintf("%s\t", container)) } - fmt.Fprintln(w, "\t\t\t\t") + fmt.Fprintln(w, "\t\t") } w.Flush() if len(installedServices) == 0 { @@ -408,7 +419,6 @@ func GetLogs(containerName string, numLogs string) { if err != nil { log.Fatalf("Failed to get container GetLogs: %v", err) } - defer reader.Close() // awesome post about the leading 8 payload/header bytes: https://medium.com/@dhanushgopinath/reading-docker-container-logs-with-golang-docker-engine-api-702233fac044 p := make([]byte, 8) _, err = reader.Read(p) @@ -418,6 +428,7 @@ func GetLogs(containerName string, numLogs string) { fmt.Printf("%s", content) _, err = reader.Read(p) } + reader.Close() } } if !found { diff --git a/documentation-docker/.docker/Dockerfile b/documentation-docker/.docker/Dockerfile new file mode 100644 index 000000000..4805508d0 --- /dev/null +++ b/documentation-docker/.docker/Dockerfile @@ -0,0 +1,7 @@ +FROM klakegg/hugo:latest + +COPY ["documentation-docker/", "/src/"] +HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \ + CMD wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT}/docs/ || exit 1 + +RUN hugo new site mythic_docs \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 92bc87d67..9f817ff8d 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1,3 +1 @@ -FROM klakegg/hugo:latest - -RUN hugo new site mythic_docs \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.12 \ No newline at end of file diff --git a/mythic-docker/.docker/Dockerfile b/mythic-docker/.docker/Dockerfile index 43692cc3a..bd6e1ffc0 100644 --- a/mythic-docker/.docker/Dockerfile +++ b/mythic-docker/.docker/Dockerfile @@ -19,4 +19,7 @@ COPY --from=0 /usr/src/app /usr/src/app WORKDIR /usr/src/app +HEALTHCHECK --interval=60s --timeout=10s --retries=5 --start-period=20s \ + CMD wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT}/health || exit 1 + CMD ["/bin/sh", "-c", "cp /mythic_server . && ./mythic_server" ] \ No newline at end of file diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index f1892f867..4d5082faf 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -1,4 +1,9 @@ FROM postgres:15-alpine COPY ["pg_hba.conf", "/var/lib/postgresql/pg_hba.conf"] COPY ["configuration.sh", "/docker-entrypoint-initdb.d/configuration.sh"] -COPY ["postgres.conf", "/etc/postgres.conf"] \ No newline at end of file +COPY ["postgres.conf", "/etc/postgres.conf"] + +HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ + CMD pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user || exit 1 + +CMD postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file diff --git a/rabbitmq-docker/.docker/Dockerfile b/rabbitmq-docker/.docker/Dockerfile index 3f0da07d8..1410d6739 100755 --- a/rabbitmq-docker/.docker/Dockerfile +++ b/rabbitmq-docker/.docker/Dockerfile @@ -1,4 +1,9 @@ FROM rabbitmq:3-management-alpine ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf ADD generate_config.sh /generate_config.sh -ADD rabbitmq.conf /tmp/base_rabbitmq.conf \ No newline at end of file +ADD rabbitmq.conf /tmp/base_rabbitmq.conf + +HEALTHCHECK --interval=60s --timeout=30s --retries=5 --start-period=20s \ + CMD rabbitmq-diagnostics -q check_port_connectivity || exit 1 + +CMD /bin/sh -c "chmod +x /generate_config.sh && /generate_config.sh && rabbitmq-server" \ No newline at end of file From ff4d4ec4248bfa26b1c4072aaf3184f5b5d6405f Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 19:35:33 -0600 Subject: [PATCH 032/117] v0.0.2.14 --- documentation-docker/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation-docker/.docker/Dockerfile b/documentation-docker/.docker/Dockerfile index 4805508d0..af2f89399 100644 --- a/documentation-docker/.docker/Dockerfile +++ b/documentation-docker/.docker/Dockerfile @@ -1,6 +1,6 @@ FROM klakegg/hugo:latest -COPY ["documentation-docker/", "/src/"] +COPY [".", "/src/"] HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \ CMD wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT}/docs/ || exit 1 From 2632e6e270fc9f6d635d9bd6a5eda7dd211a6560 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 01:45:48 +0000 Subject: [PATCH 033/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.14' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 3a7a4c7e3..4b4f37ac0 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.12 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.14 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 9f817ff8d..80230e93f 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.12 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.14 \ No newline at end of file diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 2300d3442..21056c522 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.12 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.14 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index b616d16ce..9816b8fd0 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.12 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.14 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 9b722987f..0b95c51ca 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.12 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.14 \ No newline at end of file From 7db81b9bdc0379aff45c58ba29453dda7973754e Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 20:44:22 -0600 Subject: [PATCH 034/117] v0.0.2.15 --- .github/workflows/docker.yml | 27 +++++++++++++- Mythic_CLI/src/cmd/internal/dockercompose.go | 38 ++++++++++++++++---- jupyter-docker/.docker/Dockerfile | 19 ++++++++++ jupyter-docker/Dockerfile | 17 +-------- postgres-docker/.docker/Dockerfile | 2 +- 5 files changed, 78 insertions(+), 25 deletions(-) create mode 100644 jupyter-docker/.docker/Dockerfile diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 43bf382ef..a11d99857 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -22,6 +22,7 @@ env: MYTHIC_POSTGRES_IMAGE_NAME: ${{ github.repository }}_postgres MYTHIC_RABBITMQ_IMAGE_NAME: ${{ github.repository }}_rabbitmq MYTHIC_DOCUMENTATION_IMAGE_NAME: ${{ github.repository }}_documentation + MYTHIC_JUPYTER_IMAGE_NAME: ${{ github.repository }}_jupyter # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" @@ -90,6 +91,9 @@ jobs: - name: Lowercase the documentation container image name run: echo "MYTHIC_DOCUMENTATION_IMAGE_NAME=${MYTHIC_DOCUMENTATION_IMAGE_NAME,,}" >> ${GITHUB_ENV} + + - name: Lowercase the jupyter container image name + run: echo "MYTHIC_JUPYTER_IMAGE_NAME=${MYTHIC_JUPYTER_IMAGE_NAME,,}" >> ${GITHUB_ENV} # Build and push the server container image with the specified tag and labels - name: Build and push the server container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -175,6 +179,23 @@ jobs: org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + + - name: Build and push the jupyter container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: jupyter-docker + file: jupyter-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_JUPYTER_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_JUPYTER_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag @@ -202,12 +223,16 @@ jobs: run: | sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_DOCUMENTATION_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the jupyter Dockerfile reference to reference the new release tag + working-directory: jupyter-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_JUPYTER_IMAGE_NAME}:${VERSION}|" Dockerfile # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 6949a60ce..9c8f860af 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -187,7 +187,7 @@ func addMythicServiceDockerComposeEntry(service string) { "context": "./documentation-docker", "args": buildArguments, } - pStruct["command"] = "server -p ${DOCUMENTATION_PORT}" + //pStruct["command"] = "server -p ${DOCUMENTATION_PORT}" if mythicEnv.GetBool("documentation_bind_localhost_only") { pStruct["ports"] = []string{ "127.0.0.1:${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", @@ -210,9 +210,21 @@ func addMythicServiceDockerComposeEntry(service string) { pStruct["environment"] = []string{ "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", } - pStruct["volumes"] = []string{ - "./documentation-docker/:/src", + if mythicEnv.GetBool("documentation_bind_local_mount") { + pStruct["volumes"] = []string{ + "./documentation-docker/:/src", + } + } else { + pStruct["volumes"] = []string{ + "mythic_documentation_volume:/usr/src/app", + } + } + if _, ok := volumes["mythic_documentation"]; !ok { + volumes["mythic_documentation_volume"] = map[string]interface{}{ + "name": "mythic_documentation_volume", + } } + case "mythic_graphql": pStruct["build"] = map[string]interface{}{ "context": "./hasura-docker", @@ -441,7 +453,7 @@ func addMythicServiceDockerComposeEntry(service string) { if mythicEnv.GetString("jupyter_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("jupyter_mem_limit") } - pStruct["command"] = "start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='${JUPYTER_TOKEN}' --ServerApp.base_url=\"/jupyter\" --ServerApp.default_url=\"/jupyter\"" + //pStruct["command"] = "start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='${JUPYTER_TOKEN}' --ServerApp.base_url=\"/jupyter\" --ServerApp.default_url=\"/jupyter\"" if mythicEnv.GetBool("jupyter_bind_localhost_only") { pStruct["ports"] = []string{ "127.0.0.1:${JUPYTER_PORT}:${JUPYTER_PORT}", @@ -451,15 +463,27 @@ func addMythicServiceDockerComposeEntry(service string) { "${JUPYTER_PORT}:${JUPYTER_PORT}", } } - pStruct["volumes"] = []string{ - "./jupyter-docker/jupyter:/projects", - } + pStruct["environment"] = []string{ "JUPYTER_TOKEN=${JUPYTER_TOKEN}", } if curConfig.InConfig("services.mythic_jupyter.deploy") { pStruct["deploy"] = curConfig.Get("services.mythic_jupyter.deploy") } + if mythicEnv.GetBool("jupyter_bind_local_mount") { + pStruct["volumes"] = []string{ + "./jupyter-docker/jupyter:/projects", + } + } else { + pStruct["volumes"] = []string{ + "mythic_jupyter_volume:/projects", + } + } + if _, ok := volumes["mythic_jupyter"]; !ok { + volumes["mythic_jupyter_volume"] = map[string]interface{}{ + "name": "mythic_jupyter_volume", + } + } case "mythic_server": pStruct["build"] = map[string]interface{}{ "context": "./mythic-docker", diff --git a/jupyter-docker/.docker/Dockerfile b/jupyter-docker/.docker/Dockerfile new file mode 100644 index 000000000..85e1517ad --- /dev/null +++ b/jupyter-docker/.docker/Dockerfile @@ -0,0 +1,19 @@ +FROM jupyter/base-notebook:python-3.11 + +# for offline builds, add ability for custom PIP repositories +ARG PIP_INDEX +ARG PIP_INDEX_URL +ARG PIP_TRUSTED_HOST + +RUN pip3 install mythic + +WORKDIR /projects + +#CMD start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='' --ServerApp.base_url="/jupyter" --ServerApp.default_url="/jupyter" + +ENV JUPYTERHUB_SERVICE_PREFIX "/jupyter/" + +COPY ["jupyter/", "."] + +CMD start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='${JUPYTER_TOKEN}' --ServerApp.base_url="/jupyter" --ServerApp.default_url="/jupyter" +# sudo docker run -p 8888:8888 -v `pwd`/jupyter:/projects jupyter diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index d7d14402c..ef6937e07 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1,16 +1 @@ -FROM jupyter/base-notebook:python-3.10 - -# for offline builds, add ability for custom PIP repositories -ARG PIP_INDEX -ARG PIP_INDEX_URL -ARG PIP_TRUSTED_HOST - -RUN pip3 install mythic==0.1.7 - -WORKDIR /projects - -#CMD start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='' --ServerApp.base_url="/jupyter" --ServerApp.default_url="/jupyter" - -ENV JUPYTERHUB_SERVICE_PREFIX "/jupyter/" - -# sudo docker run -p 8888:8888 -v `pwd`/jupyter:/projects jupyter +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.14 diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index 4d5082faf..e958d85ae 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ CMD pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user || exit 1 -CMD postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file +CMD docker-entrypoint.sh -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file From 36b004252a074827c28b0cd6708b93cf9b4e0d55 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 02:55:28 +0000 Subject: [PATCH 035/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.15' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 4b4f37ac0..1ded1b9be 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.14 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.15 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 80230e93f..c64c27d54 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.14 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.15 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index ef6937e07..ac96c3f03 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.14 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.15 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 21056c522..d19bbe922 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.14 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.15 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 9816b8fd0..5b7536d84 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.14 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.15 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 0b95c51ca..900ba56da 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.14 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.15 \ No newline at end of file From d7cbb4523ae97e985537b64cadb17e07896e7766 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 21:11:06 -0600 Subject: [PATCH 036/117] v0.0.2.16 --- postgres-docker/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index e958d85ae..964c18d9e 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ CMD pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user || exit 1 -CMD docker-entrypoint.sh -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file +CMD sudo -u postgres postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file From f186ca0437cc20aa54a493da6c681f491bb9e00f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 03:21:56 +0000 Subject: [PATCH 037/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.16' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 1ded1b9be..a8c6568c4 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.15 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.16 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index c64c27d54..9d13536a3 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.15 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.16 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index ac96c3f03..e39073784 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.15 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.16 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index d19bbe922..206b3a458 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.15 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.16 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 5b7536d84..28dd6844d 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.15 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.16 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 900ba56da..372f56fed 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.15 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.16 \ No newline at end of file From 5771536d7aee9ad356ff804c4586a481c4130e49 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 21:26:09 -0600 Subject: [PATCH 038/117] v0.0.2.17 --- postgres-docker/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index 964c18d9e..7bec90a5e 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ CMD pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user || exit 1 -CMD sudo -u postgres postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file +CMD su -u postgres postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file From 484f3eb08bd9a1d5c3cde32a03a0fe3ac8e2be28 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 03:37:35 +0000 Subject: [PATCH 039/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.17' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index a8c6568c4..a2212a450 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.16 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.17 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 9d13536a3..bc4c5f6bd 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.16 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.17 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index e39073784..38b50dc81 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.16 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.17 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 206b3a458..a998efc85 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.16 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.17 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 28dd6844d..1a5554af3 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.16 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.17 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 372f56fed..c2edea056 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.16 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.17 \ No newline at end of file From 0d65b055096994c441c070b4f9542056d733dff4 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 22:02:22 -0600 Subject: [PATCH 040/117] v0.0.2.18 --- .github/workflows/docker.yml | 180 ++++++++++++++++++++++++----- postgres-docker/.docker/Dockerfile | 2 +- 2 files changed, 150 insertions(+), 32 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a11d99857..4054374f3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -43,58 +43,30 @@ env: jobs: # Builds the base container image and pushes it to the container registry - build-and-push-image: + mythic_server: runs-on: ubuntu-latest - - # Provision an ephemeral Github token for the workflow which is capable of pushing - # Github packages and pushing code permissions: contents: write packages: write - steps: - # Pull in the repository code - name: Checkout the repository uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout - - # Log in to the configured container registry using the ephemeral Github token - name: Log in to the container registry uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - # setup Docker build action - name: Set up QEMU uses: docker/setup-qemu-action@v2 with: platforms: 'arm64,arm' - - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v2 - - # Container image names need to be lowercased. This changes the 'IMAGE_NAME' - # variable to all lowercase letters + # the following are unique to this job - name: Lowercase the server container image name run: echo "MYTHIC_SERVER_IMAGE_NAME=${MYTHIC_SERVER_IMAGE_NAME,,}" >> ${GITHUB_ENV} - - - name: Lowercase the cli container image name - run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} - - - name: Lowercase the postgres container image name - run: echo "MYTHIC_POSTGRES_IMAGE_NAME=${MYTHIC_POSTGRES_IMAGE_NAME,,}" >> ${GITHUB_ENV} - - - name: Lowercase the rabbitmq container image name - run: echo "MYTHIC_RABBITMQ_IMAGE_NAME=${MYTHIC_RABBITMQ_IMAGE_NAME,,}" >> ${GITHUB_ENV} - - - name: Lowercase the documentation container image name - run: echo "MYTHIC_DOCUMENTATION_IMAGE_NAME=${MYTHIC_DOCUMENTATION_IMAGE_NAME,,}" >> ${GITHUB_ENV} - - - name: Lowercase the jupyter container image name - run: echo "MYTHIC_JUPYTER_IMAGE_NAME=${MYTHIC_JUPYTER_IMAGE_NAME,,}" >> ${GITHUB_ENV} - # Build and push the server container image with the specified tag and labels - name: Build and push the server container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images with: @@ -112,6 +84,31 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_cli: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + # the following are unique to this job + - name: Lowercase the cli container image name + run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images with: @@ -129,6 +126,31 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_postgres: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + # the following are unique to this job + - name: Lowercase the postgres container image name + run: echo "MYTHIC_POSTGRES_IMAGE_NAME=${MYTHIC_POSTGRES_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Build and push the postgres container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images with: @@ -146,6 +168,31 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_rabbitmq: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + # the following are unique to this job + - name: Lowercase the rabbitmq container image name + run: echo "MYTHIC_RABBITMQ_IMAGE_NAME=${MYTHIC_RABBITMQ_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Build and push the rabbitmq container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images with: @@ -163,6 +210,31 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_documentation: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + # the following are unique to this job + - name: Lowercase the documentation container image name + run: echo "MYTHIC_DOCUMENTATION_IMAGE_NAME=${MYTHIC_DOCUMENTATION_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Build and push the documentation container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images with: @@ -180,6 +252,33 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_jupyter: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + # these two are unique + + - name: Lowercase the jupyter container image name + run: echo "MYTHIC_JUPYTER_IMAGE_NAME=${MYTHIC_JUPYTER_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Build and push the jupyter container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images with: @@ -196,6 +295,25 @@ jobs: org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + + update_files: + runs-on: ubuntu-latest + needs: + - mythic_server + - mythic_cli + - mythic_postgres + - mythic_rabbitmq + - mythic_documentation + - mythic_jupyter + permissions: + contents: write + packages: write + + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag @@ -250,4 +368,4 @@ jobs: push: origin HEAD:${{ env.RELEASE_BRANCH }} --set-upstream # Have the workflow fail in case there are pathspec issues - pathspec_error_handling: exitImmediately \ No newline at end of file + pathspec_error_handling: exitImmediately diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index 7bec90a5e..5c1825c7b 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ CMD pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user || exit 1 -CMD su -u postgres postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file +CMD su postgres postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file From 6dd70c09c453b4b4fe1fdb27dd0e7b92e6f31aa8 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 04:08:47 +0000 Subject: [PATCH 041/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.18' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index a2212a450..8a6de7072 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.17 \ No newline at end of file +FROM ghcr.io/its-a-feature/Mythic_cli:v0.0.2.18 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index bc4c5f6bd..bb0d9e873 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.17 \ No newline at end of file +FROM ghcr.io/its-a-feature/Mythic_documentation:v0.0.2.18 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 38b50dc81..afd180a13 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.17 +FROM ghcr.io/its-a-feature/Mythic_jupyter:v0.0.2.18 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index a998efc85..039d29155 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.17 \ No newline at end of file +FROM ghcr.io/its-a-feature/Mythic_server:v0.0.2.18 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 1a5554af3..c93f2dba7 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.17 \ No newline at end of file +FROM ghcr.io/its-a-feature/Mythic_postgres:v0.0.2.18 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index c2edea056..ca0ac34f2 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.17 \ No newline at end of file +FROM ghcr.io/its-a-feature/Mythic_rabbitmq:v0.0.2.18 \ No newline at end of file From ab06d59d62dda3477f6d26570888e1ac8785461b Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 22:14:31 -0600 Subject: [PATCH 042/117] v0.0.2.19 --- .github/workflows/docker.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4054374f3..a2ad13336 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -314,6 +314,19 @@ jobs: - name: Checkout the repository uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + # update names to lowercase + - name: Lowercase the server container image name + run: echo "MYTHIC_SERVER_IMAGE_NAME=${MYTHIC_SERVER_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the cli container image name + run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the postgres container image name + run: echo "MYTHIC_POSTGRES_IMAGE_NAME=${MYTHIC_POSTGRES_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the rabbitmq container image name + run: echo "MYTHIC_RABBITMQ_IMAGE_NAME=${MYTHIC_RABBITMQ_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the documentation container image name + run: echo "MYTHIC_DOCUMENTATION_IMAGE_NAME=${MYTHIC_DOCUMENTATION_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the jupyter container image name + run: echo "MYTHIC_JUPYTER_IMAGE_NAME=${MYTHIC_JUPYTER_IMAGE_NAME,,}" >> ${GITHUB_ENV} # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag From a2915399cac01483fea7b2e2c5d55637395e5d7d Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 04:21:00 +0000 Subject: [PATCH 043/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.19' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 8a6de7072..902ff84cb 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/Mythic_cli:v0.0.2.18 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.19 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index bb0d9e873..785ccf199 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/Mythic_documentation:v0.0.2.18 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.19 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index afd180a13..0a3929d78 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/Mythic_jupyter:v0.0.2.18 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.19 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 039d29155..32d7a7bc4 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/Mythic_server:v0.0.2.18 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.19 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index c93f2dba7..ffa68c119 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/Mythic_postgres:v0.0.2.18 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.19 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index ca0ac34f2..8a27a970f 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/Mythic_rabbitmq:v0.0.2.18 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.19 \ No newline at end of file From 0b7cd116a45f2ca40e14d3de5d6bac67c738a73d Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 30 Dec 2023 22:42:58 -0600 Subject: [PATCH 044/117] v0.0.2.20 --- documentation-docker/.docker/Dockerfile | 2 +- jupyter-docker/.docker/Dockerfile | 2 +- mythic-docker/.docker/Dockerfile | 2 +- postgres-docker/.docker/Dockerfile | 6 ++++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/documentation-docker/.docker/Dockerfile b/documentation-docker/.docker/Dockerfile index af2f89399..c332a122a 100644 --- a/documentation-docker/.docker/Dockerfile +++ b/documentation-docker/.docker/Dockerfile @@ -2,6 +2,6 @@ FROM klakegg/hugo:latest COPY [".", "/src/"] HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \ - CMD wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT}/docs/ || exit 1 + CMD wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT:-8090}/docs/ || exit 1 RUN hugo new site mythic_docs \ No newline at end of file diff --git a/jupyter-docker/.docker/Dockerfile b/jupyter-docker/.docker/Dockerfile index 85e1517ad..fab7a3892 100644 --- a/jupyter-docker/.docker/Dockerfile +++ b/jupyter-docker/.docker/Dockerfile @@ -15,5 +15,5 @@ ENV JUPYTERHUB_SERVICE_PREFIX "/jupyter/" COPY ["jupyter/", "."] -CMD start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='${JUPYTER_TOKEN}' --ServerApp.base_url="/jupyter" --ServerApp.default_url="/jupyter" +CMD start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='${JUPYTER_TOKEN:-mythic}' --ServerApp.base_url="/jupyter" --ServerApp.default_url="/jupyter" # sudo docker run -p 8888:8888 -v `pwd`/jupyter:/projects jupyter diff --git a/mythic-docker/.docker/Dockerfile b/mythic-docker/.docker/Dockerfile index bd6e1ffc0..b97b0b834 100644 --- a/mythic-docker/.docker/Dockerfile +++ b/mythic-docker/.docker/Dockerfile @@ -20,6 +20,6 @@ COPY --from=0 /usr/src/app /usr/src/app WORKDIR /usr/src/app HEALTHCHECK --interval=60s --timeout=10s --retries=5 --start-period=20s \ - CMD wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT}/health || exit 1 + CMD wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT:-17443}/health || exit 1 CMD ["/bin/sh", "-c", "cp /mythic_server . && ./mythic_server" ] \ No newline at end of file diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index 5c1825c7b..a633eff2a 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -4,6 +4,8 @@ COPY ["configuration.sh", "/docker-entrypoint-initdb.d/configuration.sh"] COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ - CMD pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user || exit 1 + CMD pg_isready -d mythic_db -p ${POSTGRES_PORT:-5432} -U mythic_user || exit 1 -CMD su postgres postgres -c "max_connections=100" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf \ No newline at end of file +USER postgres + +CMD postgres -c "max_connections=100" -p ${POSTGRES_PORT:-5432} -c config_file=/etc/postgres.conf \ No newline at end of file From c9fd1032579d235d68cd0fa4f5382d6ab082da78 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 04:49:20 +0000 Subject: [PATCH 045/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.20' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 902ff84cb..0219192fa 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.19 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.20 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 785ccf199..ffefb2115 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.19 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.20 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 0a3929d78..ce9c55248 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.19 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.20 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 32d7a7bc4..a78ea4edd 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.19 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.20 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index ffa68c119..a4e460f09 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.19 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.20 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 8a27a970f..3321fb73c 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.19 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.20 \ No newline at end of file From 4bccc16dad77571c70a23ea762d9f98f8f148fb7 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sun, 31 Dec 2023 10:33:35 -0600 Subject: [PATCH 046/117] v0.0.2.21 --- .github/workflows/docker.yml | 106 ++++++++++++++++++- Mythic_CLI/src/cmd/internal/dockercompose.go | 89 +++++++++++----- hasura-docker/.docker/Dockerfile | 3 + hasura-docker/Dockerfile | 3 +- nginx-docker/.docker/Dockerfile | 8 ++ nginx-docker/Dockerfile | 3 +- nginx-docker/health_check.sh | 8 ++ 7 files changed, 187 insertions(+), 33 deletions(-) create mode 100644 hasura-docker/.docker/Dockerfile create mode 100644 nginx-docker/.docker/Dockerfile create mode 100644 nginx-docker/health_check.sh diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a2ad13336..3cda6c93b 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -23,6 +23,8 @@ env: MYTHIC_RABBITMQ_IMAGE_NAME: ${{ github.repository }}_rabbitmq MYTHIC_DOCUMENTATION_IMAGE_NAME: ${{ github.repository }}_documentation MYTHIC_JUPYTER_IMAGE_NAME: ${{ github.repository }}_jupyter + MYTHIC_GRAPHQL_IMAGE_NAME: ${{ github.repository }}_graphql + MYTHIC_NGINX_IMAGE_NAME: ${{ github.repository }}_nginx # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" @@ -296,6 +298,94 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_graphql: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + # these two are unique + + - name: Lowercase the graphql container image name + run: echo "MYTHIC_GRAPHQL_IMAGE_NAME=${MYTHIC_GRAPHQL_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Build and push the graphql container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: hasura-docker + file: hasura-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_GRAPHQL_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_GRAPHQL_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 + + mythic_nginx: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + # these two are unique + + - name: Lowercase the nginx container image name + run: echo "MYTHIC_NGINX_IMAGE_NAME=${MYTHIC_NGINX_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Build and push the nginx container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: nginx-docker + file: nginx-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_NGINX_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_NGINX_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 + update_files: runs-on: ubuntu-latest needs: @@ -305,6 +395,8 @@ jobs: - mythic_rabbitmq - mythic_documentation - mythic_jupyter + - mythic_graphql + - mythic_nginx permissions: contents: write packages: write @@ -327,6 +419,10 @@ jobs: run: echo "MYTHIC_DOCUMENTATION_IMAGE_NAME=${MYTHIC_DOCUMENTATION_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Lowercase the jupyter container image name run: echo "MYTHIC_JUPYTER_IMAGE_NAME=${MYTHIC_JUPYTER_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the graphql container image name + run: echo "MYTHIC_GRAPHQL_IMAGE_NAME=${MYTHIC_GRAPHQL_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the nginx container image name + run: echo "MYTHIC_NGINX_IMAGE_NAME=${MYTHIC_NGINX_IMAGE_NAME,,}" >> ${GITHUB_ENV} # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag @@ -358,12 +454,20 @@ jobs: working-directory: jupyter-docker run: | sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_JUPYTER_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the graphql Dockerfile reference to reference the new release tag + working-directory: hasura-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_GRAPHQL_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the nginx Dockerfile reference to reference the new release tag + working-directory: nginx-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_NGINX_IMAGE_NAME}:${VERSION}|" Dockerfile # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 9c8f860af..35af9ee2e 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -133,17 +133,6 @@ func addMythicServiceDockerComposeEntry(service string) { */ //pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf" - if mythicEnv.GetBool("postgres_bind_local_mount") { - pStruct["volumes"] = []string{ - "./postgres-docker/database:/var/lib/postgresql/data", - "./postgres-docker/postgres.conf:/etc/postgresql.conf", - } - } else { - pStruct["volumes"] = []string{ - "mythic_postgres_volume:/var/lib/postgresql/data", - } - - } if imageExists("mythic_postgres") { if mythicEnv.GetBool("postgres_debug") { @@ -176,6 +165,17 @@ func addMythicServiceDockerComposeEntry(service string) { } else { pStruct["environment"] = environment } + if mythicEnv.GetBool("postgres_bind_local_mount") { + pStruct["volumes"] = []string{ + "./postgres-docker/database:/var/lib/postgresql/data", + "./postgres-docker/postgres.conf:/etc/postgresql.conf", + } + } else { + pStruct["volumes"] = []string{ + "mythic_postgres_volume:/var/lib/postgresql/data", + } + + } if _, ok := volumes["mythic_postgres"]; !ok { volumes["mythic_postgres_volume"] = map[string]interface{}{ "name": "mythic_postgres_volume", @@ -253,9 +253,7 @@ func addMythicServiceDockerComposeEntry(service string) { } else { pStruct["environment"] = environment } - pStruct["volumes"] = []string{ - "./hasura-docker/metadata:/metadata", - } + if mythicEnv.GetBool("hasura_bind_localhost_only") { pStruct["ports"] = []string{ "127.0.0.1:${HASURA_PORT}:${HASURA_PORT}", @@ -265,28 +263,49 @@ func addMythicServiceDockerComposeEntry(service string) { "${HASURA_PORT}:${HASURA_PORT}", } } + if mythicEnv.GetBool("hasura_bind_local_mount") { + pStruct["volumes"] = []string{ + "./hasura-docker/metadata:/metadata", + } + } else { + pStruct["volumes"] = []string{ + "mythic_graphql_volume:/metadata", + } + } + if _, ok := volumes["mythic_graphql"]; !ok { + volumes["mythic_graphql_volume"] = map[string]interface{}{ + "name": "mythic_graphql_volume", + } + } case "mythic_nginx": pStruct["build"] = map[string]interface{}{ "context": "./nginx-docker", "args": buildArguments, } - pStruct["healthcheck"] = map[string]interface{}{ - "test": "curl -k https://127.0.0.1:${NGINX_PORT}/new/login", - "interval": "30s", - "timeout": "60s", - "retries": 5, - "start_period": "15s", - } - nginxUseSSL := "ssl" - if !mythicEnv.GetBool("NGINX_USE_SSL") { - nginxUseSSL = "" + /* pStruct["healthcheck"] = map[string]interface{}{ - "test": "curl http://127.0.0.1:${NGINX_PORT}/new/login", + "test": "curl -k https://127.0.0.1:${NGINX_PORT}/new/login", "interval": "30s", "timeout": "60s", "retries": 5, "start_period": "15s", } + nginxUseSSL := "ssl" + if !mythicEnv.GetBool("NGINX_USE_SSL") { + nginxUseSSL = "" + pStruct["healthcheck"] = map[string]interface{}{ + "test": "curl http://127.0.0.1:${NGINX_PORT}/new/login", + "interval": "30s", + "timeout": "60s", + "retries": 5, + "start_period": "15s", + } + } + + */ + nginxUseSSL := "ssl" + if !mythicEnv.GetBool("NGINX_USE_SSL") { + nginxUseSSL = "" } nginxUseIPV4 := "" if !mythicEnv.GetBool("NGINX_USE_IPV4") { @@ -322,10 +341,7 @@ func addMythicServiceDockerComposeEntry(service string) { } } pStruct["environment"] = finalNginxEnv - pStruct["volumes"] = []string{ - "./nginx-docker/ssl:/etc/ssl/private", - "./nginx-docker/config:/etc/nginx", - } + if mythicEnv.GetBool("nginx_bind_localhost_only") { pStruct["ports"] = []string{ "127.0.0.1:${NGINX_PORT}:${NGINX_PORT}", @@ -335,6 +351,21 @@ func addMythicServiceDockerComposeEntry(service string) { "${NGINX_PORT}:${NGINX_PORT}", } } + if mythicEnv.GetBool("nginx_bind_local_mount") { + pStruct["volumes"] = []string{ + "./nginx-docker/ssl:/etc/ssl/private", + "./nginx-docker/config:/etc/nginx", + } + } else { + pStruct["volumes"] = []string{ + "mythic_nginx_volume:/etc/nginx", + } + } + if _, ok := volumes["mythic_nginx"]; !ok { + volumes["mythic_nginx_volume"] = map[string]interface{}{ + "name": "mythic_nginx_volume", + } + } case "mythic_rabbitmq": pStruct["build"] = map[string]interface{}{ "context": "./rabbitmq-docker", diff --git a/hasura-docker/.docker/Dockerfile b/hasura-docker/.docker/Dockerfile new file mode 100644 index 000000000..b8075aea7 --- /dev/null +++ b/hasura-docker/.docker/Dockerfile @@ -0,0 +1,3 @@ +FROM hasura/graphql-engine:latest.cli-migrations-v2 + +COPY ["metadata/", "/metadata"] \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 746bae78a..fd4db4788 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -4,4 +4,5 @@ #From hasura/graphql-engine:v1.3.4-beta.2.cli-migrations-v2 #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 -FROM hasura/graphql-engine:latest.cli-migrations-v2 +#FROM hasura/graphql-engine:latest.cli-migrations-v2 +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.20 \ No newline at end of file diff --git a/nginx-docker/.docker/Dockerfile b/nginx-docker/.docker/Dockerfile new file mode 100644 index 000000000..49c0dfc42 --- /dev/null +++ b/nginx-docker/.docker/Dockerfile @@ -0,0 +1,8 @@ +FROM nginx:1.25-alpine +COPY error403.html /usr/share/nginx/html/ +COPY ["config/", "/etc/nginx"] +COPY ["health_check.sh", "/health_check.sh"] +RUN chmod +x /health_check.sh + +HEALTHCHECK --interval=30s --timeout=60s --retries=5 --start-period=20s \ + CMD /health_check.sh || exit 1 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index d12758bd0..78151618d 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1,2 +1 @@ -FROM nginx:1.23-alpine -COPY error403.html /usr/share/nginx/html/ \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.20 \ No newline at end of file diff --git a/nginx-docker/health_check.sh b/nginx-docker/health_check.sh new file mode 100644 index 000000000..a43ad0bda --- /dev/null +++ b/nginx-docker/health_check.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [ "$NGINX_USE_SSL" == "ssl" ] +then + curl -k https://127.0.0.1:${NGINX_PORT:-7443}/new/login +else + curl -k http://127.0.0.1:${NGINX_PORT:-7443}/new/login +fi From 7a518239cb73011642a4d8ceba25a977ba6c2926 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 16:39:57 +0000 Subject: [PATCH 047/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.21' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 0219192fa..0c551b889 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.21 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index ffefb2115..66903f827 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.21 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index fd4db4788..830ea1695 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.21 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index ce9c55248..b6a923759 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.20 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.21 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index a78ea4edd..96df5a40c 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.21 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 78151618d..1fd5866b0 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.21 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index a4e460f09..352e2945e 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.21 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 3321fb73c..22bd24950 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.20 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.21 \ No newline at end of file From 8b0c6742dd549cc5840251d84eb71085e285f83c Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sun, 31 Dec 2023 13:47:13 -0600 Subject: [PATCH 048/117] v0.0.2.22 --- Mythic_CLI/src/cmd/internal/dockercompose.go | 10 +++++++--- Mythic_CLI/src/cmd/internal/testServices.go | 12 +++++++++--- nginx-docker/.docker/Dockerfile | 1 + 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 35af9ee2e..6954053ed 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -358,12 +358,16 @@ func addMythicServiceDockerComposeEntry(service string) { } } else { pStruct["volumes"] = []string{ - "mythic_nginx_volume:/etc/nginx", + "mythic_nginx_volume_config:/etc/nginx", + "mythic_nginx_volume_ssl:/etc/ssl/private", } } if _, ok := volumes["mythic_nginx"]; !ok { - volumes["mythic_nginx_volume"] = map[string]interface{}{ - "name": "mythic_nginx_volume", + volumes["mythic_nginx_volume_config"] = map[string]interface{}{ + "name": "mythic_nginx_volume_config", + } + volumes["mythic_nginx_volume_ssl"] = map[string]interface{}{ + "name": "mythic_nginx_volume_ssl", } } case "mythic_rabbitmq": diff --git a/Mythic_CLI/src/cmd/internal/testServices.go b/Mythic_CLI/src/cmd/internal/testServices.go index 5de89ff92..e1b91158f 100644 --- a/Mythic_CLI/src/cmd/internal/testServices.go +++ b/Mythic_CLI/src/cmd/internal/testServices.go @@ -317,14 +317,20 @@ func Status(verbose bool) { if stringInSlice(container.Image, MythicPossibleServices) { found := false for _, mnt := range container.Mounts { - if mnt.Name == container.Image+"_volume" { - info += mnt.Name + "\t" + if strings.HasPrefix(mnt.Name, container.Image+"_volume") { + if found { + info += ", " + mnt.Name + } else { + info += mnt.Name + } + found = true } } if !found { - info += "local\t" + info += "local" } + info += "\t" info = info + portString mythicLocalServices = append(mythicLocalServices, info) } else { diff --git a/nginx-docker/.docker/Dockerfile b/nginx-docker/.docker/Dockerfile index 49c0dfc42..a3408047e 100644 --- a/nginx-docker/.docker/Dockerfile +++ b/nginx-docker/.docker/Dockerfile @@ -1,6 +1,7 @@ FROM nginx:1.25-alpine COPY error403.html /usr/share/nginx/html/ COPY ["config/", "/etc/nginx"] +COPY ["ssl/", "/etc/ssl/private/"] COPY ["health_check.sh", "/health_check.sh"] RUN chmod +x /health_check.sh From b087e7b890c60297317210a040aae6bf0de97285 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sun, 31 Dec 2023 14:15:26 -0600 Subject: [PATCH 049/117] v0.0.2.23 --- nginx-docker/.docker/Dockerfile | 3 ++- nginx-docker/.docker/mythic-cert.crt | 11 +++++++++++ nginx-docker/.docker/mythic-ssl.key | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 nginx-docker/.docker/mythic-cert.crt create mode 100644 nginx-docker/.docker/mythic-ssl.key diff --git a/nginx-docker/.docker/Dockerfile b/nginx-docker/.docker/Dockerfile index a3408047e..ba5e23bc5 100644 --- a/nginx-docker/.docker/Dockerfile +++ b/nginx-docker/.docker/Dockerfile @@ -1,7 +1,8 @@ FROM nginx:1.25-alpine COPY error403.html /usr/share/nginx/html/ COPY ["config/", "/etc/nginx"] -COPY ["ssl/", "/etc/ssl/private/"] +COPY [".docker/mythic-cert.crt", "/etc/ssl/private/mythic-cert.crt"] +COPY [".docker/mythic-ssl.key", "/etc/ssl/private/mythic-ssl.key"] COPY ["health_check.sh", "/health_check.sh"] RUN chmod +x /health_check.sh diff --git a/nginx-docker/.docker/mythic-cert.crt b/nginx-docker/.docker/mythic-cert.crt new file mode 100644 index 000000000..e20687335 --- /dev/null +++ b/nginx-docker/.docker/mythic-cert.crt @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBkzCCARmgAwIBAgIRAJUPvfWHaLanlSP0QjnHMM4wCgYIKoZIzj0EAwMwETEP +MA0GA1UEChMGTXl0aGljMB4XDTIxMDUyNzAxMjMyOVoXDTIyMDUyNzAxMjMyOVow +ETEPMA0GA1UEChMGTXl0aGljMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEuOhKUl2N +vS80oyXT/9F+nMvGkmJkZcq6uTsgNpgtJ/TwX5jMx+euCrC+VoMH9As9jd3c1xRZ +SqeWZkA1TUxi55+A0jRLhqXt+eYcLZvuKi7XmAigmbV/OyhAzhDau8bWozUwMzAO +BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIw +ADAKBggqhkjOPQQDAwNoADBlAjEA9afCk4FDxMBm1LAkWpM0bWaNcpUYdlJD4rV9 +yM84ZLQx6HtOJLYwI7W8h55D4bM3AjAmPza5iBWvmCUEFjFSpApUkyLnX0CQrv8J +dRAq0QmUuLU10BPsoiUBKcYIO4SH4xw= +-----END CERTIFICATE----- diff --git a/nginx-docker/.docker/mythic-ssl.key b/nginx-docker/.docker/mythic-ssl.key new file mode 100644 index 000000000..16697d642 --- /dev/null +++ b/nginx-docker/.docker/mythic-ssl.key @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDDh5G51vOit9i5B1ci/I9fEy7SWqBjbe9BgvwzEjZ9omXA6ff52fUkZ +6VyowzNBAeagBwYFK4EEACKhZANiAAS46EpSXY29LzSjJdP/0X6cy8aSYmRlyrq5 +OyA2mC0n9PBfmMzH564KsL5Wgwf0Cz2N3dzXFFlKp5ZmQDVNTGLnn4DSNEuGpe35 +5hwtm+4qLteYCKCZtX87KEDOENq7xtY= +-----END EC PRIVATE KEY----- From 23a1aa2be0425a5621420ad29e7356bf78651a97 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 20:21:29 +0000 Subject: [PATCH 050/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.23' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 0c551b889..186b3db9c 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.23 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 66903f827..084358767 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.23 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 830ea1695..6a4347051 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.23 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index b6a923759..a7a9e22e9 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.21 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.23 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 96df5a40c..d00ba3b3e 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.23 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 1fd5866b0..8c3a87744 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.23 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 352e2945e..d68629c2b 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.23 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 22bd24950..f91338d3e 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.21 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.23 \ No newline at end of file From 354b19a466a1786ba1e420bad3df513ae5ee2ea8 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sun, 31 Dec 2023 15:11:29 -0600 Subject: [PATCH 051/117] v0.0.2.24 --- .github/workflows/docker.yml | 52 ++++++++++++++++++++ Mythic_CLI/.docker/Dockerfile | 4 +- Mythic_CLI/src/cmd/internal/dockercompose.go | 21 ++++++-- 3 files changed, 72 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 3cda6c93b..1a9256411 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -25,6 +25,7 @@ env: MYTHIC_JUPYTER_IMAGE_NAME: ${{ github.repository }}_jupyter MYTHIC_GRAPHQL_IMAGE_NAME: ${{ github.repository }}_graphql MYTHIC_NGINX_IMAGE_NAME: ${{ github.repository }}_nginx + MYTHIC_REACT_IMAGE_NAME: ${{ github.repository }}_react # Description label for the package in Github IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" @@ -386,6 +387,50 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + mythic_react: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + # these two are unique + + - name: Lowercase the react container image name + run: echo "MYTHIC_REACT_IMAGE_NAME=${MYTHIC_REACT_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Build and push the react container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: mythic-react-docker + file: mythic-react-docker/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_REACT_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_REACT_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 + update_files: runs-on: ubuntu-latest needs: @@ -397,6 +442,7 @@ jobs: - mythic_jupyter - mythic_graphql - mythic_nginx + - mythic_react permissions: contents: write packages: write @@ -423,6 +469,8 @@ jobs: run: echo "MYTHIC_GRAPHQL_IMAGE_NAME=${MYTHIC_GRAPHQL_IMAGE_NAME,,}" >> ${GITHUB_ENV} - name: Lowercase the nginx container image name run: echo "MYTHIC_NGINX_IMAGE_NAME=${MYTHIC_NGINX_IMAGE_NAME,,}" >> ${GITHUB_ENV} + - name: Lowercase the react container image name + run: echo "MYTHIC_REACT_IMAGE_NAME=${MYTHIC_REACT_IMAGE_NAME,,}" >> ${GITHUB_ENV} # The Dockerfile which Mythic uses to pull in the base container image needs to be # updated to reference the newly built container image - name: Fix the server Dockerfile reference to reference the new release tag @@ -462,6 +510,10 @@ jobs: working-directory: nginx-docker run: | sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_NGINX_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the react Dockerfile reference to reference the new release tag + working-directory: mythic-react-docker + run: | + sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_REACT_IMAGE_NAME}:${VERSION}|" Dockerfile # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index 0e6486a8b..7c3f7e10b 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -1,5 +1,5 @@ -FROM itsafeaturemythic/mythic_go_base:latest - +#FROM itsafeaturemythic/mythic_go_base:latest +FROM golang:1.21-alpine WORKDIR /usr/src/app ARG GOPROXY=proxy.golang.org diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 6954053ed..24e0d1d23 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -455,9 +455,24 @@ func addMythicServiceDockerComposeEntry(service string) { "context": "./mythic-react-docker", "args": buildArguments, } - pStruct["volumes"] = []string{ - "./mythic-react-docker/config:/etc/nginx", - "./mythic-react-docker/mythic/public:/mythic/new", + if mythicEnv.GetBool("mythic_react_bind_local_mount") { + pStruct["volumes"] = []string{ + "./mythic-react-docker/config:/etc/nginx", + "./mythic-react-docker/mythic/public:/mythic/new", + } + } else { + pStruct["volumes"] = []string{ + "mythic_react_volume_config:/etc/nginx", + "mythic_react_volume_public:/mythic/new", + } + } + } + if _, ok := volumes["mythic_react"]; !ok { + volumes["mythic_react_volume_config"] = map[string]interface{}{ + "name": "mythic_react_volume_config", + } + volumes["mythic_react_volume_ssl"] = map[string]interface{}{ + "name": "mythic_react_volume_public", } } if mythicEnv.GetBool("mythic_react_bind_localhost_only") { From 4d129ed15261599d192814c9a2e8ff44d022dd4c Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sun, 31 Dec 2023 16:54:04 -0600 Subject: [PATCH 052/117] v0.0.2.25 --- Mythic_CLI/.docker/Dockerfile | 2 ++ Mythic_CLI/src/cmd/internal/dockercompose.go | 17 ++++++++++------- mythic-react-docker/.docker/Dockerfile | 6 ++++++ mythic-react-docker/Dockerfile | 2 +- 4 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 mythic-react-docker/.docker/Dockerfile diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index 7c3f7e10b..d5375e60c 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -10,6 +10,8 @@ RUN go env -w GO111MODULE=${GO111MODULE} COPY ["src/", "."] +RUN apt-get install make + RUN make build_all FROM alpine diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 24e0d1d23..e98d48b30 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -484,13 +484,16 @@ func addMythicServiceDockerComposeEntry(service string) { "${MYTHIC_REACT_PORT}:${MYTHIC_REACT_PORT}", } } - pStruct["healthcheck"] = map[string]interface{}{ - "test": "wget -SqO - http://127.0.0.1:${MYTHIC_REACT_PORT}/new", - "interval": "30s", - "timeout": "60s", - "retries": 3, - "start_period": "15s", - } + /* + pStruct["healthcheck"] = map[string]interface{}{ + "test": "wget -SqO - http://127.0.0.1:${MYTHIC_REACT_PORT}/new", + "interval": "30s", + "timeout": "60s", + "retries": 3, + "start_period": "15s", + } + + */ pStruct["environment"] = []string{ "MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}", } diff --git a/mythic-react-docker/.docker/Dockerfile b/mythic-react-docker/.docker/Dockerfile new file mode 100644 index 000000000..3fc301efe --- /dev/null +++ b/mythic-react-docker/.docker/Dockerfile @@ -0,0 +1,6 @@ +FROM nginx:1.25-alpine +COPY ["config/", "/etc/nginx"] +COPY ["mythic/public/", "/mythic/new"] + +HEALTHCHECK --interval=30s --timeout=60s --retries=5 --start-period=20s \ + CMD wget -SqO - http://127.0.0.1:${MYTHIC_REACT_PORT:-3000}/new || exit 1 \ No newline at end of file diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 26643d7e6..8b1378917 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM nginx:1.23-alpine + From 2e15abbe405c1d59771cd249af6edfec948e29dc Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sun, 31 Dec 2023 17:01:48 -0600 Subject: [PATCH 053/117] v0.0.2.26 --- Mythic_CLI/.docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mythic_CLI/.docker/Dockerfile b/Mythic_CLI/.docker/Dockerfile index d5375e60c..750039120 100644 --- a/Mythic_CLI/.docker/Dockerfile +++ b/Mythic_CLI/.docker/Dockerfile @@ -10,7 +10,7 @@ RUN go env -w GO111MODULE=${GO111MODULE} COPY ["src/", "."] -RUN apt-get install make +RUN apk add --no-cache make RUN make build_all diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 8b1378917..8a7847021 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ - +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.23 \ No newline at end of file From 3ad15be9f075f7b7da430dbde43dafe1b8255403 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 Dec 2023 23:09:17 +0000 Subject: [PATCH 054/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.26' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 186b3db9c..1834d0ea2 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.26 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 084358767..8832f32b2 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.26 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 6a4347051..ea56ee974 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.26 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index a7a9e22e9..942266bc5 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.23 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.26 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index d00ba3b3e..74f58daf9 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.26 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 8c3a87744..106f6b895 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.26 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index d68629c2b..7b1c866a8 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.26 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index f91338d3e..b13522179 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.26 \ No newline at end of file From 80d1abda785b2c6a5d2852ad295d01cdf88b4464 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 1 Jan 2024 17:33:44 -0600 Subject: [PATCH 055/117] v0.0.2.27 --- .github/workflows/docker.yml | 2 +- Mythic_CLI/src/Makefile | 2 + Mythic_CLI/src/cmd/internal/docker.go | 223 +++++++++++++++++-- Mythic_CLI/src/cmd/internal/dockercompose.go | 2 +- Mythic_CLI/src/cmd/internal/utils.go | 104 ++++++++- Mythic_CLI/src/cmd/volume.go | 24 ++ Mythic_CLI/src/cmd/volumeCopyFrom.go | 44 ++++ Mythic_CLI/src/cmd/volumeCopyTo.go | 85 +++++++ Mythic_CLI/src/cmd/volumeList.go | 22 ++ Mythic_CLI/src/cmd/volumeRm.go | 22 ++ mythic-react-docker/Dockerfile | 2 +- nginx-docker/.docker/Dockerfile | 4 +- nginx-docker/.docker/mythic-cert.crt | 11 - nginx-docker/.docker/mythic-ssl.key | 6 - 14 files changed, 506 insertions(+), 47 deletions(-) create mode 100644 Mythic_CLI/src/cmd/volume.go create mode 100644 Mythic_CLI/src/cmd/volumeCopyFrom.go create mode 100644 Mythic_CLI/src/cmd/volumeCopyTo.go create mode 100644 Mythic_CLI/src/cmd/volumeList.go create mode 100644 Mythic_CLI/src/cmd/volumeRm.go delete mode 100644 nginx-docker/.docker/mythic-cert.crt delete mode 100644 nginx-docker/.docker/mythic-ssl.key diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 1a9256411..6c1effe60 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -519,7 +519,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile]" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com diff --git a/Mythic_CLI/src/Makefile b/Mythic_CLI/src/Makefile index 928bd6537..85b78244b 100644 --- a/Mythic_CLI/src/Makefile +++ b/Mythic_CLI/src/Makefile @@ -8,9 +8,11 @@ build: go build -o ${BINARY_NAME} . build_linux: + go mod tidy GOOS=linux go build -o ${BINARY_NAME}_linux . build_macos: + go mod tidy GOOS=darwin go build -o ${BINARY_NAME}_macos . build_all: build_linux build_macos diff --git a/Mythic_CLI/src/cmd/internal/docker.go b/Mythic_CLI/src/cmd/internal/docker.go index 8402af880..66fb0a57c 100644 --- a/Mythic_CLI/src/cmd/internal/docker.go +++ b/Mythic_CLI/src/cmd/internal/docker.go @@ -11,7 +11,10 @@ import ( "log" "os" "path/filepath" + "sort" + "strconv" "strings" + "text/tabwriter" ) var MythicPossibleServices = []string{ @@ -315,27 +318,7 @@ func DockerRemoveImages() error { } return nil } -func DockerRemoveVolume(volumeName string) error { - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() - volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) - if err != nil { - return err - } - for _, currentVolume := range volumes.Volumes { - if currentVolume.Name == volumeName { - err = cli.VolumeRemove(ctx, currentVolume.Name, true) - if err != nil { - return err - } - } - } - return nil -} + func DockerRemoveContainers(containers []string) error { if err := runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, containers...)); err != nil { return err @@ -417,3 +400,201 @@ func DockerHealth(containers []string) { } } } + +func VolumesList() error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 8, 2, '\t', 0) + fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tLOCATION") + du, err := cli.DiskUsage(ctx, types.DiskUsageOptions{}) + if err != nil { + fmt.Printf("[-] Failed to get disk sizes: %v\n", err) + os.Exit(1) + } + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + fmt.Printf("[-] Failed to get container list: %v\n", err) + os.Exit(1) + } + if du.Volumes == nil { + fmt.Printf("[-] No volumes known\n") + return nil + } + var entries []string + for _, currentVolume := range du.Volumes { + name := currentVolume.Name + size := "unknown" + if currentVolume.UsageData != nil { + size = ByteCountSI(currentVolume.UsageData.Size) + } + container := "unused" + for _, c := range containers { + for _, m := range c.Mounts { + if m.Name == currentVolume.Name { + container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" + } + } + } + entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s", + name, + size, + container, + currentVolume.Mountpoint, + )) + } + sort.Strings(entries) + for _, line := range entries { + fmt.Fprintln(w, line) + } + + defer w.Flush() + return nil +} +func DockerRemoveVolume(volumeName string) error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + err = cli.VolumeRemove(ctx, currentVolume.Name, true) + if err != nil { + return err + } + } + } + return nil +} +func ensureVolume(volumeName string) error { + containerNamePieces := strings.Split(volumeName, "_") + containerName := strings.Join(containerNamePieces[0:2], "_") + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return err + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + foundVolume := false + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + foundVolume = true + } + } + if !foundVolume { + _, err = cli.VolumeCreate(ctx, volume.CreateOptions{Name: volumeName}) + if err != nil { + return err + } + } + // now that we know the volume exists, make sure it's attached to a running container or we can't manipulate files + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + return err + } + for _, container := range containers { + if container.Image == containerName { + for _, mnt := range container.Mounts { + if mnt.Name == volumeName { + // container is running and has this mount associated with it + return nil + } + } + return errors.New(fmt.Sprintf("container, %s, isn't using volume, %s", containerName, volumeName)) + } + } + return errors.New(fmt.Sprintf("failed to find container, %s, for volume, %s", containerName, volumeName)) +} +func DockerCopyIntoVolume(sourceFile io.Reader, destinationFileName string, destinationVolume string) { + err := ensureVolume(destinationVolume) + if err != nil { + fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) + os.Exit(1) + } + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + fmt.Printf("[-] Failed to connect to docker api: %v\n", err) + os.Exit(1) + } + defer cli.Close() + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + fmt.Printf("[-] Failed to get container list: %v\n", err) + os.Exit(1) + } + for _, container := range containers { + for _, mnt := range container.Mounts { + if mnt.Name == destinationVolume { + err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{CopyUIDGID: true}) + if err != nil { + fmt.Printf("[-] Failed to write file: %v\n", err) + } else { + fmt.Printf("[+] Successfully wrote file\n") + } + return + } + } + } + fmt.Printf("[-] Failed to find that volume name in use by any containers") + os.Exit(1) +} +func DockerCopyFromVolume(sourceVolumeName string, sourceFileName string, destinationName string) { + err := ensureVolume(sourceVolumeName) + if err != nil { + fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) + os.Exit(1) + } + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + fmt.Printf("[-] Failed to connect to docker api: %v\n", err) + os.Exit(1) + } + defer cli.Close() + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + fmt.Printf("[-] Failed to get container list: %v\n", err) + os.Exit(1) + } + for _, container := range containers { + for _, mnt := range container.Mounts { + if mnt.Name == sourceVolumeName { + reader, _, err := cli.CopyFromContainer(ctx, container.ID, mnt.Destination+"/"+sourceFileName) + if err != nil { + fmt.Printf("[-] Failed to read file: %v\n", err) + return + } + destination, err := os.Create(destinationName) + if err != nil { + fmt.Printf("[-] Failed to open destination filename: %v\n", err) + return + } + defer destination.Close() + _, err = io.Copy(destination, reader) + if err != nil { + fmt.Printf("[-] Failed to get file from volume: %v\n", err) + return + } + fmt.Printf("[+] Successfully wrote file\n") + return + } + } + } + fmt.Printf("[-] Failed to find that volume name in use by any containers") + os.Exit(1) +} diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index e98d48b30..0d11dd01b 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -471,7 +471,7 @@ func addMythicServiceDockerComposeEntry(service string) { volumes["mythic_react_volume_config"] = map[string]interface{}{ "name": "mythic_react_volume_config", } - volumes["mythic_react_volume_ssl"] = map[string]interface{}{ + volumes["mythic_react_volume_public"] = map[string]interface{}{ "name": "mythic_react_volume_public", } } diff --git a/Mythic_CLI/src/cmd/internal/utils.go b/Mythic_CLI/src/cmd/internal/utils.go index 685ce019a..c8850940d 100644 --- a/Mythic_CLI/src/cmd/internal/utils.go +++ b/Mythic_CLI/src/cmd/internal/utils.go @@ -1,7 +1,9 @@ package internal import ( + "archive/tar" "bufio" + "bytes" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" @@ -267,11 +269,20 @@ func updateNginxBlockLists() { outputString += fmt.Sprintf("allow %s;\n", ip) } outputString += "deny all;" - ipFilePath := filepath.Join(getCwdFromExe(), "nginx-docker", "config", "blockips.conf") - if err := os.WriteFile(ipFilePath, []byte(outputString), 0600); err != nil { - fmt.Printf("[-] Failed to write out block list file\n") - os.Exit(1) + if mythicEnv.GetBool("nginx_bind_local_mount") { + ipFilePath := filepath.Join(getCwdFromExe(), "nginx-docker", "config", "blockips.conf") + if err := os.WriteFile(ipFilePath, []byte(outputString), 0600); err != nil { + fmt.Printf("[-] Failed to write out block list file: %v\n", err) + os.Exit(1) + } + } else { + err := moveStringToVolume("mythic_nginx_volume_config", "blockips.conf", outputString) + if err != nil { + fmt.Printf("[-] Failed to write out block list file: %v\n", err) + os.Exit(1) + } } + } // check docker version to make sure it's high enough for Mythic's features @@ -298,3 +309,88 @@ func generateSavedImageFolder() error { return os.MkdirAll(savedImagePath, 0755) } } + +func ByteCountSI(b int64) string { + const unit = 1000 + if b < unit { + return fmt.Sprintf("%d B", b) + } + div, exp := int64(unit), 0 + for n := b / unit; n >= unit; n /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %cB", + float64(b)/float64(div), "kMGTPE"[exp]) +} + +func tarFileToBytes(sourceName string) (*bytes.Buffer, error) { + source, err := os.Open(sourceName) + if err != nil { + return nil, err + } + sourceStats, err := source.Stat() + if err != nil { + return nil, err + } + var buf bytes.Buffer + tw := tar.NewWriter(&buf) + err = tw.WriteHeader(&tar.Header{ + Name: sourceName, // filename + Mode: 0777, // permissions + Size: sourceStats.Size(), // filesize + }) + if err != nil { + return nil, err + } + content, err := io.ReadAll(source) + if err != nil { + return nil, err + } + _, err = tw.Write(content) + if err != nil { + return nil, err + } + err = tw.Close() + if err != nil { + return nil, err + } + return &buf, nil +} +func tarStringToBytes(sourceName string, data string) (*bytes.Buffer, error) { + var buf bytes.Buffer + tw := tar.NewWriter(&buf) + err := tw.WriteHeader(&tar.Header{ + Name: sourceName, // filename + Mode: 0777, // permissions + Size: int64(len(data)), // filesize + }) + if err != nil { + return nil, err + } + _, err = tw.Write([]byte(data)) + if err != nil { + return nil, err + } + err = tw.Close() + if err != nil { + return nil, err + } + return &buf, nil +} +func moveFileToVolume(volumeName string, destinationName string, sourceName string) error { + contentBytes, err := tarFileToBytes(sourceName) + if err != nil { + return err + } + DockerCopyIntoVolume(contentBytes, destinationName, volumeName) + return nil +} +func moveStringToVolume(volumeName string, destinationName string, content string) error { + contentBytes, err := tarStringToBytes(destinationName, content) + if err != nil { + return err + } + DockerCopyIntoVolume(contentBytes, destinationName, volumeName) + return nil +} diff --git a/Mythic_CLI/src/cmd/volume.go b/Mythic_CLI/src/cmd/volume.go new file mode 100644 index 000000000..aa1c96445 --- /dev/null +++ b/Mythic_CLI/src/cmd/volume.go @@ -0,0 +1,24 @@ +package cmd + +import ( + "github.com/spf13/cobra" +) + +// configCmd represents the config command +var volumeCmd = &cobra.Command{ + Use: "volume", + Short: "Interact with the mythic volumes", + Long: `Run this command to interact with the Mythic volumes`, + Run: volumes, +} +var volumeName string +var sourceName string +var destinationName string + +func init() { + rootCmd.AddCommand(volumeCmd) +} + +func volumes(cmd *cobra.Command, args []string) { + +} diff --git a/Mythic_CLI/src/cmd/volumeCopyFrom.go b/Mythic_CLI/src/cmd/volumeCopyFrom.go new file mode 100644 index 000000000..eef3eca20 --- /dev/null +++ b/Mythic_CLI/src/cmd/volumeCopyFrom.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/spf13/cobra" +) + +// configCmd represents the config command +var volumeCopyFrom = &cobra.Command{ + Use: "copy_from", + Short: "Copy a file from a mounted volume to local disk", + Long: `Run this command to copy a file out of a mounted volume to local disk.`, + Run: volumesCopyFromCommand, +} + +func init() { + volumeCmd.AddCommand(volumeCopyFrom) + + volumeCopyFrom.Flags().StringVarP( + &volumeName, + "volume", + "v", + "", + `Specify the volume to copy a file from`, + ) + volumeCopyFrom.Flags().StringVarP( + &sourceName, + "source", + "s", + "", + `Specify the path of the file within the volume`, + ) + volumeCopyFrom.Flags().StringVarP( + &destinationName, + "destination", + "d", + "", + `Specify the destination path to write the file to`, + ) +} + +func volumesCopyFromCommand(cmd *cobra.Command, args []string) { + internal.DockerCopyFromVolume(volumeName, sourceName, destinationName) +} diff --git a/Mythic_CLI/src/cmd/volumeCopyTo.go b/Mythic_CLI/src/cmd/volumeCopyTo.go new file mode 100644 index 000000000..3071b9b78 --- /dev/null +++ b/Mythic_CLI/src/cmd/volumeCopyTo.go @@ -0,0 +1,85 @@ +package cmd + +import ( + "archive/tar" + "bytes" + "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/spf13/cobra" + "io" + "os" +) + +// configCmd represents the config command +var volumeCopyTo = &cobra.Command{ + Use: "copy_to", + Short: "Copy a file to a mounted volume from local disk", + Long: `Run this command to copy a file to a mounted volume from local disk.`, + Run: volumesCopyToCommand, +} + +func init() { + volumeCmd.AddCommand(volumeCopyTo) + + volumeCopyTo.Flags().StringVarP( + &volumeName, + "volume", + "v", + "", + `Specify the volume to copy a file to`, + ) + volumeCopyTo.Flags().StringVarP( + &sourceName, + "source", + "s", + "", + `Specify the path of the file locally`, + ) + volumeCopyTo.Flags().StringVarP( + &destinationName, + "destination", + "d", + "", + `Specify the destination directory to write the file to within the volume`, + ) +} + +func volumesCopyToCommand(cmd *cobra.Command, args []string) { + source, err := os.Open(sourceName) + if err != nil { + fmt.Printf("[-] Failed to open file locally: %v\n", err) + os.Exit(1) + } + sourceStats, err := source.Stat() + if err != nil { + fmt.Printf("[-] Failed to stat file: %v\n", err) + os.Exit(1) + } + var buf bytes.Buffer + tw := tar.NewWriter(&buf) + err = tw.WriteHeader(&tar.Header{ + Name: sourceName, // filename + Mode: 0777, // permissions + Size: sourceStats.Size(), // filesize + }) + if err != nil { + fmt.Printf("[-] Failed to create tar: %v\n", err) + os.Exit(1) + } + content, err := io.ReadAll(source) + if err != nil { + fmt.Printf("[-] Failed to read file contents: %v\n", err) + os.Exit(1) + } + _, err = tw.Write(content) + if err != nil { + fmt.Printf("[-] Failed to write to temp tar: %v\n", err) + os.Exit(1) + } + err = tw.Close() + if err != nil { + fmt.Printf("[-] Failed to close temp tar: %v\n", err) + os.Exit(1) + } + internal.DockerCopyIntoVolume(&buf, destinationName, volumeName) +} diff --git a/Mythic_CLI/src/cmd/volumeList.go b/Mythic_CLI/src/cmd/volumeList.go new file mode 100644 index 000000000..ed9f3f0c3 --- /dev/null +++ b/Mythic_CLI/src/cmd/volumeList.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/spf13/cobra" +) + +// configCmd represents the config command +var volumeList = &cobra.Command{ + Use: "ls", + Short: "list information about the volumes Mythic can use", + Long: `Run this command to list specific information about all of the volumes Mythic can use. `, + Run: volumesListCommand, +} + +func init() { + volumeCmd.AddCommand(volumeList) +} + +func volumesListCommand(cmd *cobra.Command, args []string) { + internal.VolumesList() +} diff --git a/Mythic_CLI/src/cmd/volumeRm.go b/Mythic_CLI/src/cmd/volumeRm.go new file mode 100644 index 000000000..9cb9d5796 --- /dev/null +++ b/Mythic_CLI/src/cmd/volumeRm.go @@ -0,0 +1,22 @@ +package cmd + +import ( + "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/spf13/cobra" +) + +// configCmd represents the config command +var volumeRm = &cobra.Command{ + Use: "rm", + Short: "Delete a volume and all of its contents", + Long: `Run this command to delete a specific volume and all of its contents `, + Run: volumesRmCommand, +} + +func init() { + volumeCmd.AddCommand(volumeRm) +} + +func volumesRmCommand(cmd *cobra.Command, args []string) { + internal.DockerRemoveVolume(args[0]) +} diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 8a7847021..c4f9a7117 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.23 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.26 \ No newline at end of file diff --git a/nginx-docker/.docker/Dockerfile b/nginx-docker/.docker/Dockerfile index ba5e23bc5..f25b6d35f 100644 --- a/nginx-docker/.docker/Dockerfile +++ b/nginx-docker/.docker/Dockerfile @@ -1,10 +1,10 @@ FROM nginx:1.25-alpine COPY error403.html /usr/share/nginx/html/ COPY ["config/", "/etc/nginx"] -COPY [".docker/mythic-cert.crt", "/etc/ssl/private/mythic-cert.crt"] -COPY [".docker/mythic-ssl.key", "/etc/ssl/private/mythic-ssl.key"] COPY ["health_check.sh", "/health_check.sh"] RUN chmod +x /health_check.sh +RUN apk add openssl +RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/mythic-ssl.key -out /etc/ssl/private/mythic-cert.crt -sha256 -days 3650 -nodes -subj "/O=Mythic/OU=Mythic/CN=Mythic" HEALTHCHECK --interval=30s --timeout=60s --retries=5 --start-period=20s \ CMD /health_check.sh || exit 1 \ No newline at end of file diff --git a/nginx-docker/.docker/mythic-cert.crt b/nginx-docker/.docker/mythic-cert.crt deleted file mode 100644 index e20687335..000000000 --- a/nginx-docker/.docker/mythic-cert.crt +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIBkzCCARmgAwIBAgIRAJUPvfWHaLanlSP0QjnHMM4wCgYIKoZIzj0EAwMwETEP -MA0GA1UEChMGTXl0aGljMB4XDTIxMDUyNzAxMjMyOVoXDTIyMDUyNzAxMjMyOVow -ETEPMA0GA1UEChMGTXl0aGljMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEuOhKUl2N -vS80oyXT/9F+nMvGkmJkZcq6uTsgNpgtJ/TwX5jMx+euCrC+VoMH9As9jd3c1xRZ -SqeWZkA1TUxi55+A0jRLhqXt+eYcLZvuKi7XmAigmbV/OyhAzhDau8bWozUwMzAO -BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIw -ADAKBggqhkjOPQQDAwNoADBlAjEA9afCk4FDxMBm1LAkWpM0bWaNcpUYdlJD4rV9 -yM84ZLQx6HtOJLYwI7W8h55D4bM3AjAmPza5iBWvmCUEFjFSpApUkyLnX0CQrv8J -dRAq0QmUuLU10BPsoiUBKcYIO4SH4xw= ------END CERTIFICATE----- diff --git a/nginx-docker/.docker/mythic-ssl.key b/nginx-docker/.docker/mythic-ssl.key deleted file mode 100644 index 16697d642..000000000 --- a/nginx-docker/.docker/mythic-ssl.key +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN EC PRIVATE KEY----- -MIGkAgEBBDDh5G51vOit9i5B1ci/I9fEy7SWqBjbe9BgvwzEjZ9omXA6ff52fUkZ -6VyowzNBAeagBwYFK4EEACKhZANiAAS46EpSXY29LzSjJdP/0X6cy8aSYmRlyrq5 -OyA2mC0n9PBfmMzH564KsL5Wgwf0Cz2N3dzXFFlKp5ZmQDVNTGLnn4DSNEuGpe35 -5hwtm+4qLteYCKCZtX87KEDOENq7xtY= ------END EC PRIVATE KEY----- From 5783a28b03c2d8435ae16c8de5be0f025f55a0bd Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 1 Jan 2024 17:41:41 -0600 Subject: [PATCH 056/117] v0.0.2.28 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6c1effe60..893bb1028 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -519,7 +519,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile]" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com From 7407f7c2e8110d20814c425a3f51a1f2ed809164 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 23:49:24 +0000 Subject: [PATCH 057/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.28' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 1834d0ea2..7d6273c4c 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.28 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 8832f32b2..07d3a6c6e 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.28 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index ea56ee974..4b4573c1d 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.28 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 942266bc5..90b906217 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.26 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.28 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 74f58daf9..e49b73005 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.28 \ No newline at end of file diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index c4f9a7117..7768ec6f5 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.28 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 106f6b895..7ff8801d8 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.28 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 7b1c866a8..566fc09e6 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.28 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index b13522179..16533e91c 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.26 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.28 \ No newline at end of file From bda80f6f70627bb242cf83d18b2b8d02d8318546 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 1 Jan 2024 19:43:30 -0600 Subject: [PATCH 058/117] v0.0.2.29 --- Mythic_CLI/src/cmd/internal/docker.go | 26 +++++-- Mythic_CLI/src/cmd/internal/dockercompose.go | 1 - Mythic_CLI/src/cmd/internal/installservice.go | 45 +++++++---- Mythic_CLI/src/cmd/internal/utils.go | 78 +++++++++++++------ Mythic_CLI/src/cmd/volumeRm.go | 10 ++- documentation-docker/.docker/Dockerfile | 4 +- 6 files changed, 115 insertions(+), 49 deletions(-) diff --git a/Mythic_CLI/src/cmd/internal/docker.go b/Mythic_CLI/src/cmd/internal/docker.go index 66fb0a57c..343563468 100644 --- a/Mythic_CLI/src/cmd/internal/docker.go +++ b/Mythic_CLI/src/cmd/internal/docker.go @@ -149,7 +149,7 @@ func DockerStart(containers []string) error { return err } } - updateNginxBlockLists() + //updateNginxBlockLists() // get all the services on disk and in docker-compose currently if diskAgents, err := getElementsOnDisk(); err != nil { return err @@ -175,7 +175,6 @@ func DockerStart(containers []string) error { } // if the user didn't explicitly call out starting certain containers, then do all of them if len(containers) == 0 { - generateCerts() containers = append(dockerComposeContainers, intendedMythicServices...) } finalContainers := []string{} @@ -240,6 +239,8 @@ func DockerStart(containers []string) error { fmt.Printf("[-] Failed to remove images\n%v\n", err) return err } + updateNginxBlockLists() + generateCerts() TestMythicRabbitmqConnection() TestMythicConnection() Status(false) @@ -410,7 +411,7 @@ func VolumesList() error { defer cli.Close() w := new(tabwriter.Writer) w.Init(os.Stdout, 0, 8, 2, '\t', 0) - fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tLOCATION") + fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tCONTAINER STATUS\tLOCATION") du, err := cli.DiskUsage(ctx, types.DiskUsageOptions{}) if err != nil { fmt.Printf("[-] Failed to get disk sizes: %v\n", err) @@ -432,18 +433,28 @@ func VolumesList() error { if currentVolume.UsageData != nil { size = ByteCountSI(currentVolume.UsageData.Size) } - container := "unused" + if !strings.HasPrefix(currentVolume.Name, "mythic_") { + continue + } + containerPieces := strings.Split(currentVolume.Name, "_") + containerName := strings.Join(containerPieces[0:2], "_") + container := "unused (0)" + containerStatus := "offline" for _, c := range containers { + if c.Image == containerName { + containerStatus = c.Status + } for _, m := range c.Mounts { if m.Name == currentVolume.Name { container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" } } } - entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s", + entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s\t%s", name, size, container, + containerStatus, currentVolume.Mountpoint, )) } @@ -540,9 +551,12 @@ func DockerCopyIntoVolume(sourceFile io.Reader, destinationFileName string, dest for _, container := range containers { for _, mnt := range container.Mounts { if mnt.Name == destinationVolume { - err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{CopyUIDGID: true}) + err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{ + CopyUIDGID: true, + }) if err != nil { fmt.Printf("[-] Failed to write file: %v\n", err) + os.Exit(1) } else { fmt.Printf("[+] Successfully wrote file\n") } diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 0d11dd01b..975febe9a 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -916,7 +916,6 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac */ curConfig.Set("version", "2.4") - fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) err = curConfig.WriteConfig() if err != nil { fmt.Printf("[-] Failed to update config: %v\n", err) diff --git a/Mythic_CLI/src/cmd/internal/installservice.go b/Mythic_CLI/src/cmd/internal/installservice.go index 94d5ce3a9..7bc42bd00 100644 --- a/Mythic_CLI/src/cmd/internal/installservice.go +++ b/Mythic_CLI/src/cmd/internal/installservice.go @@ -149,28 +149,39 @@ func InstallFolder(installPath string, overWrite bool) error { for _, f := range files { if f.IsDir() { fmt.Printf("[*] Processing Documentation for %s\n", f.Name()) - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - fmt.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) - if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next payload documentation\n") - continue + if mythicEnv.GetBool("documentation_bind_local_mount") { + if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { + if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + fmt.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to remove current version: %v\n", err) + fmt.Printf("[-] Continuing to the next payload documentation\n") + continue + } else { + fmt.Printf("[+] Successfully removed the current version\n") + } } else { - fmt.Printf("[+] Successfully removed the current version\n") + fmt.Printf("[!] Skipping documentation for , %s\n", f.Name()) + continue } - } else { - fmt.Printf("[!] Skipping documentation for , %s\n", f.Name()) + } + fmt.Printf("[*] Copying new documentation into place\n") + err = copyDir(filepath.Join(installPath, "documentation-payload", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to copy directory over\n") + continue + } + } else { + err = moveFileToVolume("mythic_documentation_volume", + filepath.Join("content", "Agents", f.Name()), + filepath.Join(installPath, "documentation-payload", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to install documentation for payload: %v\n", err) continue } } - fmt.Printf("[*] Copying new documentation into place\n") - err = copyDir(filepath.Join(installPath, "documentation-payload", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) - if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") - continue - } + } } fmt.Printf("[+] Successfully installed Payload documentation\n") diff --git a/Mythic_CLI/src/cmd/internal/utils.go b/Mythic_CLI/src/cmd/internal/utils.go index c8850940d..1c92fceef 100644 --- a/Mythic_CLI/src/cmd/internal/utils.go +++ b/Mythic_CLI/src/cmd/internal/utils.go @@ -276,7 +276,7 @@ func updateNginxBlockLists() { os.Exit(1) } } else { - err := moveStringToVolume("mythic_nginx_volume_config", "blockips.conf", outputString) + err := moveStringToVolume("mythic_nginx_volume_config", ".", "blockips.conf", outputString) if err != nil { fmt.Printf("[-] Failed to write out block list file: %v\n", err) os.Exit(1) @@ -335,27 +335,59 @@ func tarFileToBytes(sourceName string) (*bytes.Buffer, error) { } var buf bytes.Buffer tw := tar.NewWriter(&buf) - err = tw.WriteHeader(&tar.Header{ - Name: sourceName, // filename - Mode: 0777, // permissions - Size: sourceStats.Size(), // filesize - }) - if err != nil { - return nil, err - } - content, err := io.ReadAll(source) - if err != nil { - return nil, err - } - _, err = tw.Write(content) - if err != nil { - return nil, err - } - err = tw.Close() - if err != nil { - return nil, err + if sourceStats.IsDir() { + // walk through every file in the folder + err = filepath.Walk(sourceName, func(file string, fi os.FileInfo, err error) error { + // generate tar header + header, err := tar.FileInfoHeader(fi, file) + if err != nil { + return err + } + + // must provide real name + // (see https://golang.org/src/archive/tar/common.go?#L626) + header.Name = filepath.ToSlash(file) + // write header + if err = tw.WriteHeader(header); err != nil { + return err + } + // if not a dir, write file content + if !fi.IsDir() { + data, err := os.Open(file) + if err != nil { + return err + } + if _, err := io.Copy(tw, data); err != nil { + return err + } + } + return nil + }) + return &buf, err + } else { + err = tw.WriteHeader(&tar.Header{ + Name: sourceName, // filename + Mode: 0777, // permissions + Size: sourceStats.Size(), // filesize + }) + if err != nil { + return nil, err + } + content, err := io.ReadAll(source) + if err != nil { + return nil, err + } + _, err = tw.Write(content) + if err != nil { + return nil, err + } + err = tw.Close() + if err != nil { + return nil, err + } + return &buf, nil } - return &buf, nil + } func tarStringToBytes(sourceName string, data string) (*bytes.Buffer, error) { var buf bytes.Buffer @@ -386,8 +418,8 @@ func moveFileToVolume(volumeName string, destinationName string, sourceName stri DockerCopyIntoVolume(contentBytes, destinationName, volumeName) return nil } -func moveStringToVolume(volumeName string, destinationName string, content string) error { - contentBytes, err := tarStringToBytes(destinationName, content) +func moveStringToVolume(volumeName string, destinationName string, sourceName string, content string) error { + contentBytes, err := tarStringToBytes(sourceName, content) if err != nil { return err } diff --git a/Mythic_CLI/src/cmd/volumeRm.go b/Mythic_CLI/src/cmd/volumeRm.go index 9cb9d5796..753a223f8 100644 --- a/Mythic_CLI/src/cmd/volumeRm.go +++ b/Mythic_CLI/src/cmd/volumeRm.go @@ -1,8 +1,10 @@ package cmd import ( + "fmt" "github.com/MythicMeta/Mythic_CLI/cmd/internal" "github.com/spf13/cobra" + "os" ) // configCmd represents the config command @@ -18,5 +20,11 @@ func init() { } func volumesRmCommand(cmd *cobra.Command, args []string) { - internal.DockerRemoveVolume(args[0]) + err := internal.DockerRemoveVolume(args[0]) + if err != nil { + fmt.Printf("[-] error removing volume: \n%v\n", err) + os.Exit(1) + } else { + fmt.Printf("[+] Successfully removed volume\n") + } } diff --git a/documentation-docker/.docker/Dockerfile b/documentation-docker/.docker/Dockerfile index c332a122a..c58ba7e27 100644 --- a/documentation-docker/.docker/Dockerfile +++ b/documentation-docker/.docker/Dockerfile @@ -4,4 +4,6 @@ COPY [".", "/src/"] HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \ CMD wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT:-8090}/docs/ || exit 1 -RUN hugo new site mythic_docs \ No newline at end of file +RUN hugo new site mythic_docs + +CMD server -p ${DOCUMENTATION_PORT:-8090} \ No newline at end of file From 01b8fdc7093d0205e1d62dc6467ba2dce3a6678f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 01:50:54 +0000 Subject: [PATCH 059/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.29' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 7d6273c4c..0e4779136 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.29 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 07d3a6c6e..a2b78c8fe 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.29 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 4b4573c1d..5cd3bca7d 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.29 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 90b906217..0ef3e19dc 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.28 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.29 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index e49b73005..0d571c007 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.29 \ No newline at end of file diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 7768ec6f5..b1ee10d7a 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.29 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 7ff8801d8..e66ab5dd3 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.29 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 566fc09e6..059c2e13a 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.29 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 16533e91c..6034daa51 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.28 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.29 \ No newline at end of file From c1e072e2375a29418f89da4c9cf6e46c1a491b7f Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 1 Jan 2024 20:37:59 -0600 Subject: [PATCH 060/117] v0.0.2.30 --- documentation-docker/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation-docker/.docker/Dockerfile b/documentation-docker/.docker/Dockerfile index c58ba7e27..2c9eb022f 100644 --- a/documentation-docker/.docker/Dockerfile +++ b/documentation-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \ RUN hugo new site mythic_docs -CMD server -p ${DOCUMENTATION_PORT:-8090} \ No newline at end of file +ENTRYPOINT server -p ${DOCUMENTATION_PORT:-8090} \ No newline at end of file From 3ef1d892b7e5a8dbd9d1f13fe1566c90e175b0d2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 02:45:18 +0000 Subject: [PATCH 061/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.30' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 0e4779136..535e15b10 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.30 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index a2b78c8fe..9f796af9b 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.30 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 5cd3bca7d..8d309f00a 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.30 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 0ef3e19dc..cef2cd745 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.29 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.30 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 0d571c007..9224f9cc3 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.30 \ No newline at end of file diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index b1ee10d7a..cdb60f780 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.30 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index e66ab5dd3..6d126c4f3 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.30 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 059c2e13a..c47550bd4 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.30 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 6034daa51..53708e46c 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.29 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.30 \ No newline at end of file From 9ae70f5ec109fc0f3a313531f44f8c52b3a35d7b Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 1 Jan 2024 21:02:37 -0600 Subject: [PATCH 062/117] v0.0.2.31 --- documentation-docker/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation-docker/.docker/Dockerfile b/documentation-docker/.docker/Dockerfile index 2c9eb022f..5e17f79aa 100644 --- a/documentation-docker/.docker/Dockerfile +++ b/documentation-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ HEALTHCHECK --interval=30s --timeout=10s --retries=5 --start-period=10s \ RUN hugo new site mythic_docs -ENTRYPOINT server -p ${DOCUMENTATION_PORT:-8090} \ No newline at end of file +ENTRYPOINT hugo server -p ${DOCUMENTATION_PORT:-8090} \ No newline at end of file From 5d17b8c7675d2dfc5dcbac5a4286e765dc961d4e Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 03:10:04 +0000 Subject: [PATCH 063/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.31' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 535e15b10..ed367da91 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.31 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 9f796af9b..766f7496a 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.31 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 8d309f00a..7e908f238 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.31 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index cef2cd745..2ccea4ba1 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.30 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.31 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 9224f9cc3..2d729a99f 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.31 \ No newline at end of file diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index cdb60f780..1a85fae01 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.31 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 6d126c4f3..3b4968b48 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.31 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index c47550bd4..b893ec711 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.31 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 53708e46c..b3757d118 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.30 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.31 \ No newline at end of file From 5b37ef995d791617d86e1bf639648ea290951719 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 1 Jan 2024 21:43:14 -0600 Subject: [PATCH 064/117] v0.0.2.32 --- Mythic_CLI/src/cmd/internal/dockercompose.go | 2 +- Mythic_CLI/src/cmd/internal/installservice.go | 92 ++++++++++++------- Mythic_CLI/src/cmd/internal/utils.go | 13 ++- .../content/C2 Profiles/_index.md | 12 +++ 4 files changed, 79 insertions(+), 40 deletions(-) create mode 100644 documentation-docker/content/C2 Profiles/_index.md diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 975febe9a..045863d50 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -216,7 +216,7 @@ func addMythicServiceDockerComposeEntry(service string) { } } else { pStruct["volumes"] = []string{ - "mythic_documentation_volume:/usr/src/app", + "mythic_documentation_volume:/src", } } if _, ok := volumes["mythic_documentation"]; !ok { diff --git a/Mythic_CLI/src/cmd/internal/installservice.go b/Mythic_CLI/src/cmd/internal/installservice.go index 7bc42bd00..3e34773ae 100644 --- a/Mythic_CLI/src/cmd/internal/installservice.go +++ b/Mythic_CLI/src/cmd/internal/installservice.go @@ -174,7 +174,7 @@ func InstallFolder(installPath string, overWrite bool) error { } } else { err = moveFileToVolume("mythic_documentation_volume", - filepath.Join("content", "Agents", f.Name()), + filepath.Join("content", "Agents"), filepath.Join(installPath, "documentation-payload", f.Name())) if err != nil { fmt.Printf("[-] Failed to install documentation for payload: %v\n", err) @@ -199,28 +199,40 @@ func InstallFolder(installPath string, overWrite bool) error { for _, f := range files { if f.IsDir() { fmt.Printf("[*] Processing Documentation for %s\n", f.Name()) - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - fmt.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) - if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next c2 documentation\n") - continue + if mythicEnv.GetBool("document_bind_local_mount") { + if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { + if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + fmt.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to remove current version: %v\n", err) + fmt.Printf("[-] Continuing to the next c2 documentation\n") + continue + } else { + fmt.Printf("[+] Successfully removed the current version\n") + } } else { - fmt.Printf("[+] Successfully removed the current version\n") + fmt.Printf("[!] Skipping documentation for %s\n", f.Name()) + continue } - } else { - fmt.Printf("[!] Skipping documentation for %s\n", f.Name()) + } + fmt.Printf("[*] Copying new documentation version into place\n") + err = copyDir(filepath.Join(installPath, "documentation-c2", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to copy directory over\n") continue } + } else { + err = moveFileToVolume("mythic_documentation_volume", + filepath.Join("content", "C2 Profiles"), + filepath.Join(installPath, "documentation-c2", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to install documentation for c2: %v\n", err) + continue + } + } - fmt.Printf("[*] Copying new documentation version into place\n") - err = copyDir(filepath.Join(installPath, "documentation-c2", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) - if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") - continue - } + } } fmt.Printf("[+] Successfully installed c2 documentation\n") @@ -238,27 +250,37 @@ func InstallFolder(installPath string, overWrite bool) error { for _, f := range files { if f.IsDir() { fmt.Printf("[*] Processing Documentation for %s\n", f.Name()) - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - fmt.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) - if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next wrapper documentation\n") - continue + if mythicEnv.GetBool("document_local_bind_mount") { + if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) { + if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + fmt.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to remove current version: %v\n", err) + fmt.Printf("[-] Continuing to the next wrapper documentation\n") + continue + } else { + fmt.Printf("[+] Successfully removed the current version\n") + } } else { - fmt.Printf("[+] Successfully removed the current version\n") + fmt.Printf("[!] Skipping documentation for , %s\n", f.Name()) + continue } - } else { - fmt.Printf("[!] Skipping documentation for , %s\n", f.Name()) + } + fmt.Printf("[*] Copying new documentation into place\n") + err = copyDir(filepath.Join(installPath, "documentation-wrapper", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to copy directory over\n") + continue + } + } else { + err = moveFileToVolume("mythic_documentation_volume", + filepath.Join("content", "Wrappers"), + filepath.Join(installPath, "documentation-wrapper", f.Name())) + if err != nil { + fmt.Printf("[-] Failed to install documentation for wrapper: %v\n", err) continue } - } - fmt.Printf("[*] Copying new documentation into place\n") - err = copyDir(filepath.Join(installPath, "documentation-wrapper", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) - if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") - continue } } } diff --git a/Mythic_CLI/src/cmd/internal/utils.go b/Mythic_CLI/src/cmd/internal/utils.go index 1c92fceef..a1ad25032 100644 --- a/Mythic_CLI/src/cmd/internal/utils.go +++ b/Mythic_CLI/src/cmd/internal/utils.go @@ -337,16 +337,21 @@ func tarFileToBytes(sourceName string) (*bytes.Buffer, error) { tw := tar.NewWriter(&buf) if sourceStats.IsDir() { // walk through every file in the folder + absSourcePath, err := filepath.Abs(sourceName) + if err != nil { + fmt.Printf("[-] Failed to get absolute path of folder to copy over. Resulting directory structure might be weird\n") + return nil, err + } + // absSourcePath is the parent directory to copy over now + // ex: say to move over apfell/ so we'll get a folder called apfell on the target volume + absSourcePath = filepath.Dir(absSourcePath) err = filepath.Walk(sourceName, func(file string, fi os.FileInfo, err error) error { // generate tar header header, err := tar.FileInfoHeader(fi, file) if err != nil { return err } - - // must provide real name - // (see https://golang.org/src/archive/tar/common.go?#L626) - header.Name = filepath.ToSlash(file) + header.Name = strings.ReplaceAll(file, absSourcePath, "") // write header if err = tw.WriteHeader(header); err != nil { return err diff --git a/documentation-docker/content/C2 Profiles/_index.md b/documentation-docker/content/C2 Profiles/_index.md new file mode 100644 index 000000000..cd17fc74d --- /dev/null +++ b/documentation-docker/content/C2 Profiles/_index.md @@ -0,0 +1,12 @@ ++++ +title = "C2 Profiles" +chapter = false +weight = 5 ++++ + +## C2 Documentation + +This section aims to be an in-depth way to reference documentation about specific c2 profiles. Each agent has the following breakdown: + + +{{% children %}} \ No newline at end of file From be01e731e25d9211669f5a3474d0828c954324dc Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 03:50:36 +0000 Subject: [PATCH 065/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.32' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index ed367da91..c13729947 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.32 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 766f7496a..2da2f5736 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.32 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 7e908f238..ec533cd42 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.32 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 2ccea4ba1..d2144078f 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.31 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.32 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 2d729a99f..a0fb190c4 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 \ No newline at end of file diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 1a85fae01..46cfea4e5 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.32 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 3b4968b48..a3e3427f0 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.32 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index b893ec711..9a2d1726a 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.32 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index b3757d118..5dc18f84c 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.31 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.32 \ No newline at end of file From 3428de2a117a9bc16b11b23f8f972c2f0cd3a6da Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Wed, 3 Jan 2024 08:21:27 -0600 Subject: [PATCH 066/117] v0.0.2.33 --- mythic-docker/Dockerfile | 27 ++- .../recv_mythic_rpc_callback_search.go | 176 +++++++++--------- 2 files changed, 114 insertions(+), 89 deletions(-) diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index a0fb190c4..57b2b667b 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1 +1,26 @@ -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 \ No newline at end of file +#FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 + +FROM itsafeaturemythic/mythic_go_base:latest + +WORKDIR /usr/src/app + +ARG GOPROXY=proxy.golang.org +ARG GO111MODULE + +RUN go env -w GOPROXY=${GOPROXY} +RUN go env -w GO111MODULE=${GO111MODULE} + +COPY ["src/", "."] + +RUN make build_final + +FROM alpine + +COPY --from=0 /mythic_server /mythic_server + +WORKDIR /usr/src/app + +HEALTHCHECK --interval=60s --timeout=10s --retries=5 --start-period=20s \ + CMD wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT:-17443}/health || exit 1 + +CMD ["/bin/sh", "-c", "cp /mythic_server . && ./mythic_server" ] \ No newline at end of file diff --git a/mythic-docker/src/rabbitmq/recv_mythic_rpc_callback_search.go b/mythic-docker/src/rabbitmq/recv_mythic_rpc_callback_search.go index e00a14899..56bd5a1ad 100644 --- a/mythic-docker/src/rabbitmq/recv_mythic_rpc_callback_search.go +++ b/mythic-docker/src/rabbitmq/recv_mythic_rpc_callback_search.go @@ -83,112 +83,112 @@ func MythicRPCCallbackSearch(input MythicRPCCallbackSearchMessage) MythicRPCCall } searchResults := databaseStructs.Callback{} callback := databaseStructs.Callback{} - if err := database.DB.Get(&callback, `SELECT + err := database.DB.Get(&callback, `SELECT operation_id FROM callback - WHERE agent_callback_id=$1 OR id=$2`, input.AgentCallbackUUID, input.AgentCallbackID); err != nil { + WHERE agent_callback_id=$1 OR id=$2`, input.AgentCallbackUUID, input.AgentCallbackID) + if err != nil { logging.LogError(err, "Failed to find callback UUID") response.Error = err.Error() return response - } else { - targetCallback := databaseStructs.Callback{ - OperationID: callback.OperationID, - } - if input.SearchCallbackID != nil { - targetCallback.ID = *input.SearchCallbackID - } - if input.SearchCallbackUUID != nil { - targetCallback.AgentCallbackID = *input.SearchCallbackUUID - } - if input.SearchCallbackDisplayID != nil { - targetCallback.DisplayID = *input.SearchCallbackDisplayID - } - searchString := `SELECT + } + targetCallback := databaseStructs.Callback{ + OperationID: callback.OperationID, + } + if input.SearchCallbackID != nil { + targetCallback.ID = *input.SearchCallbackID + } + if input.SearchCallbackUUID != nil { + targetCallback.AgentCallbackID = *input.SearchCallbackUUID + } + if input.SearchCallbackDisplayID != nil { + targetCallback.DisplayID = *input.SearchCallbackDisplayID + } + searchString := `SELECT callback.*, payload.uuid "payload.uuid" FROM callback JOIN payload on callback.registered_payload_id = payload.id WHERE callback.operation_id=:operation_id ` - // if we're not actually searching for another callback, just set ours - if input.SearchCallbackDisplayID != nil || input.SearchCallbackID != nil || input.SearchCallbackUUID != nil { - searchString += ` AND (callback.id=:id OR + // if we're not actually searching for another callback, just set ours + if input.SearchCallbackDisplayID != nil || input.SearchCallbackID != nil || input.SearchCallbackUUID != nil { + searchString += ` AND (callback.id=:id OR callback.agent_callback_id=:agent_callback_id OR callback.display_id=:display_id)` + } + if input.SearchCallbackUser != nil { + targetCallback.User = *input.SearchCallbackUser + searchString += `AND user=:user ` + } + if input.SearchCallbackHost != nil { + targetCallback.Host = strings.ToUpper(*input.SearchCallbackHost) + if targetCallback.Host == "" { + targetCallback.Host = "UNKNOWN" } - if input.SearchCallbackUser != nil { - targetCallback.User = *input.SearchCallbackUser - searchString += `AND user=:user ` - } - if input.SearchCallbackHost != nil { - targetCallback.Host = strings.ToUpper(*input.SearchCallbackHost) - if targetCallback.Host == "" { - targetCallback.Host = "UNKNOWN" - } - searchString += `AND host=:host ` - } - if input.SearchCallbackPID != nil { - targetCallback.PID = *input.SearchCallbackPID - searchString += `AND pid=:pid ` - } - if input.SearchCallbackIP != nil { - targetCallback.IP = *input.SearchCallbackIP - searchString += `AND ip ILIKE :ip ` - } - if input.SearchCallbackExtraInfo != nil { - targetCallback.ExtraInfo = *input.SearchCallbackExtraInfo - searchString += `AND extra_info ILIKE :extra_info ` - } - if input.SearchCallbackSleepInfo != nil { - targetCallback.SleepInfo = *input.SearchCallbackSleepInfo - searchString += `AND sleep_info ILIKE :sleep_info ` - } - if input.SearchCallbackExternalIP != nil { - targetCallback.ExternalIp = *input.SearchCallbackExternalIP - searchString += `AND external_ip ILIKE :external_ip ` - } - if input.SearchCallbackIntegrityLevel != nil { - targetCallback.IntegrityLevel = *input.SearchCallbackIntegrityLevel - searchString += `AND integrity_level=:integrity_level ` - } - if input.SearchCallbackOs != nil { - targetCallback.Os = *input.SearchCallbackOs - searchString += `AND callback.os ILIKE :os ` - } - if input.SearchCallbackDomain != nil { - targetCallback.Domain = *input.SearchCallbackDomain - searchString += `AND domain ILIKE :domain ` - } - if input.SearchCallbackArchitecture != nil { - targetCallback.Architecture = *input.SearchCallbackArchitecture - searchString += `AND architecture ILIKE :architecture` - } - if input.SearchCallbackDescription != nil { - targetCallback.Description = *input.SearchCallbackDescription - searchString += `AND callback.description ILIKE :description` - } - if rows, err := database.DB.NamedQuery(searchString, targetCallback); err != nil { - logging.LogError(err, "Failed to search callback information") + searchString += `AND host=:host ` + } + if input.SearchCallbackPID != nil { + targetCallback.PID = *input.SearchCallbackPID + searchString += `AND pid=:pid ` + } + if input.SearchCallbackIP != nil { + targetCallback.IP = *input.SearchCallbackIP + searchString += `AND ip ILIKE :ip ` + } + if input.SearchCallbackExtraInfo != nil { + targetCallback.ExtraInfo = *input.SearchCallbackExtraInfo + searchString += `AND extra_info ILIKE :extra_info ` + } + if input.SearchCallbackSleepInfo != nil { + targetCallback.SleepInfo = *input.SearchCallbackSleepInfo + searchString += `AND sleep_info ILIKE :sleep_info ` + } + if input.SearchCallbackExternalIP != nil { + targetCallback.ExternalIp = *input.SearchCallbackExternalIP + searchString += `AND external_ip ILIKE :external_ip ` + } + if input.SearchCallbackIntegrityLevel != nil { + targetCallback.IntegrityLevel = *input.SearchCallbackIntegrityLevel + searchString += `AND integrity_level=:integrity_level ` + } + if input.SearchCallbackOs != nil { + targetCallback.Os = *input.SearchCallbackOs + searchString += `AND callback.os ILIKE :os ` + } + if input.SearchCallbackDomain != nil { + targetCallback.Domain = *input.SearchCallbackDomain + searchString += `AND domain ILIKE :domain ` + } + if input.SearchCallbackArchitecture != nil { + targetCallback.Architecture = *input.SearchCallbackArchitecture + searchString += `AND architecture ILIKE :architecture` + } + if input.SearchCallbackDescription != nil { + targetCallback.Description = *input.SearchCallbackDescription + searchString += `AND callback.description ILIKE :description` + } + rows, err := database.DB.NamedQuery(searchString, targetCallback) + if err != nil { + logging.LogError(err, "Failed to search callback information") + response.Error = err.Error() + return response + } + for rows.Next() { + result := MythicRPCCallbackSearchMessageResult{} + if err = rows.StructScan(&searchResults); err != nil { + logging.LogError(err, "Failed to get row from callbacks for search") + } else if err = mapstructure.Decode(searchResults, &result); err != nil { + logging.LogError(err, "Failed to map callback search results into array") response.Error = err.Error() return response } else { - for rows.Next() { - result := MythicRPCCallbackSearchMessageResult{} - if err = rows.StructScan(&searchResults); err != nil { - logging.LogError(err, "Failed to get row from callbacks for search") - } else if err = mapstructure.Decode(searchResults, &result); err != nil { - logging.LogError(err, "Failed to map callback search results into array") - response.Error = err.Error() - return response - } else { - result.RegisteredPayloadUUID = searchResults.Payload.UuID - result.LockedOperatorID = int(searchResults.LockedOperatorID.Int64) - response.Results = append(response.Results, result) - } - } - response.Success = true - return response + result.RegisteredPayloadUUID = searchResults.Payload.UuID + result.LockedOperatorID = int(searchResults.LockedOperatorID.Int64) + response.Results = append(response.Results, result) } } + response.Success = true + return response } func processMythicRPCCallbackSearch(msg amqp.Delivery) interface{} { incomingMessage := MythicRPCCallbackSearchMessage{} From 013009e3e2687aed6827c7009340b1a06587dcad Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:28:58 +0000 Subject: [PATCH 067/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.33' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 4 ++-- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index c13729947..6e05007af 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.33 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 2da2f5736..cbeacdc38 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.33 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index ec533cd42..c3af00e0a 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.33 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index d2144078f..24f5c4064 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.32 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.33 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 57b2b667b..e6e2fba53 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1,6 +1,6 @@ #FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 -FROM itsafeaturemythic/mythic_go_base:latest +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.33 WORKDIR /usr/src/app @@ -14,7 +14,7 @@ COPY ["src/", "."] RUN make build_final -FROM alpine +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.33 COPY --from=0 /mythic_server /mythic_server diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 46cfea4e5..6b479fad0 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.33 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index a3e3427f0..d136512ff 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.33 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 9a2d1726a..fdbf96f7f 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.33 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 5dc18f84c..07a8f80ac 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.32 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.33 \ No newline at end of file From d09b4701c1cc69463ef4668be3a3f13fe668579f Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 5 Jan 2024 16:48:07 -0600 Subject: [PATCH 068/117] refactor and updated docker-compose to remove "networks" --- Mythic_CLI/src/cmd/internal/dockercompose.go | 216 ++++--------------- 1 file changed, 41 insertions(+), 175 deletions(-) diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go index 045863d50..ce11e244b 100644 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ b/Mythic_CLI/src/cmd/internal/dockercompose.go @@ -15,6 +15,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/spf13/viper" + "gopkg.in/yaml.v3" ) func isServiceRunning(service string) bool { @@ -38,40 +39,8 @@ func isServiceRunning(service string) bool { return false } func addMythicServiceDockerComposeEntry(service string) { - var curConfig = viper.New() - curConfig.SetConfigName("docker-compose") - curConfig.SetConfigType("yaml") - curConfig.AddConfigPath(getCwdFromExe()) - if err := curConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) - } else { - log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) - } - } - /* - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", - }, - }, - } - if !curConfig.InConfig("networks") { - // don't blow away changes to the network configuration - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + curConfig := readInDockerCompose() - */ volumes := map[string]interface{}{} if curConfig.InConfig("volumes") { volumes = curConfig.GetStringMap("volumes") @@ -711,60 +680,14 @@ func addMythicServiceDockerComposeEntry(service string) { } else { curConfig.Set("services."+strings.ToLower(service), pStruct) } - /* - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } - - */ curConfig.Set("volumes", volumes) - curConfig.Set("version", "2.4") - err := curConfig.WriteConfig() + err := setDockerComposeDefaultsAndWrite(curConfig) if err != nil { fmt.Printf("[-] Failed to update config: %v\n", err) - } else { - fmt.Println("[+] Successfully updated docker-compose.yml") } } func removeMythicServiceDockerComposeEntry(service string) { - var curConfig = viper.New() - curConfig.SetConfigName("docker-compose") - curConfig.SetConfigType("yaml") - curConfig.AddConfigPath(getCwdFromExe()) - if err := curConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) - } else { - log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) - } - } - /* - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", - }, - }, - } - if !curConfig.InConfig("networks") { - // don't blow away changes to the network configuration - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } - - */ + curConfig := readInDockerCompose() if isServiceRunning(service) { DockerStop([]string{strings.ToLower(service)}) @@ -778,19 +701,8 @@ func removeMythicServiceDockerComposeEntry(service string) { } } - /* - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } - */ - curConfig.Set("version", "2.4") - fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) - err := curConfig.WriteConfig() + err := setDockerComposeDefaultsAndWrite(curConfig) if err != nil { fmt.Printf("[-] Failed to update config: %v\n", err) } else { @@ -800,39 +712,8 @@ func removeMythicServiceDockerComposeEntry(service string) { func AddDockerComposeEntry(service string, additionalConfigs map[string]interface{}) error { // add c2/payload [name] as type [group] to the main yaml file - var curConfig = viper.New() - curConfig.SetConfigName("docker-compose") - curConfig.SetConfigType("yaml") - curConfig.AddConfigPath(getCwdFromExe()) - if err := curConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) - } else { - log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) - } - } - /* - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", - }, - }, - } - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } + curConfig := readInDockerCompose() - */ absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)) if err != nil { fmt.Printf("[-] Failed to get the absolute path to the %s folder, does the folder exist?\n", InstalledServicesFolder) @@ -905,18 +786,8 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac } } curConfig.Set("services."+strings.ToLower(service), pStruct) - /* - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } - */ - curConfig.Set("version", "2.4") - err = curConfig.WriteConfig() + err = setDockerComposeDefaultsAndWrite(curConfig) if err != nil { fmt.Printf("[-] Failed to update config: %v\n", err) } else { @@ -927,32 +798,7 @@ func AddDockerComposeEntry(service string, additionalConfigs map[string]interfac } func RemoveDockerComposeEntry(service string) error { // add c2/payload [name] as type [group] to the main yaml file - var curConfig = viper.New() - curConfig.SetConfigName("docker-compose") - curConfig.SetConfigType("yaml") - curConfig.AddConfigPath(getCwdFromExe()) - if err := curConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) - } else { - log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) - } - } - /* - networkInfo := map[string]interface{}{ - "default_network": map[string]interface{}{ - "driver": "bridge", - "driver_opts": map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }, - "labels": []string{ - "mythic_network", - "default_network", - }, - }, - } - - */ + curConfig := readInDockerCompose() if !stringInSlice(service, MythicPossibleServices) { if isServiceRunning(service) { @@ -962,19 +808,7 @@ func RemoveDockerComposeEntry(service string) error { fmt.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) } - /* - if !curConfig.InConfig("networks") { - curConfig.Set("networks", networkInfo) - } else { - curConfig.Set("networks.default_network.driver_opts", map[string]string{ - "com.docker.network.bridge.name": "mythic_if", - }) - } - - */ - curConfig.Set("version", "2.4") - fmt.Printf("set volume: %v\n", curConfig.GetStringMap("volumes")) - err := curConfig.WriteConfig() + err := setDockerComposeDefaultsAndWrite(curConfig) if err != nil { fmt.Printf("[-] Failed to update config: %v\n", err) } else { @@ -1228,3 +1062,35 @@ func CheckDockerCompose() { log.Fatalf("[-] Bad docker version\n") } } +func setDockerComposeDefaultsAndWrite(curConfig *viper.Viper) error { + curConfig.Set("version", "2.4") + file := curConfig.ConfigFileUsed() + if len(file) == 0 { + file = "./docker-compose.yml" + } + configMap := curConfig.AllSettings() + ignoredKeys := []string{"networks"} + for _, key := range ignoredKeys { + delete(configMap, key) + } + + content, err := yaml.Marshal(configMap) + if err != nil { + return err + } + return os.WriteFile(file, content, 0644) +} +func readInDockerCompose() *viper.Viper { + var curConfig = viper.New() + curConfig.SetConfigName("docker-compose") + curConfig.SetConfigType("yaml") + curConfig.AddConfigPath(getCwdFromExe()) + if err := curConfig.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) + } else { + log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) + } + } + return curConfig +} From 2510ffd9c55838ada4d6445faea679f86a305a87 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 13 Jan 2024 17:31:45 -0600 Subject: [PATCH 069/117] mythic-cli refactor --- Mythic_CLI/src/cmd/addDockerCompose.go | 2 +- Mythic_CLI/src/cmd/build.go | 2 +- Mythic_CLI/src/cmd/config.go | 4 +- .../src/cmd/{internal => config}/env.go | 173 ++- Mythic_CLI/src/cmd/configGet.go | 4 +- Mythic_CLI/src/cmd/configService.go | 8 +- Mythic_CLI/src/cmd/configSet.go | 8 +- Mythic_CLI/src/cmd/internal/docker.go | 614 --------- Mythic_CLI/src/cmd/internal/dockercompose.go | 1096 ----------------- Mythic_CLI/src/cmd/internal/git.go | 4 +- Mythic_CLI/src/cmd/internal/installservice.go | 494 ++++---- Mythic_CLI/src/cmd/internal/reset.go | 8 +- .../src/cmd/internal/serviceExecution.go | 357 ++++++ .../src/cmd/internal/serviceMetadata.go | 564 +++++++++ Mythic_CLI/src/cmd/internal/testServices.go | 173 +-- Mythic_CLI/src/cmd/internal/utils.go | 222 +--- .../src/cmd/manager/dockerComposeManager.go | 783 ++++++++++++ .../src/cmd/manager/managerInterface.go | 71 ++ Mythic_CLI/src/cmd/removeContainer.go | 2 +- Mythic_CLI/src/cmd/removeDockerCompose.go | 2 +- Mythic_CLI/src/cmd/rootCmd.go | 1 + Mythic_CLI/src/cmd/start.go | 2 +- Mythic_CLI/src/cmd/stop.go | 2 +- Mythic_CLI/src/cmd/utils/utils.go | 171 +++ mythic-docker/Dockerfile | 4 +- 25 files changed, 2414 insertions(+), 2357 deletions(-) rename Mythic_CLI/src/cmd/{internal => config}/env.go (55%) delete mode 100644 Mythic_CLI/src/cmd/internal/docker.go delete mode 100644 Mythic_CLI/src/cmd/internal/dockercompose.go create mode 100644 Mythic_CLI/src/cmd/internal/serviceExecution.go create mode 100644 Mythic_CLI/src/cmd/internal/serviceMetadata.go create mode 100644 Mythic_CLI/src/cmd/manager/dockerComposeManager.go create mode 100644 Mythic_CLI/src/cmd/manager/managerInterface.go create mode 100644 Mythic_CLI/src/cmd/utils/utils.go diff --git a/Mythic_CLI/src/cmd/addDockerCompose.go b/Mythic_CLI/src/cmd/addDockerCompose.go index 8b18e6c7e..990500c1a 100644 --- a/Mythic_CLI/src/cmd/addDockerCompose.go +++ b/Mythic_CLI/src/cmd/addDockerCompose.go @@ -19,7 +19,7 @@ func init() { } func addDockerCompose(cmd *cobra.Command, args []string) { - if err := internal.AddDockerComposeEntry(args[0], make(map[string]interface{})); err != nil { + if err := internal.Add3rdPartyService(args[0], make(map[string]interface{})); err != nil { } } diff --git a/Mythic_CLI/src/cmd/build.go b/Mythic_CLI/src/cmd/build.go index e2a2a3dc6..e9a3d7098 100644 --- a/Mythic_CLI/src/cmd/build.go +++ b/Mythic_CLI/src/cmd/build.go @@ -18,7 +18,7 @@ func init() { } func buildContainer(cmd *cobra.Command, args []string) { - if err := internal.DockerBuild(args); err != nil { + if err := internal.ServiceBuild(args); err != nil { } } diff --git a/Mythic_CLI/src/cmd/config.go b/Mythic_CLI/src/cmd/config.go index d30fee2f6..d9eaa5011 100644 --- a/Mythic_CLI/src/cmd/config.go +++ b/Mythic_CLI/src/cmd/config.go @@ -2,7 +2,7 @@ package cmd import ( "fmt" - "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/spf13/cobra" "os" "sort" @@ -35,7 +35,7 @@ func configDisplay(cmd *cobra.Command, args []string) { fmt.Fprintf(writer, "\n %s\t%s", "Setting", "Value") fmt.Fprintf(writer, "\n %s\t%s", "–––––––", "–––––––") - configuration := internal.GetConfigAllStrings() + configuration := config.GetConfigAllStrings() keys := make([]string, 0, len(configuration)) for k := range configuration { keys = append(keys, k) diff --git a/Mythic_CLI/src/cmd/internal/env.go b/Mythic_CLI/src/cmd/config/env.go similarity index 55% rename from Mythic_CLI/src/cmd/internal/env.go rename to Mythic_CLI/src/cmd/config/env.go index 8b898eb54..2b47a8069 100644 --- a/Mythic_CLI/src/cmd/internal/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -1,18 +1,101 @@ -package internal +package config import ( + "bufio" "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "github.com/spf13/viper" "log" "os" "path/filepath" "sort" "strings" - - "github.com/spf13/viper" ) +var MythicPossibleServices = []string{ + "mythic_postgres", + "mythic_react", + "mythic_server", + "mythic_nginx", + "mythic_rabbitmq", + "mythic_graphql", + "mythic_documentation", + "mythic_jupyter", + "mythic_sync", + "mythic_grafana", + "mythic_prometheus", + "mythic_postgres_exporter", +} var mythicEnv = viper.New() +// GetIntendedMythicServiceNames uses MythicEnv host values for various services to see if they should be local or remote +func GetIntendedMythicServiceNames() ([]string, error) { + // need to see about adding services back in if they were for remote hosts before + containerList := []string{} + for _, service := range MythicPossibleServices { + // service is a mythic service, but it's not in our current container list (i.e. not in docker-compose) + switch service { + case "mythic_react": + if mythicEnv.GetString("MYTHIC_REACT_HOST") == "127.0.0.1" || mythicEnv.GetString("MYTHIC_REACT_HOST") == "mythic_react" { + containerList = append(containerList, service) + } + case "mythic_nginx": + if mythicEnv.GetString("NGINX_HOST") == "127.0.0.1" || mythicEnv.GetString("NGINX_HOST") == "mythic_nginx" { + containerList = append(containerList, service) + } + case "mythic_rabbitmq": + if mythicEnv.GetString("RABBITMQ_HOST") == "127.0.0.1" || mythicEnv.GetString("RABBITMQ_HOST") == "mythic_rabbitmq" { + containerList = append(containerList, service) + } + case "mythic_server": + if mythicEnv.GetString("MYTHIC_SERVER_HOST") == "127.0.0.1" || mythicEnv.GetString("MYTHIC_SERVER_HOST") == "mythic_server" { + containerList = append(containerList, service) + } + case "mythic_postgres": + if mythicEnv.GetString("POSTGRES_HOST") == "127.0.0.1" || mythicEnv.GetString("POSTGRES_HOST") == "mythic_postgres" { + containerList = append(containerList, service) + } + case "mythic_graphql": + if mythicEnv.GetString("HASURA_HOST") == "127.0.0.1" || mythicEnv.GetString("HASURA_HOST") == "mythic_graphql" { + containerList = append(containerList, service) + } + case "mythic_documentation": + if mythicEnv.GetString("DOCUMENTATION_HOST") == "127.0.0.1" || mythicEnv.GetString("DOCUMENTATION_HOST") == "mythic_documentation" { + containerList = append(containerList, service) + } + case "mythic_jupyter": + if mythicEnv.GetString("JUPYTER_HOST") == "127.0.0.1" || mythicEnv.GetString("JUPYTER_HOST") == "mythic_jupyter" { + containerList = append(containerList, service) + } + case "mythic_grafana": + if mythicEnv.GetBool("postgres_debug") { + containerList = append(containerList, service) + } + case "mythic_prometheus": + if mythicEnv.GetBool("postgres_debug") { + containerList = append(containerList, service) + } + case "mythic_postgres_exporter": + if mythicEnv.GetBool("postgres_debug") { + containerList = append(containerList, service) + } + /* + case "mythic_sync": + if mythicSyncPath, err := filepath.Abs(filepath.Join(utils.GetCwdFromExe(), InstalledServicesFolder, "mythic_sync")); err != nil { + fmt.Printf("[-] Failed to get the absolute path to mythic_sync: %v\n", err) + } else if _, err = os.Stat(mythicSyncPath); !os.IsNotExist(err) { + // this means that the mythic_sync folder _does_ exist + containerList = append(containerList, service) + } + + */ + } + } + return containerList, nil +} +func GetMythicEnv() *viper.Viper { + return mythicEnv +} func setMythicConfigDefaultValues() { // global configuration mythicEnv.SetDefault("debug_level", "warning") @@ -54,7 +137,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("postgres_bind_localhost_only", true) mythicEnv.SetDefault("postgres_db", "mythic_db") mythicEnv.SetDefault("postgres_user", "mythic_user") - mythicEnv.SetDefault("postgres_password", generateRandomPassword(30)) + mythicEnv.SetDefault("postgres_password", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("postgres_cpus", "2") mythicEnv.SetDefault("postgres_mem_limit", "") mythicEnv.SetDefault("postgres_bind_local_mount", true) @@ -63,18 +146,18 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("rabbitmq_port", 5672) mythicEnv.SetDefault("rabbitmq_bind_localhost_only", true) mythicEnv.SetDefault("rabbitmq_user", "mythic_user") - mythicEnv.SetDefault("rabbitmq_password", generateRandomPassword(30)) + mythicEnv.SetDefault("rabbitmq_password", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("rabbitmq_vhost", "mythic_vhost") mythicEnv.SetDefault("rabbitmq_cpus", "2") mythicEnv.SetDefault("rabbitmq_mem_limit", "") mythicEnv.SetDefault("rabbitmq_bind_local_mount", true) // jwt configuration - mythicEnv.SetDefault("jwt_secret", generateRandomPassword(30)) + mythicEnv.SetDefault("jwt_secret", utils.GenerateRandomPassword(30)) // hasura configuration mythicEnv.SetDefault("hasura_host", "mythic_graphql") mythicEnv.SetDefault("hasura_port", 8080) mythicEnv.SetDefault("hasura_bind_localhost_only", true) - mythicEnv.SetDefault("hasura_secret", generateRandomPassword(30)) + mythicEnv.SetDefault("hasura_secret", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("hasura_cpus", "2") mythicEnv.SetDefault("hasura_mem_limit", "2gb") mythicEnv.SetDefault("hasura_bind_local_mount", true) @@ -83,7 +166,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("REBUILD_ON_START", true) // Mythic instance configuration mythicEnv.SetDefault("mythic_admin_user", "mythic_admin") - mythicEnv.SetDefault("mythic_admin_password", generateRandomPassword(30)) + mythicEnv.SetDefault("mythic_admin_password", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("default_operation_name", "Operation Chimera") mythicEnv.SetDefault("allowed_ip_blocks", "0.0.0.0/0,::/0") mythicEnv.SetDefault("default_operation_webhook_url", "") @@ -114,10 +197,10 @@ func parseMythicEnvironmentVariables() { setMythicConfigDefaultValues() mythicEnv.SetConfigName(".env") mythicEnv.SetConfigType("env") - mythicEnv.AddConfigPath(getCwdFromExe()) + mythicEnv.AddConfigPath(utils.GetCwdFromExe()) mythicEnv.AutomaticEnv() - if !fileExists(filepath.Join(getCwdFromExe(), ".env")) { - _, err := os.Create(filepath.Join(getCwdFromExe(), ".env")) + if !utils.FileExists(filepath.Join(utils.GetCwdFromExe(), ".env")) { + _, err := os.Create(filepath.Join(utils.GetCwdFromExe(), ".env")) if err != nil { log.Fatalf("[-] .env doesn't exist and couldn't be created\n") } @@ -178,7 +261,7 @@ func writeMythicEnvironmentVariables() { keys = append(keys, k) } sort.Strings(keys) - f, err := os.Create(filepath.Join(getCwdFromExe(), ".env")) + f, err := os.Create(filepath.Join(utils.GetCwdFromExe(), ".env")) if err != nil { log.Fatalf("[-] Error writing out environment!\n%v", err) } @@ -233,8 +316,72 @@ func SetConfigStrings(key string, value string) { mythicEnv.Get(key) writeMythicEnvironmentVariables() } +func GetBuildArguments() []string { + var buildEnv = viper.New() + buildEnv.SetConfigName("build.env") + buildEnv.SetConfigType("env") + buildEnv.AddConfigPath(utils.GetCwdFromExe()) + buildEnv.AutomaticEnv() + if !utils.FileExists(filepath.Join(utils.GetCwdFromExe(), "build.env")) { + log.Printf("[*] No build.env file detected in Mythic's root directory; not supplying build arguments to docker containers\n") + log.Printf(" If you need to supply build arguments to docker containers, create build.env and supply key=value entries there\n") + return []string{} + } + if err := buildEnv.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + log.Fatalf("[-] Error while reading in build.env file: %s\n", err) + } else { + log.Fatalf("[-]Error while parsing build.env file: %s\n", err) + } + } + c := buildEnv.AllSettings() + // to make it easier to read and look at, get all the keys, sort them, and display variables in order + keys := make([]string, 0, len(c)) + for k := range c { + keys = append(keys, k) + } + sort.Strings(keys) + var args []string + for _, key := range keys { + args = append(args, fmt.Sprintf("%s=%s", strings.ToUpper(key), buildEnv.GetString(key))) + } + return args +} + +// https://gist.github.com/r0l1/3dcbb0c8f6cfe9c66ab8008f55f8f28b +func AskConfirm(prompt string) bool { + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("%s [y/n]: ", prompt) + input, err := reader.ReadString('\n') + if err != nil { + fmt.Printf("[-] Failed to read user input\n") + return false + } + input = strings.ToLower(strings.TrimSpace(input)) + if input == "y" || input == "yes" { + return true + } else if input == "n" || input == "no" { + return false + } + } +} + +// https://gist.github.com/r0l1/3dcbb0c8f6cfe9c66ab8008f55f8f28b +func AskVariable(prompt string, environmentVariable string) { + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("%s: ", prompt) + input, err := reader.ReadString('\n') + if err != nil { + fmt.Printf("[-] Failed to read user input\n") + } + input = strings.TrimSpace(input) + mythicEnv.Set(environmentVariable, input) + writeMythicEnvironmentVariables() + } +} func Initialize() { parseMythicEnvironmentVariables() writeMythicEnvironmentVariables() - CheckDockerCompose() } diff --git a/Mythic_CLI/src/cmd/configGet.go b/Mythic_CLI/src/cmd/configGet.go index c0e147135..a3da35369 100644 --- a/Mythic_CLI/src/cmd/configGet.go +++ b/Mythic_CLI/src/cmd/configGet.go @@ -2,7 +2,7 @@ package cmd import ( "fmt" - "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/spf13/cobra" "os" "strings" @@ -35,7 +35,7 @@ func configGet(cmd *cobra.Command, args []string) { fmt.Fprintf(writer, "\n %s\t%s", "Setting", "Value") fmt.Fprintf(writer, "\n %s\t%s", "–––––––", "–––––––") - configuration := internal.GetConfigStrings(args) + configuration := config.GetConfigStrings(args) for key, val := range configuration { fmt.Fprintf(writer, "\n %s\t%s", strings.ToUpper(key), val) } diff --git a/Mythic_CLI/src/cmd/configService.go b/Mythic_CLI/src/cmd/configService.go index 47ac473d7..d1404b1a8 100644 --- a/Mythic_CLI/src/cmd/configService.go +++ b/Mythic_CLI/src/cmd/configService.go @@ -2,7 +2,7 @@ package cmd import ( "fmt" - "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/spf13/cobra" "os" "sort" @@ -35,7 +35,7 @@ func configService(cmd *cobra.Command, args []string) { fmt.Fprintf(writer, "\n %s\t%s", "Setting", "Value") fmt.Fprintf(writer, "\n %s\t%s", "–––––––", "–––––––") - configuration := internal.GetConfigStrings([]string{ + configuration := config.GetConfigStrings([]string{ "MYTHIC_SERVER_HOST", "MYTHIC_SERVER_PORT", "MYTHIC_SERVER_GRPC_PORT", @@ -51,14 +51,14 @@ func configService(cmd *cobra.Command, args []string) { for _, key := range keys { fmt.Fprintf(writer, "\n %s\t%s", strings.ToUpper(key), configuration[key]) } - mythicServerStatus := internal.GetConfigStrings([]string{"MYTHIC_SERVER_BIND_LOCALHOST_ONLY"}) + mythicServerStatus := config.GetConfigStrings([]string{"MYTHIC_SERVER_BIND_LOCALHOST_ONLY"}) if val, ok := mythicServerStatus["MYTHIC_SERVER_BIND_LOCALHOST_ONLY"]; ok { if val == "true" { fmt.Fprintf(writer, "\t\t") fmt.Fprintf(writer, "MYTHIC_SERVER_BIND_LOCALHOST_ONLY is set to true - set this to false and restart Mythic") } } - rabbitmqStatus := internal.GetConfigStrings([]string{"RABBITMQ_BIND_LOCALHOST_ONLY"}) + rabbitmqStatus := config.GetConfigStrings([]string{"RABBITMQ_BIND_LOCALHOST_ONLY"}) if val, ok := rabbitmqStatus["RABBITMQ_BIND_LOCALHOST_ONLY"]; ok { if val == "true" { fmt.Fprintf(writer, "\t\t") diff --git a/Mythic_CLI/src/cmd/configSet.go b/Mythic_CLI/src/cmd/configSet.go index 53e70ba1a..fbb71efff 100644 --- a/Mythic_CLI/src/cmd/configSet.go +++ b/Mythic_CLI/src/cmd/configSet.go @@ -1,9 +1,9 @@ package cmd import ( - "fmt" - "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/spf13/cobra" + "log" ) // configSetCmd represents the configSet command @@ -22,6 +22,6 @@ func init() { } func configSet(cmd *cobra.Command, args []string) { - internal.SetConfigStrings(args[0], args[1]) - fmt.Println("[+] Configuration successfully updated. Bring containers down and up for changes to take effect.") + config.SetConfigStrings(args[0], args[1]) + log.Println("[+] Configuration successfully updated. Bring containers down and up for changes to take effect.") } diff --git a/Mythic_CLI/src/cmd/internal/docker.go b/Mythic_CLI/src/cmd/internal/docker.go deleted file mode 100644 index 343563468..000000000 --- a/Mythic_CLI/src/cmd/internal/docker.go +++ /dev/null @@ -1,614 +0,0 @@ -package internal - -import ( - "context" - "errors" - "fmt" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/volume" - "github.com/docker/docker/client" - "io" - "log" - "os" - "path/filepath" - "sort" - "strconv" - "strings" - "text/tabwriter" -) - -var MythicPossibleServices = []string{ - "mythic_postgres", - "mythic_react", - "mythic_server", - "mythic_nginx", - "mythic_rabbitmq", - "mythic_graphql", - "mythic_documentation", - "mythic_jupyter", - "mythic_sync", - "mythic_grafana", - "mythic_prometheus", - "mythic_postgres_exporter", -} -var buildArguments []string - -const InstalledServicesFolder = "InstalledServices" - -func updateEnvironmentVariables(originalList []string, updates []string) []string { - var finalList []string - for _, entry := range originalList { - entryPieces := strings.Split(entry, "=") - found := false - for _, update := range updates { - updatePieces := strings.Split(update, "=") - if updatePieces[0] == entryPieces[0] { - // the current env vars has a key that we want to update, so don't include the old version - found = true - } - } - if !found { - finalList = append(finalList, entry) - } - } - for _, update := range updates { - finalList = append(finalList, update) - } - return finalList -} -func GetIntendedMythicServiceNames() ([]string, error) { - // need to see about adding services back in if they were for remote hosts before - containerList := []string{} - for _, service := range MythicPossibleServices { - // service is a mythic service, but it's not in our current container list (i.e. not in docker-compose) - switch service { - case "mythic_react": - if mythicEnv.GetString("MYTHIC_REACT_HOST") == "127.0.0.1" || mythicEnv.GetString("MYTHIC_REACT_HOST") == "mythic_react" { - containerList = append(containerList, service) - } - case "mythic_nginx": - if mythicEnv.GetString("NGINX_HOST") == "127.0.0.1" || mythicEnv.GetString("NGINX_HOST") == "mythic_nginx" { - containerList = append(containerList, service) - } - case "mythic_rabbitmq": - if mythicEnv.GetString("RABBITMQ_HOST") == "127.0.0.1" || mythicEnv.GetString("RABBITMQ_HOST") == "mythic_rabbitmq" { - containerList = append(containerList, service) - } - case "mythic_server": - if mythicEnv.GetString("MYTHIC_SERVER_HOST") == "127.0.0.1" || mythicEnv.GetString("MYTHIC_SERVER_HOST") == "mythic_server" { - containerList = append(containerList, service) - } - case "mythic_postgres": - if mythicEnv.GetString("POSTGRES_HOST") == "127.0.0.1" || mythicEnv.GetString("POSTGRES_HOST") == "mythic_postgres" { - containerList = append(containerList, service) - } - case "mythic_graphql": - if mythicEnv.GetString("HASURA_HOST") == "127.0.0.1" || mythicEnv.GetString("HASURA_HOST") == "mythic_graphql" { - containerList = append(containerList, service) - } - case "mythic_documentation": - if mythicEnv.GetString("DOCUMENTATION_HOST") == "127.0.0.1" || mythicEnv.GetString("DOCUMENTATION_HOST") == "mythic_documentation" { - containerList = append(containerList, service) - } - case "mythic_jupyter": - if mythicEnv.GetString("JUPYTER_HOST") == "127.0.0.1" || mythicEnv.GetString("JUPYTER_HOST") == "mythic_jupyter" { - containerList = append(containerList, service) - } - case "mythic_grafana": - if mythicEnv.GetBool("postgres_debug") { - containerList = append(containerList, service) - } - case "mythic_prometheus": - if mythicEnv.GetBool("postgres_debug") { - containerList = append(containerList, service) - } - case "mythic_postgres_exporter": - if mythicEnv.GetBool("postgres_debug") { - containerList = append(containerList, service) - } - case "mythic_sync": - if mythicSyncPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, "mythic_sync")); err != nil { - fmt.Printf("[-] Failed to get the absolute path to mythic_sync: %v\n", err) - } else if _, err = os.Stat(mythicSyncPath); !os.IsNotExist(err) { - // this means that the mythic_sync folder _does_ exist - containerList = append(containerList, service) - } - } - } - return containerList, nil -} -func getElementsOnDisk() ([]string, error) { - var agentsOnDisk []string - installedServicesFilePath := filepath.Join(getCwdFromExe(), InstalledServicesFolder) - if !dirExists(installedServicesFilePath) { - if err := os.Mkdir(installedServicesFilePath, 0775); err != nil { - return nil, err - } - } - if files, err := os.ReadDir(installedServicesFilePath); err != nil { - log.Printf("[-] Failed to list contents of %s folder\n", InstalledServicesFolder) - return nil, err - } else { - for _, f := range files { - if f.IsDir() { - agentsOnDisk = append(agentsOnDisk, f.Name()) - } - } - } - return agentsOnDisk, nil -} -func DockerStart(containers []string) error { - // first stop everything that's currently running - buildArguments = getBuildArguments() - if err := DockerStop(containers); err != nil { - return err - } - // make sure that ports are available for us to use - if len(containers) == 0 { - if err := TestPorts(); err != nil { - return err - } - } - //updateNginxBlockLists() - // get all the services on disk and in docker-compose currently - if diskAgents, err := getElementsOnDisk(); err != nil { - return err - } else if dockerComposeContainers, err := GetAllExistingNonMythicServiceNames(); err != nil { - return err - } else if intendedMythicServices, err := GetIntendedMythicServiceNames(); err != nil { - return err - } else if currentMythicServices, err := GetCurrentMythicServiceNames(); err != nil { - return err - } else { - for _, val := range currentMythicServices { - if stringInSlice(val, intendedMythicServices) { - } else { - removeMythicServiceDockerComposeEntry(val) - } - } - for _, val := range intendedMythicServices { - if stringInSlice(val, currentMythicServices) { - - } else { - addMythicServiceDockerComposeEntry(val) - } - } - // if the user didn't explicitly call out starting certain containers, then do all of them - if len(containers) == 0 { - containers = append(dockerComposeContainers, intendedMythicServices...) - } - finalContainers := []string{} - //fmt.Printf("container list: %v\n", containers) - //fmt.Printf("dockerComposeContainers: %v\n", dockerComposeContainers) - //fmt.Printf("mythicPossibleServices: %v\n", MythicPossibleServices) - for _, val := range containers { // these are specified containers or all in docker compose - if !stringInSlice(val, dockerComposeContainers) && !stringInSlice(val, MythicPossibleServices) { - if stringInSlice(val, diskAgents) { - // the agent mentioned isn't in docker-compose, but is on disk, ask to add - add := askConfirm(fmt.Sprintf("\n%s isn't in docker-compose, but is on disk. Would you like to add it? ", val)) - if add { - finalContainers = append(finalContainers, val) - AddDockerComposeEntry(val, map[string]interface{}{}) - } - } else { - add := askConfirm(fmt.Sprintf("\n%s isn't in docker-compose and is not on disk. Would you like to install it from https://github.com/? ", val)) - if add { - finalContainers = append(finalContainers, val) - installServiceByName(val) - } - } - } else { - finalContainers = append(finalContainers, val) - } - - } - //fmt.Printf("final container list: %v\n", finalContainers) - // update all the mythic service entries to make sure they're the latest - for _, service := range finalContainers { - if stringInSlice(service, MythicPossibleServices) { - addMythicServiceDockerComposeEntry(service) - } - } - if mythicEnv.GetBool("REBUILD_ON_START") { - if err := runDockerCompose(append([]string{"up", "--build", "-d"}, finalContainers...)); err != nil { - return err - } - } else { - var needToBuild []string - var alreadyBuilt []string - for _, val := range finalContainers { - if !imageExists(val) { - needToBuild = append(needToBuild, val) - } else { - alreadyBuilt = append(alreadyBuilt, val) - } - } - if len(needToBuild) > 0 { - if err := runDockerCompose(append([]string{"up", "--build", "-d"}, needToBuild...)); err != nil { - return err - } - } - if len(alreadyBuilt) > 0 { - if err := runDockerCompose(append([]string{"up", "-d"}, alreadyBuilt...)); err != nil { - return err - } - } - } - err = DockerRemoveImages() - if err != nil { - fmt.Printf("[-] Failed to remove images\n%v\n", err) - return err - } - updateNginxBlockLists() - generateCerts() - TestMythicRabbitmqConnection() - TestMythicConnection() - Status(false) - return nil - } -} -func DockerStop(containers []string) error { - if dockerComposeContainers, err := GetAllExistingNonMythicServiceNames(); err != nil { - return err - } else if currentMythicServices, err := GetCurrentMythicServiceNames(); err != nil { - return err - } else { - if len(containers) == 0 { - containers = append(dockerComposeContainers, currentMythicServices...) - } - if stringInSlice("mythic_react", containers) { - if mythicEnv.GetBool("mythic_react_debug") { - // only need to remove the container if we're switching between debug and regular - if err = runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, "mythic_react")); err != nil { - fmt.Printf("[-] Failed to remove mythic_react\n") - return err - } - } - } - if mythicEnv.GetBool("REBUILD_ON_START") { - return runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, containers...)) - } else { - return runDockerCompose(append([]string{"stop"}, containers...)) - } - } -} -func DockerBuild(containers []string) error { - if len(containers) == 0 { - return nil - } else { - for _, container := range containers { - if stringInSlice(container, MythicPossibleServices) { - // update the necessary docker compose entries for mythic services - addMythicServiceDockerComposeEntry(container) - } - } - if err := runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, containers...)); err != nil { - return err - } else if err = runDockerCompose(append([]string{"up", "--build", "-d"}, containers...)); err != nil { - return err - } - err := DockerRemoveImages() - if err != nil { - fmt.Printf("[-] Failed to remove images\n%v\n", err) - return err - } - return nil - } -} -func DockerRemoveImages() error { - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - return err - } - defer cli.Close() - - images, err := cli.ImageList(ctx, types.ImageListOptions{}) - if err != nil { - panic(err) - } - - for _, image := range images { - //fmt.Printf("image: %v\n", image.RepoTags) - if stringInSlice(":", image.RepoTags) { - cli.ImageRemove(ctx, image.ID, types.ImageRemoveOptions{ - Force: true, - PruneChildren: true, - }) - } - } - return nil -} - -func DockerRemoveContainers(containers []string) error { - if err := runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, containers...)); err != nil { - return err - } else if _, err = runDocker(append([]string{"rm", "-f"}, containers...)); err != nil { - return nil - } else { - return nil - } -} -func DockerBuildReactUI() error { - if _, err := runDocker([]string{"exec", "mythic_react", "/bin/sh", "-c", "npm run react-build"}); err != nil { - return err - } - return nil -} -func DockerSave(containers []string) error { - if err := generateSavedImageFolder(); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to generate folder to save images: %v\n", err)) - } else if cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to connect to Docker: %v\n", err)) - } else { - savedContainers := containers - if len(savedContainers) == 0 { - if diskAgents, err := getElementsOnDisk(); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to get agents on disk: %v\n", err)) - } else if currentMythicServices, err := GetCurrentMythicServiceNames(); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to get mythic service list: %v\n", err)) - } else { - savedContainers = append([]string{}, diskAgents...) - savedContainers = append(savedContainers, currentMythicServices...) - } - } - savedImagePath := filepath.Join(getCwdFromExe(), "saved_images", "mythic_save.tar") - finalSavedContainers := []string{} - for i, _ := range savedContainers { - if imageExists(savedContainers[i]) { - containerName := fmt.Sprintf("%s:latest", savedContainers[i]) - finalSavedContainers = append(finalSavedContainers, containerName) - } else { - fmt.Printf("[-] No image locally for %s\n", savedContainers[i]) - } - } - fmt.Printf("[*] Saving the following images:\n%v\n", finalSavedContainers) - fmt.Printf("[*] This will take a while for Docker to compress and generate the layers...\n") - if ioReadCloser, err := cli.ImageSave(context.Background(), finalSavedContainers); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to get contents of docker image: %v\n", err)) - } else if outFile, err := os.Create(savedImagePath); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to create output file: %v\n", err)) - } else { - defer outFile.Close() - fmt.Printf("[*] Saving to %s\nThis will take a while...\n", savedImagePath) - if _, err = io.Copy(outFile, ioReadCloser); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to write contents to file: %v\n", err)) - } - } - return nil - } -} -func DockerLoad() error { - savedImagePath := filepath.Join(getCwdFromExe(), "saved_images", "mythic_save.tar") - if cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to connect to Docker: %v\n", err)) - } else if ioReadCloser, err := os.OpenFile(savedImagePath, os.O_RDONLY, 0x600); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to read tar file: %v\n", err)) - } else if _, err := cli.ImageLoad(context.Background(), ioReadCloser, false); err != nil { - return errors.New(fmt.Sprintf("[-] Failed to load image into Docker: %v\n", err)) - } else { - fmt.Printf("[+] loaded docker images!\n") - return nil - } -} -func DockerHealth(containers []string) { - for _, container := range containers { - outputString, err := runDocker([]string{"inspect", "--format", "{{json .State.Health }}", container}) - if err != nil { - fmt.Printf("failed to check status: %s", err.Error()) - } else { - fmt.Printf("%s:\n%s\n\n", container, outputString) - } - } -} - -func VolumesList() error { - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() - w := new(tabwriter.Writer) - w.Init(os.Stdout, 0, 8, 2, '\t', 0) - fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tCONTAINER STATUS\tLOCATION") - du, err := cli.DiskUsage(ctx, types.DiskUsageOptions{}) - if err != nil { - fmt.Printf("[-] Failed to get disk sizes: %v\n", err) - os.Exit(1) - } - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - fmt.Printf("[-] Failed to get container list: %v\n", err) - os.Exit(1) - } - if du.Volumes == nil { - fmt.Printf("[-] No volumes known\n") - return nil - } - var entries []string - for _, currentVolume := range du.Volumes { - name := currentVolume.Name - size := "unknown" - if currentVolume.UsageData != nil { - size = ByteCountSI(currentVolume.UsageData.Size) - } - if !strings.HasPrefix(currentVolume.Name, "mythic_") { - continue - } - containerPieces := strings.Split(currentVolume.Name, "_") - containerName := strings.Join(containerPieces[0:2], "_") - container := "unused (0)" - containerStatus := "offline" - for _, c := range containers { - if c.Image == containerName { - containerStatus = c.Status - } - for _, m := range c.Mounts { - if m.Name == currentVolume.Name { - container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" - } - } - } - entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s\t%s", - name, - size, - container, - containerStatus, - currentVolume.Mountpoint, - )) - } - sort.Strings(entries) - for _, line := range entries { - fmt.Fprintln(w, line) - } - - defer w.Flush() - return nil -} -func DockerRemoveVolume(volumeName string) error { - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() - volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) - if err != nil { - return err - } - for _, currentVolume := range volumes.Volumes { - if currentVolume.Name == volumeName { - err = cli.VolumeRemove(ctx, currentVolume.Name, true) - if err != nil { - return err - } - } - } - return nil -} -func ensureVolume(volumeName string) error { - containerNamePieces := strings.Split(volumeName, "_") - containerName := strings.Join(containerNamePieces[0:2], "_") - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - return err - } - defer cli.Close() - volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) - if err != nil { - return err - } - foundVolume := false - for _, currentVolume := range volumes.Volumes { - if currentVolume.Name == volumeName { - foundVolume = true - } - } - if !foundVolume { - _, err = cli.VolumeCreate(ctx, volume.CreateOptions{Name: volumeName}) - if err != nil { - return err - } - } - // now that we know the volume exists, make sure it's attached to a running container or we can't manipulate files - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - return err - } - for _, container := range containers { - if container.Image == containerName { - for _, mnt := range container.Mounts { - if mnt.Name == volumeName { - // container is running and has this mount associated with it - return nil - } - } - return errors.New(fmt.Sprintf("container, %s, isn't using volume, %s", containerName, volumeName)) - } - } - return errors.New(fmt.Sprintf("failed to find container, %s, for volume, %s", containerName, volumeName)) -} -func DockerCopyIntoVolume(sourceFile io.Reader, destinationFileName string, destinationVolume string) { - err := ensureVolume(destinationVolume) - if err != nil { - fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) - os.Exit(1) - } - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - fmt.Printf("[-] Failed to connect to docker api: %v\n", err) - os.Exit(1) - } - defer cli.Close() - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - fmt.Printf("[-] Failed to get container list: %v\n", err) - os.Exit(1) - } - for _, container := range containers { - for _, mnt := range container.Mounts { - if mnt.Name == destinationVolume { - err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{ - CopyUIDGID: true, - }) - if err != nil { - fmt.Printf("[-] Failed to write file: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully wrote file\n") - } - return - } - } - } - fmt.Printf("[-] Failed to find that volume name in use by any containers") - os.Exit(1) -} -func DockerCopyFromVolume(sourceVolumeName string, sourceFileName string, destinationName string) { - err := ensureVolume(sourceVolumeName) - if err != nil { - fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) - os.Exit(1) - } - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - fmt.Printf("[-] Failed to connect to docker api: %v\n", err) - os.Exit(1) - } - defer cli.Close() - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - fmt.Printf("[-] Failed to get container list: %v\n", err) - os.Exit(1) - } - for _, container := range containers { - for _, mnt := range container.Mounts { - if mnt.Name == sourceVolumeName { - reader, _, err := cli.CopyFromContainer(ctx, container.ID, mnt.Destination+"/"+sourceFileName) - if err != nil { - fmt.Printf("[-] Failed to read file: %v\n", err) - return - } - destination, err := os.Create(destinationName) - if err != nil { - fmt.Printf("[-] Failed to open destination filename: %v\n", err) - return - } - defer destination.Close() - _, err = io.Copy(destination, reader) - if err != nil { - fmt.Printf("[-] Failed to get file from volume: %v\n", err) - return - } - fmt.Printf("[+] Successfully wrote file\n") - return - } - } - } - fmt.Printf("[-] Failed to find that volume name in use by any containers") - os.Exit(1) -} diff --git a/Mythic_CLI/src/cmd/internal/dockercompose.go b/Mythic_CLI/src/cmd/internal/dockercompose.go deleted file mode 100644 index ce11e244b..000000000 --- a/Mythic_CLI/src/cmd/internal/dockercompose.go +++ /dev/null @@ -1,1096 +0,0 @@ -package internal - -import ( - "bufio" - "context" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "sort" - "strings" - "sync" - - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" - "github.com/spf13/viper" - "gopkg.in/yaml.v3" -) - -func isServiceRunning(service string) bool { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Fatalf("[-] Failed to get client connection to Docker: %v", err) - } - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ - All: true, - }) - if err != nil { - log.Fatalf("[-] Failed to get container list from Docker: %v", err) - } - if len(containers) > 0 { - for _, container := range containers { - if container.Labels["name"] == strings.ToLower(service) { - return true - } - } - } - return false -} -func addMythicServiceDockerComposeEntry(service string) { - curConfig := readInDockerCompose() - - volumes := map[string]interface{}{} - if curConfig.InConfig("volumes") { - volumes = curConfig.GetStringMap("volumes") - } - - // adding or setting services in the docker-compose file - var pStruct map[string]interface{} - - if curConfig.InConfig("services." + strings.ToLower(service)) { - pStruct = curConfig.GetStringMap("services." + strings.ToLower(service)) - delete(pStruct, "network_mode") - delete(pStruct, "extra_hosts") - delete(pStruct, "build") - delete(pStruct, "networks") - /* - pStruct["networks"] = []string{ - "default_network", - } - - */ - } else { - pStruct = map[string]interface{}{ - "logging": map[string]interface{}{ - "driver": "json-file", - "options": map[string]string{ - "max-file": "1", - "max-size": "10m", - }, - }, - "restart": "always", - "labels": map[string]string{ - "name": service, - }, - "container_name": service, - "image": service, - /* - "networks": []string{ - "default_network", - }, - - */ - } - } - - switch service { - case "mythic_postgres": - pStruct["build"] = map[string]interface{}{ - "context": "./postgres-docker", - "args": buildArguments, - } - /* - pStruct["healthcheck"] = map[string]interface{}{ - "test": "pg_isready -d mythic_db -p ${POSTGRES_PORT} -U mythic_user", - "interval": "30s", - "timeout": "60s", - "retries": 5, - "start_period": "20s", - } - - */ - //pStruct["command"] = "postgres -c \"max_connections=100\" -p ${POSTGRES_PORT} -c config_file=/etc/postgres.conf" - - if imageExists("mythic_postgres") { - if mythicEnv.GetBool("postgres_debug") { - pStruct["volumes"] = []string{ - "./postgres-docker/database:/var/lib/postgresql/data", - "./postgres-docker/postgres_debug.conf:/etc/postgresql.conf", - } - } - } - pStruct["cpus"] = mythicEnv.GetInt("POSTGRES_CPUS") - if mythicEnv.GetString("postgres_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("postgres_mem_limit") - } - if mythicEnv.GetBool("postgres_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${POSTGRES_PORT}:${POSTGRES_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${POSTGRES_PORT}:${POSTGRES_PORT}", - } - } - environment := []string{ - "POSTGRES_DB=${POSTGRES_DB}", - "POSTGRES_USER=${POSTGRES_USER}", - "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}", - } - if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } else { - pStruct["environment"] = environment - } - if mythicEnv.GetBool("postgres_bind_local_mount") { - pStruct["volumes"] = []string{ - "./postgres-docker/database:/var/lib/postgresql/data", - "./postgres-docker/postgres.conf:/etc/postgresql.conf", - } - } else { - pStruct["volumes"] = []string{ - "mythic_postgres_volume:/var/lib/postgresql/data", - } - - } - if _, ok := volumes["mythic_postgres"]; !ok { - volumes["mythic_postgres_volume"] = map[string]interface{}{ - "name": "mythic_postgres_volume", - } - } - case "mythic_documentation": - pStruct["build"] = "./documentation-docker" - pStruct["build"] = map[string]interface{}{ - "context": "./documentation-docker", - "args": buildArguments, - } - //pStruct["command"] = "server -p ${DOCUMENTATION_PORT}" - if mythicEnv.GetBool("documentation_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", - } - } - /* - pStruct["healthcheck"] = map[string]interface{}{ - "test": "wget -nv -t1 -O /dev/null http://127.0.0.1:${DOCUMENTATION_PORT}/docs/", - "interval": "10s", - "timeout": "10s", - "retries": 5, - "start_period": "10s", - } - - */ - pStruct["environment"] = []string{ - "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", - } - if mythicEnv.GetBool("documentation_bind_local_mount") { - pStruct["volumes"] = []string{ - "./documentation-docker/:/src", - } - } else { - pStruct["volumes"] = []string{ - "mythic_documentation_volume:/src", - } - } - if _, ok := volumes["mythic_documentation"]; !ok { - volumes["mythic_documentation_volume"] = map[string]interface{}{ - "name": "mythic_documentation_volume", - } - } - - case "mythic_graphql": - pStruct["build"] = map[string]interface{}{ - "context": "./hasura-docker", - "args": buildArguments, - } - pStruct["cpus"] = mythicEnv.GetInt("HASURA_CPUS") - if mythicEnv.GetString("hasura_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("hasura_mem_limit") - } - environment := []string{ - "HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}", - "HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}", - "HASURA_GRAPHQL_ENABLE_CONSOLE=true", - "HASURA_GRAPHQL_DEV_MODE=false", - "HASURA_GRAPHQL_ADMIN_SECRET=${HASURA_SECRET}", - "HASURA_GRAPHQL_INSECURE_SKIP_TLS_VERIFY=true", - "HASURA_GRAPHQL_SERVER_PORT=${HASURA_PORT}", - "HASURA_GRAPHQL_METADATA_DIR=/metadata", - "HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=1000", - "HASURA_GRAPHQL_AUTH_HOOK=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/graphql/webhook", - "MYTHIC_ACTIONS_URL_BASE=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/api/v1.4", - "HASURA_GRAPHQL_CONSOLE_ASSETS_DIR=/srv/console-assets", - } - if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } else { - pStruct["environment"] = environment - } - - if mythicEnv.GetBool("hasura_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${HASURA_PORT}:${HASURA_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${HASURA_PORT}:${HASURA_PORT}", - } - } - if mythicEnv.GetBool("hasura_bind_local_mount") { - pStruct["volumes"] = []string{ - "./hasura-docker/metadata:/metadata", - } - } else { - pStruct["volumes"] = []string{ - "mythic_graphql_volume:/metadata", - } - } - if _, ok := volumes["mythic_graphql"]; !ok { - volumes["mythic_graphql_volume"] = map[string]interface{}{ - "name": "mythic_graphql_volume", - } - } - case "mythic_nginx": - pStruct["build"] = map[string]interface{}{ - "context": "./nginx-docker", - "args": buildArguments, - } - /* - pStruct["healthcheck"] = map[string]interface{}{ - "test": "curl -k https://127.0.0.1:${NGINX_PORT}/new/login", - "interval": "30s", - "timeout": "60s", - "retries": 5, - "start_period": "15s", - } - nginxUseSSL := "ssl" - if !mythicEnv.GetBool("NGINX_USE_SSL") { - nginxUseSSL = "" - pStruct["healthcheck"] = map[string]interface{}{ - "test": "curl http://127.0.0.1:${NGINX_PORT}/new/login", - "interval": "30s", - "timeout": "60s", - "retries": 5, - "start_period": "15s", - } - } - - */ - nginxUseSSL := "ssl" - if !mythicEnv.GetBool("NGINX_USE_SSL") { - nginxUseSSL = "" - } - nginxUseIPV4 := "" - if !mythicEnv.GetBool("NGINX_USE_IPV4") { - nginxUseIPV4 = "#" - } - nginxUseIPV6 := "" - if !mythicEnv.GetBool("NGINX_USE_IPV6") { - nginxUseIPV6 = "#" - } - environment := []string{ - "DOCUMENTATION_HOST=${DOCUMENTATION_HOST}", - "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", - "NGINX_PORT=${NGINX_PORT}", - "MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}", - "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", - "HASURA_HOST=${HASURA_HOST}", - "HASURA_PORT=${HASURA_PORT}", - "MYTHIC_REACT_HOST=${MYTHIC_REACT_HOST}", - "MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}", - "JUPYTER_HOST=${JUPYTER_HOST}", - "JUPYTER_PORT=${JUPYTER_PORT}", - fmt.Sprintf("NGINX_USE_SSL=%s", nginxUseSSL), - fmt.Sprintf("NGINX_USE_IPV4=%s", nginxUseIPV4), - fmt.Sprintf("NGINX_USE_IPV6=%s", nginxUseIPV6), - } - if _, ok := pStruct["environment"]; ok { - environment = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } - var finalNginxEnv []string - for _, val := range environment { - if !strings.Contains(val, "NEW_UI") { - finalNginxEnv = append(finalNginxEnv, val) - } - } - pStruct["environment"] = finalNginxEnv - - if mythicEnv.GetBool("nginx_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${NGINX_PORT}:${NGINX_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${NGINX_PORT}:${NGINX_PORT}", - } - } - if mythicEnv.GetBool("nginx_bind_local_mount") { - pStruct["volumes"] = []string{ - "./nginx-docker/ssl:/etc/ssl/private", - "./nginx-docker/config:/etc/nginx", - } - } else { - pStruct["volumes"] = []string{ - "mythic_nginx_volume_config:/etc/nginx", - "mythic_nginx_volume_ssl:/etc/ssl/private", - } - } - if _, ok := volumes["mythic_nginx"]; !ok { - volumes["mythic_nginx_volume_config"] = map[string]interface{}{ - "name": "mythic_nginx_volume_config", - } - volumes["mythic_nginx_volume_ssl"] = map[string]interface{}{ - "name": "mythic_nginx_volume_ssl", - } - } - case "mythic_rabbitmq": - pStruct["build"] = map[string]interface{}{ - "context": "./rabbitmq-docker", - "args": buildArguments, - } - /* - pStruct["healthcheck"] = map[string]interface{}{ - "test": "rabbitmq-diagnostics -q check_port_connectivity", - "interval": "60s", - "timeout": "30s", - "retries": 5, - "start_period": "15s", - } - - */ - pStruct["cpus"] = mythicEnv.GetInt("RABBITMQ_CPUS") - if mythicEnv.GetString("rabbitmq_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("rabbitmq_mem_limit") - } - //pStruct["command"] = "/bin/sh -c \"chmod +x /generate_config.sh && /generate_config.sh && rabbitmq-server\"" - if mythicEnv.GetBool("rabbitmq_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${RABBITMQ_PORT}:${RABBITMQ_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${RABBITMQ_PORT}:${RABBITMQ_PORT}", - } - } - environment := []string{ - "RABBITMQ_USER=${RABBITMQ_USER}", - "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", - "RABBITMQ_VHOST=${RABBITMQ_VHOST}", - "RABBITMQ_PORT=${RABBITMQ_PORT}", - } - if _, ok := pStruct["environment"]; ok { - environment = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } - var finalRabbitEnv []string - badRabbitMqEnvs := []string{ - "RABBITMQ_DEFAULT_USER=${RABBITMQ_USER}", - "RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}", - "RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST}", - } - for _, val := range environment { - if !stringInSlice(val, badRabbitMqEnvs) { - finalRabbitEnv = append(finalRabbitEnv, val) - } - } - pStruct["environment"] = finalRabbitEnv - if mythicEnv.GetBool("rabbitmq_bind_local_mount") { - pStruct["volumes"] = []string{ - "./rabbitmq-docker/storage:/var/lib/rabbitmq", - "./rabbitmq-docker/generate_config.sh:/generate_config.sh", - "./rabbitmq-docker/rabbitmq.conf:/tmp/base_rabbitmq.conf", - } - } else { - pStruct["volumes"] = []string{ - "mythic_rabbitmq_volume:/var/lib/rabbitmq", - } - } - if _, ok := volumes["mythic_rabbitmq"]; !ok { - volumes["mythic_rabbitmq_volume"] = map[string]interface{}{ - "name": "mythic_rabbitmq_volume", - } - } - - case "mythic_react": - if mythicEnv.GetBool("mythic_react_debug") { - pStruct["build"] = map[string]interface{}{ - "context": "./MythicReactUI", - "args": buildArguments, - } - pStruct["volumes"] = []string{ - "./MythicReactUI/src:/app/src", - "./MythicReactUI/public:/app/public", - "./MythicReactUI/package.json:/app/package.json", - "./MythicReactUI/package-lock.json:/app/package-lock.json", - "./mythic-react-docker/mythic/public:/app/build", - } - } else { - pStruct["build"] = map[string]interface{}{ - "context": "./mythic-react-docker", - "args": buildArguments, - } - if mythicEnv.GetBool("mythic_react_bind_local_mount") { - pStruct["volumes"] = []string{ - "./mythic-react-docker/config:/etc/nginx", - "./mythic-react-docker/mythic/public:/mythic/new", - } - } else { - pStruct["volumes"] = []string{ - "mythic_react_volume_config:/etc/nginx", - "mythic_react_volume_public:/mythic/new", - } - } - } - if _, ok := volumes["mythic_react"]; !ok { - volumes["mythic_react_volume_config"] = map[string]interface{}{ - "name": "mythic_react_volume_config", - } - volumes["mythic_react_volume_public"] = map[string]interface{}{ - "name": "mythic_react_volume_public", - } - } - if mythicEnv.GetBool("mythic_react_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${MYTHIC_REACT_PORT}:${MYTHIC_REACT_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${MYTHIC_REACT_PORT}:${MYTHIC_REACT_PORT}", - } - } - /* - pStruct["healthcheck"] = map[string]interface{}{ - "test": "wget -SqO - http://127.0.0.1:${MYTHIC_REACT_PORT}/new", - "interval": "30s", - "timeout": "60s", - "retries": 3, - "start_period": "15s", - } - - */ - pStruct["environment"] = []string{ - "MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}", - } - case "mythic_jupyter": - pStruct["build"] = map[string]interface{}{ - "context": "./jupyter-docker", - "args": buildArguments, - } - pStruct["cpus"] = mythicEnv.GetInt("JUPYTER_CPUS") - if mythicEnv.GetString("jupyter_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("jupyter_mem_limit") - } - //pStruct["command"] = "start.sh jupyter lab --ServerApp.open_browser=false --IdentityProvider.token='${JUPYTER_TOKEN}' --ServerApp.base_url=\"/jupyter\" --ServerApp.default_url=\"/jupyter\"" - if mythicEnv.GetBool("jupyter_bind_localhost_only") { - pStruct["ports"] = []string{ - "127.0.0.1:${JUPYTER_PORT}:${JUPYTER_PORT}", - } - } else { - pStruct["ports"] = []string{ - "${JUPYTER_PORT}:${JUPYTER_PORT}", - } - } - - pStruct["environment"] = []string{ - "JUPYTER_TOKEN=${JUPYTER_TOKEN}", - } - if curConfig.InConfig("services.mythic_jupyter.deploy") { - pStruct["deploy"] = curConfig.Get("services.mythic_jupyter.deploy") - } - if mythicEnv.GetBool("jupyter_bind_local_mount") { - pStruct["volumes"] = []string{ - "./jupyter-docker/jupyter:/projects", - } - } else { - pStruct["volumes"] = []string{ - "mythic_jupyter_volume:/projects", - } - } - if _, ok := volumes["mythic_jupyter"]; !ok { - volumes["mythic_jupyter_volume"] = map[string]interface{}{ - "name": "mythic_jupyter_volume", - } - } - case "mythic_server": - pStruct["build"] = map[string]interface{}{ - "context": "./mythic-docker", - "args": buildArguments, - } - pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SERVER_CPUS") - if mythicEnv.GetString("mythic_server_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("mythic_server_mem_limit") - } - /* - pStruct["healthcheck"] = map[string]interface{}{ - "test": "wget -SqO - http://127.0.0.1:${MYTHIC_SERVER_PORT}/health", - "interval": "60s", - "timeout": "10s", - "retries": 5, - "start_period": "20s", - } - - */ - //pStruct["command"] = "${MYTHIC_SERVER_COMMAND}" - environment := []string{ - "POSTGRES_HOST=${POSTGRES_HOST}", - "POSTGRES_PORT=${POSTGRES_PORT}", - "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}", - "RABBITMQ_HOST=${RABBITMQ_HOST}", - "RABBITMQ_PORT=${RABBITMQ_PORT}", - "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", - "JWT_SECRET=${JWT_SECRET}", - "DEBUG_LEVEL=${DEBUG_LEVEL}", - "MYTHIC_DEBUG_AGENT_MESSAGE=${MYTHIC_DEBUG_AGENT_MESSAGE}", - "MYTHIC_ADMIN_PASSWORD=${MYTHIC_ADMIN_PASSWORD}", - "MYTHIC_ADMIN_USER=${MYTHIC_ADMIN_USER}", - "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", - "MYTHIC_SERVER_BIND_LOCALHOST_ONLY=${MYTHIC_SERVER_BIND_LOCALHOST_ONLY}", - "MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT}", - "ALLOWED_IP_BLOCKS=${ALLOWED_IP_BLOCKS}", - "DEFAULT_OPERATION_NAME=${DEFAULT_OPERATION_NAME}", - "DEFAULT_OPERATION_WEBHOOK_URL=${DEFAULT_OPERATION_WEBHOOK_URL}", - "DEFAULT_OPERATION_WEBHOOK_CHANNEL=${DEFAULT_OPERATION_WEBHOOK_CHANNEL}", - "NGINX_PORT=${NGINX_PORT}", - "NGINX_HOST=${NGINX_HOST}", - "MYTHIC_SERVER_DYNAMIC_PORTS=${MYTHIC_SERVER_DYNAMIC_PORTS}", - } - mythicServerPorts := []string{ - "${MYTHIC_SERVER_PORT}:${MYTHIC_SERVER_PORT}", - "${MYTHIC_SERVER_GRPC_PORT}:${MYTHIC_SERVER_GRPC_PORT}", - } - if mythicEnv.GetBool("MYTHIC_SERVER_BIND_LOCALHOST_ONLY") { - mythicServerPorts = []string{ - "127.0.0.1:${MYTHIC_SERVER_PORT}:${MYTHIC_SERVER_PORT}", - "127.0.0.1:${MYTHIC_SERVER_GRPC_PORT}:${MYTHIC_SERVER_GRPC_PORT}", - } - } - dynamicPortPieces := strings.Split(mythicEnv.GetString("MYTHIC_SERVER_DYNAMIC_PORTS"), ",") - for _, val := range dynamicPortPieces { - if mythicEnv.GetBool("mythic_server_dynamic_ports_bind_localhost_only") { - mythicServerPorts = append(mythicServerPorts, fmt.Sprintf("127.0.0.1:%s:%s", val, val)) - } else { - mythicServerPorts = append(mythicServerPorts, fmt.Sprintf("%s:%s", val, val)) - } - - } - pStruct["ports"] = mythicServerPorts - if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } else { - pStruct["environment"] = environment - } - if mythicEnv.GetBool("mythic_server_bind_local_mount") { - pStruct["volumes"] = []string{ - "./mythic-docker/src:/usr/src/app", - } - } else { - pStruct["volumes"] = []string{ - "mythic_server_volume:/usr/src/app", - } - } - if _, ok := volumes["mythic_server"]; !ok { - volumes["mythic_server_volume"] = map[string]interface{}{ - "name": "mythic_server_volume", - } - } - case "mythic_sync": - if absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)); err != nil { - fmt.Printf("[-] Failed to get abs path for mythic_sync\n") - return - } else { - pStruct["build"] = map[string]interface{}{ - "context": absPath, - "args": buildArguments, - } - pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SYNC_CPUS") - if mythicEnv.GetString("mythic_sync_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("mythic_sync_mem_limit") - } - pStruct["environment"] = []string{ - "MYTHIC_IP=${NGINX_HOST}", - "MYTHIC_PORT=${NGINX_PORT}", - "MYTHIC_USERNAME=${MYTHIC_ADMIN_USER}", - "MYTHIC_PASSWORD=${MYTHIC_ADMIN_PASSWORD}", - "MYTHIC_API_KEY=${MYTHIC_API_KEY}", - "GHOSTWRITER_API_KEY=${GHOSTWRITER_API_KEY}", - "GHOSTWRITER_URL=${GHOSTWRITER_URL}", - "GHOSTWRITER_OPLOG_ID=${GHOSTWRITER_OPLOG_ID}", - } - if !mythicEnv.InConfig("GHOSTWRITER_API_KEY") { - key := askVariable("Please enter your GhostWriter API Key") - mythicEnv.Set("GHOSTWRITER_API_KEY", key) - } - if !mythicEnv.InConfig("GHOSTWRITER_URL") { - url := askVariable("Please enter your GhostWriter URL") - mythicEnv.Set("GHOSTWRITER_URL", url) - } - if !mythicEnv.InConfig("GHOSTWRITER_OPLOG_ID") { - gwID := askVariable("Please enter your GhostWriter OpLog ID") - mythicEnv.Set("GHOSTWRITER_OPLOG_ID", gwID) - } - if !mythicEnv.InConfig("MYTHIC_API_KEY") { - mythicID := askVariable("Please enter your Mythic API Key (optional)") - mythicEnv.Set("MYTHIC_API_KEY", mythicID) - } - // just got new variables, need to update our .env - writeMythicEnvironmentVariables() - } - - case "mythic_grafana": - pStruct["build"] = map[string]interface{}{ - "context": "./grafana-docker", - "args": buildArguments, - } - pStruct["ports"] = []string{ - "127.0.0.1:3000:3000", - } - pStruct["volumes"] = []string{ - "./grafana-docker/storage:/var/lib/grafana", - } - pStruct["user"] = "root" - case "mythic_prometheus": - pStruct["build"] = map[string]interface{}{ - "context": "./prometheus-docker", - "args": buildArguments, - } - pStruct["ports"] = []string{ - "127.0.0.1:9090:9090", - } - pStruct["volumes"] = []string{ - "./prometheus-docker/prometheus.yml:/etc/prometheus/prometheus.yml:ro", - } - case "mythic_postgres_exporter": - pStruct["build"] = map[string]interface{}{ - "context": "./postgres-exporter-docker", - "args": buildArguments, - } - pStruct["ports"] = []string{ - "127.0.0.1:9187:9187", - } - pStruct["volumes"] = []string{ - "./postgres-exporter-docker/queries.yaml:/queries.yaml", - } - pStruct["links"] = []string{ - "mythic_postgres", - "mythic_prometheus", - } - pStruct["environment"] = []string{ - "DATA_SOURCE_NAME=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}?sslmode=disable", - } - pStruct["command"] = "--extend.query-path=/queries.yaml" - } - if !curConfig.InConfig("services." + strings.ToLower(service)) { - curConfig.Set("services."+strings.ToLower(service), pStruct) - fmt.Printf("[+] Added %s to docker-compose\n", strings.ToLower(service)) - } else { - curConfig.Set("services."+strings.ToLower(service), pStruct) - } - curConfig.Set("volumes", volumes) - err := setDockerComposeDefaultsAndWrite(curConfig) - if err != nil { - fmt.Printf("[-] Failed to update config: %v\n", err) - } -} -func removeMythicServiceDockerComposeEntry(service string) { - curConfig := readInDockerCompose() - - if isServiceRunning(service) { - DockerStop([]string{strings.ToLower(service)}) - } - if curConfig.InConfig("services." + strings.ToLower(service)) { - delete(curConfig.Get("services").(map[string]interface{}), strings.ToLower(service)) - if stringInSlice(service, []string{"mythic_grafana", "mythic_prometheus", "mythic_postgres_exporter"}) { - fmt.Printf("[+] Removed %s from docker-compose because postgres_debug is set to false\n", strings.ToLower(service)) - } else { - fmt.Printf("[+] Removed %s from docker-compose because it's running on a different host\n", strings.ToLower(service)) - } - - } - - err := setDockerComposeDefaultsAndWrite(curConfig) - if err != nil { - fmt.Printf("[-] Failed to update config: %v\n", err) - } else { - fmt.Println("[+] Successfully updated docker-compose.yml") - } -} - -func AddDockerComposeEntry(service string, additionalConfigs map[string]interface{}) error { - // add c2/payload [name] as type [group] to the main yaml file - curConfig := readInDockerCompose() - - absPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder, service)) - if err != nil { - fmt.Printf("[-] Failed to get the absolute path to the %s folder, does the folder exist?\n", InstalledServicesFolder) - fmt.Printf("[*] If the service doesn't exist, you might need to install with 'mythic-cli install'\n") - os.Exit(1) - } - if !dirExists(absPath) { - fmt.Printf("[-] %s does not exist, not adding to Mythic\n", absPath) - os.Exit(1) - } - pStruct := map[string]interface{}{ - "labels": map[string]string{ - "name": service, - }, - "image": strings.ToLower(service), - "hostname": service, - "logging": map[string]interface{}{ - "driver": "json-file", - "options": map[string]string{ - "max-file": "1", - "max-size": "10m", - }, - }, - "restart": "always", - "container_name": strings.ToLower(service), - "cpus": mythicEnv.GetInt("INSTALLED_SERVICE_CPUS"), - } - if mythicEnv.GetString("installed_service_mem_limit") != "" { - pStruct["mem_limit"] = mythicEnv.GetString("installed_service_mem_limit") - } - for key, element := range additionalConfigs { - pStruct[key] = element - } - pStruct["build"] = map[string]interface{}{ - "context": absPath, - "args": buildArguments, - } - pStruct["network_mode"] = "host" - pStruct["extra_hosts"] = []string{ - "mythic_server:127.0.0.1", - "mythic_rabbitmq:127.0.0.1", - } - environment := []string{ - "MYTHIC_ADDRESS=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/agent_message", - "MYTHIC_WEBSOCKET=ws://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/ws/agent_message", - "RABBITMQ_USER=${RABBITMQ_USER}", - "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", - "RABBITMQ_PORT=${RABBITMQ_PORT}", - "RABBITMQ_HOST=${RABBITMQ_HOST}", - "MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}", - "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", - "MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT}", - "WEBHOOK_DEFAULT_URL=${WEBHOOK_DEFAULT_URL}", - "WEBHOOK_DEFAULT_CALLBACK_CHANNEL=${WEBHOOK_DEFAULT_CALLBACK_CHANNEL}", - "WEBHOOK_DEFAULT_FEEDBACK_CHANNEL=${WEBHOOK_DEFAULT_FEEDBACK_CHANNEL}", - "WEBHOOK_DEFAULT_STARTUP_CHANNEL=${WEBHOOK_DEFAULT_STARTUP_CHANNEL}", - "WEBHOOK_DEFAULT_ALERT_CHANNEL=${WEBHOOK_DEFAULT_ALERT_CHANNEL}", - "WEBHOOK_DEFAULT_CUSTOM_CHANNEL=${WEBHOOK_DEFAULT_CUSTOM_CHANNEL}", - "DEBUG_LEVEL=${DEBUG_LEVEL}", - } - if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = updateEnvironmentVariables(curConfig.GetStringSlice("services."+strings.ToLower(service)+".environment"), environment) - } else { - pStruct["environment"] = environment - } - // only add in volumes if some aren't already listed - if _, ok := pStruct["volumes"]; !ok { - pStruct["volumes"] = []string{ - absPath + ":/Mythic/", - } - } - curConfig.Set("services."+strings.ToLower(service), pStruct) - - err = setDockerComposeDefaultsAndWrite(curConfig) - if err != nil { - fmt.Printf("[-] Failed to update config: %v\n", err) - } else { - fmt.Println("[+] Successfully updated docker-compose.yml") - } - - return nil -} -func RemoveDockerComposeEntry(service string) error { - // add c2/payload [name] as type [group] to the main yaml file - curConfig := readInDockerCompose() - - if !stringInSlice(service, MythicPossibleServices) { - if isServiceRunning(service) { - DockerStop([]string{strings.ToLower(service)}) - } - delete(curConfig.Get("services").(map[string]interface{}), strings.ToLower(service)) - fmt.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) - - } - err := setDockerComposeDefaultsAndWrite(curConfig) - if err != nil { - fmt.Printf("[-] Failed to update config: %v\n", err) - } else { - fmt.Println("[+] Successfully updated docker-compose.yml") - } - return nil -} - -func runDockerCompose(args []string) error { - lookPath, err := exec.LookPath("docker-compose") - if err != nil { - lookPath, err = exec.LookPath("docker") - if err != nil { - log.Fatalf("[-] docker-compose and docker are not installed or available in the current PATH\n") - } else { - // adjust the current args for docker compose subcommand - args = append([]string{"compose"}, args...) - } - } - exe, err := os.Executable() - if err != nil { - log.Fatalf("[-] Failed to get lookPath to current executable\n") - } - exePath := filepath.Dir(exe) - command := exec.Command(lookPath, args...) - command.Dir = exePath - command.Env = getMythicEnvList() - - stdout, err := command.StdoutPipe() - if err != nil { - log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") - } - stderr, err := command.StderrPipe() - if err != nil { - log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") - } - - stdoutScanner := bufio.NewScanner(stdout) - stderrScanner := bufio.NewScanner(stderr) - wg := sync.WaitGroup{} - wg.Add(2) - go func() { - for stdoutScanner.Scan() { - fmt.Printf("%s\n", stdoutScanner.Text()) - } - wg.Done() - }() - go func() { - for stderrScanner.Scan() { - fmt.Printf("%s\n", stderrScanner.Text()) - } - wg.Done() - }() - err = command.Start() - if err != nil { - log.Fatalf("[-] Error trying to start docker-compose: %v\n", err) - } - wg.Wait() - err = command.Wait() - if err != nil { - fmt.Printf("[-] Error from docker-compose: %v\n", err) - fmt.Printf("[*] Docker compose command: %v\n", args) - return err - } - return nil -} -func runDocker(args []string) (string, error) { - lookPath, err := exec.LookPath("docker") - if err != nil { - log.Fatalf("[-] docker is not installed or available in the current PATH\n") - } - exe, err := os.Executable() - if err != nil { - log.Fatalf("[-] Failed to get lookPath to current executable\n") - } - exePath := filepath.Dir(exe) - command := exec.Command(lookPath, args...) - command.Dir = exePath - command.Env = getMythicEnvList() - stdout, err := command.StdoutPipe() - if err != nil { - log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") - } - stderr, err := command.StderrPipe() - if err != nil { - log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") - } - stdoutScanner := bufio.NewScanner(stdout) - stderrScanner := bufio.NewScanner(stderr) - outputString := "" - wg := sync.WaitGroup{} - wg.Add(2) - go func() { - for stdoutScanner.Scan() { - outputString += stdoutScanner.Text() - } - wg.Done() - }() - go func() { - for stderrScanner.Scan() { - fmt.Printf("%s\n", stderrScanner.Text()) - } - wg.Done() - }() - err = command.Start() - if err != nil { - log.Fatalf("[-] Error trying to start docker: %v\n", err) - } - wg.Wait() - err = command.Wait() - if err != nil { - fmt.Printf("[-] Error from docker: %v\n", err) - fmt.Printf("[*] Docker command: %v\n", args) - return "", err - } - return outputString, nil -} -func GetAllExistingNonMythicServiceNames() ([]string, error) { - // get all services that exist within the loaded config - groupNameConfig := viper.New() - groupNameConfig.SetConfigName("docker-compose") - groupNameConfig.SetConfigType("yaml") - groupNameConfig.AddConfigPath(getCwdFromExe()) - if err := groupNameConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) - return []string{}, err - } else { - fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) - return []string{}, err - } - } - servicesSub := groupNameConfig.Sub("services") - services := servicesSub.AllSettings() - containerList := []string{} - for service := range services { - if !stringInSlice(service, MythicPossibleServices) { - containerList = append(containerList, service) - } - } - return containerList, nil -} -func GetCurrentMythicServiceNames() ([]string, error) { - groupNameConfig := viper.New() - groupNameConfig.SetConfigName("docker-compose") - groupNameConfig.SetConfigType("yaml") - groupNameConfig.AddConfigPath(getCwdFromExe()) - if err := groupNameConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) - return []string{}, err - } else { - fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) - return []string{}, err - } - } - servicesSub := groupNameConfig.Sub("services") - services := servicesSub.AllSettings() - containerList := []string{} - for service := range services { - if stringInSlice(service, MythicPossibleServices) { - containerList = append(containerList, service) - } - } - return containerList, nil -} - -func getBuildArguments() []string { - var buildEnv = viper.New() - buildEnv.SetConfigName("build.env") - buildEnv.SetConfigType("env") - buildEnv.AddConfigPath(getCwdFromExe()) - buildEnv.AutomaticEnv() - if !fileExists(filepath.Join(getCwdFromExe(), "build.env")) { - fmt.Printf("[*] No build.env file detected in Mythic's root directory; not supplying build arguments to docker containers\n") - fmt.Printf(" If you need to supply build arguments to docker containers, create build.env and supply key=value entries there\n") - return []string{} - } - if err := buildEnv.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Fatalf("[-] Error while reading in build.env file: %s\n", err) - } else { - log.Fatalf("[-]Error while parsing build.env file: %s\n", err) - } - } - c := buildEnv.AllSettings() - // to make it easier to read and look at, get all the keys, sort them, and display variables in order - keys := make([]string, 0, len(c)) - for k := range c { - keys = append(keys, k) - } - sort.Strings(keys) - var args []string - for _, key := range keys { - args = append(args, fmt.Sprintf("%s=%s", strings.ToUpper(key), buildEnv.GetString(key))) - } - return args -} -func getMythicEnvList() []string { - env := mythicEnv.AllSettings() - var envList []string - for key := range env { - val := mythicEnv.GetString(key) - if val != "" { - // prevent trying to append arrays or dictionaries to our environment list - //fmt.Println(strings.ToUpper(key), val) - envList = append(envList, strings.ToUpper(key)+"="+val) - } - } - envList = append(envList, os.Environ()...) - return envList -} - -func CheckDockerCompose() { - groupNameConfig := viper.New() - groupNameConfig.SetConfigName("docker-compose") - groupNameConfig.SetConfigType("yaml") - groupNameConfig.AddConfigPath(getCwdFromExe()) - if err := groupNameConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) - if _, err := os.Create("docker-compose.yml"); err != nil { - fmt.Printf("[-] Failed to create docker-compose.yml file: %v\n", err) - os.Exit(1) - } else { - if err := groupNameConfig.ReadInConfig(); err != nil { - fmt.Printf("[-] Failed to read in new docker-compose.yml file: %v\n", err) - } else { - fmt.Printf("[+] Successfully created new docker-compose.yml file. Populating it now...\n") - } - intendedMythicContainers, _ := GetIntendedMythicServiceNames() - for _, container := range intendedMythicContainers { - addMythicServiceDockerComposeEntry(container) - } - return - } - - } else { - fmt.Printf("[-] Error while parsing docker-compose file: %s", err) - os.Exit(1) - } - } - servicesSub := groupNameConfig.Sub("services") - if servicesSub == nil { - intendedMythicContainers, _ := GetIntendedMythicServiceNames() - for _, container := range intendedMythicContainers { - addMythicServiceDockerComposeEntry(container) - } - } - if !checkDockerVersion() { - log.Fatalf("[-] Bad docker version\n") - } -} -func setDockerComposeDefaultsAndWrite(curConfig *viper.Viper) error { - curConfig.Set("version", "2.4") - file := curConfig.ConfigFileUsed() - if len(file) == 0 { - file = "./docker-compose.yml" - } - configMap := curConfig.AllSettings() - ignoredKeys := []string{"networks"} - for _, key := range ignoredKeys { - delete(configMap, key) - } - - content, err := yaml.Marshal(configMap) - if err != nil { - return err - } - return os.WriteFile(file, content, 0644) -} -func readInDockerCompose() *viper.Viper { - var curConfig = viper.New() - curConfig.SetConfigName("docker-compose") - curConfig.SetConfigType("yaml") - curConfig.AddConfigPath(getCwdFromExe()) - if err := curConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) - } else { - log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) - } - } - return curConfig -} diff --git a/Mythic_CLI/src/cmd/internal/git.go b/Mythic_CLI/src/cmd/internal/git.go index 66e98a61b..0cbfce70e 100644 --- a/Mythic_CLI/src/cmd/internal/git.go +++ b/Mythic_CLI/src/cmd/internal/git.go @@ -21,7 +21,7 @@ func runGitClone(args []string) error { command := exec.Command(lookPath, args...) command.Dir = exePath - command.Env = getMythicEnvList() + //command.Env = getMythicEnvList() if stdout, err := command.StdoutPipe(); err != nil { fmt.Printf("[-] Failed to get stdout pipe for running git") @@ -66,7 +66,7 @@ func runGitLsRemote(args []string) (err error) { // git ls-remote URL HEAD command := exec.Command(lookPath, args...) command.Dir = exePath - command.Env = getMythicEnvList() + //command.Env = getMythicEnvList() command.Env = append(command.Env, "GIT_TERMINAL_PROMPT=0") if err = command.Run(); err != nil { diff --git a/Mythic_CLI/src/cmd/internal/installservice.go b/Mythic_CLI/src/cmd/internal/installservice.go index 3e34773ae..f9121cf1b 100644 --- a/Mythic_CLI/src/cmd/internal/installservice.go +++ b/Mythic_CLI/src/cmd/internal/installservice.go @@ -2,6 +2,9 @@ package internal import ( "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/manager" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" "io/ioutil" "log" "os" @@ -12,23 +15,23 @@ import ( ) func InstallFolder(installPath string, overWrite bool) error { - workingPath := getCwdFromExe() - if fileExists(filepath.Join(installPath, "config.json")) { - var config = viper.New() - config.SetConfigName("config") - config.SetConfigType("json") - fmt.Printf("[*] Parsing config.json\n") - config.AddConfigPath(installPath) - if err := config.ReadInConfig(); err != nil { + workingPath := utils.GetCwdFromExe() + if utils.FileExists(filepath.Join(installPath, "config.json")) { + var installConfig = viper.New() + installConfig.SetConfigName("config") + installConfig.SetConfigType("json") + log.Printf("[*] Parsing installConfig.json\n") + installConfig.AddConfigPath(installPath) + if err := installConfig.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in config file: %s", err) + fmt.Printf("[-] Error while reading in installConfig file: %s", err) return err } else { - fmt.Printf("[-] Error while parsing config file: %s", err) + fmt.Printf("[-] Error while parsing installConfig file: %s", err) return err } } - if !config.GetBool("exclude_payload_type") { + if !installConfig.GetBool("exclude_payload_type") { // handle the payload type copying here files, err := ioutil.ReadDir(filepath.Join(installPath, "Payload_Type")) if err != nil { @@ -38,138 +41,142 @@ func InstallFolder(installPath string, overWrite bool) error { for _, f := range files { if f.IsDir() { fmt.Printf("[*] Processing Payload Type %s\n", f.Name()) - if dirExists(filepath.Join(workingPath, InstalledServicesFolder, f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { - fmt.Printf("[*] Stopping current container\n") - if isServiceRunning(strings.ToLower(f.Name())) { - if err := DockerStop([]string{f.Name()}); err != nil { - fmt.Printf("[-] Failed to stop current container: %v\n", err) + + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { + log.Printf("[*] Stopping current container\n") + if manager.GetManager().IsServiceRunning(strings.ToLower(f.Name())) { + if err := ServiceStop([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to stop current container: %v\n", err) return err } } - fmt.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, InstalledServicesFolder, f.Name())) + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next payload\n") + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next payload\n") continue } else { - fmt.Printf("[+] Successfully removed the current version\n") + log.Printf("[+] Successfully removed the current version\n") } } else { - fmt.Printf("[!] Skipping Payload Type, %s\n", f.Name()) + log.Printf("[!] Skipping Payload Type, %s\n", f.Name()) continue } } - fmt.Printf("[*] Copying new version of payload into place\n") - err = copyDir(filepath.Join(installPath, "Payload_Type", f.Name()), filepath.Join(workingPath, InstalledServicesFolder, f.Name())) + log.Printf("[*] Copying new version of payload into place\n") + err = utils.CopyDir(filepath.Join(installPath, "Payload_Type", f.Name()), + filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) if err != nil { - fmt.Printf("[-] Failed to copy directory over: %v\n", err) + log.Printf("[-] Failed to copy directory over: %v\n", err) continue } - fmt.Printf("[*] Adding service into docker-compose\n") - if config.IsSet("docker-compose") { - if err := AddDockerComposeEntry(f.Name(), config.GetStringMap("docker-compose")); err != nil { - fmt.Printf("[-] Failed to add service to docker-compose: %v\n", err) - } else if err := DockerBuild([]string{f.Name()}); err != nil { - fmt.Printf("[-] Failed to start service: %v\n", err) + log.Printf("[*] Adding service into docker-compose\n") + if installConfig.IsSet("docker-compose") { + err := Add3rdPartyService(f.Name(), installConfig.GetStringMap("docker-compose")) + if err != nil { + log.Printf("[-] Failed to add service to docker-compose: %v\n", err) + } else if err := ServiceBuild([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to start service: %v\n", err) } } else { - if err := AddDockerComposeEntry(f.Name(), make(map[string]interface{})); err != nil { - fmt.Printf("[-] Failed to add service to docker-compose: %v\n", err) - } else if err := DockerBuild([]string{f.Name()}); err != nil { - fmt.Printf("[-] Failed to start service: %v\n", err) + if err := Add3rdPartyService(f.Name(), make(map[string]interface{})); err != nil { + log.Printf("[-] Failed to add service to docker-compose: %v\n", err) + } else if err := ServiceBuild([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to start service: %v\n", err) } } } } - fmt.Printf("[+] Successfully installed service\n") + log.Printf("[+] Successfully installed service\n") } else { - fmt.Printf("[*] Skipping over Payload Type\n") + log.Printf("[*] Skipping over Payload Type\n") } - if !config.GetBool("exclude_c2_profiles") { + if !installConfig.GetBool("exclude_c2_profiles") { // handle the c2 profile copying here files, err := ioutil.ReadDir(filepath.Join(installPath, "C2_Profiles")) if err != nil { - fmt.Printf("[-] Failed to list contents of C2_Profiles folder from clone\n") + log.Printf("[-] Failed to list contents of C2_Profiles folder from clone\n") return err } for _, f := range files { if f.IsDir() { - fmt.Printf("[*] Processing C2 Profile %s\n", f.Name()) - if dirExists(filepath.Join(workingPath, InstalledServicesFolder, f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { - fmt.Printf("[*] Stopping current container\n") - if isServiceRunning(strings.ToLower(f.Name())) { - if err := DockerStop([]string{f.Name()}); err != nil { - fmt.Printf("[-] Failed to stop container: %v\n", err) + log.Printf("[*] Processing C2 Profile %s\n", f.Name()) + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { + log.Printf("[*] Stopping current container\n") + if manager.GetManager().IsServiceRunning(strings.ToLower(f.Name())) { + if err := ServiceStop([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to stop container: %v\n", err) return err } } - fmt.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, InstalledServicesFolder, f.Name())) + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next c2 profile\n") + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next c2 profile\n") continue } else { - fmt.Printf("[+] Successfully removed the current version\n") + log.Printf("[+] Successfully removed the current version\n") } } else { - fmt.Printf("[!] Skipping C2 Profile, %s\n", f.Name()) + log.Printf("[!] Skipping C2 Profile, %s\n", f.Name()) continue } } - fmt.Printf("[*] Copying new version into place\n") - err = copyDir(filepath.Join(installPath, "C2_Profiles", f.Name()), filepath.Join(workingPath, InstalledServicesFolder, f.Name())) + log.Printf("[*] Copying new version into place\n") + err = utils.CopyDir(filepath.Join(installPath, "C2_Profiles", f.Name()), + filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") + log.Printf("[-] Failed to copy directory over\n") continue } - // now add payload type to yaml config - fmt.Printf("[*] Adding c2, %s, into docker-compose\n", f.Name()) - if err := AddDockerComposeEntry(f.Name(), make(map[string]interface{})); err != nil { - fmt.Printf("[-] Failed to add %s to docker-compose: %v\n", f.Name(), err) - } else if err := DockerBuild([]string{f.Name()}); err != nil { - fmt.Printf("[-] Failed to start service: %v\n", err) + // now add payload type to yaml installConfig + log.Printf("[*] Adding c2, %s, into docker-compose\n", f.Name()) + if err = Add3rdPartyService(f.Name(), make(map[string]interface{})); err != nil { + log.Printf("[-] Failed to add %s to docker-compose: %v\n", f.Name(), err) + } else if err := ServiceBuild([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to start service: %v\n", err) } } } - fmt.Printf("[+] Successfully installed c2\n") + log.Printf("[+] Successfully installed c2\n") } else { - fmt.Printf("[*] Skipping over C2 Profile\n") + log.Printf("[*] Skipping over C2 Profile\n") } - if !config.GetBool("exclude_documentation_payload") { + if !installConfig.GetBool("exclude_documentation_payload") { // handle payload documentation copying here files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-payload")) if err != nil { - fmt.Printf("[-] Failed to list contents of documentation_payload folder from clone: %v\n", err) + log.Printf("[-] Failed to list contents of documentation_payload folder from clone: %v\n", err) } else { for _, f := range files { if f.IsDir() { - fmt.Printf("[*] Processing Documentation for %s\n", f.Name()) - if mythicEnv.GetBool("documentation_bind_local_mount") { - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - fmt.Printf("[*] Removing current version\n") + log.Printf("[*] Processing Documentation for %s\n", f.Name()) + if config.GetMythicEnv().GetBool("documentation_bind_local_mount") { + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + log.Printf("[*] Removing current version\n") err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next payload documentation\n") + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next payload documentation\n") continue } else { - fmt.Printf("[+] Successfully removed the current version\n") + log.Printf("[+] Successfully removed the current version\n") } } else { - fmt.Printf("[!] Skipping documentation for , %s\n", f.Name()) + log.Printf("[!] Skipping documentation for , %s\n", f.Name()) continue } } - fmt.Printf("[*] Copying new documentation into place\n") - err = copyDir(filepath.Join(installPath, "documentation-payload", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) + log.Printf("[*] Copying new documentation into place\n") + err = utils.CopyDir(filepath.Join(installPath, "documentation-payload", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") + log.Printf("[-] Failed to copy directory over\n") continue } } else { @@ -177,49 +184,50 @@ func InstallFolder(installPath string, overWrite bool) error { filepath.Join("content", "Agents"), filepath.Join(installPath, "documentation-payload", f.Name())) if err != nil { - fmt.Printf("[-] Failed to install documentation for payload: %v\n", err) + log.Printf("[-] Failed to install documentation for payload: %v\n", err) continue } } } } - fmt.Printf("[+] Successfully installed Payload documentation\n") + log.Printf("[+] Successfully installed Payload documentation\n") } } else { - fmt.Printf("[*] Skipping over Payload Documentation\n") + log.Printf("[*] Skipping over Payload Documentation\n") } - if !config.GetBool("exclude_documentation_c2") { + if !installConfig.GetBool("exclude_documentation_c2") { // handle the c2 documentation copying here files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-c2")) if err != nil { - fmt.Printf("[-] Failed to list contents of documentation_payload folder from clone") + log.Printf("[-] Failed to list contents of documentation_payload folder from clone") } else { for _, f := range files { if f.IsDir() { - fmt.Printf("[*] Processing Documentation for %s\n", f.Name()) - if mythicEnv.GetBool("document_bind_local_mount") { - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - fmt.Printf("[*] Removing current version\n") + log.Printf("[*] Processing Documentation for %s\n", f.Name()) + if config.GetMythicEnv().GetBool("document_bind_local_mount") { + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + log.Printf("[*] Removing current version\n") err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next c2 documentation\n") + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next c2 documentation\n") continue } else { - fmt.Printf("[+] Successfully removed the current version\n") + log.Printf("[+] Successfully removed the current version\n") } } else { - fmt.Printf("[!] Skipping documentation for %s\n", f.Name()) + log.Printf("[!] Skipping documentation for %s\n", f.Name()) continue } } - fmt.Printf("[*] Copying new documentation version into place\n") - err = copyDir(filepath.Join(installPath, "documentation-c2", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) + log.Printf("[*] Copying new documentation version into place\n") + err = utils.CopyDir(filepath.Join(installPath, "documentation-c2", f.Name()), + filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") + log.Printf("[-] Failed to copy directory over\n") continue } } else { @@ -227,7 +235,7 @@ func InstallFolder(installPath string, overWrite bool) error { filepath.Join("content", "C2 Profiles"), filepath.Join(installPath, "documentation-c2", f.Name())) if err != nil { - fmt.Printf("[-] Failed to install documentation for c2: %v\n", err) + log.Printf("[-] Failed to install documentation for c2: %v\n", err) continue } @@ -235,42 +243,43 @@ func InstallFolder(installPath string, overWrite bool) error { } } - fmt.Printf("[+] Successfully installed c2 documentation\n") + log.Printf("[+] Successfully installed c2 documentation\n") } } else { - fmt.Printf("[*] Skipping over C2 Documentation\n") + log.Printf("[*] Skipping over C2 Documentation\n") } - if !config.GetBool("exclude_documentation_wrapper") { + if !installConfig.GetBool("exclude_documentation_wrapper") { // handle payload documentation copying here files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-wrapper")) if err != nil { - fmt.Printf("[-] Failed to list contents of documentation-wrapper folder from clone: %v\n", err) + log.Printf("[-] Failed to list contents of documentation-wrapper folder from clone: %v\n", err) } else { for _, f := range files { if f.IsDir() { - fmt.Printf("[*] Processing Documentation for %s\n", f.Name()) - if mythicEnv.GetBool("document_local_bind_mount") { - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) { - if overWrite || askConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - fmt.Printf("[*] Removing current version\n") + log.Printf("[*] Processing Documentation for %s\n", f.Name()) + if config.GetMythicEnv().GetBool("document_local_bind_mount") { + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + log.Printf("[*] Removing current version\n") err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) if err != nil { - fmt.Printf("[-] Failed to remove current version: %v\n", err) - fmt.Printf("[-] Continuing to the next wrapper documentation\n") + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next wrapper documentation\n") continue } else { - fmt.Printf("[+] Successfully removed the current version\n") + log.Printf("[+] Successfully removed the current version\n") } } else { - fmt.Printf("[!] Skipping documentation for , %s\n", f.Name()) + log.Printf("[!] Skipping documentation for , %s\n", f.Name()) continue } } - fmt.Printf("[*] Copying new documentation into place\n") - err = copyDir(filepath.Join(installPath, "documentation-wrapper", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) + log.Printf("[*] Copying new documentation into place\n") + err = utils.CopyDir(filepath.Join(installPath, "documentation-wrapper", f.Name()), + filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) if err != nil { - fmt.Printf("[-] Failed to copy directory over\n") + log.Printf("[-] Failed to copy directory over\n") continue } } else { @@ -278,21 +287,21 @@ func InstallFolder(installPath string, overWrite bool) error { filepath.Join("content", "Wrappers"), filepath.Join(installPath, "documentation-wrapper", f.Name())) if err != nil { - fmt.Printf("[-] Failed to install documentation for wrapper: %v\n", err) + log.Printf("[-] Failed to install documentation for wrapper: %v\n", err) continue } } } } - fmt.Printf("[+] Successfully installed Wrapper documentation\n") + log.Printf("[+] Successfully installed Wrapper documentation\n") } } else { - fmt.Printf("[*] Skipping over Wrapper Documentation\n") + log.Printf("[*] Skipping over Wrapper Documentation\n") } - if isServiceRunning("mythic_documentation") { + if manager.GetManager().IsServiceRunning("mythic_documentation") { fmt.Printf("[*] Restarting mythic_documentation container to pull in changes\n") - DockerStop([]string{"mythic_documentation"}) - DockerStart([]string{"mythic_documentation"}) + ServiceStop([]string{"mythic_documentation"}) + ServiceStart([]string{"mythic_documentation"}) } } else { log.Fatal("[-] Failed to find config.json in cloned down repo\n") @@ -301,34 +310,34 @@ func InstallFolder(installPath string, overWrite bool) error { } func InstallService(url string, branch string, overWrite bool) error { // make our temp directory to clone into - workingPath := getCwdFromExe() - fmt.Printf("[*] Creating temporary directory\n") - if dirExists(filepath.Join(workingPath, "tmp")) { + workingPath := utils.GetCwdFromExe() + log.Printf("[*] Creating temporary directory\n") + if utils.DirExists(filepath.Join(workingPath, "tmp")) { err := os.RemoveAll(filepath.Join(workingPath, "tmp")) if err != nil { - fmt.Printf("[-] tmp directory couldn't be deleted for a fresh install: %v\n", err) + log.Printf("[-] tmp directory couldn't be deleted for a fresh install: %v\n", err) return err } } err := os.Mkdir(filepath.Join(workingPath, "tmp"), 0755) defer os.RemoveAll(filepath.Join(workingPath, "tmp")) if err != nil { - fmt.Printf("[-] Failed to make temp directory for cloning: %v\n", err) + log.Printf("[-] Failed to make temp directory for cloning: %v\n", err) return err } if branch == "" { - fmt.Printf("[*] Cloning %s\n", url) + log.Printf("[*] Cloning %s\n", url) err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--recurse-submodules", "--single-branch", url, filepath.Join(workingPath, "tmp")}) } else { - fmt.Printf("[*] Cloning branch \"%s\" from %s\n", branch, url) + log.Printf("[*] Cloning branch \"%s\" from %s\n", branch, url) err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--recurse-submodules", "--single-branch", "--branch", branch, url, filepath.Join(workingPath, "tmp")}) } if err != nil { - fmt.Printf("[-] Failed to clone down repository: %v\n", err) + log.Printf("[-] Failed to clone down repository: %v\n", err) return err } if err = InstallFolder(filepath.Join(workingPath, "tmp"), overWrite); err != nil { - fmt.Printf("[-] Failed to install: %v\n", err) + log.Printf("[-] Failed to install: %v\n", err) return err } else { return nil @@ -351,54 +360,119 @@ func installServiceByName(service string) error { return InstallService(agentURL, "", true) } } -func InstallMythicSyncFolder(installPath string) error { - workingPath := getCwdFromExe() - viper.SetConfigName("docker-compose") - viper.SetConfigType("yaml") - viper.AddConfigPath(getCwdFromExe()) - if err := viper.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) - return err +func UninstallService(services []string) { + workingPath := utils.GetCwdFromExe() + for _, service := range services { + if utils.StringInSlice(strings.ToLower(service), config.MythicPossibleServices) { + log.Fatalf("[-] Trying to uninstall Mythic services not allowed\nIf you need to remove it locally send the corresponding environment host name to an IP address or hostname") + } + found := false + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) { + log.Printf("[*] Stopping and removing container\n") + if manager.GetManager().IsServiceRunning(strings.ToLower(service)) { + if err := ServiceStop([]string{strings.ToLower(service)}); err != nil { + log.Printf("[-] Failed to stop container: %v\n", err) + return + } + } + log.Printf("[*] Removing %s from docker-compose\n", strings.ToLower(service)) + err := manager.GetManager().RemoveServices([]string{strings.ToLower(service)}) + if err != nil { + log.Printf("[-] Failed to remove docker compose entry: %v\n", err) + return + } + log.Printf("[*] Removing Payload Type folder from disk\n") + found = true + err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) + if err != nil { + log.Fatalf("[-] Failed to remove folder: %v\n", err) + } + log.Printf("[+] Successfully removed %s's folder\n", service) + + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", service)) { + log.Printf("[*] Removing Payload Type's Documentation from disk\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", service)) + if err != nil { + log.Fatalf("[-] Failed to remove Payload Type's Documentation: %v\n", err) + } + log.Printf("[+] Successfully removed Payload Type's Documentation\n") + + } + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", service)) { + log.Printf("[*] Removing C2 Profile's Documentation\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", service)) + if err != nil { + log.Fatalf("[-] Failed to remove C2 Profile's Documentation: %v\n", err) + } + log.Printf("[+] Successfully removed C2 Profile's Documentation\n") + + } + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", service)) { + log.Printf("[*] Removing C2 Profile's Documentation\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", service)) + if err != nil { + log.Fatalf("[-] Failed to remove C2 Profile's Documentation: %v\n", err) + } + log.Printf("[+] Successfully removed C2 Profile's Documentation\n") + + } + } + + if found { + log.Printf("[+] Successfully Uninstalled %s\n", service) + if manager.GetManager().IsServiceRunning("mythic_documentation") { + log.Printf("[*] Restarting mythic_documentation container to pull in changes\n") + ServiceStop([]string{"mythic_documentation"}) + ServiceStart([]string{"mythic_documentation"}) + } + return } else { - fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) - return err + log.Fatalf("[-] Failed to find any service folder by that name\n") } } +} + +// Mythic Sync Specific + +func InstallMythicSyncFolder(installPath string) error { service := "mythic_sync" - if isServiceRunning(service) { - if err := DockerStop([]string{service}); err != nil { - fmt.Printf("[-] Failed to stop current docker container: %v\n", err) + if manager.GetManager().IsServiceRunning(service) { + err := manager.GetManager().StopServices([]string{service}, config.GetMythicEnv().GetBool("REBUILD_ON_START")) + if err != nil { + log.Printf("[-] Failed to stop current docker container: %v\n", err) return err } } - if dirExists(filepath.Join(workingPath, InstalledServicesFolder, service)) { - err := os.RemoveAll(filepath.Join(workingPath, InstalledServicesFolder, service)) + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) { + err := os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) if err != nil { - fmt.Printf("[-] %s directory couldn't be deleted for a fresh install: %v\n", filepath.Join(workingPath, InstalledServicesFolder, service), err) + log.Printf("[-] %s directory couldn't be deleted for a fresh install: %v\n", + filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service), err) return err } } - if err := copyDir(installPath, filepath.Join(workingPath, InstalledServicesFolder, service)); err != nil { - fmt.Printf("[-] Failed to create %s directory to install mythic_sync: %v\n", service, err) + err := utils.CopyDir(installPath, filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) + if err != nil { + log.Printf("[-] Failed to create %s directory to install mythic_sync: %v\n", service, err) return err } - addMythicServiceDockerComposeEntry(service) - fmt.Printf("[+] Successfully installed mythic_sync!\n") - if isServiceRunning("mythic_server") { - if err := DockerStart([]string{strings.ToLower(service)}); err != nil { - fmt.Printf("[-] Failed to start mythic_sync: %v\n", err) + AddMythicService(service) + log.Printf("[+] Successfully installed mythic_sync!\n") + if manager.GetManager().IsServiceRunning("mythic_server") { + err = ServiceStart([]string{strings.ToLower(service)}) + if err != nil { + log.Printf("[-] Failed to start mythic_sync: %v\n", err) } } return nil } func InstallMythicSync(url string, branch string) error { // make our temp directory to clone into - workingPath := getCwdFromExe() - fmt.Printf("[*] Creating temporary directory\n") - if dirExists(filepath.Join(workingPath, "tmp")) { + workingPath := utils.GetCwdFromExe() + log.Printf("[*] Creating temporary directory\n") + if utils.DirExists(filepath.Join(workingPath, "tmp")) { if err := os.RemoveAll(filepath.Join(workingPath, "tmp")); err != nil { - fmt.Printf("[-] %s directory couldn't be deleted for a fresh install: %v\n", filepath.Join(workingPath, "tmp"), err) + log.Printf("[-] %s directory couldn't be deleted for a fresh install: %v\n", filepath.Join(workingPath, "tmp"), err) return err } } @@ -408,121 +482,35 @@ func InstallMythicSync(url string, branch string) error { log.Fatalf("[-] Failed to make temp directory for cloning: %v\n", err) } if branch == "" { - fmt.Printf("[*] Cloning %s\n", url) + log.Printf("[*] Cloning %s\n", url) err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--recurse-submodules", "--single-branch", url, filepath.Join(workingPath, "tmp")}) } else { - fmt.Printf("[*] Cloning branch \"%s\" from %s\n", branch, url) + log.Printf("[*] Cloning branch \"%s\" from %s\n", branch, url) err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--recurse-submodules", "--single-branch", "--branch", branch, url, filepath.Join(workingPath, "tmp")}) } if err != nil { - fmt.Printf("[-] Failed to clone down repository: %v\n", err) + log.Printf("[-] Failed to clone down repository: %v\n", err) return err } return InstallMythicSyncFolder(filepath.Join(workingPath, "tmp")) } func UninstallMythicSync() { - workingPath := getCwdFromExe() service := "mythic_sync" - if isServiceRunning(service) { - DockerStop([]string{service}) + if manager.GetManager().IsServiceRunning(service) { + ServiceStop([]string{service}) } - removeMythicServiceDockerComposeEntry(service) - if dirExists(filepath.Join(workingPath, InstalledServicesFolder, service)) { - err := os.RemoveAll(filepath.Join(workingPath, InstalledServicesFolder, service)) + RemoveService(service) + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) { + err := os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)) if err != nil { log.Fatalf("[-] %s directory couldn't be deleted: %v\n", service, err) } else { - fmt.Printf("[+] Successfully removed %s from disk\n", service) - } - } else { - fmt.Printf("[+] %s was not installed on disk\n", service) - } - fmt.Printf("[+] Successfully uninstalled mythic_sync\n") -} -func UninstallService(services []string) { - workingPath := getCwdFromExe() - for _, service := range services { - if stringInSlice(strings.ToLower(service), MythicPossibleServices) { - fmt.Printf("[-] Trying to uninstall Mythic services not allowed\n") - os.Exit(1) - } - found := false - if dirExists(filepath.Join(workingPath, InstalledServicesFolder, service)) { - fmt.Printf("[*] Stopping and removing container\n") - if isServiceRunning(strings.ToLower(service)) { - if err := DockerStop([]string{strings.ToLower(service)}); err != nil { - fmt.Printf("[-] Failed to stop container: %v\n", err) - return - } - } - fmt.Printf("[*] Removing %s from docker-compose\n", strings.ToLower(service)) - if err := RemoveDockerComposeEntry(strings.ToLower(service)); err != nil { - fmt.Printf("[-] Failed to remove docker compose entry: %v\n", err) - return - } - fmt.Printf("[*] Removing Payload Type folder from disk\n") - found = true - err := os.RemoveAll(filepath.Join(workingPath, InstalledServicesFolder, service)) - if err != nil { - fmt.Printf("[-] Failed to remove folder: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully removed %s's folder\n", service) - } - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", service)) { - fmt.Printf("[*] Removing Payload Type's Documentation from disk\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", service)) - if err != nil { - fmt.Printf("[-] Failed to remove Payload Type's Documentation: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully removed Payload Type's Documentation\n") - } - } - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", service)) { - fmt.Printf("[*] Removing C2 Profile's Documentation\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", service)) - if err != nil { - fmt.Printf("[-] Failed to remove C2 Profile's Documentation: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully removed C2 Profile's Documentation\n") - } - } - if dirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", service)) { - fmt.Printf("[*] Removing C2 Profile's Documentation\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", service)) - if err != nil { - fmt.Printf("[-] Failed to remove C2 Profile's Documentation: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully removed C2 Profile's Documentation\n") - } - } - if fileExists(filepath.Join(workingPath, "mythic-docker", "src", "static", service+".svg")) { - found = true - err := os.RemoveAll(filepath.Join(workingPath, "src", "static", service+".svg")) - if err != nil { - fmt.Printf("[-] Failed to agent icon: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully removed %s's old UI icon\n", service) - } - } - } - - if found { - fmt.Printf("[+] Successfully Uninstalled %s\n", service) - if isServiceRunning("mythic_documentation") { - fmt.Printf("[*] Restarting mythic_documentation container to pull in changes\n") - DockerStop([]string{"mythic_documentation"}) - DockerStart([]string{"mythic_documentation"}) - } + log.Printf("[+] Successfully removed %s from disk\n", service) return - } else { - fmt.Printf("[-] Failed to find any service folder by that name\n") - os.Exit(1) } + } else { + log.Printf("[+] %s was not installed on disk\n", service) + return } } diff --git a/Mythic_CLI/src/cmd/internal/reset.go b/Mythic_CLI/src/cmd/internal/reset.go index 9c441f9ac..925e2bbf3 100644 --- a/Mythic_CLI/src/cmd/internal/reset.go +++ b/Mythic_CLI/src/cmd/internal/reset.go @@ -9,7 +9,7 @@ import ( func DatabaseReset() { fmt.Printf("[*] Stopping Mythic\n") - DockerStop([]string{}) + ServiceStop([]string{}) workingPath := getCwdFromExe() fmt.Printf("[*] Removing database files\n") if mythicEnv.GetBool("postgres_bind_local_mount") { @@ -20,7 +20,7 @@ func DatabaseReset() { fmt.Printf("[+] Successfully reset datbase files\n") } } else { - DockerRemoveContainers([]string{"mythic_postgres"}) + ServiceRemoveContainers([]string{"mythic_postgres"}) err := DockerRemoveVolume("mythic_postgres_volume") if err != nil { fmt.Printf("[-] Failed to remove database:\n%v\n", err) @@ -31,7 +31,7 @@ func DatabaseReset() { func RabbitmqReset(explicitCall bool) { if explicitCall { fmt.Printf("[*] Stopping Mythic\n") - DockerStop([]string{}) + ServiceStop([]string{}) fmt.Printf("[*] Removing rabbitmq files\n") } if mythicEnv.GetBool("rabbitmq_bind_local_mount") { @@ -45,7 +45,7 @@ func RabbitmqReset(explicitCall bool) { } } } else { - DockerRemoveContainers([]string{"mythic_rabbitmq"}) + ServiceRemoveContainers([]string{"mythic_rabbitmq"}) err := DockerRemoveVolume("mythic_rabbitmq_volume") if err != nil { fmt.Printf("[-] Failed to remove rabbitmq files:\n%v\n", err) diff --git a/Mythic_CLI/src/cmd/internal/serviceExecution.go b/Mythic_CLI/src/cmd/internal/serviceExecution.go new file mode 100644 index 000000000..35e5b4bbf --- /dev/null +++ b/Mythic_CLI/src/cmd/internal/serviceExecution.go @@ -0,0 +1,357 @@ +package internal + +import ( + "context" + "errors" + "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/manager" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/volume" + "github.com/docker/docker/client" + "io" + "log" + "os" + "sort" + "strconv" + "strings" + "text/tabwriter" +) + +// ServiceStart is entrypoint from commands to start containers +func ServiceStart(containers []string) error { + // first stop all the containers or the ones specified + _ = manager.GetManager().StopServices(containers, config.GetMythicEnv().GetBool("REBUILD_ON_START")) + + // get all the services on disk and in docker-compose currently + diskAgents, err := manager.GetManager().GetInstalled3rdPartyServicesOnDisk() + if err != nil { + return err + } + dockerComposeContainers, err := manager.GetManager().GetAllExistingNonMythicServiceNames() + if err != nil { + return err + } + intendedMythicServices, err := config.GetIntendedMythicServiceNames() + if err != nil { + return err + } + currentMythicServices, err := manager.GetManager().GetCurrentMythicServiceNames() + if err != nil { + return err + } + for _, val := range currentMythicServices { + if utils.StringInSlice(val, intendedMythicServices) { + } else { + _ = manager.GetManager().RemoveServices([]string{val}) + } + } + for _, val := range intendedMythicServices { + if utils.StringInSlice(val, currentMythicServices) { + + } else { + AddMythicService(val) + } + } + // if the user didn't explicitly call out starting certain containers, then do all of them + if len(containers) == 0 { + containers = append(dockerComposeContainers, intendedMythicServices...) + } + finalContainers := []string{} + for _, val := range containers { // these are specified containers or all in docker compose + if !utils.StringInSlice(val, dockerComposeContainers) && !utils.StringInSlice(val, config.MythicPossibleServices) { + if utils.StringInSlice(val, diskAgents) { + // the agent mentioned isn't in docker-compose, but is on disk, ask to add + add := config.AskConfirm(fmt.Sprintf("\n%s isn't in docker-compose, but is on disk. Would you like to add it? ", val)) + if add { + finalContainers = append(finalContainers, val) + Add3rdPartyService(val, map[string]interface{}{}) + } + } else { + add := config.AskConfirm(fmt.Sprintf("\n%s isn't in docker-compose and is not on disk. Would you like to install it from https://github.com/? ", val)) + if add { + finalContainers = append(finalContainers, val) + installServiceByName(val) + } + } + } else { + finalContainers = append(finalContainers, val) + } + } + for _, service := range finalContainers { + if utils.StringInSlice(service, config.MythicPossibleServices) { + AddMythicService(service) + } + } + manager.GetManager().TestPorts() + err = manager.GetManager().StartServices(finalContainers, config.GetMythicEnv().GetBool("REBUILD_ON_START")) + err = manager.GetManager().RemoveImages() + if err != nil { + fmt.Printf("[-] Failed to remove images\n%v\n", err) + return err + } + updateNginxBlockLists() + generateCerts() + TestMythicRabbitmqConnection() + TestMythicConnection() + Status(false) + return nil +} +func ServiceStop(containers []string) error { + return manager.GetManager().StopServices(containers, config.GetMythicEnv().GetBool("REBUILD_ON_START")) +} +func ServiceBuild(containers []string) error { + for _, container := range containers { + if utils.StringInSlice(container, config.MythicPossibleServices) { + // update the necessary docker compose entries for mythic services + AddMythicService(container) + } + } + err := manager.GetManager().BuildServices(containers) + if err != nil { + return err + } + return nil +} +func ServiceRemoveContainers(containers []string) error { + return manager.GetManager().RemoveContainers(containers) +} + +// Docker Save / Load commands + +func DockerSave(containers []string) error { + return manager.GetManager().SaveImages(containers, "saved_images") +} +func DockerLoad() error { + return manager.GetManager().LoadImages("saved_images") +} +func DockerHealth(containers []string) { + manager.GetManager().GetHealthCheck(containers) +} + +// Build new Docker UI + +func DockerBuildReactUI() error { + if config.GetMythicEnv().GetBool("MYTHIC_REACT_DEBUG") { + err := manager.GetManager().BuildUI() + if err != nil { + log.Fatalf("[-] Failed to build new UI from debug build") + } + } + log.Printf("[-] Not using MYTHIC_REACT_DEBUG to generate new UI, aborting...\n") + return nil +} + +// Docker Volume commands + +func VolumesList() error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 8, 2, '\t', 0) + fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tCONTAINER STATUS\tLOCATION") + du, err := cli.DiskUsage(ctx, types.DiskUsageOptions{}) + if err != nil { + fmt.Printf("[-] Failed to get disk sizes: %v\n", err) + os.Exit(1) + } + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + fmt.Printf("[-] Failed to get container list: %v\n", err) + os.Exit(1) + } + if du.Volumes == nil { + fmt.Printf("[-] No volumes known\n") + return nil + } + var entries []string + for _, currentVolume := range du.Volumes { + name := currentVolume.Name + size := "unknown" + if currentVolume.UsageData != nil { + size = utils.ByteCountSI(currentVolume.UsageData.Size) + } + if !strings.HasPrefix(currentVolume.Name, "mythic_") { + continue + } + containerPieces := strings.Split(currentVolume.Name, "_") + containerName := strings.Join(containerPieces[0:2], "_") + container := "unused (0)" + containerStatus := "offline" + for _, c := range containers { + if c.Image == containerName { + containerStatus = c.Status + } + for _, m := range c.Mounts { + if m.Name == currentVolume.Name { + container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" + } + } + } + entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s\t%s", + name, + size, + container, + containerStatus, + currentVolume.Mountpoint, + )) + } + sort.Strings(entries) + for _, line := range entries { + fmt.Fprintln(w, line) + } + + defer w.Flush() + return nil +} +func DockerRemoveVolume(volumeName string) error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + err = cli.VolumeRemove(ctx, currentVolume.Name, true) + if err != nil { + return err + } + } + } + return nil +} +func ensureVolume(volumeName string) error { + containerNamePieces := strings.Split(volumeName, "_") + containerName := strings.Join(containerNamePieces[0:2], "_") + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return err + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + foundVolume := false + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + foundVolume = true + } + } + if !foundVolume { + _, err = cli.VolumeCreate(ctx, volume.CreateOptions{Name: volumeName}) + if err != nil { + return err + } + } + // now that we know the volume exists, make sure it's attached to a running container or we can't manipulate files + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + return err + } + for _, container := range containers { + if container.Image == containerName { + for _, mnt := range container.Mounts { + if mnt.Name == volumeName { + // container is running and has this mount associated with it + return nil + } + } + return errors.New(fmt.Sprintf("container, %s, isn't using volume, %s", containerName, volumeName)) + } + } + return errors.New(fmt.Sprintf("failed to find container, %s, for volume, %s", containerName, volumeName)) +} +func DockerCopyIntoVolume(sourceFile io.Reader, destinationFileName string, destinationVolume string) { + err := ensureVolume(destinationVolume) + if err != nil { + fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) + os.Exit(1) + } + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + fmt.Printf("[-] Failed to connect to docker api: %v\n", err) + os.Exit(1) + } + defer cli.Close() + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + fmt.Printf("[-] Failed to get container list: %v\n", err) + os.Exit(1) + } + for _, container := range containers { + for _, mnt := range container.Mounts { + if mnt.Name == destinationVolume { + err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{ + CopyUIDGID: true, + }) + if err != nil { + fmt.Printf("[-] Failed to write file: %v\n", err) + os.Exit(1) + } else { + fmt.Printf("[+] Successfully wrote file\n") + } + return + } + } + } + fmt.Printf("[-] Failed to find that volume name in use by any containers") + os.Exit(1) +} +func DockerCopyFromVolume(sourceVolumeName string, sourceFileName string, destinationName string) { + err := ensureVolume(sourceVolumeName) + if err != nil { + fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) + os.Exit(1) + } + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + fmt.Printf("[-] Failed to connect to docker api: %v\n", err) + os.Exit(1) + } + defer cli.Close() + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + fmt.Printf("[-] Failed to get container list: %v\n", err) + os.Exit(1) + } + for _, container := range containers { + for _, mnt := range container.Mounts { + if mnt.Name == sourceVolumeName { + reader, _, err := cli.CopyFromContainer(ctx, container.ID, mnt.Destination+"/"+sourceFileName) + if err != nil { + fmt.Printf("[-] Failed to read file: %v\n", err) + return + } + destination, err := os.Create(destinationName) + if err != nil { + fmt.Printf("[-] Failed to open destination filename: %v\n", err) + return + } + defer destination.Close() + _, err = io.Copy(destination, reader) + if err != nil { + fmt.Printf("[-] Failed to get file from volume: %v\n", err) + return + } + fmt.Printf("[+] Successfully wrote file\n") + return + } + } + } + fmt.Printf("[-] Failed to find that volume name in use by any containers") + os.Exit(1) +} diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go new file mode 100644 index 000000000..03e9fa11f --- /dev/null +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -0,0 +1,564 @@ +package internal + +import ( + "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/manager" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "log" + "path/filepath" + "strings" +) + +func AddMythicService(service string) { + pStruct, err := manager.GetManager().GetServiceConfiguration(service) + if err != nil { + log.Fatalf("[-] Failed to get current configuration information: %v\n", err) + } + if _, ok := pStruct["environment"]; !ok { + pStruct["environment"] = []string{} + } + mythicEnv := config.GetMythicEnv() + volumes, _ := manager.GetManager().GetVolumes() + switch service { + case "mythic_postgres": + pStruct["build"] = map[string]interface{}{ + "context": "./postgres-docker", + "args": config.GetBuildArguments(), + } + pStruct["cpus"] = mythicEnv.GetInt("POSTGRES_CPUS") + if mythicEnv.GetString("postgres_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("postgres_mem_limit") + } + if mythicEnv.GetBool("postgres_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${POSTGRES_PORT}:${POSTGRES_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${POSTGRES_PORT}:${POSTGRES_PORT}", + } + } + environment := []string{ + "POSTGRES_DB=${POSTGRES_DB}", + "POSTGRES_USER=${POSTGRES_USER}", + "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}", + } + if _, ok := pStruct["environment"]; ok { + pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + } else { + pStruct["environment"] = environment + } + if mythicEnv.GetBool("postgres_bind_local_mount") { + pStruct["volumes"] = []string{ + "./postgres-docker/database:/var/lib/postgresql/data", + "./postgres-docker/postgres.conf:/etc/postgresql.conf", + } + } else { + pStruct["volumes"] = []string{ + "mythic_postgres_volume:/var/lib/postgresql/data", + } + + } + if _, ok := volumes["mythic_postgres"]; !ok { + volumes["mythic_postgres_volume"] = map[string]interface{}{ + "name": "mythic_postgres_volume", + } + } + case "mythic_documentation": + pStruct["build"] = "./documentation-docker" + pStruct["build"] = map[string]interface{}{ + "context": "./documentation-docker", + "args": config.GetBuildArguments(), + } + if mythicEnv.GetBool("documentation_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", + } + } + pStruct["environment"] = []string{ + "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", + } + if mythicEnv.GetBool("documentation_bind_local_mount") { + pStruct["volumes"] = []string{ + "./documentation-docker/:/src", + } + } else { + pStruct["volumes"] = []string{ + "mythic_documentation_volume:/src", + } + } + if _, ok := volumes["mythic_documentation"]; !ok { + volumes["mythic_documentation_volume"] = map[string]interface{}{ + "name": "mythic_documentation_volume", + } + } + case "mythic_graphql": + pStruct["build"] = map[string]interface{}{ + "context": "./hasura-docker", + "args": config.GetBuildArguments(), + } + pStruct["cpus"] = mythicEnv.GetInt("HASURA_CPUS") + if mythicEnv.GetString("hasura_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("hasura_mem_limit") + } + environment := []string{ + "HASURA_GRAPHQL_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}", + "HASURA_GRAPHQL_METADATA_DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}", + "HASURA_GRAPHQL_ENABLE_CONSOLE=true", + "HASURA_GRAPHQL_DEV_MODE=false", + "HASURA_GRAPHQL_ADMIN_SECRET=${HASURA_SECRET}", + "HASURA_GRAPHQL_INSECURE_SKIP_TLS_VERIFY=true", + "HASURA_GRAPHQL_SERVER_PORT=${HASURA_PORT}", + "HASURA_GRAPHQL_METADATA_DIR=/metadata", + "HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=1000", + "HASURA_GRAPHQL_AUTH_HOOK=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/graphql/webhook", + "MYTHIC_ACTIONS_URL_BASE=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/api/v1.4", + "HASURA_GRAPHQL_CONSOLE_ASSETS_DIR=/srv/console-assets", + } + if _, ok := pStruct["environment"]; ok { + pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + } else { + pStruct["environment"] = environment + } + + if mythicEnv.GetBool("hasura_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${HASURA_PORT}:${HASURA_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${HASURA_PORT}:${HASURA_PORT}", + } + } + if mythicEnv.GetBool("hasura_bind_local_mount") { + pStruct["volumes"] = []string{ + "./hasura-docker/metadata:/metadata", + } + } else { + pStruct["volumes"] = []string{ + "mythic_graphql_volume:/metadata", + } + } + if _, ok := volumes["mythic_graphql"]; !ok { + volumes["mythic_graphql_volume"] = map[string]interface{}{ + "name": "mythic_graphql_volume", + } + } + case "mythic_nginx": + pStruct["build"] = map[string]interface{}{ + "context": "./nginx-docker", + "args": config.GetBuildArguments(), + } + nginxUseSSL := "ssl" + if !mythicEnv.GetBool("NGINX_USE_SSL") { + nginxUseSSL = "" + } + nginxUseIPV4 := "" + if !mythicEnv.GetBool("NGINX_USE_IPV4") { + nginxUseIPV4 = "#" + } + nginxUseIPV6 := "" + if !mythicEnv.GetBool("NGINX_USE_IPV6") { + nginxUseIPV6 = "#" + } + environment := []string{ + "DOCUMENTATION_HOST=${DOCUMENTATION_HOST}", + "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", + "NGINX_PORT=${NGINX_PORT}", + "MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}", + "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", + "HASURA_HOST=${HASURA_HOST}", + "HASURA_PORT=${HASURA_PORT}", + "MYTHIC_REACT_HOST=${MYTHIC_REACT_HOST}", + "MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}", + "JUPYTER_HOST=${JUPYTER_HOST}", + "JUPYTER_PORT=${JUPYTER_PORT}", + fmt.Sprintf("NGINX_USE_SSL=%s", nginxUseSSL), + fmt.Sprintf("NGINX_USE_IPV4=%s", nginxUseIPV4), + fmt.Sprintf("NGINX_USE_IPV6=%s", nginxUseIPV6), + } + if _, ok := pStruct["environment"]; ok { + environment = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + } + var finalNginxEnv []string + for _, val := range environment { + if !strings.Contains(val, "NEW_UI") { + finalNginxEnv = append(finalNginxEnv, val) + } + } + pStruct["environment"] = finalNginxEnv + + if mythicEnv.GetBool("nginx_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${NGINX_PORT}:${NGINX_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${NGINX_PORT}:${NGINX_PORT}", + } + } + if mythicEnv.GetBool("nginx_bind_local_mount") { + pStruct["volumes"] = []string{ + "./nginx-docker/ssl:/etc/ssl/private", + "./nginx-docker/config:/etc/nginx", + } + } else { + pStruct["volumes"] = []string{ + "mythic_nginx_volume_config:/etc/nginx", + "mythic_nginx_volume_ssl:/etc/ssl/private", + } + } + if _, ok := volumes["mythic_nginx"]; !ok { + volumes["mythic_nginx_volume_config"] = map[string]interface{}{ + "name": "mythic_nginx_volume_config", + } + volumes["mythic_nginx_volume_ssl"] = map[string]interface{}{ + "name": "mythic_nginx_volume_ssl", + } + } + case "mythic_rabbitmq": + pStruct["build"] = map[string]interface{}{ + "context": "./rabbitmq-docker", + "args": config.GetBuildArguments(), + } + pStruct["cpus"] = mythicEnv.GetInt("RABBITMQ_CPUS") + if mythicEnv.GetString("rabbitmq_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("rabbitmq_mem_limit") + } + if mythicEnv.GetBool("rabbitmq_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${RABBITMQ_PORT}:${RABBITMQ_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${RABBITMQ_PORT}:${RABBITMQ_PORT}", + } + } + environment := []string{ + "RABBITMQ_USER=${RABBITMQ_USER}", + "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", + "RABBITMQ_VHOST=${RABBITMQ_VHOST}", + "RABBITMQ_PORT=${RABBITMQ_PORT}", + } + if _, ok := pStruct["environment"]; ok { + environment = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + } + var finalRabbitEnv []string + badRabbitMqEnvs := []string{ + "RABBITMQ_DEFAULT_USER=${RABBITMQ_USER}", + "RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD}", + "RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST}", + } + for _, val := range environment { + if !utils.StringInSlice(val, badRabbitMqEnvs) { + finalRabbitEnv = append(finalRabbitEnv, val) + } + } + pStruct["environment"] = finalRabbitEnv + if mythicEnv.GetBool("rabbitmq_bind_local_mount") { + pStruct["volumes"] = []string{ + "./rabbitmq-docker/storage:/var/lib/rabbitmq", + "./rabbitmq-docker/generate_config.sh:/generate_config.sh", + "./rabbitmq-docker/rabbitmq.conf:/tmp/base_rabbitmq.conf", + } + } else { + pStruct["volumes"] = []string{ + "mythic_rabbitmq_volume:/var/lib/rabbitmq", + } + } + if _, ok := volumes["mythic_rabbitmq"]; !ok { + volumes["mythic_rabbitmq_volume"] = map[string]interface{}{ + "name": "mythic_rabbitmq_volume", + } + } + case "mythic_react": + if mythicEnv.GetBool("mythic_react_debug") { + pStruct["build"] = map[string]interface{}{ + "context": "./MythicReactUI", + "args": config.GetBuildArguments(), + } + pStruct["volumes"] = []string{ + "./MythicReactUI/src:/app/src", + "./MythicReactUI/public:/app/public", + "./MythicReactUI/package.json:/app/package.json", + "./MythicReactUI/package-lock.json:/app/package-lock.json", + "./mythic-react-docker/mythic/public:/app/build", + } + } else { + pStruct["build"] = map[string]interface{}{ + "context": "./mythic-react-docker", + "args": config.GetBuildArguments(), + } + if mythicEnv.GetBool("mythic_react_bind_local_mount") { + pStruct["volumes"] = []string{ + "./mythic-react-docker/config:/etc/nginx", + "./mythic-react-docker/mythic/public:/mythic/new", + } + } else { + pStruct["volumes"] = []string{ + "mythic_react_volume_config:/etc/nginx", + "mythic_react_volume_public:/mythic/new", + } + } + } + if _, ok := volumes["mythic_react"]; !ok { + volumes["mythic_react_volume_config"] = map[string]interface{}{ + "name": "mythic_react_volume_config", + } + volumes["mythic_react_volume_public"] = map[string]interface{}{ + "name": "mythic_react_volume_public", + } + } + if mythicEnv.GetBool("mythic_react_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${MYTHIC_REACT_PORT}:${MYTHIC_REACT_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${MYTHIC_REACT_PORT}:${MYTHIC_REACT_PORT}", + } + } + pStruct["environment"] = []string{ + "MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}", + } + case "mythic_jupyter": + pStruct["build"] = map[string]interface{}{ + "context": "./jupyter-docker", + "args": config.GetBuildArguments(), + } + pStruct["cpus"] = mythicEnv.GetInt("JUPYTER_CPUS") + if mythicEnv.GetString("jupyter_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("jupyter_mem_limit") + } + if mythicEnv.GetBool("jupyter_bind_localhost_only") { + pStruct["ports"] = []string{ + "127.0.0.1:${JUPYTER_PORT}:${JUPYTER_PORT}", + } + } else { + pStruct["ports"] = []string{ + "${JUPYTER_PORT}:${JUPYTER_PORT}", + } + } + + pStruct["environment"] = []string{ + "JUPYTER_TOKEN=${JUPYTER_TOKEN}", + } + /* + if curConfig.InConfig("services.mythic_jupyter.deploy") { + pStruct["deploy"] = curConfig.Get("services.mythic_jupyter.deploy") + } + + */ + if mythicEnv.GetBool("jupyter_bind_local_mount") { + pStruct["volumes"] = []string{ + "./jupyter-docker/jupyter:/projects", + } + } else { + pStruct["volumes"] = []string{ + "mythic_jupyter_volume:/projects", + } + } + if _, ok := volumes["mythic_jupyter"]; !ok { + volumes["mythic_jupyter_volume"] = map[string]interface{}{ + "name": "mythic_jupyter_volume", + } + } + case "mythic_server": + pStruct["build"] = map[string]interface{}{ + "context": "./mythic-docker", + "args": config.GetBuildArguments(), + } + pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SERVER_CPUS") + if mythicEnv.GetString("mythic_server_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("mythic_server_mem_limit") + } + environment := []string{ + "POSTGRES_HOST=${POSTGRES_HOST}", + "POSTGRES_PORT=${POSTGRES_PORT}", + "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}", + "RABBITMQ_HOST=${RABBITMQ_HOST}", + "RABBITMQ_PORT=${RABBITMQ_PORT}", + "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", + "JWT_SECRET=${JWT_SECRET}", + "DEBUG_LEVEL=${DEBUG_LEVEL}", + "MYTHIC_DEBUG_AGENT_MESSAGE=${MYTHIC_DEBUG_AGENT_MESSAGE}", + "MYTHIC_ADMIN_PASSWORD=${MYTHIC_ADMIN_PASSWORD}", + "MYTHIC_ADMIN_USER=${MYTHIC_ADMIN_USER}", + "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", + "MYTHIC_SERVER_BIND_LOCALHOST_ONLY=${MYTHIC_SERVER_BIND_LOCALHOST_ONLY}", + "MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT}", + "ALLOWED_IP_BLOCKS=${ALLOWED_IP_BLOCKS}", + "DEFAULT_OPERATION_NAME=${DEFAULT_OPERATION_NAME}", + "DEFAULT_OPERATION_WEBHOOK_URL=${DEFAULT_OPERATION_WEBHOOK_URL}", + "DEFAULT_OPERATION_WEBHOOK_CHANNEL=${DEFAULT_OPERATION_WEBHOOK_CHANNEL}", + "NGINX_PORT=${NGINX_PORT}", + "NGINX_HOST=${NGINX_HOST}", + "MYTHIC_SERVER_DYNAMIC_PORTS=${MYTHIC_SERVER_DYNAMIC_PORTS}", + } + mythicServerPorts := []string{ + "${MYTHIC_SERVER_PORT}:${MYTHIC_SERVER_PORT}", + "${MYTHIC_SERVER_GRPC_PORT}:${MYTHIC_SERVER_GRPC_PORT}", + } + if mythicEnv.GetBool("MYTHIC_SERVER_BIND_LOCALHOST_ONLY") { + mythicServerPorts = []string{ + "127.0.0.1:${MYTHIC_SERVER_PORT}:${MYTHIC_SERVER_PORT}", + "127.0.0.1:${MYTHIC_SERVER_GRPC_PORT}:${MYTHIC_SERVER_GRPC_PORT}", + } + } + dynamicPortPieces := strings.Split(mythicEnv.GetString("MYTHIC_SERVER_DYNAMIC_PORTS"), ",") + for _, val := range dynamicPortPieces { + if mythicEnv.GetBool("mythic_server_dynamic_ports_bind_localhost_only") { + mythicServerPorts = append(mythicServerPorts, fmt.Sprintf("127.0.0.1:%s:%s", val, val)) + } else { + mythicServerPorts = append(mythicServerPorts, fmt.Sprintf("%s:%s", val, val)) + } + + } + pStruct["ports"] = mythicServerPorts + if _, ok := pStruct["environment"]; ok { + pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + } else { + pStruct["environment"] = environment + } + if mythicEnv.GetBool("mythic_server_bind_local_mount") { + pStruct["volumes"] = []string{ + "./mythic-docker/src:/usr/src/app", + } + } else { + pStruct["volumes"] = []string{ + "mythic_server_volume:/usr/src/app", + } + } + if _, ok := volumes["mythic_server"]; !ok { + volumes["mythic_server_volume"] = map[string]interface{}{ + "name": "mythic_server_volume", + } + } + case "mythic_sync": + if absPath, err := filepath.Abs(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service)); err != nil { + fmt.Printf("[-] Failed to get abs path for mythic_sync\n") + return + } else { + pStruct["build"] = map[string]interface{}{ + "context": absPath, + "args": config.GetBuildArguments(), + } + pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SYNC_CPUS") + if mythicEnv.GetString("mythic_sync_mem_limit") != "" { + pStruct["mem_limit"] = mythicEnv.GetString("mythic_sync_mem_limit") + } + pStruct["environment"] = []string{ + "MYTHIC_IP=${NGINX_HOST}", + "MYTHIC_PORT=${NGINX_PORT}", + "MYTHIC_USERNAME=${MYTHIC_ADMIN_USER}", + "MYTHIC_PASSWORD=${MYTHIC_ADMIN_PASSWORD}", + "MYTHIC_API_KEY=${MYTHIC_API_KEY}", + "GHOSTWRITER_API_KEY=${GHOSTWRITER_API_KEY}", + "GHOSTWRITER_URL=${GHOSTWRITER_URL}", + "GHOSTWRITER_OPLOG_ID=${GHOSTWRITER_OPLOG_ID}", + } + if !mythicEnv.InConfig("GHOSTWRITER_API_KEY") { + config.AskVariable("Please enter your GhostWriter API Key", "GHOSTWRITER_API_KEY") + } + if !mythicEnv.InConfig("GHOSTWRITER_URL") { + config.AskVariable("Please enter your GhostWriter URL", "GHOSTWRITER_URL") + } + if !mythicEnv.InConfig("GHOSTWRITER_OPLOG_ID") { + config.AskVariable("Please enter your GhostWriter OpLog ID", "GHOSTWRITER_OPLOG_ID") + } + if !mythicEnv.InConfig("MYTHIC_API_KEY") { + config.AskVariable("Please enter your Mythic API Key (optional)", "MYTHIC_API_KEY") + } + } + } + manager.GetManager().SetVolumes(volumes) + _ = manager.GetManager().SetServiceConfiguration(service, pStruct) +} +func Add3rdPartyService(service string, additionalConfigs map[string]interface{}) error { + existingConfig, _ := manager.GetManager().GetServiceConfiguration(service) + if _, ok := existingConfig["environment"]; !ok { + existingConfig["environment"] = []string{} + } + pStruct := map[string]interface{}{ + "labels": map[string]string{ + "name": service, + }, + "image": strings.ToLower(service), + "hostname": service, + "logging": map[string]interface{}{ + "driver": "json-file", + "options": map[string]string{ + "max-file": "1", + "max-size": "10m", + }, + }, + "restart": "always", + "container_name": strings.ToLower(service), + "cpus": config.GetMythicEnv().GetInt("INSTALLED_SERVICE_CPUS"), + } + if config.GetMythicEnv().GetString("installed_service_mem_limit") != "" { + pStruct["mem_limit"] = config.GetMythicEnv().GetString("installed_service_mem_limit") + } + for key, element := range additionalConfigs { + pStruct[key] = element + } + pStruct["build"] = map[string]interface{}{ + "context": manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), + "args": config.GetBuildArguments(), + } + pStruct["network_mode"] = "host" + pStruct["extra_hosts"] = []string{ + "mythic_server:127.0.0.1", + "mythic_rabbitmq:127.0.0.1", + } + environment := []string{ + "MYTHIC_ADDRESS=http://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/agent_message", + "MYTHIC_WEBSOCKET=ws://${MYTHIC_SERVER_HOST}:${MYTHIC_SERVER_PORT}/ws/agent_message", + "RABBITMQ_USER=${RABBITMQ_USER}", + "RABBITMQ_PASSWORD=${RABBITMQ_PASSWORD}", + "RABBITMQ_PORT=${RABBITMQ_PORT}", + "RABBITMQ_HOST=${RABBITMQ_HOST}", + "MYTHIC_SERVER_HOST=${MYTHIC_SERVER_HOST}", + "MYTHIC_SERVER_PORT=${MYTHIC_SERVER_PORT}", + "MYTHIC_SERVER_GRPC_PORT=${MYTHIC_SERVER_GRPC_PORT}", + "WEBHOOK_DEFAULT_URL=${WEBHOOK_DEFAULT_URL}", + "WEBHOOK_DEFAULT_CALLBACK_CHANNEL=${WEBHOOK_DEFAULT_CALLBACK_CHANNEL}", + "WEBHOOK_DEFAULT_FEEDBACK_CHANNEL=${WEBHOOK_DEFAULT_FEEDBACK_CHANNEL}", + "WEBHOOK_DEFAULT_STARTUP_CHANNEL=${WEBHOOK_DEFAULT_STARTUP_CHANNEL}", + "WEBHOOK_DEFAULT_ALERT_CHANNEL=${WEBHOOK_DEFAULT_ALERT_CHANNEL}", + "WEBHOOK_DEFAULT_CUSTOM_CHANNEL=${WEBHOOK_DEFAULT_CUSTOM_CHANNEL}", + "DEBUG_LEVEL=${DEBUG_LEVEL}", + } + if _, ok := pStruct["environment"]; ok { + pStruct["environment"] = utils.UpdateEnvironmentVariables(existingConfig["environment"].([]string), environment) + } else { + pStruct["environment"] = environment + } + // only add in volumes if some aren't already listed + if _, ok := pStruct["volumes"]; !ok { + pStruct["volumes"] = []string{ + manager.GetManager().GetPathTo3rdPartyServicesOnDisk() + ":/Mythic/", + } + } + return manager.GetManager().SetServiceConfiguration(service, pStruct) +} +func RemoveService(service string) error { + return manager.GetManager().RemoveServices([]string{service}) +} + +func Initialize() { + manager.GetManager().GenerateRequiredConfig() + // based on .env, find out which mythic services are supposed to be running and add them to docker compose + intendedMythicContainers, _ := config.GetIntendedMythicServiceNames() + for _, container := range intendedMythicContainers { + AddMythicService(container) + } + if !manager.GetManager().CheckRequiredManagerVersion() { + log.Fatalf("[-] Bad %s version\n", manager.GetManager().GetManagerName()) + } +} diff --git a/Mythic_CLI/src/cmd/internal/testServices.go b/Mythic_CLI/src/cmd/internal/testServices.go index e1b91158f..4fcc5fd5c 100644 --- a/Mythic_CLI/src/cmd/internal/testServices.go +++ b/Mythic_CLI/src/cmd/internal/testServices.go @@ -3,13 +3,13 @@ package internal import ( "context" "crypto/tls" - "encoding/binary" "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/manager" "github.com/docker/docker/api/types" "github.com/docker/docker/client" "github.com/streadway/amqp" "log" - "net" "net/http" "os" "path/filepath" @@ -20,27 +20,9 @@ import ( "time" ) -func imageExists(containerName string) bool { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Fatalf("Failed to get client in GetLogs: %v", err) - } - desiredImage := fmt.Sprintf("%v:latest", strings.ToLower(containerName)) - images, err := cli.ImageList(context.Background(), types.ImageListOptions{All: true}) - if err != nil { - log.Fatalf("Failed to get container list: %v", err) - } - for _, image := range images { - for _, name := range image.RepoTags { - if name == desiredImage { - return true - } - } - } - return false -} func TestMythicConnection() { webAddress := "127.0.0.1" + mythicEnv := config.GetMythicEnv() if mythicEnv.GetString("NGINX_HOST") == "mythic_nginx" { if mythicEnv.GetBool("NGINX_USE_SSL") { webAddress = "https://127.0.0.1" @@ -58,41 +40,42 @@ func TestMythicConnection() { sleepTime := int64(10) count := make([]int, maxCount) http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true} - fmt.Printf("[*] Waiting for Mythic Server and Nginx to come online (Retry Count = %d)\n", maxCount) + log.Printf("[*] Waiting for Mythic Server and Nginx to come online (Retry Count = %d)\n", maxCount) for i := range count { - fmt.Printf("[*] Attempting to connect to Mythic UI at %s:%d, attempt %d/%d\n", webAddress, mythicEnv.GetInt("NGINX_PORT"), i+1, maxCount) + log.Printf("[*] Attempting to connect to Mythic UI at %s:%d, attempt %d/%d\n", webAddress, mythicEnv.GetInt("NGINX_PORT"), i+1, maxCount) resp, err := http.Get(webAddress + ":" + strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))) if err != nil { - fmt.Printf("[-] Failed to make connection to host, retrying in %ds\n", sleepTime) - fmt.Printf("%v\n", err) + log.Printf("[-] Failed to make connection to host, retrying in %ds\n", sleepTime) + log.Printf("%v\n", err) } else { - defer resp.Body.Close() + resp.Body.Close() if resp.StatusCode == 200 || resp.StatusCode == 404 { - fmt.Printf("[+] Successfully connected to Mythic at " + webAddress + ":" + strconv.Itoa(mythicEnv.GetInt("NGINX_PORT")) + "\n\n") + log.Printf("[+] Successfully connected to Mythic at " + webAddress + ":" + strconv.Itoa(mythicEnv.GetInt("NGINX_PORT")) + "\n\n") return } else if resp.StatusCode == 502 || resp.StatusCode == 504 { - fmt.Printf("[-] Nginx is up, but waiting for Mythic Server, retrying connection in %ds\n", sleepTime) + log.Printf("[-] Nginx is up, but waiting for Mythic Server, retrying connection in %ds\n", sleepTime) } else { - fmt.Printf("[-] Connection failed with HTTP Status Code %d, retrying in %ds\n", resp.StatusCode, sleepTime) + log.Printf("[-] Connection failed with HTTP Status Code %d, retrying in %ds\n", resp.StatusCode, sleepTime) } } time.Sleep(time.Duration(sleepTime) * time.Second) } - fmt.Printf("[-] Failed to make connection to Mythic Server\n") - fmt.Printf(" This could be due to limited resources on the host (recommended at least 2CPU and 4GB RAM)\n") - fmt.Printf(" If there is an issue with Mythic server, use 'mythic-cli logs mythic_server' to view potential errors\n") + log.Printf("[-] Failed to make connection to Mythic Server\n") + log.Printf(" This could be due to limited resources on the host (recommended at least 2CPU and 4GB RAM)\n") + log.Printf(" If there is an issue with Mythic server, use 'mythic-cli logs mythic_server' to view potential errors\n") Status(false) - fmt.Printf("[*] Fetching logs from mythic_server now:\n") + log.Printf("[*] Fetching logs from mythic_server now:\n") GetLogs("mythic_server", "500") os.Exit(1) } func TestMythicRabbitmqConnection() { rabbitmqAddress := "127.0.0.1" + mythicEnv := config.GetMythicEnv() rabbitmqPort := mythicEnv.GetString("RABBITMQ_PORT") if mythicEnv.GetString("RABBITMQ_HOST") != "mythic_rabbitmq" && mythicEnv.GetString("RABBITMQ_HOST") != "127.0.0.1" { rabbitmqAddress = mythicEnv.GetString("RABBITMQ_HOST") } - if rabbitmqAddress == "127.0.0.1" && !isServiceRunning("mythic_rabbitmq") { + if rabbitmqAddress == "127.0.0.1" && !manager.GetManager().IsServiceRunning("mythic_rabbitmq") { log.Printf("[-] Service mythic_rabbitmq should be running on the host, but isn't. Containers will be unable to connect.\nStart it by starting Mythic ('sudo ./mythic-cli mythic start') or manually with 'sudo ./mythic-cli mythic start mythic_rabbitmq'\n") return } @@ -100,21 +83,21 @@ func TestMythicRabbitmqConnection() { var err error count := make([]int, maxCount) sleepTime := int64(10) - fmt.Printf("[*] Waiting for RabbitMQ to come online (Retry Count = %d)\n", maxCount) + log.Printf("[*] Waiting for RabbitMQ to come online (Retry Count = %d)\n", maxCount) for i := range count { - fmt.Printf("[*] Attempting to connect to RabbitMQ at %s:%s, attempt %d/%d\n", rabbitmqAddress, rabbitmqPort, i+1, maxCount) + log.Printf("[*] Attempting to connect to RabbitMQ at %s:%s, attempt %d/%d\n", rabbitmqAddress, rabbitmqPort, i+1, maxCount) conn, err := amqp.Dial(fmt.Sprintf("amqp://%s:%s@%s:%s/mythic_vhost", mythicEnv.GetString("RABBITMQ_USER"), mythicEnv.GetString("RABBITMQ_PASSWORD"), rabbitmqAddress, rabbitmqPort)) if err != nil { - fmt.Printf("[-] Failed to connect to RabbitMQ, retrying in %ds\n", sleepTime) + log.Printf("[-] Failed to connect to RabbitMQ, retrying in %ds\n", sleepTime) time.Sleep(10 * time.Second) } else { conn.Close() - fmt.Printf("[+] Successfully connected to RabbitMQ at amqp://%s:***@%s:%s/mythic_vhost\n\n", mythicEnv.GetString("RABBITMQ_USER"), rabbitmqAddress, rabbitmqPort) + log.Printf("[+] Successfully connected to RabbitMQ at amqp://%s:***@%s:%s/mythic_vhost\n\n", mythicEnv.GetString("RABBITMQ_USER"), rabbitmqAddress, rabbitmqPort) return } } - fmt.Printf("[-] Failed to make a connection to the RabbitMQ server: %v\n", err) - if isServiceRunning("mythic_rabbitmq") { + log.Printf("[-] Failed to make a connection to the RabbitMQ server: %v\n", err) + if manager.GetManager().IsServiceRunning("mythic_rabbitmq") { log.Printf(" The mythic_rabbitmq service is running, but mythic-cli is unable to connect\n") } else { if rabbitmqAddress == "127.0.0.1" { @@ -126,76 +109,12 @@ func TestMythicRabbitmqConnection() { } } func TestPorts() error { - // go through the different services in mythicEnv and check to make sure their ports aren't already used by trying to open them - //MYTHIC_SERVER_HOST:MYTHIC_SERVER_PORT - //POSTGRES_HOST:POSTGRES_PORT - //HASURA_HOST:HASURA_PORT - //RABBITMQ_HOST:RABBITMQ_PORT - //DOCUMENTATION_HOST:DOCUMENTATION_PORT - //NGINX_HOST:NGINX_PORT - portChecks := map[string][]string{ - "MYTHIC_SERVER_HOST": { - "MYTHIC_SERVER_PORT", - "mythic_server", - }, - "POSTGRES_HOST": { - "POSTGRES_PORT", - "mythic_postgres", - }, - "HASURA_HOST": { - "HASURA_PORT", - "mythic_graphql", - }, - "RABBITMQ_HOST": { - "RABBITMQ_PORT", - "mythic_rabbitmq", - }, - "DOCUMENTATION_HOST": { - "DOCUMENTATION_PORT", - "mythic_documentation", - }, - "NGINX_HOST": { - "NGINX_PORT", - "mythic_nginx", - }, - "MYTHIC_REACT_HOST": { - "MYTHIC_REACT_PORT", - "mythic_react", - }, - "JUPYTER_HOST": { - "JUPYTER_PORT", - "mythic_jupyter", - }, - } - var addServices []string - var removeServices []string - if mythicEnv.GetBool("postgres_debug") { - addServices = append(addServices, "mythic_grafana", "mythic_prometheus", "mythic_postgres_exporter") - } - for key, val := range portChecks { - if mythicEnv.GetString(key) == val[1] || mythicEnv.GetString(key) == "127.0.0.1" { - addServices = append(addServices, val[1]) - p, err := net.Listen("tcp", ":"+strconv.Itoa(mythicEnv.GetInt(val[0]))) - if err != nil { - fmt.Printf("[-] Port %d, from variable %s, appears to already be in use: %v\n", mythicEnv.GetInt(val[0]), key, err) - return err - } - err = p.Close() - if err != nil { - fmt.Printf("[-] Failed to close connection: %v\n", err) - return err - } - } else { - removeServices = append(removeServices, val[1]) - } - } - if mythicEnv.GetBool("postgres_debug") { - addServices = append(addServices, "mythic_grafana", "mythic_prometheus", "mythic_postgres_exporter") - } + manager.GetManager().TestPorts() return nil } func PrintMythicConnectionInfo() { w := new(tabwriter.Writer) + mythicEnv := config.GetMythicEnv() w.Init(os.Stdout, 0, 8, 2, '\t', 0) fmt.Fprintln(w, "MYTHIC SERVICE\tWEB ADDRESS\tBOUND LOCALLY") if mythicEnv.GetString("NGINX_HOST") == "mythic_nginx" { @@ -404,45 +323,11 @@ func Status(verbose bool) { fmt.Printf(" Use 'sudo ./mythic-cli config service' for configs for these services.\n") } func GetLogs(containerName string, numLogs string) { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + logCount, err := strconv.Atoi(numLogs) if err != nil { - log.Fatalf("Failed to get client in GetLogs: %v", err) - } - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) - if err != nil { - log.Fatalf("Failed to get container list: %v", err) - } - if len(containers) > 0 { - found := false - for _, container := range containers { - if container.Labels["name"] == containerName { - found = true - reader, err := cli.ContainerLogs(context.Background(), container.ID, types.ContainerLogsOptions{ - ShowStdout: true, - ShowStderr: true, - Tail: numLogs, - }) - if err != nil { - log.Fatalf("Failed to get container GetLogs: %v", err) - } - // awesome post about the leading 8 payload/header bytes: https://medium.com/@dhanushgopinath/reading-docker-container-logs-with-golang-docker-engine-api-702233fac044 - p := make([]byte, 8) - _, err = reader.Read(p) - for err == nil { - content := make([]byte, binary.BigEndian.Uint32(p[4:])) - reader.Read(content) - fmt.Printf("%s", content) - _, err = reader.Read(p) - } - reader.Close() - } - } - if !found { - fmt.Println("[-] Failed to find that container") - } - } else { - fmt.Println("[-] No containers running") + log.Fatalf("[-] Bad log count: %v\n", err) } + manager.GetManager().GetLogs(containerName, logCount) } func ListServices() { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) @@ -461,7 +346,7 @@ func ListServices() { sort.Slice(containers[:], func(i, j int) bool { return containers[i].Labels["name"] < containers[j].Labels["name"] }) - elementsOnDisk, err := getElementsOnDisk() + elementsOnDisk, err := manager.GetManager().GetInstalled3rdPartyServicesOnDisk() if err != nil { log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) } diff --git a/Mythic_CLI/src/cmd/internal/utils.go b/Mythic_CLI/src/cmd/internal/utils.go index a1ad25032..9d87abd69 100644 --- a/Mythic_CLI/src/cmd/internal/utils.go +++ b/Mythic_CLI/src/cmd/internal/utils.go @@ -2,7 +2,6 @@ package internal import ( "archive/tar" - "bufio" "bytes" "crypto/ecdsa" "crypto/elliptic" @@ -11,175 +10,17 @@ import ( "crypto/x509/pkix" "encoding/pem" "fmt" - "golang.org/x/mod/semver" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" "io" - "io/ioutil" "log" "math/big" "os" - "path" "path/filepath" "strings" "time" ) -func generateRandomPassword(pwLength int) string { - chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") - var b strings.Builder - for i := 0; i < pwLength; i++ { - nBig, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars)))) - if err != nil { - log.Fatalf("[-] Failed to generate random number for password generation\n") - } - b.WriteRune(chars[nBig.Int64()]) - } - return b.String() -} -func getCwdFromExe() string { - exe, err := os.Executable() - if err != nil { - log.Fatalf("[-] Failed to get path to current executable\n") - } - return filepath.Dir(exe) -} -func stringInSlice(value string, list []string) bool { - for _, e := range list { - if e == value { - return true - } - } - return false -} -func RemoveStringFromSliceNoOrder(source []string, str string) []string { - - for index, value := range source { - if str == value { - source[index] = source[len(source)-1] - source[len(source)-1] = "" - source = source[:len(source)-1] - return source - } - } - // we didn't find the element to remove - return source -} - -// https://golangcode.com/check-if-a-file-exists/ -func fileExists(path string) bool { - info, err := os.Stat(path) - if err != nil { - if os.IsNotExist(err) { - return false - } - } - return !info.IsDir() -} - -// https://golangcode.com/check-if-a-file-exists/ -func dirExists(path string) bool { - info, err := os.Stat(path) - if err != nil { - if os.IsNotExist(err) { - return false - } - } - return info.IsDir() -} - -// https://blog.depa.do/post/copy-files-and-directories-in-go -func copyFile(src, dst string) error { - var err error - var srcfd *os.File - var dstfd *os.File - var srcinfo os.FileInfo - - if srcfd, err = os.Open(src); err != nil { - return err - } - defer srcfd.Close() - - if dstfd, err = os.Create(dst); err != nil { - return err - } - defer dstfd.Close() - - if _, err = io.Copy(dstfd, srcfd); err != nil { - return err - } - if srcinfo, err = os.Stat(src); err != nil { - return err - } - return os.Chmod(dst, srcinfo.Mode()) -} - -// https://blog.depa.do/post/copy-files-and-directories-in-go -func copyDir(src string, dst string) error { - var err error - var fds []os.FileInfo - var srcinfo os.FileInfo - - if srcinfo, err = os.Stat(src); err != nil { - return err - } - - if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil { - return err - } - - if fds, err = ioutil.ReadDir(src); err != nil { - return err - } - for _, fd := range fds { - srcfp := path.Join(src, fd.Name()) - dstfp := path.Join(dst, fd.Name()) - - if fd.IsDir() { - if err = copyDir(srcfp, dstfp); err != nil { - fmt.Println(err) - } - } else { - if err = copyFile(srcfp, dstfp); err != nil { - fmt.Println(err) - } - } - } - return nil -} - -// https://gist.github.com/r0l1/3dcbb0c8f6cfe9c66ab8008f55f8f28b -func askConfirm(prompt string) bool { - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("%s [y/n]: ", prompt) - input, err := reader.ReadString('\n') - if err != nil { - fmt.Printf("[-] Failed to read user input\n") - return false - } - input = strings.ToLower(strings.TrimSpace(input)) - if input == "y" || input == "yes" { - return true - } else if input == "n" || input == "no" { - return false - } - } -} - -// https://gist.github.com/r0l1/3dcbb0c8f6cfe9c66ab8008f55f8f28b -func askVariable(prompt string) string { - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("%s: ", prompt) - input, err := reader.ReadString('\n') - if err != nil { - fmt.Printf("[-] Failed to read user input\n") - return "" - } - input = strings.TrimSpace(input) - return input - } -} - // code to generate self-signed certs pulled from github.com/kabukky/httpscerts // and from http://golang.org/src/crypto/tls/generate_cert.go. // only modifications were to use a specific elliptic curve cipher @@ -192,16 +33,16 @@ func checkCerts(certPath string, keyPath string) error { return nil } func generateCerts() error { - if !dirExists(filepath.Join(getCwdFromExe(), "nginx-docker", "ssl")) { - err := os.MkdirAll(filepath.Join(getCwdFromExe(), "nginx-docker", "ssl"), os.ModePerm) + if !utils.DirExists(filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "ssl")) { + err := os.MkdirAll(filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "ssl"), os.ModePerm) if err != nil { fmt.Printf("[-] Failed to make ssl folder in nginx-docker folder\n") return err } fmt.Printf("[+] Successfully made ssl folder in nginx-docker folder\n") } - certPath := filepath.Join(getCwdFromExe(), "nginx-docker", "ssl", "mythic-cert.crt") - keyPath := filepath.Join(getCwdFromExe(), "nginx-docker", "ssl", "mythic-ssl.key") + certPath := filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "ssl", "mythic-cert.crt") + keyPath := filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "ssl", "mythic-ssl.key") if checkCerts(certPath, keyPath) == nil { return nil } @@ -262,68 +103,27 @@ func generateCerts() error { // generate allow/block lists for nginx from environment variables func updateNginxBlockLists() { - ipString := mythicEnv.GetString("allowed_ip_blocks") + ipString := config.GetMythicEnv().GetString("allowed_ip_blocks") ipList := strings.Split(ipString, ",") outputString := "" for _, ip := range ipList { outputString += fmt.Sprintf("allow %s;\n", ip) } outputString += "deny all;" - if mythicEnv.GetBool("nginx_bind_local_mount") { - ipFilePath := filepath.Join(getCwdFromExe(), "nginx-docker", "config", "blockips.conf") + if config.GetMythicEnv().GetBool("nginx_bind_local_mount") { + ipFilePath := filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "config", "blockips.conf") if err := os.WriteFile(ipFilePath, []byte(outputString), 0600); err != nil { - fmt.Printf("[-] Failed to write out block list file: %v\n", err) - os.Exit(1) + log.Fatalf("[-] Failed to write out block list file: %v\n", err) } } else { err := moveStringToVolume("mythic_nginx_volume_config", ".", "blockips.conf", outputString) if err != nil { - fmt.Printf("[-] Failed to write out block list file: %v\n", err) - os.Exit(1) + log.Fatalf("[-] Failed to write out block list file: %v\n", err) } } } -// check docker version to make sure it's high enough for Mythic's features -func checkDockerVersion() bool { - if outputString, err := runDocker([]string{"version", "--format", "{{.Server.Version}}"}); err != nil { - fmt.Printf("[-] Failed to get docker version\n") - return false - } else if !semver.IsValid("v" + outputString) { - fmt.Printf("[-] Invalid version string: %s\n", outputString) - return false - } else if semver.Compare("v"+outputString, "v20.10.22") >= 0 { - return true - } else { - fmt.Printf("[-] Docker version is too old, %s, for Mythic. Please update\n", outputString) - return false - } -} - -func generateSavedImageFolder() error { - savedImagePath := filepath.Join(getCwdFromExe(), "saved_images") - if dirExists(savedImagePath) { - return nil - } else { - return os.MkdirAll(savedImagePath, 0755) - } -} - -func ByteCountSI(b int64) string { - const unit = 1000 - if b < unit { - return fmt.Sprintf("%d B", b) - } - div, exp := int64(unit), 0 - for n := b / unit; n >= unit; n /= unit { - div *= unit - exp++ - } - return fmt.Sprintf("%.1f %cB", - float64(b)/float64(div), "kMGTPE"[exp]) -} - func tarFileToBytes(sourceName string) (*bytes.Buffer, error) { source, err := os.Open(sourceName) if err != nil { diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go new file mode 100644 index 000000000..0a8c6af2e --- /dev/null +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -0,0 +1,783 @@ +package manager + +import ( + "bufio" + "context" + "encoding/binary" + "errors" + "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "github.com/docker/docker/api/types" + "github.com/docker/docker/client" + "github.com/spf13/viper" + "golang.org/x/mod/semver" + "gopkg.in/yaml.v3" + "io" + "log" + "net" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "sync" +) + +type DockerComposeManager struct { + InstalledServicesPath string + InstalledServicesFolder string +} + +// Interface Necessary commands + +func (d *DockerComposeManager) GetManagerName() string { + return "docker" +} + +// GenerateRequiredConfig ensure that the docker-compose.yml file exists +func (d *DockerComposeManager) GenerateRequiredConfig() { + groupNameConfig := viper.New() + groupNameConfig.SetConfigName("docker-compose") + groupNameConfig.SetConfigType("yaml") + groupNameConfig.AddConfigPath(utils.GetCwdFromExe()) + if err := groupNameConfig.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + log.Printf("[-] Error while reading in docker-compose file: %s\n", err) + if _, err := os.Create("docker-compose.yml"); err != nil { + log.Fatalf("[-] Failed to create docker-compose.yml file: %v\n", err) + } else { + if err := groupNameConfig.ReadInConfig(); err != nil { + log.Printf("[-] Failed to read in new docker-compose.yml file: %v\n", err) + } else { + log.Printf("[+] Successfully created new docker-compose.yml file.\n") + } + return + } + } else { + log.Fatalf("[-] Error while parsing docker-compose file: %s", err) + } + } +} + +// IsServiceRunning use Docker API to check running container list for the specified name +func (d *DockerComposeManager) IsServiceRunning(service string) bool { + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("[-] Failed to get client connection to Docker: %v", err) + } + containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ + All: true, + }) + if err != nil { + log.Fatalf("[-] Failed to get container list from Docker: %v", err) + } + if len(containers) > 0 { + for _, container := range containers { + if container.Labels["name"] == strings.ToLower(service) { + return true + } + } + } + return false +} + +// DoesImageExist use Docker API to check existing images for the specified name +func (d *DockerComposeManager) DoesImageExist(service string) bool { + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("Failed to get client in GetLogs: %v", err) + } + desiredImage := fmt.Sprintf("%v:latest", strings.ToLower(service)) + images, err := cli.ImageList(context.Background(), types.ImageListOptions{All: true}) + if err != nil { + log.Fatalf("Failed to get container list: %v", err) + } + for _, image := range images { + for _, name := range image.RepoTags { + if name == desiredImage { + return true + } + } + } + return false +} + +// RemoveImages deletes unused images that aren't tied to any running Docker containers +func (d *DockerComposeManager) RemoveImages() error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return err + } + defer cli.Close() + + images, err := cli.ImageList(ctx, types.ImageListOptions{}) + if err != nil { + log.Fatalf("[-] Failed to get list of images: %v\n", err) + } + + for _, image := range images { + if utils.StringInSlice(":", image.RepoTags) { + _, err = cli.ImageRemove(ctx, image.ID, types.ImageRemoveOptions{ + Force: true, + PruneChildren: true, + }) + if err != nil { + log.Printf("[-] Failed to remove unused image: %v\n", err) + } + } + } + return nil +} + +func (d *DockerComposeManager) RemoveContainers(services []string) error { + err := d.runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, services...)) + if err != nil { + return err + } + _, err = d.runDocker(append([]string{"rm", "-f"}, services...)) + if err != nil { + return err + } else { + return nil + } +} + +func (d *DockerComposeManager) SaveImages(services []string, outputPath string) error { + savedImagePath := filepath.Join(utils.GetCwdFromExe(), outputPath) + if !utils.DirExists(savedImagePath) { + err := os.MkdirAll(savedImagePath, 0755) + if err != nil { + log.Fatalf("[-] Failed to create output folder: %v\n", err) + } + } + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to connect to Docker: %v\n", err)) + } + savedContainers := services + if len(savedContainers) == 0 { + diskAgents, err := d.GetInstalled3rdPartyServicesOnDisk() + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to get agents on disk: %v\n", err)) + } + currentMythicServices, err := d.GetCurrentMythicServiceNames() + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to get mythic service list: %v\n", err)) + } + savedContainers = append([]string{}, diskAgents...) + savedContainers = append(savedContainers, currentMythicServices...) + + } + savedImagePath = filepath.Join(utils.GetCwdFromExe(), "saved_images", "mythic_save.tar") + finalSavedContainers := []string{} + for i, _ := range savedContainers { + if d.DoesImageExist(savedContainers[i]) { + containerName := fmt.Sprintf("%s:latest", savedContainers[i]) + finalSavedContainers = append(finalSavedContainers, containerName) + } else { + log.Printf("[-] No image locally for %s\n", savedContainers[i]) + } + } + log.Printf("[*] Saving the following images:\n%v\n", finalSavedContainers) + log.Printf("[*] This will take a while for Docker to compress and generate the layers...\n") + ioReadCloser, err := cli.ImageSave(context.Background(), finalSavedContainers) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to get contents of docker image: %v\n", err)) + } + outFile, err := os.Create(savedImagePath) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to create output file: %v\n", err)) + } + defer outFile.Close() + fmt.Printf("[*] Saving to %s\nThis will take a while...\n", savedImagePath) + _, err = io.Copy(outFile, ioReadCloser) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to write contents to file: %v\n", err)) + } + return nil +} + +func (d *DockerComposeManager) LoadImages(outputPath string) error { + savedImagePath := filepath.Join(utils.GetCwdFromExe(), outputPath, "mythic_save.tar") + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to connect to Docker: %v\n", err)) + } + ioReadCloser, err := os.OpenFile(savedImagePath, os.O_RDONLY, 0x600) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to read tar file: %v\n", err)) + } + _, err = cli.ImageLoad(context.Background(), ioReadCloser, false) + if err != nil { + return errors.New(fmt.Sprintf("[-] Failed to load image into Docker: %v\n", err)) + } + fmt.Printf("[+] loaded docker images!\n") + return nil + +} + +// CheckRequiredManagerVersion checks docker and docker-compose versions to make sure they're high enough +func (d *DockerComposeManager) CheckRequiredManagerVersion() bool { + outputString, err := d.runDocker([]string{"version", "--format", "{{.Server.Version}}"}) + if err != nil { + log.Printf("[-] Failed to get docker version\n") + return false + } + if !semver.IsValid("v" + outputString) { + log.Printf("[-] Invalid version string: %s\n", outputString) + return false + } + if semver.Compare("v"+outputString, "v20.10.22") >= 0 { + return true + } + log.Printf("[-] Docker version is too old, %s, for Mythic. Please update\n", outputString) + return false + +} + +// GetVolumes returns a dictionary of defined volume information from the docker-compose file. +// +// This is not looking up existing volume information at runtime. +func (d *DockerComposeManager) GetVolumes() (map[string]interface{}, error) { + curConfig := d.readInDockerCompose() + volumes := map[string]interface{}{} + if curConfig.InConfig("volumes") { + volumes = curConfig.GetStringMap("volumes") + } + return volumes, nil +} + +// SetVolumes sets a specific volume configuration into the docker-compose file. +func (d *DockerComposeManager) SetVolumes(volumes map[string]interface{}) { + curConfig := d.readInDockerCompose() + curConfig.Set("volumes", volumes) + err := d.setDockerComposeDefaultsAndWrite(curConfig) + if err != nil { + fmt.Printf("[-] Failed to update config: %v\n", err) + } +} + +// GetServiceConfiguration checks docker-compose to see if that service is defined or not and returns its config or a generic one +func (d *DockerComposeManager) GetServiceConfiguration(service string) (map[string]interface{}, error) { + curConfig := d.readInDockerCompose() + pStruct := map[string]interface{}{} + if curConfig.InConfig("services." + strings.ToLower(service)) { + pStruct = curConfig.GetStringMap("services." + strings.ToLower(service)) + delete(pStruct, "network_mode") + delete(pStruct, "extra_hosts") + delete(pStruct, "build") + delete(pStruct, "networks") + delete(pStruct, "command") + delete(pStruct, "healthcheck") + } else { + pStruct = map[string]interface{}{ + "logging": map[string]interface{}{ + "driver": "json-file", + "options": map[string]string{ + "max-file": "1", + "max-size": "10m", + }, + }, + "restart": "always", + "labels": map[string]string{ + "name": service, + }, + "container_name": service, + "image": service, + } + } + return pStruct, nil +} + +// SetServiceConfiguration sets a service configuration into docker-compose +func (d *DockerComposeManager) SetServiceConfiguration(service string, pStruct map[string]interface{}) error { + curConfig := d.readInDockerCompose() + if !curConfig.InConfig("services." + strings.ToLower(service)) { + curConfig.Set("services."+strings.ToLower(service), pStruct) + log.Printf("[+] Added %s to docker-compose\n", strings.ToLower(service)) + } else { + curConfig.Set("services."+strings.ToLower(service), pStruct) + } + err := d.setDockerComposeDefaultsAndWrite(curConfig) + if err != nil { + fmt.Printf("[-] Failed to update config: %v\n", err) + } + return err +} + +// GetPathTo3rdPartyServicesOnDisk returns to path on disk to where 3rd party services are installed +func (d *DockerComposeManager) GetPathTo3rdPartyServicesOnDisk() string { + return d.InstalledServicesFolder +} + +// StopServices stops certain containers that are running and optionally deletes the backing images +func (d *DockerComposeManager) StopServices(services []string, deleteImages bool) error { + dockerComposeContainers, err := d.GetAllExistingNonMythicServiceNames() + if err != nil { + return err + } + currentMythicServices, err := d.GetCurrentMythicServiceNames() + if err != nil { + return err + } + // in case somebody says "stop" but doesn't list containers, they mean everything + if len(services) == 0 { + services = append(dockerComposeContainers, currentMythicServices...) + } + /* + if utils.StringInSlice("mythic_react", services) { + if mythicEnv.GetBool("mythic_react_debug") { + // only need to remove the container if we're switching between debug and regular + if err = d.runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, "mythic_react")); err != nil { + fmt.Printf("[-] Failed to remove mythic_react\n") + return err + } + } + } + + */ + if deleteImages { + return d.runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, services...)) + } else { + return d.runDockerCompose(append([]string{"stop"}, services...)) + } + +} + +// RemoveServices removes certain container entries from the docker-compose +func (d *DockerComposeManager) RemoveServices(services []string) error { + curConfig := d.readInDockerCompose() + for _, service := range services { + if !utils.StringInSlice(service, config.MythicPossibleServices) { + if d.IsServiceRunning(service) { + _ = d.StopServices([]string{strings.ToLower(service)}, true) + + } + delete(curConfig.Get("services").(map[string]interface{}), strings.ToLower(service)) + log.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) + } + } + err := d.setDockerComposeDefaultsAndWrite(curConfig) + if err != nil { + log.Printf("[-] Failed to update config: %v\n", err) + return err + } else { + log.Println("[+] Successfully updated docker-compose.yml") + } + return nil +} + +// StartServices kicks off docker/docker-compose for the specified services +func (d *DockerComposeManager) StartServices(services []string, rebuildOnStart bool) error { + + if rebuildOnStart { + err := d.runDockerCompose(append([]string{"up", "--build", "-d"}, services...)) + if err != nil { + return err + } + } else { + var needToBuild []string + var alreadyBuilt []string + for _, val := range services { + if !d.DoesImageExist(val) { + needToBuild = append(needToBuild, val) + } else { + alreadyBuilt = append(alreadyBuilt, val) + } + } + if len(needToBuild) > 0 { + if err := d.runDockerCompose(append([]string{"up", "--build", "-d"}, needToBuild...)); err != nil { + return err + } + } + if len(alreadyBuilt) > 0 { + if err := d.runDockerCompose(append([]string{"up", "-d"}, alreadyBuilt...)); err != nil { + return err + } + } + } + + return nil + +} + +// BuildServices rebuilds services images and creates containers based on those images +func (d *DockerComposeManager) BuildServices(services []string) error { + if len(services) == 0 { + return nil + } + + err := d.runDockerCompose(append([]string{"rm", "-s", "-v", "-f"}, services...)) + if err != nil { + return err + } + err = d.runDockerCompose(append([]string{"up", "--build", "-d"}, services...)) + if err != nil { + return err + } + return nil + +} + +// GetInstalled3rdPartyServicesOnDisk lists out the name of all 3rd party software installed on disk +func (d *DockerComposeManager) GetInstalled3rdPartyServicesOnDisk() ([]string, error) { + var agentsOnDisk []string + if !utils.DirExists(d.InstalledServicesFolder) { + if err := os.Mkdir(d.InstalledServicesFolder, 0775); err != nil { + return nil, err + } + } + if files, err := os.ReadDir(d.InstalledServicesFolder); err != nil { + log.Printf("[-] Failed to list contents of %s folder\n", d.InstalledServicesFolder) + return nil, err + } else { + for _, f := range files { + if f.IsDir() { + agentsOnDisk = append(agentsOnDisk, f.Name()) + } + } + } + return agentsOnDisk, nil +} + +func (d *DockerComposeManager) GetHealthCheck(services []string) { + for _, container := range services { + outputString, err := d.runDocker([]string{"inspect", "--format", "{{json .State.Health }}", container}) + if err != nil { + log.Printf("failed to check status: %s", err.Error()) + } else { + log.Printf("%s:\n%s\n\n", container, outputString) + } + } +} + +func (d *DockerComposeManager) BuildUI() error { + _, err := d.runDocker([]string{"exec", "mythic_react", "/bin/sh", "-c", "npm run react-build"}) + if err != nil { + log.Printf("[-] Failed to build new UI from MythicReactUI: %v\n", err) + } + return err +} + +func (d *DockerComposeManager) GetLogs(service string, logCount int) { + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("Failed to get client in GetLogs: %v", err) + } + containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{}) + if err != nil { + log.Fatalf("Failed to get container list: %v", err) + } + if len(containers) > 0 { + found := false + for _, container := range containers { + if container.Labels["name"] == service { + found = true + reader, err := cli.ContainerLogs(context.Background(), container.ID, types.ContainerLogsOptions{ + ShowStdout: true, + ShowStderr: true, + Tail: fmt.Sprintf("%d", logCount), + }) + if err != nil { + log.Fatalf("Failed to get container GetLogs: %v", err) + } + // awesome post about the leading 8 payload/header bytes: https://medium.com/@dhanushgopinath/reading-docker-container-logs-with-golang-docker-engine-api-702233fac044 + p := make([]byte, 8) + _, err = reader.Read(p) + for err == nil { + content := make([]byte, binary.BigEndian.Uint32(p[4:])) + reader.Read(content) + fmt.Printf("%s", content) + _, err = reader.Read(p) + } + reader.Close() + } + } + if !found { + log.Println("[-] Failed to find that container") + } + } else { + log.Println("[-] No containers running") + } +} + +func (d *DockerComposeManager) TestPorts() { + // go through the different services in mythicEnv and check to make sure their ports aren't already used by trying to open them + //MYTHIC_SERVER_HOST:MYTHIC_SERVER_PORT + //POSTGRES_HOST:POSTGRES_PORT + //HASURA_HOST:HASURA_PORT + //RABBITMQ_HOST:RABBITMQ_PORT + //DOCUMENTATION_HOST:DOCUMENTATION_PORT + //NGINX_HOST:NGINX_PORT + portChecks := map[string][]string{ + "MYTHIC_SERVER_HOST": { + "MYTHIC_SERVER_PORT", + "mythic_server", + }, + "POSTGRES_HOST": { + "POSTGRES_PORT", + "mythic_postgres", + }, + "HASURA_HOST": { + "HASURA_PORT", + "mythic_graphql", + }, + "RABBITMQ_HOST": { + "RABBITMQ_PORT", + "mythic_rabbitmq", + }, + "DOCUMENTATION_HOST": { + "DOCUMENTATION_PORT", + "mythic_documentation", + }, + "NGINX_HOST": { + "NGINX_PORT", + "mythic_nginx", + }, + "MYTHIC_REACT_HOST": { + "MYTHIC_REACT_PORT", + "mythic_react", + }, + "JUPYTER_HOST": { + "JUPYTER_PORT", + "mythic_jupyter", + }, + } + var addServices []string + var removeServices []string + mythicEnv := config.GetMythicEnv() + for key, val := range portChecks { + if mythicEnv.GetString(key) == val[1] || mythicEnv.GetString(key) == "127.0.0.1" { + addServices = append(addServices, val[1]) + p, err := net.Listen("tcp", ":"+strconv.Itoa(mythicEnv.GetInt(val[0]))) + if err != nil { + log.Fatalf("[-] Port %d, from variable %s, appears to already be in use: %v\n", mythicEnv.GetInt(val[0]), key, err) + } + err = p.Close() + if err != nil { + log.Printf("[-] Failed to close connection: %v\n", err) + } + } else { + removeServices = append(removeServices, val[1]) + } + } +} + +// Internal Support Commands +func (d *DockerComposeManager) getMythicEnvList() []string { + env := config.GetMythicEnv().AllSettings() + var envList []string + for key := range env { + val := config.GetMythicEnv().GetString(key) + if val != "" { + // prevent trying to append arrays or dictionaries to our environment list + //fmt.Println(strings.ToUpper(key), val) + envList = append(envList, strings.ToUpper(key)+"="+val) + } + } + envList = append(envList, os.Environ()...) + return envList +} +func (d *DockerComposeManager) getCwdFromExe() string { + exe, err := os.Executable() + if err != nil { + log.Fatalf("[-] Failed to get path to current executable\n") + } + return filepath.Dir(exe) +} +func (d *DockerComposeManager) runDocker(args []string) (string, error) { + lookPath, err := exec.LookPath("docker") + if err != nil { + log.Fatalf("[-] docker is not installed or available in the current PATH\n") + } + exe, err := os.Executable() + if err != nil { + log.Fatalf("[-] Failed to get lookPath to current executable\n") + } + exePath := filepath.Dir(exe) + command := exec.Command(lookPath, args...) + command.Dir = exePath + command.Env = d.getMythicEnvList() + stdout, err := command.StdoutPipe() + if err != nil { + log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") + } + stderr, err := command.StderrPipe() + if err != nil { + log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") + } + stdoutScanner := bufio.NewScanner(stdout) + stderrScanner := bufio.NewScanner(stderr) + outputString := "" + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + for stdoutScanner.Scan() { + outputString += stdoutScanner.Text() + } + wg.Done() + }() + go func() { + for stderrScanner.Scan() { + fmt.Printf("%s\n", stderrScanner.Text()) + } + wg.Done() + }() + err = command.Start() + if err != nil { + log.Fatalf("[-] Error trying to start docker: %v\n", err) + } + wg.Wait() + err = command.Wait() + if err != nil { + log.Printf("[-] Error from docker: %v\n", err) + log.Printf("[*] Docker command: %v\n", args) + return "", err + } + return outputString, nil +} +func (d *DockerComposeManager) runDockerCompose(args []string) error { + lookPath, err := exec.LookPath("docker-compose") + if err != nil { + lookPath, err = exec.LookPath("docker") + if err != nil { + log.Fatalf("[-] docker-compose and docker are not installed or available in the current PATH\n") + } else { + // adjust the current args for docker compose subcommand + args = append([]string{"compose"}, args...) + } + } + exe, err := os.Executable() + if err != nil { + log.Fatalf("[-] Failed to get lookPath to current executable\n") + } + exePath := filepath.Dir(exe) + command := exec.Command(lookPath, args...) + command.Dir = exePath + command.Env = d.getMythicEnvList() + + stdout, err := command.StdoutPipe() + if err != nil { + log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") + } + stderr, err := command.StderrPipe() + if err != nil { + log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") + } + + stdoutScanner := bufio.NewScanner(stdout) + stderrScanner := bufio.NewScanner(stderr) + wg := sync.WaitGroup{} + wg.Add(2) + go func() { + for stdoutScanner.Scan() { + fmt.Printf("%s\n", stdoutScanner.Text()) + } + wg.Done() + }() + go func() { + for stderrScanner.Scan() { + fmt.Printf("%s\n", stderrScanner.Text()) + } + wg.Done() + }() + err = command.Start() + if err != nil { + log.Fatalf("[-] Error trying to start docker-compose: %v\n", err) + } + wg.Wait() + err = command.Wait() + if err != nil { + fmt.Printf("[-] Error from docker-compose: %v\n", err) + fmt.Printf("[*] Docker compose command: %v\n", args) + return err + } + return nil +} +func (d *DockerComposeManager) setDockerComposeDefaultsAndWrite(curConfig *viper.Viper) error { + curConfig.Set("version", "2.4") + file := curConfig.ConfigFileUsed() + if len(file) == 0 { + file = "./docker-compose.yml" + } + configMap := curConfig.AllSettings() + ignoredKeys := []string{"networks"} + for _, key := range ignoredKeys { + delete(configMap, key) + } + + content, err := yaml.Marshal(configMap) + if err != nil { + return err + } + return os.WriteFile(file, content, 0644) +} +func (d *DockerComposeManager) readInDockerCompose() *viper.Viper { + var curConfig = viper.New() + curConfig.SetConfigName("docker-compose") + curConfig.SetConfigType("yaml") + curConfig.AddConfigPath(d.getCwdFromExe()) + if err := curConfig.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + log.Fatalf("[-] Error while reading in docker-compose file: %s\n", err) + } else { + log.Fatalf("[-] Error while parsing docker-compose file: %s\n", err) + } + } + return curConfig +} + +// GetAllExistingNonMythicServiceNames from reading in the docker-compose file, not necessarily what's running +func (d *DockerComposeManager) GetAllExistingNonMythicServiceNames() ([]string, error) { + // get all services that exist within the loaded config + groupNameConfig := viper.New() + groupNameConfig.SetConfigName("docker-compose") + groupNameConfig.SetConfigType("yaml") + groupNameConfig.AddConfigPath(utils.GetCwdFromExe()) + if err := groupNameConfig.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) + return []string{}, err + } else { + fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) + return []string{}, err + } + } + servicesSub := groupNameConfig.Sub("services") + services := servicesSub.AllSettings() + containerList := []string{} + for service := range services { + if !utils.StringInSlice(service, config.MythicPossibleServices) { + containerList = append(containerList, service) + } + } + return containerList, nil +} + +// GetCurrentMythicServiceNames from reading in the docker-compose file, not necessarily what should be there or what's running +func (d *DockerComposeManager) GetCurrentMythicServiceNames() ([]string, error) { + groupNameConfig := viper.New() + groupNameConfig.SetConfigName("docker-compose") + groupNameConfig.SetConfigType("yaml") + groupNameConfig.AddConfigPath(utils.GetCwdFromExe()) + if err := groupNameConfig.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) + return []string{}, err + } else { + fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) + return []string{}, err + } + } + servicesSub := groupNameConfig.Sub("services") + services := servicesSub.AllSettings() + containerList := []string{} + for service := range services { + if utils.StringInSlice(service, config.MythicPossibleServices) { + containerList = append(containerList, service) + } + } + return containerList, nil +} diff --git a/Mythic_CLI/src/cmd/manager/managerInterface.go b/Mythic_CLI/src/cmd/manager/managerInterface.go new file mode 100644 index 000000000..ed6097a55 --- /dev/null +++ b/Mythic_CLI/src/cmd/manager/managerInterface.go @@ -0,0 +1,71 @@ +package manager + +import ( + "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "path/filepath" +) + +type CLIManager interface { + // GetManagerName returns the human understandable name of the manager that's being used + GetManagerName() string + // IsServiceRunning checks if a service by the specified name is currently running or not + IsServiceRunning(service string) bool + // CheckRequiredManagerVersion checks if the version of the management software installed is a valid version or not + CheckRequiredManagerVersion() bool + // GenerateRequiredConfig creates any necessary base configuration files needed by the manager, like a docker-compose.yml file + GenerateRequiredConfig() + // DoesImageExist check if a local image exists for the service or if it needs to be built first + DoesImageExist(service string) bool + // RemoveImages deletes unused images from the system to help free up space + RemoveImages() error + // SaveImages saves off the backing built images for the specified services + SaveImages(services []string, outputPath string) error + // LoadImages loads the images specified at the outputPath + LoadImages(outputPath string) error + // RemoveContainers stop existing containers and removes them completely + RemoveContainers(services []string) error + // GetVolumes returns a map of volumes and their configurations specified to be used (not necessarily what's actually created) + GetVolumes() (map[string]interface{}, error) + // SetVolumes updates the information about volumes that should be expected to exist or tracked + SetVolumes(map[string]interface{}) + // GetServiceConfiguration gets the current configuration for a Mythic or 3rd party service + GetServiceConfiguration(string) (map[string]interface{}, error) + // SetServiceConfiguration sets the specified configuration for a Mythic or specified 3rd party service + SetServiceConfiguration(string, map[string]interface{}) error + // StopServices should stop the listed services from running + StopServices(services []string, deleteImages bool) error + // RemoveServices should stop and remove services from the configuration so that they aren't started again + RemoveServices(services []string) error + // StartServices should build images if needed and start the associated containers + StartServices(services []string, rebuildOnStart bool) error + // BuildServices should re-build specific images and start those new containers + BuildServices(services []string) error + // GetInstalled3rdPartyServicesOnDisk returns the names of the installed services on disk + GetInstalled3rdPartyServicesOnDisk() ([]string, error) + // GetAllExistingNonMythicServiceNames reads current configuration and returns all non-mythic services + GetAllExistingNonMythicServiceNames() ([]string, error) + // GetCurrentMythicServiceNames reads current configuration and returns all mythic services + GetCurrentMythicServiceNames() ([]string, error) + // GetPathTo3rdPartyServicesOnDisk returns the path where a 3rd party services Dockerfile lives on disk + GetPathTo3rdPartyServicesOnDisk() string + // GetHealthCheck returns the output from the health checks of the specified services + GetHealthCheck(services []string) + // BuildUI a new instance of the Mythic React UI and save it in the mythic-react-docker folder + BuildUI() error + // GetLogs fetches logCount of the most recent logs from the service container + GetLogs(service string, logCount int) + // TestPorts check to make sure all ports are available for services to use + TestPorts() +} + +var currentManager CLIManager + +func init() { + currentManager = &DockerComposeManager{ + InstalledServicesPath: "InstalledServices", + InstalledServicesFolder: filepath.Join(utils.GetCwdFromExe(), "InstalledServices"), + } +} +func GetManager() CLIManager { + return currentManager +} diff --git a/Mythic_CLI/src/cmd/removeContainer.go b/Mythic_CLI/src/cmd/removeContainer.go index 7bb67e12c..1dbd83ea0 100644 --- a/Mythic_CLI/src/cmd/removeContainer.go +++ b/Mythic_CLI/src/cmd/removeContainer.go @@ -18,7 +18,7 @@ func init() { } func removeContainer(cmd *cobra.Command, args []string) { - if err := internal.DockerRemoveContainers(args); err != nil { + if err := internal.ServiceRemoveContainers(args); err != nil { } } diff --git a/Mythic_CLI/src/cmd/removeDockerCompose.go b/Mythic_CLI/src/cmd/removeDockerCompose.go index 4d1be4739..fa10fb4b9 100644 --- a/Mythic_CLI/src/cmd/removeDockerCompose.go +++ b/Mythic_CLI/src/cmd/removeDockerCompose.go @@ -19,7 +19,7 @@ func init() { } func removeDockerCompose(cmd *cobra.Command, args []string) { - if err := internal.RemoveDockerComposeEntry(args[0]); err != nil { + if err := internal.RemoveService(args[0]); err != nil { } } diff --git a/Mythic_CLI/src/cmd/rootCmd.go b/Mythic_CLI/src/cmd/rootCmd.go index 8980c30d6..bd0db9ec3 100644 --- a/Mythic_CLI/src/cmd/rootCmd.go +++ b/Mythic_CLI/src/cmd/rootCmd.go @@ -30,5 +30,6 @@ func Execute() { func init() { // Create or parse the Docker ``.env`` file + config.Initialize() internal.Initialize() } diff --git a/Mythic_CLI/src/cmd/start.go b/Mythic_CLI/src/cmd/start.go index 07f79d670..7b4030aa1 100644 --- a/Mythic_CLI/src/cmd/start.go +++ b/Mythic_CLI/src/cmd/start.go @@ -18,7 +18,7 @@ func init() { } func start(cmd *cobra.Command, args []string) { - if err := internal.DockerStart(args); err != nil { + if err := internal.ServiceStart(args); err != nil { } } diff --git a/Mythic_CLI/src/cmd/stop.go b/Mythic_CLI/src/cmd/stop.go index 78ca8ec85..fa4d4a3d6 100644 --- a/Mythic_CLI/src/cmd/stop.go +++ b/Mythic_CLI/src/cmd/stop.go @@ -19,7 +19,7 @@ func init() { } func stop(cmd *cobra.Command, args []string) { - if err := internal.DockerStop(args); err != nil { + if err := internal.ServiceStop(args); err != nil { } } diff --git a/Mythic_CLI/src/cmd/utils/utils.go b/Mythic_CLI/src/cmd/utils/utils.go new file mode 100644 index 000000000..f40de7445 --- /dev/null +++ b/Mythic_CLI/src/cmd/utils/utils.go @@ -0,0 +1,171 @@ +package utils + +import ( + "crypto/rand" + "fmt" + "io" + "io/ioutil" + "log" + "math/big" + "os" + "path" + "path/filepath" + "strings" +) + +func GenerateRandomPassword(pwLength int) string { + chars := []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") + var b strings.Builder + for i := 0; i < pwLength; i++ { + nBig, err := rand.Int(rand.Reader, big.NewInt(int64(len(chars)))) + if err != nil { + log.Fatalf("[-] Failed to generate random number for password generation\n") + } + b.WriteRune(chars[nBig.Int64()]) + } + return b.String() +} +func GetCwdFromExe() string { + exe, err := os.Executable() + if err != nil { + log.Fatalf("[-] Failed to get path to current executable\n") + } + return filepath.Dir(exe) +} +func StringInSlice(value string, list []string) bool { + for _, e := range list { + if e == value { + return true + } + } + return false +} +func RemoveStringFromSliceNoOrder(source []string, str string) []string { + + for index, value := range source { + if str == value { + source[index] = source[len(source)-1] + source[len(source)-1] = "" + source = source[:len(source)-1] + return source + } + } + // we didn't find the element to remove + return source +} +func UpdateEnvironmentVariables(originalList []string, updates []string) []string { + var finalList []string + for _, entry := range originalList { + entryPieces := strings.Split(entry, "=") + found := false + for _, update := range updates { + updatePieces := strings.Split(update, "=") + if updatePieces[0] == entryPieces[0] { + // the current env vars has a key that we want to update, so don't include the old version + found = true + } + } + if !found { + finalList = append(finalList, entry) + } + } + for _, update := range updates { + finalList = append(finalList, update) + } + return finalList +} +func ByteCountSI(b int64) string { + const unit = 1000 + if b < unit { + return fmt.Sprintf("%d B", b) + } + div, exp := int64(unit), 0 + for n := b / unit; n >= unit; n /= unit { + div *= unit + exp++ + } + return fmt.Sprintf("%.1f %cB", + float64(b)/float64(div), "kMGTPE"[exp]) +} + +// https://golangcode.com/check-if-a-file-exists/ +func FileExists(path string) bool { + info, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return false + } + } + return !info.IsDir() +} + +// https://golangcode.com/check-if-a-file-exists/ +func DirExists(path string) bool { + info, err := os.Stat(path) + if err != nil { + if os.IsNotExist(err) { + return false + } + } + return info.IsDir() +} + +// https://blog.depa.do/post/copy-files-and-directories-in-go +func CopyFile(src, dst string) error { + var err error + var srcfd *os.File + var dstfd *os.File + var srcinfo os.FileInfo + + if srcfd, err = os.Open(src); err != nil { + return err + } + defer srcfd.Close() + + if dstfd, err = os.Create(dst); err != nil { + return err + } + defer dstfd.Close() + + if _, err = io.Copy(dstfd, srcfd); err != nil { + return err + } + if srcinfo, err = os.Stat(src); err != nil { + return err + } + return os.Chmod(dst, srcinfo.Mode()) +} + +// https://blog.depa.do/post/copy-files-and-directories-in-go +func CopyDir(src string, dst string) error { + var err error + var fds []os.FileInfo + var srcinfo os.FileInfo + + if srcinfo, err = os.Stat(src); err != nil { + return err + } + + if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil { + return err + } + + if fds, err = ioutil.ReadDir(src); err != nil { + return err + } + for _, fd := range fds { + srcfp := path.Join(src, fd.Name()) + dstfp := path.Join(dst, fd.Name()) + + if fd.IsDir() { + if err = CopyDir(srcfp, dstfp); err != nil { + fmt.Println(err) + } + } else { + if err = CopyFile(srcfp, dstfp); err != nil { + fmt.Println(err) + } + } + } + return nil +} diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index e6e2fba53..57b2b667b 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1,6 +1,6 @@ #FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.33 +FROM itsafeaturemythic/mythic_go_base:latest WORKDIR /usr/src/app @@ -14,7 +14,7 @@ COPY ["src/", "."] RUN make build_final -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.33 +FROM alpine COPY --from=0 /mythic_server /mythic_server From ade564ca7e2aa0377a2f5b74a80dc3bf0167e4cf Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Wed, 17 Jan 2024 11:15:48 -0600 Subject: [PATCH 070/117] mythic-cli refactor --- Mythic_CLI/src/cmd/config/env.go | 2 - Mythic_CLI/src/cmd/internal/reset.go | 53 +- .../src/cmd/internal/serviceExecution.go | 227 +------- .../src/cmd/internal/serviceMetadata.go | 12 +- Mythic_CLI/src/cmd/internal/testServices.go | 284 +-------- .../src/cmd/manager/dockerComposeManager.go | 550 ++++++++++++++++-- .../src/cmd/manager/managerInterface.go | 17 + Mythic_CLI/src/cmd/rabbitmqReset.go | 22 - Mythic_CLI/src/cmd/utils/utils.go | 6 +- 9 files changed, 572 insertions(+), 601 deletions(-) delete mode 100644 Mythic_CLI/src/cmd/rabbitmqReset.go diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index 2b47a8069..761adb669 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -323,8 +323,6 @@ func GetBuildArguments() []string { buildEnv.AddConfigPath(utils.GetCwdFromExe()) buildEnv.AutomaticEnv() if !utils.FileExists(filepath.Join(utils.GetCwdFromExe(), "build.env")) { - log.Printf("[*] No build.env file detected in Mythic's root directory; not supplying build arguments to docker containers\n") - log.Printf(" If you need to supply build arguments to docker containers, create build.env and supply key=value entries there\n") return []string{} } if err := buildEnv.ReadInConfig(); err != nil { diff --git a/Mythic_CLI/src/cmd/internal/reset.go b/Mythic_CLI/src/cmd/internal/reset.go index 925e2bbf3..c15cc9a4b 100644 --- a/Mythic_CLI/src/cmd/internal/reset.go +++ b/Mythic_CLI/src/cmd/internal/reset.go @@ -1,54 +1,21 @@ package internal import ( - "fmt" + "github.com/MythicMeta/Mythic_CLI/cmd/config" + "github.com/MythicMeta/Mythic_CLI/cmd/manager" "log" - "os" - "path/filepath" ) func DatabaseReset() { - fmt.Printf("[*] Stopping Mythic\n") - ServiceStop([]string{}) - workingPath := getCwdFromExe() - fmt.Printf("[*] Removing database files\n") - if mythicEnv.GetBool("postgres_bind_local_mount") { - err := os.RemoveAll(filepath.Join(workingPath, "postgres-docker", "database")) - if err != nil { - fmt.Printf("[-] Failed to remove database files\n%v\n", err) - } else { - fmt.Printf("[+] Successfully reset datbase files\n") - } - } else { - ServiceRemoveContainers([]string{"mythic_postgres"}) - err := DockerRemoveVolume("mythic_postgres_volume") - if err != nil { - fmt.Printf("[-] Failed to remove database:\n%v\n", err) + confirm := config.AskConfirm("Are you sure you want to reset the database? ") + if confirm { + confirm = config.AskConfirm("Are you absolutely sure? This will delete ALL data with your database forever. ") + if confirm { + log.Printf("[*] Stopping Mythic\n") + manager.GetManager().StopServices([]string{}, config.GetMythicEnv().GetBool("REBUILD_ON_START")) + manager.GetManager().ResetDatabase(config.GetMythicEnv().GetBool("postgres_bind_local_mount")) + log.Printf("[*] Removing database files\n") } } } -func RabbitmqReset(explicitCall bool) { - if explicitCall { - fmt.Printf("[*] Stopping Mythic\n") - ServiceStop([]string{}) - fmt.Printf("[*] Removing rabbitmq files\n") - } - if mythicEnv.GetBool("rabbitmq_bind_local_mount") { - workingPath := getCwdFromExe() - err := os.RemoveAll(filepath.Join(workingPath, "rabbitmq-docker", "storage")) - if err != nil { - log.Fatalf("[-] Failed to reset rabbitmq files: %v\n", err) - } else { - if explicitCall { - fmt.Printf("[+] Successfully reset rabbitmq files\n") - } - } - } else { - ServiceRemoveContainers([]string{"mythic_rabbitmq"}) - err := DockerRemoveVolume("mythic_rabbitmq_volume") - if err != nil { - fmt.Printf("[-] Failed to remove rabbitmq files:\n%v\n", err) - } - } -} diff --git a/Mythic_CLI/src/cmd/internal/serviceExecution.go b/Mythic_CLI/src/cmd/internal/serviceExecution.go index 35e5b4bbf..dc9299411 100644 --- a/Mythic_CLI/src/cmd/internal/serviceExecution.go +++ b/Mythic_CLI/src/cmd/internal/serviceExecution.go @@ -1,22 +1,12 @@ package internal import ( - "context" - "errors" "fmt" "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/manager" "github.com/MythicMeta/Mythic_CLI/cmd/utils" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/volume" - "github.com/docker/docker/client" "io" "log" - "os" - "sort" - "strconv" - "strings" - "text/tabwriter" ) // ServiceStart is entrypoint from commands to start containers @@ -48,15 +38,13 @@ func ServiceStart(containers []string) error { } } for _, val := range intendedMythicServices { - if utils.StringInSlice(val, currentMythicServices) { - - } else { - AddMythicService(val) - } + AddMythicService(val) } // if the user didn't explicitly call out starting certain containers, then do all of them if len(containers) == 0 { containers = append(dockerComposeContainers, intendedMythicServices...) + // make sure the ports are open that we're going to need + TestPorts() } finalContainers := []string{} for _, val := range containers { // these are specified containers or all in docker compose @@ -145,213 +133,16 @@ func DockerBuildReactUI() error { // Docker Volume commands -func VolumesList() error { - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() - w := new(tabwriter.Writer) - w.Init(os.Stdout, 0, 8, 2, '\t', 0) - fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tCONTAINER STATUS\tLOCATION") - du, err := cli.DiskUsage(ctx, types.DiskUsageOptions{}) - if err != nil { - fmt.Printf("[-] Failed to get disk sizes: %v\n", err) - os.Exit(1) - } - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - fmt.Printf("[-] Failed to get container list: %v\n", err) - os.Exit(1) - } - if du.Volumes == nil { - fmt.Printf("[-] No volumes known\n") - return nil - } - var entries []string - for _, currentVolume := range du.Volumes { - name := currentVolume.Name - size := "unknown" - if currentVolume.UsageData != nil { - size = utils.ByteCountSI(currentVolume.UsageData.Size) - } - if !strings.HasPrefix(currentVolume.Name, "mythic_") { - continue - } - containerPieces := strings.Split(currentVolume.Name, "_") - containerName := strings.Join(containerPieces[0:2], "_") - container := "unused (0)" - containerStatus := "offline" - for _, c := range containers { - if c.Image == containerName { - containerStatus = c.Status - } - for _, m := range c.Mounts { - if m.Name == currentVolume.Name { - container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" - } - } - } - entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s\t%s", - name, - size, - container, - containerStatus, - currentVolume.Mountpoint, - )) - } - sort.Strings(entries) - for _, line := range entries { - fmt.Fprintln(w, line) - } - - defer w.Flush() - return nil +func VolumesList() { + manager.GetManager().ListVolumes() } func DockerRemoveVolume(volumeName string) error { - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - panic(err) - } - defer cli.Close() - volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) - if err != nil { - return err - } - for _, currentVolume := range volumes.Volumes { - if currentVolume.Name == volumeName { - err = cli.VolumeRemove(ctx, currentVolume.Name, true) - if err != nil { - return err - } - } - } - return nil -} -func ensureVolume(volumeName string) error { - containerNamePieces := strings.Split(volumeName, "_") - containerName := strings.Join(containerNamePieces[0:2], "_") - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - return err - } - defer cli.Close() - volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) - if err != nil { - return err - } - foundVolume := false - for _, currentVolume := range volumes.Volumes { - if currentVolume.Name == volumeName { - foundVolume = true - } - } - if !foundVolume { - _, err = cli.VolumeCreate(ctx, volume.CreateOptions{Name: volumeName}) - if err != nil { - return err - } - } - // now that we know the volume exists, make sure it's attached to a running container or we can't manipulate files - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - return err - } - for _, container := range containers { - if container.Image == containerName { - for _, mnt := range container.Mounts { - if mnt.Name == volumeName { - // container is running and has this mount associated with it - return nil - } - } - return errors.New(fmt.Sprintf("container, %s, isn't using volume, %s", containerName, volumeName)) - } - } - return errors.New(fmt.Sprintf("failed to find container, %s, for volume, %s", containerName, volumeName)) + return manager.GetManager().RemoveVolume(volumeName) } + func DockerCopyIntoVolume(sourceFile io.Reader, destinationFileName string, destinationVolume string) { - err := ensureVolume(destinationVolume) - if err != nil { - fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) - os.Exit(1) - } - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - fmt.Printf("[-] Failed to connect to docker api: %v\n", err) - os.Exit(1) - } - defer cli.Close() - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - fmt.Printf("[-] Failed to get container list: %v\n", err) - os.Exit(1) - } - for _, container := range containers { - for _, mnt := range container.Mounts { - if mnt.Name == destinationVolume { - err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{ - CopyUIDGID: true, - }) - if err != nil { - fmt.Printf("[-] Failed to write file: %v\n", err) - os.Exit(1) - } else { - fmt.Printf("[+] Successfully wrote file\n") - } - return - } - } - } - fmt.Printf("[-] Failed to find that volume name in use by any containers") - os.Exit(1) + manager.GetManager().CopyIntoVolume(sourceFile, destinationFileName, destinationVolume) } func DockerCopyFromVolume(sourceVolumeName string, sourceFileName string, destinationName string) { - err := ensureVolume(sourceVolumeName) - if err != nil { - fmt.Printf("[-] Failed to ensure volume exists: %v\n", err) - os.Exit(1) - } - ctx := context.Background() - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - fmt.Printf("[-] Failed to connect to docker api: %v\n", err) - os.Exit(1) - } - defer cli.Close() - containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) - if err != nil { - fmt.Printf("[-] Failed to get container list: %v\n", err) - os.Exit(1) - } - for _, container := range containers { - for _, mnt := range container.Mounts { - if mnt.Name == sourceVolumeName { - reader, _, err := cli.CopyFromContainer(ctx, container.ID, mnt.Destination+"/"+sourceFileName) - if err != nil { - fmt.Printf("[-] Failed to read file: %v\n", err) - return - } - destination, err := os.Create(destinationName) - if err != nil { - fmt.Printf("[-] Failed to open destination filename: %v\n", err) - return - } - defer destination.Close() - _, err = io.Copy(destination, reader) - if err != nil { - fmt.Printf("[-] Failed to get file from volume: %v\n", err) - return - } - fmt.Printf("[+] Successfully wrote file\n") - return - } - } - } - fmt.Printf("[-] Failed to find that volume name in use by any containers") - os.Exit(1) + manager.GetManager().CopyFromVolume(sourceVolumeName, sourceFileName, destinationName) } diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index 03e9fa11f..c2d4a4107 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -45,7 +45,7 @@ func AddMythicService(service string) { "POSTGRES_PASSWORD=${POSTGRES_PASSWORD}", } if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]interface{}), environment) } else { pStruct["environment"] = environment } @@ -121,7 +121,7 @@ func AddMythicService(service string) { "HASURA_GRAPHQL_CONSOLE_ASSETS_DIR=/srv/console-assets", } if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]interface{}), environment) } else { pStruct["environment"] = environment } @@ -183,7 +183,7 @@ func AddMythicService(service string) { fmt.Sprintf("NGINX_USE_IPV6=%s", nginxUseIPV6), } if _, ok := pStruct["environment"]; ok { - environment = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + environment = utils.UpdateEnvironmentVariables(pStruct["environment"].([]interface{}), environment) } var finalNginxEnv []string for _, val := range environment { @@ -246,7 +246,7 @@ func AddMythicService(service string) { "RABBITMQ_PORT=${RABBITMQ_PORT}", } if _, ok := pStruct["environment"]; ok { - environment = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + environment = utils.UpdateEnvironmentVariables(pStruct["environment"].([]interface{}), environment) } var finalRabbitEnv []string badRabbitMqEnvs := []string{ @@ -421,7 +421,7 @@ func AddMythicService(service string) { } pStruct["ports"] = mythicServerPorts if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]string), environment) + pStruct["environment"] = utils.UpdateEnvironmentVariables(pStruct["environment"].([]interface{}), environment) } else { pStruct["environment"] = environment } @@ -535,7 +535,7 @@ func Add3rdPartyService(service string, additionalConfigs map[string]interface{} "DEBUG_LEVEL=${DEBUG_LEVEL}", } if _, ok := pStruct["environment"]; ok { - pStruct["environment"] = utils.UpdateEnvironmentVariables(existingConfig["environment"].([]string), environment) + pStruct["environment"] = utils.UpdateEnvironmentVariables(existingConfig["environment"].([]interface{}), environment) } else { pStruct["environment"] = environment } diff --git a/Mythic_CLI/src/cmd/internal/testServices.go b/Mythic_CLI/src/cmd/internal/testServices.go index 4fcc5fd5c..9da735acd 100644 --- a/Mythic_CLI/src/cmd/internal/testServices.go +++ b/Mythic_CLI/src/cmd/internal/testServices.go @@ -1,22 +1,15 @@ package internal import ( - "context" "crypto/tls" "fmt" "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/manager" - "github.com/docker/docker/api/types" - "github.com/docker/docker/client" "github.com/streadway/amqp" "log" "net/http" "os" - "path/filepath" - "sort" "strconv" - "strings" - "text/tabwriter" "time" ) @@ -112,215 +105,31 @@ func TestPorts() error { manager.GetManager().TestPorts() return nil } -func PrintMythicConnectionInfo() { - w := new(tabwriter.Writer) - mythicEnv := config.GetMythicEnv() - w.Init(os.Stdout, 0, 8, 2, '\t', 0) - fmt.Fprintln(w, "MYTHIC SERVICE\tWEB ADDRESS\tBOUND LOCALLY") - if mythicEnv.GetString("NGINX_HOST") == "mythic_nginx" { - if mythicEnv.GetBool("NGINX_USE_SSL") { - fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttps://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) - } - } else { - if mythicEnv.GetBool("NGINX_USE_SSL") { - fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttps://"+mythicEnv.GetString("NGINX_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttp://"+mythicEnv.GetString("NGINX_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) - } - } - if mythicEnv.GetString("MYTHIC_SERVER_HOST") == "mythic_server" { - fmt.Fprintln(w, "Mythic Backend Server\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_SERVER_PORT"))+"\t", mythicEnv.GetBool("mythic_server_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Mythic Backend Server\thttp://"+mythicEnv.GetString("MYTHIC_SERVER_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_SERVER_PORT"))+"\t", mythicEnv.GetBool("mythic_server_bind_localhost_only")) - } - if mythicEnv.GetString("HASURA_HOST") == "mythic_graphql" { - fmt.Fprintln(w, "Hasura GraphQL Console\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("HASURA_PORT"))+"\t", mythicEnv.GetBool("hasura_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Hasura GraphQL Console\thttp://"+mythicEnv.GetString("HASURA_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("HASURA_PORT"))+"\t", mythicEnv.GetBool("hasura_bind_localhost_only")) - } - if mythicEnv.GetString("JUPYTER_HOST") == "mythic_jupyter" { - fmt.Fprintln(w, "Jupyter Console\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("JUPYTER_PORT"))+"\t", mythicEnv.GetBool("jupyter_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Jupyter Console\thttp://"+mythicEnv.GetString("JUPYTER_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("JUPYTER_PORT"))+"\t", mythicEnv.GetBool("jupyter_bind_localhost_only")) - } - if mythicEnv.GetString("DOCUMENTATION_HOST") == "mythic_documentation" { - fmt.Fprintln(w, "Internal Documentation\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("DOCUMENTATION_PORT"))+"\t", mythicEnv.GetBool("documentation_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Internal Documentation\thttp://"+mythicEnv.GetString("DOCUMENTATION_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("DOCUMENTATION_PORT"))+"\t", mythicEnv.GetBool("documentation_bind_localhost_only")) - } - fmt.Fprintln(w, "\t\t\t\t") - fmt.Fprintln(w, "ADDITIONAL SERVICES\tIP\tPORT\tBOUND LOCALLY") - if mythicEnv.GetString("POSTGRES_HOST") == "mythic_postgres" { - fmt.Fprintln(w, "Postgres Database\t127.0.0.1\t"+strconv.Itoa(mythicEnv.GetInt("POSTGRES_PORT"))+"\t", mythicEnv.GetBool("postgres_bind_localhost_only")) - } else { - fmt.Fprintln(w, "Postgres Database\t"+mythicEnv.GetString("POSTGRES_HOST")+"\t"+strconv.Itoa(mythicEnv.GetInt("POSTGRES_PORT"))+"\t", mythicEnv.GetBool("postgres_bind_localhost_only")) - } - if mythicEnv.GetString("MYTHIC_REACT_HOST") == "mythic_react" { - fmt.Fprintln(w, "React Server\t127.0.0.1\t"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_REACT_PORT"))+"\t", mythicEnv.GetBool("mythic_react_bind_localhost_only")) - } else { - fmt.Fprintln(w, "React Server\t"+mythicEnv.GetString("MYTHIC_REACT_HOST")+"\t"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_REACT_PORT"))+"\t", mythicEnv.GetBool("mythic_react_bind_localhost_only")) - } - if mythicEnv.GetString("RABBITMQ_HOST") == "mythic_rabbitmq" { - fmt.Fprintln(w, "RabbitMQ\t127.0.0.1\t"+strconv.Itoa(mythicEnv.GetInt("RABBITMQ_PORT"))+"\t", mythicEnv.GetBool("rabbitmq_bind_localhost_only")) - } else { - fmt.Fprintln(w, "RabbitMQ\t"+mythicEnv.GetString("RABBITMQ_HOST")+"\t"+strconv.Itoa(mythicEnv.GetInt("RABBITMQ_PORT"))+"\t", mythicEnv.GetBool("rabbitmq_bind_localhost_only")) - } - fmt.Fprintln(w, "\t\t\t\t") - w.Flush() -} func Status(verbose bool) { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Fatalf("[-] Failed to get client in Status check: %v", err) - } - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ - All: true, - }) - if err != nil { - log.Fatalf("[-] Failed to get container list: %v\n", err) - } - PrintMythicConnectionInfo() - w := new(tabwriter.Writer) - w.Init(os.Stdout, 0, 8, 2, '\t', 0) - var mythicLocalServices []string - var installedServices []string - sort.Slice(containers[:], func(i, j int) bool { - return containers[i].Labels["name"] < containers[j].Labels["name"] - }) - elementsOnDisk, err := getElementsOnDisk() + manager.GetManager().PrintConnectionInfo() + manager.GetManager().Status(verbose) + installedServices, err := manager.GetManager().GetInstalled3rdPartyServicesOnDisk() if err != nil { - log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) - } - elementsInCompose, err := GetAllExistingNonMythicServiceNames() - if err != nil { - log.Fatalf("[-] Failed to get list of installed services in docker-compose: %v\n", err) - } - for _, container := range containers { - if container.Labels["name"] == "" { - continue - } - var portRanges []uint16 - var portRangeMaps []string - portString := "" - info := fmt.Sprintf("%s\t%s\t%s\t", container.Labels["name"], container.State, container.Status) - if len(container.Ports) > 0 { - sort.Slice(container.Ports[:], func(i, j int) bool { - return container.Ports[i].PublicPort < container.Ports[j].PublicPort - }) - for _, port := range container.Ports { - if port.PublicPort > 0 { - if port.PrivatePort == port.PublicPort && port.IP == "0.0.0.0" { - portRanges = append(portRanges, port.PrivatePort) - } else { - portRangeMaps = append(portRangeMaps, fmt.Sprintf("%d/%s -> %s:%d", port.PrivatePort, port.Type, port.IP, port.PublicPort)) - } - - } - } - if len(portRanges) > 0 { - sort.Slice(portRanges, func(i, j int) bool { return portRanges[i] < portRanges[j] }) - } - portString = strings.Join(portRangeMaps[:], ", ") - var stringPortRanges []string - for _, val := range portRanges { - stringPortRanges = append(stringPortRanges, fmt.Sprintf("%d", val)) - } - if len(stringPortRanges) > 0 && len(portString) > 0 { - portString = portString + ", " - } - portString = portString + strings.Join(stringPortRanges[:], ", ") - } - if stringInSlice(container.Image, MythicPossibleServices) { - found := false - for _, mnt := range container.Mounts { - if strings.HasPrefix(mnt.Name, container.Image+"_volume") { - if found { - info += ", " + mnt.Name - } else { - info += mnt.Name - } - - found = true - } - } - if !found { - info += "local" - } - info += "\t" - info = info + portString - mythicLocalServices = append(mythicLocalServices, info) - } else { - installedServicesAbsPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder)) - if err != nil { - fmt.Printf("[-] failed to get the absolute path to the InstalledServices folder") - continue - } - - for _, mnt := range container.Mounts { - if strings.Contains(mnt.Source, installedServicesAbsPath) { - installedServices = append(installedServices, info) - elementsOnDisk = RemoveStringFromSliceNoOrder(elementsOnDisk, container.Labels["name"]) - elementsInCompose = RemoveStringFromSliceNoOrder(elementsInCompose, container.Labels["name"]) - } - } - } - + log.Fatalf("[-] failed to get installed services: %v\n", err) } - fmt.Fprintln(w, "Mythic Main Services") - fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tMOUNT\tPORTS") - for _, line := range mythicLocalServices { - fmt.Fprintln(w, line) - } - fmt.Fprintln(w, "\t\t\t\t\t") - w.Flush() - fmt.Fprintln(w, "Installed Services") - fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS") - for _, line := range installedServices { - fmt.Fprintln(w, line) - } - fmt.Fprintln(w, "\t\t\t") - // remove all elementsInCompose from elementsOnDisk - for _, container := range elementsInCompose { - elementsOnDisk = RemoveStringFromSliceNoOrder(elementsOnDisk, container) - } - if len(elementsInCompose) > 0 && verbose { - fmt.Fprintln(w, "Docker Compose services not running, start with: ./mythic-cli start [name]") - fmt.Fprintln(w, "NAME\t") - sort.Strings(elementsInCompose) - for _, container := range elementsInCompose { - fmt.Fprintln(w, fmt.Sprintf("%s\t", container)) - } - fmt.Fprintln(w, "\t") - } - if len(elementsOnDisk) > 0 && verbose { - fmt.Fprintln(w, "Extra Services, add to docker compose with: ./mythic-cli add [name]") - fmt.Fprintln(w, "NAME\t") - sort.Strings(elementsOnDisk) - for _, container := range elementsOnDisk { - fmt.Fprintln(w, fmt.Sprintf("%s\t", container)) - } - fmt.Fprintln(w, "\t\t") - } - w.Flush() + mythicEnv := config.GetMythicEnv() if len(installedServices) == 0 { - fmt.Printf("[*] There are no services installed\n") - fmt.Printf(" To install one, use \"sudo ./mythic-cli install github \"\n") - fmt.Printf(" Agents can be found at: https://github.com/MythicAgents\n") - fmt.Printf(" C2 Profiles can be found at: https://github.com/MythicC2Profiles\n") + log.Printf("[*] There are no services installed\n") + log.Printf(" To install one, use \"sudo ./mythic-cli install github \"\n") + log.Printf(" Agents can be found at: https://github.com/MythicAgents\n") + log.Printf(" C2 Profiles can be found at: https://github.com/MythicC2Profiles\n") } if mythicEnv.GetString("RABBITMQ_HOST") == "mythic_rabbitmq" && mythicEnv.GetBool("rabbitmq_bind_localhost_only") { - fmt.Printf("\n[*] RabbitMQ is currently listening on localhost. If you have a remote Service, they will be unable to connect (i.e. one running on another server)") - fmt.Printf("\n Use 'sudo ./mythic-cli config set rabbitmq_bind_localhost_only false' and restart mythic ('sudo ./mythic-cli restart') to change this\n") + log.Printf("\n[*] RabbitMQ is currently listening on localhost. If you have a remote Service, they will be unable to connect (i.e. one running on another server)") + log.Printf("\n Use 'sudo ./mythic-cli config set rabbitmq_bind_localhost_only false' and restart mythic ('sudo ./mythic-cli restart') to change this\n") } if mythicEnv.GetString("MYTHIC_SERVER_HOST") == "mythic_server" && mythicEnv.GetBool("mythic_server_bind_localhost_only") { - fmt.Printf("\n[*] MythicServer is currently listening on localhost. If you have a remote Service, they will be unable to connect (i.e. one running on another server)") - fmt.Printf("\n Use 'sudo ./mythic-cli config set mythic_server_bind_localhost_only false' and restart mythic ('sudo ./mythic-cli restart') to change this\n") + log.Printf("\n[*] MythicServer is currently listening on localhost. If you have a remote Service, they will be unable to connect (i.e. one running on another server)") + log.Printf("\n Use 'sudo ./mythic-cli config set mythic_server_bind_localhost_only false' and restart mythic ('sudo ./mythic-cli restart') to change this\n") } - fmt.Printf("[*] If you are using a remote PayloadType or C2Profile, they will need certain environment variables to properly connect to Mythic.\n") - fmt.Printf(" Use 'sudo ./mythic-cli config service' for configs for these services.\n") + log.Printf("[*] If you are using a remote PayloadType or C2Profile, they will need certain environment variables to properly connect to Mythic.\n") + log.Printf(" Use 'sudo ./mythic-cli config service' for configs for these services.\n") } func GetLogs(containerName string, numLogs string) { logCount, err := strconv.Atoi(numLogs) @@ -330,66 +139,5 @@ func GetLogs(containerName string, numLogs string) { manager.GetManager().GetLogs(containerName, logCount) } func ListServices() { - cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) - if err != nil { - log.Fatalf("[-] Failed to get client in List Services: %v", err) - } - containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ - All: true, - }) - if err != nil { - log.Fatalf("[-] Failed to get container list: %v\n", err) - } - w := new(tabwriter.Writer) - w.Init(os.Stdout, 0, 8, 2, '\t', 0) - var installedServices []string - sort.Slice(containers[:], func(i, j int) bool { - return containers[i].Labels["name"] < containers[j].Labels["name"] - }) - elementsOnDisk, err := manager.GetManager().GetInstalled3rdPartyServicesOnDisk() - if err != nil { - log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) - } - elementsInCompose, err := GetAllExistingNonMythicServiceNames() - if err != nil { - log.Fatalf("[-] Failed to get list of installed services in docker-compose: %v\n", err) - } - for _, container := range containers { - if container.Labels["name"] == "" { - continue - } - installedServicesAbsPath, err := filepath.Abs(filepath.Join(getCwdFromExe(), InstalledServicesFolder)) - if err != nil { - fmt.Printf("[-] failed to get the absolute path to the InstalledServices folder") - continue - } - for _, mnt := range container.Mounts { - if strings.Contains(mnt.Source, installedServicesAbsPath) { - info := fmt.Sprintf("%s\t%s\t%v\t%v", container.Labels["name"], container.Status, true, stringInSlice(container.Labels["name"], elementsInCompose)) - installedServices = append(installedServices, info) - elementsOnDisk = RemoveStringFromSliceNoOrder(elementsOnDisk, container.Labels["name"]) - elementsInCompose = RemoveStringFromSliceNoOrder(elementsInCompose, container.Labels["name"]) - } - } - } - for _, container := range elementsInCompose { - elementsOnDisk = RemoveStringFromSliceNoOrder(elementsOnDisk, container) - } - fmt.Fprintln(w, "Name\tContainerStatus\tImageBuilt\tDockerComposeEntry") - for _, line := range installedServices { - fmt.Fprintln(w, line) - } - if len(elementsInCompose) > 0 { - sort.Strings(elementsInCompose) - for _, container := range elementsInCompose { - fmt.Fprintln(w, fmt.Sprintf("%s\t%s\t%v\t%v", container, "N/A", imageExists(container), true)) - } - } - if len(elementsOnDisk) > 0 { - sort.Strings(elementsOnDisk) - for _, container := range elementsOnDisk { - fmt.Fprintln(w, fmt.Sprintf("%s\t%s\t%v\t%v", container, "N/A", imageExists(container), false)) - } - } - w.Flush() + manager.GetManager().ListServices() } diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go index 0a8c6af2e..4db2ffbfa 100644 --- a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -9,6 +9,7 @@ import ( "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/utils" "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" "github.com/spf13/viper" "golang.org/x/mod/semver" @@ -19,9 +20,11 @@ import ( "os" "os/exec" "path/filepath" + "sort" "strconv" "strings" "sync" + "text/tabwriter" ) type DockerComposeManager struct { @@ -191,7 +194,7 @@ func (d *DockerComposeManager) SaveImages(services []string, outputPath string) return errors.New(fmt.Sprintf("[-] Failed to create output file: %v\n", err)) } defer outFile.Close() - fmt.Printf("[*] Saving to %s\nThis will take a while...\n", savedImagePath) + log.Printf("[*] Saving to %s\nThis will take a while...\n", savedImagePath) _, err = io.Copy(outFile, ioReadCloser) if err != nil { return errors.New(fmt.Sprintf("[-] Failed to write contents to file: %v\n", err)) @@ -213,7 +216,7 @@ func (d *DockerComposeManager) LoadImages(outputPath string) error { if err != nil { return errors.New(fmt.Sprintf("[-] Failed to load image into Docker: %v\n", err)) } - fmt.Printf("[+] loaded docker images!\n") + log.Printf("[+] loaded docker images!\n") return nil } @@ -252,10 +255,11 @@ func (d *DockerComposeManager) GetVolumes() (map[string]interface{}, error) { // SetVolumes sets a specific volume configuration into the docker-compose file. func (d *DockerComposeManager) SetVolumes(volumes map[string]interface{}) { curConfig := d.readInDockerCompose() - curConfig.Set("volumes", volumes) - err := d.setDockerComposeDefaultsAndWrite(curConfig) + allConfigSettings := curConfig.AllSettings() + allConfigSettings["volumes"] = volumes + err := d.setDockerComposeDefaultsAndWrite(allConfigSettings) if err != nil { - fmt.Printf("[-] Failed to update config: %v\n", err) + log.Printf("[-] Failed to update config: %v\n", err) } } @@ -294,15 +298,20 @@ func (d *DockerComposeManager) GetServiceConfiguration(service string) (map[stri // SetServiceConfiguration sets a service configuration into docker-compose func (d *DockerComposeManager) SetServiceConfiguration(service string, pStruct map[string]interface{}) error { curConfig := d.readInDockerCompose() - if !curConfig.InConfig("services." + strings.ToLower(service)) { - curConfig.Set("services."+strings.ToLower(service), pStruct) - log.Printf("[+] Added %s to docker-compose\n", strings.ToLower(service)) - } else { - curConfig.Set("services."+strings.ToLower(service), pStruct) + allConfigValues := curConfig.AllSettings() + for key, _ := range allConfigValues { + if key == "services" { + allServices := allConfigValues["services"].(map[string]interface{}) + if _, ok := allServices[service]; !ok { + log.Printf("[+] Added %s to docker-compose\n", strings.ToLower(service)) + } + allServices[service] = pStruct + allConfigValues["services"] = allServices + } } - err := d.setDockerComposeDefaultsAndWrite(curConfig) + err := d.setDockerComposeDefaultsAndWrite(allConfigValues) if err != nil { - fmt.Printf("[-] Failed to update config: %v\n", err) + log.Printf("[-] Failed to update config: %v\n", err) } return err } @@ -349,17 +358,24 @@ func (d *DockerComposeManager) StopServices(services []string, deleteImages bool // RemoveServices removes certain container entries from the docker-compose func (d *DockerComposeManager) RemoveServices(services []string) error { curConfig := d.readInDockerCompose() - for _, service := range services { - if !utils.StringInSlice(service, config.MythicPossibleServices) { - if d.IsServiceRunning(service) { - _ = d.StopServices([]string{strings.ToLower(service)}, true) + allConfigValues := curConfig.AllSettings() + for key, _ := range allConfigValues { + if key == "services" { + allServices := allConfigValues["services"].(map[string]interface{}) + for _, service := range services { + if !utils.StringInSlice(service, config.MythicPossibleServices) { + if d.IsServiceRunning(service) { + _ = d.StopServices([]string{strings.ToLower(service)}, true) + } + delete(allServices, strings.ToLower(service)) + log.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) + } } - delete(curConfig.Get("services").(map[string]interface{}), strings.ToLower(service)) - log.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) } } - err := d.setDockerComposeDefaultsAndWrite(curConfig) + + err := d.setDockerComposeDefaultsAndWrite(allConfigValues) if err != nil { log.Printf("[-] Failed to update config: %v\n", err) return err @@ -565,6 +581,428 @@ func (d *DockerComposeManager) TestPorts() { } } +func (d *DockerComposeManager) PrintConnectionInfo() { + w := new(tabwriter.Writer) + mythicEnv := config.GetMythicEnv() + w.Init(os.Stdout, 0, 8, 2, '\t', 0) + fmt.Fprintln(w, "MYTHIC SERVICE\tWEB ADDRESS\tBOUND LOCALLY") + if mythicEnv.GetString("NGINX_HOST") == "mythic_nginx" { + if mythicEnv.GetBool("NGINX_USE_SSL") { + fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttps://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) + } + } else { + if mythicEnv.GetBool("NGINX_USE_SSL") { + fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttps://"+mythicEnv.GetString("NGINX_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Nginx (Mythic Web UI)\thttp://"+mythicEnv.GetString("NGINX_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("NGINX_PORT"))+"\t", mythicEnv.GetBool("nginx_bind_localhost_only")) + } + } + if mythicEnv.GetString("MYTHIC_SERVER_HOST") == "mythic_server" { + fmt.Fprintln(w, "Mythic Backend Server\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_SERVER_PORT"))+"\t", mythicEnv.GetBool("mythic_server_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Mythic Backend Server\thttp://"+mythicEnv.GetString("MYTHIC_SERVER_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_SERVER_PORT"))+"\t", mythicEnv.GetBool("mythic_server_bind_localhost_only")) + } + if mythicEnv.GetString("HASURA_HOST") == "mythic_graphql" { + fmt.Fprintln(w, "Hasura GraphQL Console\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("HASURA_PORT"))+"\t", mythicEnv.GetBool("hasura_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Hasura GraphQL Console\thttp://"+mythicEnv.GetString("HASURA_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("HASURA_PORT"))+"\t", mythicEnv.GetBool("hasura_bind_localhost_only")) + } + if mythicEnv.GetString("JUPYTER_HOST") == "mythic_jupyter" { + fmt.Fprintln(w, "Jupyter Console\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("JUPYTER_PORT"))+"\t", mythicEnv.GetBool("jupyter_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Jupyter Console\thttp://"+mythicEnv.GetString("JUPYTER_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("JUPYTER_PORT"))+"\t", mythicEnv.GetBool("jupyter_bind_localhost_only")) + } + if mythicEnv.GetString("DOCUMENTATION_HOST") == "mythic_documentation" { + fmt.Fprintln(w, "Internal Documentation\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("DOCUMENTATION_PORT"))+"\t", mythicEnv.GetBool("documentation_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Internal Documentation\thttp://"+mythicEnv.GetString("DOCUMENTATION_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("DOCUMENTATION_PORT"))+"\t", mythicEnv.GetBool("documentation_bind_localhost_only")) + } + fmt.Fprintln(w, "\t\t\t\t") + fmt.Fprintln(w, "ADDITIONAL SERVICES\tADDRESS\tBOUND LOCALLY") + if mythicEnv.GetString("POSTGRES_HOST") == "mythic_postgres" { + fmt.Fprintln(w, "Postgres Database\tpostgresql://mythic_user:password@127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("POSTGRES_PORT"))+"/mythic_db\t", mythicEnv.GetBool("postgres_bind_localhost_only")) + } else { + fmt.Fprintln(w, "Postgres Database\tpostgresql://mythic_user:password@"+mythicEnv.GetString("POSTGRES_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("POSTGRES_PORT"))+"/mythic_db\t", mythicEnv.GetBool("postgres_bind_localhost_only")) + } + if mythicEnv.GetString("MYTHIC_REACT_HOST") == "mythic_react" { + fmt.Fprintln(w, "React Server\thttp://127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_REACT_PORT"))+"/new\t", mythicEnv.GetBool("mythic_react_bind_localhost_only")) + } else { + fmt.Fprintln(w, "React Server\thttp://"+mythicEnv.GetString("MYTHIC_REACT_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("MYTHIC_REACT_PORT"))+"/new\t", mythicEnv.GetBool("mythic_react_bind_localhost_only")) + } + if mythicEnv.GetString("RABBITMQ_HOST") == "mythic_rabbitmq" { + fmt.Fprintln(w, "RabbitMQ\tamqp://"+mythicEnv.GetString("RABBITMQ_USER")+":password@127.0.0.1:"+strconv.Itoa(mythicEnv.GetInt("RABBITMQ_PORT"))+"\t", mythicEnv.GetBool("rabbitmq_bind_localhost_only")) + } else { + fmt.Fprintln(w, "RabbitMQ\tamqp://"+mythicEnv.GetString("RABBITMQ_USER")+":password@"+mythicEnv.GetString("RABBITMQ_HOST")+":"+strconv.Itoa(mythicEnv.GetInt("RABBITMQ_PORT"))+"\t", mythicEnv.GetBool("rabbitmq_bind_localhost_only")) + } + fmt.Fprintln(w, "\t\t\t\t") + w.Flush() +} + +func (d *DockerComposeManager) Status(verbose bool) { + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("[-] Failed to get client in Status check: %v", err) + } + containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ + All: true, + }) + if err != nil { + log.Fatalf("[-] Failed to get container list: %v\n", err) + } + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 8, 2, '\t', 0) + var mythicLocalServices []string + var installedServices []string + sort.Slice(containers[:], func(i, j int) bool { + return containers[i].Labels["name"] < containers[j].Labels["name"] + }) + elementsOnDisk, err := d.GetInstalled3rdPartyServicesOnDisk() + if err != nil { + log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) + } + elementsInCompose, err := d.GetAllExistingNonMythicServiceNames() + if err != nil { + log.Fatalf("[-] Failed to get list of installed services in docker-compose: %v\n", err) + } + for _, container := range containers { + if container.Labels["name"] == "" { + continue + } + var portRanges []uint16 + var portRangeMaps []string + portString := "" + info := fmt.Sprintf("%s\t%s\t%s\t", container.Labels["name"], container.State, container.Status) + if len(container.Ports) > 0 { + sort.Slice(container.Ports[:], func(i, j int) bool { + return container.Ports[i].PublicPort < container.Ports[j].PublicPort + }) + for _, port := range container.Ports { + if port.PublicPort > 0 { + if port.PrivatePort == port.PublicPort && port.IP == "0.0.0.0" { + portRanges = append(portRanges, port.PrivatePort) + } else { + portRangeMaps = append(portRangeMaps, fmt.Sprintf("%d/%s -> %s:%d", port.PrivatePort, port.Type, port.IP, port.PublicPort)) + } + + } + } + if len(portRanges) > 0 { + sort.Slice(portRanges, func(i, j int) bool { return portRanges[i] < portRanges[j] }) + } + portString = strings.Join(portRangeMaps[:], ", ") + var stringPortRanges []string + for _, val := range portRanges { + stringPortRanges = append(stringPortRanges, fmt.Sprintf("%d", val)) + } + if len(stringPortRanges) > 0 && len(portString) > 0 { + portString = portString + ", " + } + portString = portString + strings.Join(stringPortRanges[:], ", ") + } + if utils.StringInSlice(container.Image, config.MythicPossibleServices) { + found := false + for _, mnt := range container.Mounts { + if strings.HasPrefix(mnt.Name, container.Image+"_volume") { + if found { + info += ", " + mnt.Name + } else { + info += mnt.Name + } + + found = true + } + } + if !found { + info += "local" + } + info += "\t" + info = info + portString + mythicLocalServices = append(mythicLocalServices, info) + } else { + for _, mnt := range container.Mounts { + if strings.Contains(mnt.Source, d.InstalledServicesPath) { + installedServices = append(installedServices, info) + elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container.Labels["name"]) + elementsInCompose = utils.RemoveStringFromSliceNoOrder(elementsInCompose, container.Labels["name"]) + } + } + } + + } + fmt.Fprintln(w, "Mythic Main Services") + fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tMOUNT\tPORTS") + for _, line := range mythicLocalServices { + fmt.Fprintln(w, line) + } + fmt.Fprintln(w, "\t\t\t\t\t") + w.Flush() + fmt.Fprintln(w, "Installed Services") + fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS") + for _, line := range installedServices { + fmt.Fprintln(w, line) + } + fmt.Fprintln(w, "\t\t\t") + // remove all elementsInCompose from elementsOnDisk + for _, container := range elementsInCompose { + elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container) + } + if len(elementsInCompose) > 0 && verbose { + fmt.Fprintln(w, "Docker Compose services not running, start with: ./mythic-cli start [name]") + fmt.Fprintln(w, "NAME\t") + sort.Strings(elementsInCompose) + for _, container := range elementsInCompose { + fmt.Fprintln(w, fmt.Sprintf("%s\t", container)) + } + fmt.Fprintln(w, "\t") + } + if len(elementsOnDisk) > 0 && verbose { + fmt.Fprintln(w, "Extra Services, add to docker compose with: ./mythic-cli add [name]") + fmt.Fprintln(w, "NAME\t") + sort.Strings(elementsOnDisk) + for _, container := range elementsOnDisk { + fmt.Fprintln(w, fmt.Sprintf("%s\t", container)) + } + fmt.Fprintln(w, "\t\t") + } + w.Flush() +} + +func (d *DockerComposeManager) ListServices() { + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("[-] Failed to get client in List Services: %v", err) + } + containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{ + All: true, + }) + if err != nil { + log.Fatalf("[-] Failed to get container list: %v\n", err) + } + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 8, 2, '\t', 0) + var installedServices []string + sort.Slice(containers[:], func(i, j int) bool { + return containers[i].Labels["name"] < containers[j].Labels["name"] + }) + elementsOnDisk, err := d.GetInstalled3rdPartyServicesOnDisk() + if err != nil { + log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) + } + elementsInCompose, err := d.GetAllExistingNonMythicServiceNames() + if err != nil { + log.Fatalf("[-] Failed to get list of installed services in docker-compose: %v\n", err) + } + for _, container := range containers { + if container.Labels["name"] == "" { + continue + } + for _, mnt := range container.Mounts { + if strings.Contains(mnt.Source, d.InstalledServicesPath) { + info := fmt.Sprintf("%s\t%s\t%v\t%v", container.Labels["name"], container.Status, true, utils.StringInSlice(container.Labels["name"], elementsInCompose)) + installedServices = append(installedServices, info) + elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container.Labels["name"]) + elementsInCompose = utils.RemoveStringFromSliceNoOrder(elementsInCompose, container.Labels["name"]) + } + } + } + for _, container := range elementsInCompose { + elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container) + } + fmt.Fprintln(w, "Name\tContainerStatus\tImageBuilt\tDockerComposeEntry") + for _, line := range installedServices { + fmt.Fprintln(w, line) + } + if len(elementsInCompose) > 0 { + sort.Strings(elementsInCompose) + for _, container := range elementsInCompose { + fmt.Fprintln(w, fmt.Sprintf("%s\t%s\t%v\t%v", container, "N/A", d.DoesImageExist(container), true)) + } + } + if len(elementsOnDisk) > 0 { + sort.Strings(elementsOnDisk) + for _, container := range elementsOnDisk { + fmt.Fprintln(w, fmt.Sprintf("%s\t%s\t%v\t%v", container, "N/A", d.DoesImageExist(container), false)) + } + } + w.Flush() +} + +func (d *DockerComposeManager) ResetDatabase(localMount bool) { + if localMount { + workingPath := utils.GetCwdFromExe() + err := os.RemoveAll(filepath.Join(workingPath, "postgres-docker", "database")) + if err != nil { + log.Printf("[-] Failed to remove database files\n%v\n", err) + } else { + log.Printf("[+] Successfully reset datbase files\n") + } + } else { + d.RemoveContainers([]string{"mythic_postgres"}) + err := d.RemoveVolume("mythic_postgres_volume") + if err != nil { + log.Printf("[-] Failed to remove database:\n%v\n", err) + } + } +} +func (d *DockerComposeManager) ListVolumes() { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + w := new(tabwriter.Writer) + w.Init(os.Stdout, 0, 8, 2, '\t', 0) + fmt.Fprintln(w, "VOLUME\tSIZE\tCONTAINER (Ref Count)\tCONTAINER STATUS\tLOCATION") + du, err := cli.DiskUsage(ctx, types.DiskUsageOptions{}) + if err != nil { + log.Fatalf("[-] Failed to get disk sizes: %v\n", err) + } + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + log.Fatalf("[-] Failed to get container list: %v\n", err) + } + if du.Volumes == nil { + log.Printf("[-] No volumes known\n") + return + } + var entries []string + for _, currentVolume := range du.Volumes { + name := currentVolume.Name + size := "unknown" + if currentVolume.UsageData != nil { + size = utils.ByteCountSI(currentVolume.UsageData.Size) + } + if !strings.HasPrefix(currentVolume.Name, "mythic_") { + continue + } + containerPieces := strings.Split(currentVolume.Name, "_") + containerName := strings.Join(containerPieces[0:2], "_") + container := "unused (0)" + containerStatus := "offline" + for _, c := range containers { + if c.Image == containerName { + containerStatus = c.Status + } + for _, m := range c.Mounts { + if m.Name == currentVolume.Name { + container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" + } + } + } + entries = append(entries, fmt.Sprintf("%s\t%s\t%s\t%s\t%s", + name, + size, + container, + containerStatus, + currentVolume.Mountpoint, + )) + } + sort.Strings(entries) + for _, line := range entries { + fmt.Fprintln(w, line) + } + + defer w.Flush() + return +} +func (d *DockerComposeManager) RemoveVolume(volumeName string) error { + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + panic(err) + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + err = cli.VolumeRemove(ctx, currentVolume.Name, true) + if err != nil { + return err + } + } + } + return nil +} +func (d *DockerComposeManager) CopyIntoVolume(sourceFile io.Reader, destinationFileName string, destinationVolume string) { + err := d.ensureVolume(destinationVolume) + if err != nil { + log.Fatalf("[-] Failed to ensure volume exists: %v\n", err) + } + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("[-] Failed to connect to docker api: %v\n", err) + } + defer cli.Close() + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + log.Fatalf("[-] Failed to get container list: %v\n", err) + } + for _, container := range containers { + for _, mnt := range container.Mounts { + if mnt.Name == destinationVolume { + err = cli.CopyToContainer(ctx, container.ID, mnt.Destination+"/"+destinationFileName, sourceFile, types.CopyToContainerOptions{ + CopyUIDGID: true, + }) + if err != nil { + log.Fatalf("[-] Failed to write file: %v\n", err) + } else { + log.Printf("[+] Successfully wrote file\n") + } + return + } + } + } + log.Fatalf("[-] Failed to find that volume name in use by any containers") +} +func (d *DockerComposeManager) CopyFromVolume(sourceVolumeName string, sourceFileName string, destinationName string) { + err := d.ensureVolume(sourceVolumeName) + if err != nil { + log.Fatalf("[-] Failed to ensure volume exists: %v\n", err) + } + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + log.Fatalf("[-] Failed to connect to docker api: %v\n", err) + } + defer cli.Close() + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + log.Fatalf("[-] Failed to get container list: %v\n", err) + } + for _, container := range containers { + for _, mnt := range container.Mounts { + if mnt.Name == sourceVolumeName { + reader, _, err := cli.CopyFromContainer(ctx, container.ID, mnt.Destination+"/"+sourceFileName) + if err != nil { + log.Printf("[-] Failed to read file: %v\n", err) + return + } + destination, err := os.Create(destinationName) + if err != nil { + log.Printf("[-] Failed to open destination filename: %v\n", err) + return + } + _, err = io.Copy(destination, reader) + destination.Close() + if err != nil { + log.Printf("[-] Failed to get file from volume: %v\n", err) + return + } + log.Printf("[+] Successfully wrote file\n") + return + } + } + } + log.Fatalf("[-] Failed to find that volume name in use by any containers") +} + // Internal Support Commands func (d *DockerComposeManager) getMythicEnvList() []string { env := config.GetMythicEnv().AllSettings() @@ -573,7 +1011,6 @@ func (d *DockerComposeManager) getMythicEnvList() []string { val := config.GetMythicEnv().GetString(key) if val != "" { // prevent trying to append arrays or dictionaries to our environment list - //fmt.Println(strings.ToUpper(key), val) envList = append(envList, strings.ToUpper(key)+"="+val) } } @@ -690,25 +1127,17 @@ func (d *DockerComposeManager) runDockerCompose(args []string) error { wg.Wait() err = command.Wait() if err != nil { - fmt.Printf("[-] Error from docker-compose: %v\n", err) - fmt.Printf("[*] Docker compose command: %v\n", args) + log.Printf("[-] Error from docker-compose: %v\n", err) + log.Printf("[*] Docker compose command: %v\n", args) return err } return nil } -func (d *DockerComposeManager) setDockerComposeDefaultsAndWrite(curConfig *viper.Viper) error { - curConfig.Set("version", "2.4") - file := curConfig.ConfigFileUsed() - if len(file) == 0 { - file = "./docker-compose.yml" - } - configMap := curConfig.AllSettings() - ignoredKeys := []string{"networks"} - for _, key := range ignoredKeys { - delete(configMap, key) - } - - content, err := yaml.Marshal(configMap) +func (d *DockerComposeManager) setDockerComposeDefaultsAndWrite(curConfig map[string]interface{}) error { + file := filepath.Join(utils.GetCwdFromExe(), "docker-compose.yml") + curConfig["version"] = "2.4" + delete(curConfig, "networks") + content, err := yaml.Marshal(curConfig) if err != nil { return err } @@ -728,6 +1157,49 @@ func (d *DockerComposeManager) readInDockerCompose() *viper.Viper { } return curConfig } +func (d *DockerComposeManager) ensureVolume(volumeName string) error { + containerNamePieces := strings.Split(volumeName, "_") + containerName := strings.Join(containerNamePieces[0:2], "_") + ctx := context.Background() + cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) + if err != nil { + return err + } + defer cli.Close() + volumes, err := cli.VolumeList(ctx, volume.ListOptions{}) + if err != nil { + return err + } + foundVolume := false + for _, currentVolume := range volumes.Volumes { + if currentVolume.Name == volumeName { + foundVolume = true + } + } + if !foundVolume { + _, err = cli.VolumeCreate(ctx, volume.CreateOptions{Name: volumeName}) + if err != nil { + return err + } + } + // now that we know the volume exists, make sure it's attached to a running container or we can't manipulate files + containers, err := cli.ContainerList(ctx, types.ContainerListOptions{Size: true}) + if err != nil { + return err + } + for _, container := range containers { + if container.Image == containerName { + for _, mnt := range container.Mounts { + if mnt.Name == volumeName { + // container is running and has this mount associated with it + return nil + } + } + return errors.New(fmt.Sprintf("container, %s, isn't using volume, %s", containerName, volumeName)) + } + } + return errors.New(fmt.Sprintf("failed to find container, %s, for volume, %s", containerName, volumeName)) +} // GetAllExistingNonMythicServiceNames from reading in the docker-compose file, not necessarily what's running func (d *DockerComposeManager) GetAllExistingNonMythicServiceNames() ([]string, error) { @@ -738,10 +1210,10 @@ func (d *DockerComposeManager) GetAllExistingNonMythicServiceNames() ([]string, groupNameConfig.AddConfigPath(utils.GetCwdFromExe()) if err := groupNameConfig.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) + log.Printf("[-] Error while reading in docker-compose file: %s\n", err) return []string{}, err } else { - fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) + log.Printf("[-] Error while parsing docker-compose file: %s\n", err) return []string{}, err } } @@ -764,10 +1236,10 @@ func (d *DockerComposeManager) GetCurrentMythicServiceNames() ([]string, error) groupNameConfig.AddConfigPath(utils.GetCwdFromExe()) if err := groupNameConfig.ReadInConfig(); err != nil { if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in docker-compose file: %s\n", err) + log.Printf("[-] Error while reading in docker-compose file: %s\n", err) return []string{}, err } else { - fmt.Printf("[-] Error while parsing docker-compose file: %s\n", err) + log.Printf("[-] Error while parsing docker-compose file: %s\n", err) return []string{}, err } } diff --git a/Mythic_CLI/src/cmd/manager/managerInterface.go b/Mythic_CLI/src/cmd/manager/managerInterface.go index ed6097a55..f9577018d 100644 --- a/Mythic_CLI/src/cmd/manager/managerInterface.go +++ b/Mythic_CLI/src/cmd/manager/managerInterface.go @@ -2,6 +2,7 @@ package manager import ( "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "io" "path/filepath" ) @@ -56,6 +57,22 @@ type CLIManager interface { GetLogs(service string, logCount int) // TestPorts check to make sure all ports are available for services to use TestPorts() + // PrintConnectionInfo lists out connection information for the various services (web endpoints, open ports, etc) + PrintConnectionInfo() + // Status prints out the current status of all the containers and volumes in use + Status(verbose bool) + // ListServices prints out all the 3rd party services on disk and currently installed + ListServices() + // ResetDatabase deletes the current database or volume + ResetDatabase(localMount bool) + // ListVolumes prints out all of the volumes in use by Mythic + ListVolumes() + // RemoveVolume removes the named volume + RemoveVolume(volumeName string) error + // CopyIntoVolume copies from a source io.Reader to the destination filename on the destination volume + CopyIntoVolume(sourceFile io.Reader, destinationFileName string, destinationVolume string) + // CopyFromVolume copies from the source filename in the volume to the destination filename outside of the volume + CopyFromVolume(sourceVolumeName string, sourceFileName string, destinationName string) } var currentManager CLIManager diff --git a/Mythic_CLI/src/cmd/rabbitmqReset.go b/Mythic_CLI/src/cmd/rabbitmqReset.go deleted file mode 100644 index fdcaada7d..000000000 --- a/Mythic_CLI/src/cmd/rabbitmqReset.go +++ /dev/null @@ -1,22 +0,0 @@ -package cmd - -import ( - "github.com/MythicMeta/Mythic_CLI/cmd/internal" - "github.com/spf13/cobra" -) - -// configCmd represents the config command -var rabbitmqResetCmd = &cobra.Command{ - Use: "reset", - Short: "reset rabbitmq", - Long: `Run this command to stop mythic and delete the current RabbitMQ storage`, - Run: rabbitmqReset, -} - -func init() { - rabbitmqCmd.AddCommand(rabbitmqResetCmd) -} - -func rabbitmqReset(cmd *cobra.Command, args []string) { - internal.RabbitmqReset(true) -} diff --git a/Mythic_CLI/src/cmd/utils/utils.go b/Mythic_CLI/src/cmd/utils/utils.go index f40de7445..84947d9b4 100644 --- a/Mythic_CLI/src/cmd/utils/utils.go +++ b/Mythic_CLI/src/cmd/utils/utils.go @@ -53,10 +53,10 @@ func RemoveStringFromSliceNoOrder(source []string, str string) []string { // we didn't find the element to remove return source } -func UpdateEnvironmentVariables(originalList []string, updates []string) []string { +func UpdateEnvironmentVariables(originalList []interface{}, updates []string) []string { var finalList []string for _, entry := range originalList { - entryPieces := strings.Split(entry, "=") + entryPieces := strings.Split(entry.(string), "=") found := false for _, update := range updates { updatePieces := strings.Split(update, "=") @@ -66,7 +66,7 @@ func UpdateEnvironmentVariables(originalList []string, updates []string) []strin } } if !found { - finalList = append(finalList, entry) + finalList = append(finalList, entry.(string)) } } for _, update := range updates { From bf2f8a0d0b89dffc9bc4cd58373047aea0f77c32 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 08:52:26 -0600 Subject: [PATCH 071/117] v0.0.2.34 --- Mythic_CLI/src/cmd/addDockerCompose.go | 12 +- Mythic_CLI/src/cmd/config/env.go | 16 +-- Mythic_CLI/src/cmd/internal/installservice.go | 9 +- Mythic_CLI/src/cmd/internal/reset.go | 2 +- .../src/cmd/internal/serviceExecution.go | 6 +- .../src/cmd/internal/serviceMetadata.go | 27 ++--- Mythic_CLI/src/cmd/internal/testServices.go | 11 +- Mythic_CLI/src/cmd/internal/utils.go | 2 +- Mythic_CLI/src/cmd/logs.go | 15 ++- .../src/cmd/manager/dockerComposeManager.go | 104 +++++++----------- .../src/cmd/manager/managerInterface.go | 12 +- Mythic_CLI/src/cmd/mythic_sync.go | 3 +- Mythic_CLI/src/cmd/mythic_sync_install.go | 3 +- .../src/cmd/mythic_sync_install_github.go | 2 +- Mythic_CLI/src/cmd/removeDockerCompose.go | 8 +- Mythic_CLI/src/go.mod | 1 + Mythic_CLI/src/go.sum | 2 + nginx-docker/health_check.sh | 8 +- 18 files changed, 122 insertions(+), 121 deletions(-) diff --git a/Mythic_CLI/src/cmd/addDockerCompose.go b/Mythic_CLI/src/cmd/addDockerCompose.go index 990500c1a..72c8615d4 100644 --- a/Mythic_CLI/src/cmd/addDockerCompose.go +++ b/Mythic_CLI/src/cmd/addDockerCompose.go @@ -1,8 +1,11 @@ package cmd import ( + "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/MythicMeta/Mythic_CLI/cmd/utils" "github.com/spf13/cobra" + "log" ) // configCmd represents the config command @@ -19,7 +22,12 @@ func init() { } func addDockerCompose(cmd *cobra.Command, args []string) { - if err := internal.Add3rdPartyService(args[0], make(map[string]interface{})); err != nil { - + if utils.StringInSlice(args[0], config.MythicPossibleServices) { + internal.AddMythicService(args[0]) + return + } + err := internal.Add3rdPartyService(args[0], make(map[string]interface{})) + if err != nil { + log.Printf("[-] Failed to add service") } } diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index 761adb669..3a699585b 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -106,17 +106,17 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("nginx_use_ssl", true) mythicEnv.SetDefault("nginx_use_ipv4", true) mythicEnv.SetDefault("nginx_use_ipv6", true) - mythicEnv.SetDefault("nginx_bind_local_mount", true) + mythicEnv.SetDefault("nginx_bind_use_volume", false) // mythic react UI configuration mythicEnv.SetDefault("mythic_react_host", "mythic_react") mythicEnv.SetDefault("mythic_react_port", 3000) mythicEnv.SetDefault("mythic_react_bind_localhost_only", true) - mythicEnv.SetDefault("mythic_react_local_mount", true) + mythicEnv.SetDefault("mythic_react_use_volume", false) // documentation configuration mythicEnv.SetDefault("documentation_host", "mythic_documentation") mythicEnv.SetDefault("documentation_port", 8090) mythicEnv.SetDefault("documentation_bind_localhost_only", true) - mythicEnv.SetDefault("documentation_bind_local_mount", true) + mythicEnv.SetDefault("documentation_bind_use_volume", false) // mythic server configuration mythicEnv.SetDefault("mythic_debug_agent_message", false) mythicEnv.SetDefault("mythic_server_port", 17443) @@ -127,7 +127,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("mythic_server_mem_limit", "") mythicEnv.SetDefault("mythic_server_dynamic_ports", "7000-7010") mythicEnv.SetDefault("mythic_server_dynamic_ports_bind_localhost_only", false) - mythicEnv.SetDefault("mythic_server_bind_local_mount", true) + mythicEnv.SetDefault("mythic_server_bind_use_volume", false) mythicEnv.SetDefault("mythic_server_command", "") mythicEnv.SetDefault("mythic_sync_cpus", "2") mythicEnv.SetDefault("mythic_sync_mem_limit", "") @@ -140,7 +140,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("postgres_password", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("postgres_cpus", "2") mythicEnv.SetDefault("postgres_mem_limit", "") - mythicEnv.SetDefault("postgres_bind_local_mount", true) + mythicEnv.SetDefault("postgres_bind_use_volume", false) // rabbitmq configuration mythicEnv.SetDefault("rabbitmq_host", "mythic_rabbitmq") mythicEnv.SetDefault("rabbitmq_port", 5672) @@ -150,7 +150,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("rabbitmq_vhost", "mythic_vhost") mythicEnv.SetDefault("rabbitmq_cpus", "2") mythicEnv.SetDefault("rabbitmq_mem_limit", "") - mythicEnv.SetDefault("rabbitmq_bind_local_mount", true) + mythicEnv.SetDefault("rabbitmq_bind_use_volume", false) // jwt configuration mythicEnv.SetDefault("jwt_secret", utils.GenerateRandomPassword(30)) // hasura configuration @@ -160,7 +160,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("hasura_secret", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("hasura_cpus", "2") mythicEnv.SetDefault("hasura_mem_limit", "2gb") - mythicEnv.SetDefault("hasura_bind_local_mount", true) + mythicEnv.SetDefault("hasura_bind_use_volume", false) // docker-compose configuration mythicEnv.SetDefault("COMPOSE_PROJECT_NAME", "mythic") mythicEnv.SetDefault("REBUILD_ON_START", true) @@ -178,7 +178,7 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("jupyter_cpus", "2") mythicEnv.SetDefault("jupyter_mem_limit", "") mythicEnv.SetDefault("jupyter_bind_localhost_only", true) - mythicEnv.SetDefault("jupyter_bind_local_mount", true) + mythicEnv.SetDefault("jupyter_bind_use_volume", false) // debugging help mythicEnv.SetDefault("postgres_debug", false) mythicEnv.SetDefault("mythic_react_debug", false) diff --git a/Mythic_CLI/src/cmd/internal/installservice.go b/Mythic_CLI/src/cmd/internal/installservice.go index f9121cf1b..50d1490ba 100644 --- a/Mythic_CLI/src/cmd/internal/installservice.go +++ b/Mythic_CLI/src/cmd/internal/installservice.go @@ -156,7 +156,7 @@ func InstallFolder(installPath string, overWrite bool) error { for _, f := range files { if f.IsDir() { log.Printf("[*] Processing Documentation for %s\n", f.Name()) - if config.GetMythicEnv().GetBool("documentation_bind_local_mount") { + if !config.GetMythicEnv().GetBool("documentation_bind_use_volume") { if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { log.Printf("[*] Removing current version\n") @@ -206,7 +206,7 @@ func InstallFolder(installPath string, overWrite bool) error { for _, f := range files { if f.IsDir() { log.Printf("[*] Processing Documentation for %s\n", f.Name()) - if config.GetMythicEnv().GetBool("document_bind_local_mount") { + if !config.GetMythicEnv().GetBool("document_bind_use_volume") { if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { log.Printf("[*] Removing current version\n") @@ -459,6 +459,7 @@ func InstallMythicSyncFolder(installPath string) error { AddMythicService(service) log.Printf("[+] Successfully installed mythic_sync!\n") if manager.GetManager().IsServiceRunning("mythic_server") { + log.Printf("[*] Starting mythic_sync") err = ServiceStart([]string{strings.ToLower(service)}) if err != nil { log.Printf("[-] Failed to start mythic_sync: %v\n", err) @@ -483,10 +484,10 @@ func InstallMythicSync(url string, branch string) error { } if branch == "" { log.Printf("[*] Cloning %s\n", url) - err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--recurse-submodules", "--single-branch", url, filepath.Join(workingPath, "tmp")}) + err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--depth 1", "--recurse-submodules", "--single-branch", url, filepath.Join(workingPath, "tmp")}) } else { log.Printf("[*] Cloning branch \"%s\" from %s\n", branch, url) - err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--recurse-submodules", "--single-branch", "--branch", branch, url, filepath.Join(workingPath, "tmp")}) + err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--depth 1", "--recurse-submodules", "--single-branch", "--branch", branch, url, filepath.Join(workingPath, "tmp")}) } if err != nil { log.Printf("[-] Failed to clone down repository: %v\n", err) diff --git a/Mythic_CLI/src/cmd/internal/reset.go b/Mythic_CLI/src/cmd/internal/reset.go index c15cc9a4b..2b86a515e 100644 --- a/Mythic_CLI/src/cmd/internal/reset.go +++ b/Mythic_CLI/src/cmd/internal/reset.go @@ -13,7 +13,7 @@ func DatabaseReset() { if confirm { log.Printf("[*] Stopping Mythic\n") manager.GetManager().StopServices([]string{}, config.GetMythicEnv().GetBool("REBUILD_ON_START")) - manager.GetManager().ResetDatabase(config.GetMythicEnv().GetBool("postgres_bind_local_mount")) + manager.GetManager().ResetDatabase(config.GetMythicEnv().GetBool("postgres_bind_use_volume")) log.Printf("[*] Removing database files\n") } } diff --git a/Mythic_CLI/src/cmd/internal/serviceExecution.go b/Mythic_CLI/src/cmd/internal/serviceExecution.go index dc9299411..42a0bc97f 100644 --- a/Mythic_CLI/src/cmd/internal/serviceExecution.go +++ b/Mythic_CLI/src/cmd/internal/serviceExecution.go @@ -19,7 +19,7 @@ func ServiceStart(containers []string) error { if err != nil { return err } - dockerComposeContainers, err := manager.GetManager().GetAllExistingNonMythicServiceNames() + dockerComposeContainers, err := manager.GetManager().GetAllInstalled3rdPartyServiceNames() if err != nil { return err } @@ -72,7 +72,7 @@ func ServiceStart(containers []string) error { AddMythicService(service) } } - manager.GetManager().TestPorts() + manager.GetManager().TestPorts(finalContainers) err = manager.GetManager().StartServices(finalContainers, config.GetMythicEnv().GetBool("REBUILD_ON_START")) err = manager.GetManager().RemoveImages() if err != nil { @@ -134,7 +134,7 @@ func DockerBuildReactUI() error { // Docker Volume commands func VolumesList() { - manager.GetManager().ListVolumes() + manager.GetManager().PrintVolumeInformation() } func DockerRemoveVolume(volumeName string) error { return manager.GetManager().RemoveVolume(volumeName) diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index c2d4a4107..814c3ca1e 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -49,7 +49,7 @@ func AddMythicService(service string) { } else { pStruct["environment"] = environment } - if mythicEnv.GetBool("postgres_bind_local_mount") { + if !mythicEnv.GetBool("postgres_bind_use_volume") { pStruct["volumes"] = []string{ "./postgres-docker/database:/var/lib/postgresql/data", "./postgres-docker/postgres.conf:/etc/postgresql.conf", @@ -83,7 +83,7 @@ func AddMythicService(service string) { pStruct["environment"] = []string{ "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", } - if mythicEnv.GetBool("documentation_bind_local_mount") { + if !mythicEnv.GetBool("documentation_bind_use_volume") { pStruct["volumes"] = []string{ "./documentation-docker/:/src", } @@ -135,7 +135,7 @@ func AddMythicService(service string) { "${HASURA_PORT}:${HASURA_PORT}", } } - if mythicEnv.GetBool("hasura_bind_local_mount") { + if !mythicEnv.GetBool("hasura_bind_use_volume") { pStruct["volumes"] = []string{ "./hasura-docker/metadata:/metadata", } @@ -202,7 +202,7 @@ func AddMythicService(service string) { "${NGINX_PORT}:${NGINX_PORT}", } } - if mythicEnv.GetBool("nginx_bind_local_mount") { + if !mythicEnv.GetBool("nginx_bind_use_volume") { pStruct["volumes"] = []string{ "./nginx-docker/ssl:/etc/ssl/private", "./nginx-docker/config:/etc/nginx", @@ -260,7 +260,7 @@ func AddMythicService(service string) { } } pStruct["environment"] = finalRabbitEnv - if mythicEnv.GetBool("rabbitmq_bind_local_mount") { + if !mythicEnv.GetBool("rabbitmq_bind_use_volume") { pStruct["volumes"] = []string{ "./rabbitmq-docker/storage:/var/lib/rabbitmq", "./rabbitmq-docker/generate_config.sh:/generate_config.sh", @@ -294,7 +294,7 @@ func AddMythicService(service string) { "context": "./mythic-react-docker", "args": config.GetBuildArguments(), } - if mythicEnv.GetBool("mythic_react_bind_local_mount") { + if !mythicEnv.GetBool("mythic_react_bind_use_volume") { pStruct["volumes"] = []string{ "./mythic-react-docker/config:/etc/nginx", "./mythic-react-docker/mythic/public:/mythic/new", @@ -354,7 +354,7 @@ func AddMythicService(service string) { } */ - if mythicEnv.GetBool("jupyter_bind_local_mount") { + if !mythicEnv.GetBool("jupyter_bind_use_volume") { pStruct["volumes"] = []string{ "./jupyter-docker/jupyter:/projects", } @@ -425,7 +425,7 @@ func AddMythicService(service string) { } else { pStruct["environment"] = environment } - if mythicEnv.GetBool("mythic_server_bind_local_mount") { + if !mythicEnv.GetBool("mythic_server_bind_use_volume") { pStruct["volumes"] = []string{ "./mythic-docker/src:/usr/src/app", } @@ -508,7 +508,7 @@ func Add3rdPartyService(service string, additionalConfigs map[string]interface{} pStruct[key] = element } pStruct["build"] = map[string]interface{}{ - "context": manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), + "context": filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service), "args": config.GetBuildArguments(), } pStruct["network_mode"] = "host" @@ -542,7 +542,7 @@ func Add3rdPartyService(service string, additionalConfigs map[string]interface{} // only add in volumes if some aren't already listed if _, ok := pStruct["volumes"]; !ok { pStruct["volumes"] = []string{ - manager.GetManager().GetPathTo3rdPartyServicesOnDisk() + ":/Mythic/", + filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service) + ":/Mythic/", } } return manager.GetManager().SetServiceConfiguration(service, pStruct) @@ -552,13 +552,14 @@ func RemoveService(service string) error { } func Initialize() { + if !manager.GetManager().CheckRequiredManagerVersion() { + log.Fatalf("[-] Bad %s version\n", manager.GetManager().GetManagerName()) + } manager.GetManager().GenerateRequiredConfig() // based on .env, find out which mythic services are supposed to be running and add them to docker compose intendedMythicContainers, _ := config.GetIntendedMythicServiceNames() for _, container := range intendedMythicContainers { AddMythicService(container) } - if !manager.GetManager().CheckRequiredManagerVersion() { - log.Fatalf("[-] Bad %s version\n", manager.GetManager().GetManagerName()) - } + } diff --git a/Mythic_CLI/src/cmd/internal/testServices.go b/Mythic_CLI/src/cmd/internal/testServices.go index 9da735acd..117276cc6 100644 --- a/Mythic_CLI/src/cmd/internal/testServices.go +++ b/Mythic_CLI/src/cmd/internal/testServices.go @@ -58,7 +58,7 @@ func TestMythicConnection() { log.Printf(" If there is an issue with Mythic server, use 'mythic-cli logs mythic_server' to view potential errors\n") Status(false) log.Printf("[*] Fetching logs from mythic_server now:\n") - GetLogs("mythic_server", "500") + GetLogs("mythic_server", "500", false) os.Exit(1) } func TestMythicRabbitmqConnection() { @@ -102,7 +102,8 @@ func TestMythicRabbitmqConnection() { } } func TestPorts() error { - manager.GetManager().TestPorts() + intendedServices, _ := config.GetIntendedMythicServiceNames() + manager.GetManager().TestPorts(intendedServices) return nil } @@ -131,13 +132,13 @@ func Status(verbose bool) { log.Printf("[*] If you are using a remote PayloadType or C2Profile, they will need certain environment variables to properly connect to Mythic.\n") log.Printf(" Use 'sudo ./mythic-cli config service' for configs for these services.\n") } -func GetLogs(containerName string, numLogs string) { +func GetLogs(containerName string, numLogs string, follow bool) { logCount, err := strconv.Atoi(numLogs) if err != nil { log.Fatalf("[-] Bad log count: %v\n", err) } - manager.GetManager().GetLogs(containerName, logCount) + manager.GetManager().GetLogs(containerName, logCount, follow) } func ListServices() { - manager.GetManager().ListServices() + manager.GetManager().PrintAllServices() } diff --git a/Mythic_CLI/src/cmd/internal/utils.go b/Mythic_CLI/src/cmd/internal/utils.go index 9d87abd69..dea32ddd4 100644 --- a/Mythic_CLI/src/cmd/internal/utils.go +++ b/Mythic_CLI/src/cmd/internal/utils.go @@ -110,7 +110,7 @@ func updateNginxBlockLists() { outputString += fmt.Sprintf("allow %s;\n", ip) } outputString += "deny all;" - if config.GetMythicEnv().GetBool("nginx_bind_local_mount") { + if !config.GetMythicEnv().GetBool("nginx_bind_use_volume") { ipFilePath := filepath.Join(utils.GetCwdFromExe(), "nginx-docker", "config", "blockips.conf") if err := os.WriteFile(ipFilePath, []byte(outputString), 0600); err != nil { log.Fatalf("[-] Failed to write out block list file: %v\n", err) diff --git a/Mythic_CLI/src/cmd/logs.go b/Mythic_CLI/src/cmd/logs.go index ff1f26745..32a04a98b 100644 --- a/Mythic_CLI/src/cmd/logs.go +++ b/Mythic_CLI/src/cmd/logs.go @@ -16,9 +16,20 @@ var logsCmd = &cobra.Command{ func init() { rootCmd.AddCommand(logsCmd) - logsCmd.Flags().StringP("lines", "l", "500", "Number of lines to display") + logsCmd.Flags().StringP("lines", "l", "200", "Number of lines to display") + logsCmd.Flags().BoolP( + "follow", + "f", + false, + `Follow a constant stream of logs from the specified container.`, + ) } func getLogs(cmd *cobra.Command, args []string) { - internal.GetLogs(args[0], cmd.Flag("lines").Value.String()) + if cmd.Flag("follow").Value.String() == "true" { + internal.GetLogs(args[0], cmd.Flag("lines").Value.String(), true) + } else { + internal.GetLogs(args[0], cmd.Flag("lines").Value.String(), false) + } + } diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go index 4db2ffbfa..6b5bc03b1 100644 --- a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -8,6 +8,7 @@ import ( "fmt" "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/utils" + "github.com/creack/pty" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/volume" "github.com/docker/docker/client" @@ -323,7 +324,7 @@ func (d *DockerComposeManager) GetPathTo3rdPartyServicesOnDisk() string { // StopServices stops certain containers that are running and optionally deletes the backing images func (d *DockerComposeManager) StopServices(services []string, deleteImages bool) error { - dockerComposeContainers, err := d.GetAllExistingNonMythicServiceNames() + dockerComposeContainers, err := d.GetAllInstalled3rdPartyServiceNames() if err != nil { return err } @@ -363,14 +364,12 @@ func (d *DockerComposeManager) RemoveServices(services []string) error { if key == "services" { allServices := allConfigValues["services"].(map[string]interface{}) for _, service := range services { - if !utils.StringInSlice(service, config.MythicPossibleServices) { - if d.IsServiceRunning(service) { - _ = d.StopServices([]string{strings.ToLower(service)}, true) + if d.IsServiceRunning(service) { + _ = d.StopServices([]string{strings.ToLower(service)}, true) - } - delete(allServices, strings.ToLower(service)) - log.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) } + delete(allServices, strings.ToLower(service)) + log.Printf("[+] Removed %s from docker-compose\n", strings.ToLower(service)) } } } @@ -477,7 +476,7 @@ func (d *DockerComposeManager) BuildUI() error { return err } -func (d *DockerComposeManager) GetLogs(service string, logCount int) { +func (d *DockerComposeManager) GetLogs(service string, logCount int, follow bool) { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Fatalf("Failed to get client in GetLogs: %v", err) @@ -494,6 +493,7 @@ func (d *DockerComposeManager) GetLogs(service string, logCount int) { reader, err := cli.ContainerLogs(context.Background(), container.ID, types.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, + Follow: follow, Tail: fmt.Sprintf("%d", logCount), }) if err != nil { @@ -519,7 +519,7 @@ func (d *DockerComposeManager) GetLogs(service string, logCount int) { } } -func (d *DockerComposeManager) TestPorts() { +func (d *DockerComposeManager) TestPorts(services []string) { // go through the different services in mythicEnv and check to make sure their ports aren't already used by trying to open them //MYTHIC_SERVER_HOST:MYTHIC_SERVER_PORT //POSTGRES_HOST:POSTGRES_PORT @@ -565,19 +565,23 @@ func (d *DockerComposeManager) TestPorts() { var removeServices []string mythicEnv := config.GetMythicEnv() for key, val := range portChecks { - if mythicEnv.GetString(key) == val[1] || mythicEnv.GetString(key) == "127.0.0.1" { - addServices = append(addServices, val[1]) - p, err := net.Listen("tcp", ":"+strconv.Itoa(mythicEnv.GetInt(val[0]))) - if err != nil { - log.Fatalf("[-] Port %d, from variable %s, appears to already be in use: %v\n", mythicEnv.GetInt(val[0]), key, err) - } - err = p.Close() - if err != nil { - log.Printf("[-] Failed to close connection: %v\n", err) + // only check ports for services we're about to start + if utils.StringInSlice(val[1], services) { + if mythicEnv.GetString(key) == val[1] || mythicEnv.GetString(key) == "127.0.0.1" { + addServices = append(addServices, val[1]) + p, err := net.Listen("tcp", ":"+strconv.Itoa(mythicEnv.GetInt(val[0]))) + if err != nil { + log.Fatalf("[-] Port %d, from variable %s, appears to already be in use: %v\n", mythicEnv.GetInt(val[0]), key, err) + } + err = p.Close() + if err != nil { + log.Printf("[-] Failed to close connection: %v\n", err) + } + } else { + removeServices = append(removeServices, val[1]) } - } else { - removeServices = append(removeServices, val[1]) } + } } @@ -662,7 +666,7 @@ func (d *DockerComposeManager) Status(verbose bool) { if err != nil { log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) } - elementsInCompose, err := d.GetAllExistingNonMythicServiceNames() + elementsInCompose, err := d.GetAllInstalled3rdPartyServiceNames() if err != nil { log.Fatalf("[-] Failed to get list of installed services in docker-compose: %v\n", err) } @@ -710,12 +714,11 @@ func (d *DockerComposeManager) Status(verbose bool) { } else { info += mnt.Name } - found = true } } if !found { - info += "local" + info += "N/A" } info += "\t" info = info + portString @@ -769,7 +772,7 @@ func (d *DockerComposeManager) Status(verbose bool) { w.Flush() } -func (d *DockerComposeManager) ListServices() { +func (d *DockerComposeManager) PrintAllServices() { cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { log.Fatalf("[-] Failed to get client in List Services: %v", err) @@ -790,7 +793,7 @@ func (d *DockerComposeManager) ListServices() { if err != nil { log.Fatalf("[-] Failed to get list of installed services on disk: %v\n", err) } - elementsInCompose, err := d.GetAllExistingNonMythicServiceNames() + elementsInCompose, err := d.GetAllInstalled3rdPartyServiceNames() if err != nil { log.Fatalf("[-] Failed to get list of installed services in docker-compose: %v\n", err) } @@ -829,24 +832,24 @@ func (d *DockerComposeManager) ListServices() { w.Flush() } -func (d *DockerComposeManager) ResetDatabase(localMount bool) { - if localMount { +func (d *DockerComposeManager) ResetDatabase(useVolume bool) { + if !useVolume { workingPath := utils.GetCwdFromExe() err := os.RemoveAll(filepath.Join(workingPath, "postgres-docker", "database")) if err != nil { - log.Printf("[-] Failed to remove database files\n%v\n", err) + log.Fatalf("[-] Failed to remove database files\n%v\n", err) } else { log.Printf("[+] Successfully reset datbase files\n") } } else { - d.RemoveContainers([]string{"mythic_postgres"}) + _ = d.RemoveContainers([]string{"mythic_postgres"}) err := d.RemoveVolume("mythic_postgres_volume") if err != nil { log.Printf("[-] Failed to remove database:\n%v\n", err) } } } -func (d *DockerComposeManager) ListVolumes() { +func (d *DockerComposeManager) PrintVolumeInformation() { ctx := context.Background() cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) if err != nil { @@ -1094,43 +1097,11 @@ func (d *DockerComposeManager) runDockerCompose(args []string) error { command := exec.Command(lookPath, args...) command.Dir = exePath command.Env = d.getMythicEnvList() - - stdout, err := command.StdoutPipe() + f, err := pty.Start(command) if err != nil { - log.Fatalf("[-] Failed to get stdout pipe for running docker-compose\n") - } - stderr, err := command.StderrPipe() - if err != nil { - log.Fatalf("[-] Failed to get stderr pipe for running docker-compose\n") - } - - stdoutScanner := bufio.NewScanner(stdout) - stderrScanner := bufio.NewScanner(stderr) - wg := sync.WaitGroup{} - wg.Add(2) - go func() { - for stdoutScanner.Scan() { - fmt.Printf("%s\n", stdoutScanner.Text()) - } - wg.Done() - }() - go func() { - for stderrScanner.Scan() { - fmt.Printf("%s\n", stderrScanner.Text()) - } - wg.Done() - }() - err = command.Start() - if err != nil { - log.Fatalf("[-] Error trying to start docker-compose: %v\n", err) - } - wg.Wait() - err = command.Wait() - if err != nil { - log.Printf("[-] Error from docker-compose: %v\n", err) - log.Printf("[*] Docker compose command: %v\n", args) - return err + log.Fatalf("[-] Failed to run docker command: %v\n", err) } + io.Copy(os.Stdout, f) return nil } func (d *DockerComposeManager) setDockerComposeDefaultsAndWrite(curConfig map[string]interface{}) error { @@ -1201,8 +1172,7 @@ func (d *DockerComposeManager) ensureVolume(volumeName string) error { return errors.New(fmt.Sprintf("failed to find container, %s, for volume, %s", containerName, volumeName)) } -// GetAllExistingNonMythicServiceNames from reading in the docker-compose file, not necessarily what's running -func (d *DockerComposeManager) GetAllExistingNonMythicServiceNames() ([]string, error) { +func (d *DockerComposeManager) GetAllInstalled3rdPartyServiceNames() ([]string, error) { // get all services that exist within the loaded config groupNameConfig := viper.New() groupNameConfig.SetConfigName("docker-compose") diff --git a/Mythic_CLI/src/cmd/manager/managerInterface.go b/Mythic_CLI/src/cmd/manager/managerInterface.go index f9577018d..121a37ebb 100644 --- a/Mythic_CLI/src/cmd/manager/managerInterface.go +++ b/Mythic_CLI/src/cmd/manager/managerInterface.go @@ -44,7 +44,7 @@ type CLIManager interface { // GetInstalled3rdPartyServicesOnDisk returns the names of the installed services on disk GetInstalled3rdPartyServicesOnDisk() ([]string, error) // GetAllExistingNonMythicServiceNames reads current configuration and returns all non-mythic services - GetAllExistingNonMythicServiceNames() ([]string, error) + GetAllInstalled3rdPartyServiceNames() ([]string, error) // GetCurrentMythicServiceNames reads current configuration and returns all mythic services GetCurrentMythicServiceNames() ([]string, error) // GetPathTo3rdPartyServicesOnDisk returns the path where a 3rd party services Dockerfile lives on disk @@ -54,19 +54,19 @@ type CLIManager interface { // BuildUI a new instance of the Mythic React UI and save it in the mythic-react-docker folder BuildUI() error // GetLogs fetches logCount of the most recent logs from the service container - GetLogs(service string, logCount int) + GetLogs(service string, logCount int, follow bool) // TestPorts check to make sure all ports are available for services to use - TestPorts() + TestPorts(services []string) // PrintConnectionInfo lists out connection information for the various services (web endpoints, open ports, etc) PrintConnectionInfo() // Status prints out the current status of all the containers and volumes in use Status(verbose bool) // ListServices prints out all the 3rd party services on disk and currently installed - ListServices() + PrintAllServices() // ResetDatabase deletes the current database or volume - ResetDatabase(localMount bool) + ResetDatabase(useVolume bool) // ListVolumes prints out all of the volumes in use by Mythic - ListVolumes() + PrintVolumeInformation() // RemoveVolume removes the named volume RemoveVolume(volumeName string) error // CopyIntoVolume copies from a source io.Reader to the destination filename on the destination volume diff --git a/Mythic_CLI/src/cmd/mythic_sync.go b/Mythic_CLI/src/cmd/mythic_sync.go index 8a1ae5ab6..6b98fda0c 100644 --- a/Mythic_CLI/src/cmd/mythic_sync.go +++ b/Mythic_CLI/src/cmd/mythic_sync.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/spf13/cobra" + "log" ) // installCmd represents the config command @@ -17,5 +18,5 @@ func init() { } func mythicSync(cmd *cobra.Command, args []string) { - + log.Fatalf("[-] Must specify install/uninstall") } diff --git a/Mythic_CLI/src/cmd/mythic_sync_install.go b/Mythic_CLI/src/cmd/mythic_sync_install.go index 3f8d1a088..fc2ec3c63 100644 --- a/Mythic_CLI/src/cmd/mythic_sync_install.go +++ b/Mythic_CLI/src/cmd/mythic_sync_install.go @@ -2,6 +2,7 @@ package cmd import ( "github.com/spf13/cobra" + "log" ) // installCmd represents the config command @@ -18,5 +19,5 @@ func init() { } func installMythicSync(cmd *cobra.Command, args []string) { - + log.Fatalf("[-] Must specify github or folder") } diff --git a/Mythic_CLI/src/cmd/mythic_sync_install_github.go b/Mythic_CLI/src/cmd/mythic_sync_install_github.go index 92a12b986..e4c7089bb 100644 --- a/Mythic_CLI/src/cmd/mythic_sync_install_github.go +++ b/Mythic_CLI/src/cmd/mythic_sync_install_github.go @@ -23,7 +23,7 @@ func init() { "force", "f", false, - `Force installing from GitHub and don't prompt to overwrite files if an older version is already installed'`, + `Force installing from GitHub and don't prompt to overwrite files if an older version is already installed`, ) installMythicSyncGitHubCmd.Flags().StringVarP( &branch, diff --git a/Mythic_CLI/src/cmd/removeDockerCompose.go b/Mythic_CLI/src/cmd/removeDockerCompose.go index fa10fb4b9..b7016c15f 100644 --- a/Mythic_CLI/src/cmd/removeDockerCompose.go +++ b/Mythic_CLI/src/cmd/removeDockerCompose.go @@ -3,6 +3,7 @@ package cmd import ( "github.com/MythicMeta/Mythic_CLI/cmd/internal" "github.com/spf13/cobra" + "log" ) // configCmd represents the config command @@ -19,7 +20,10 @@ func init() { } func removeDockerCompose(cmd *cobra.Command, args []string) { - if err := internal.RemoveService(args[0]); err != nil { - + err := internal.RemoveService(args[0]) + if err != nil { + log.Printf("[-] Failed to remove service") + return } + log.Printf("[+] Successfully removed service") } diff --git a/Mythic_CLI/src/go.mod b/Mythic_CLI/src/go.mod index 3cdcd308e..42a712b96 100644 --- a/Mythic_CLI/src/go.mod +++ b/Mythic_CLI/src/go.mod @@ -12,6 +12,7 @@ require ( require ( github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/creack/pty v1.1.21 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect diff --git a/Mythic_CLI/src/go.sum b/Mythic_CLI/src/go.sum index 04c3cdad6..01da836b3 100644 --- a/Mythic_CLI/src/go.sum +++ b/Mythic_CLI/src/go.sum @@ -51,6 +51,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= +github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= diff --git a/nginx-docker/health_check.sh b/nginx-docker/health_check.sh index a43ad0bda..85c9fe8a0 100644 --- a/nginx-docker/health_check.sh +++ b/nginx-docker/health_check.sh @@ -1,8 +1,8 @@ -#!/bin/bash +#!/bin/sh -if [ "$NGINX_USE_SSL" == "ssl" ] +if [ "$NGINX_USE_SSL" = "ssl" ] then - curl -k https://127.0.0.1:${NGINX_PORT:-7443}/new/login + curl -k https://127.0.0.1:"${NGINX_PORT:-7443}"/new/login else - curl -k http://127.0.0.1:${NGINX_PORT:-7443}/new/login + curl -k http://127.0.0.1:"${NGINX_PORT:-7443}"/new/login fi From 318eed0ea6bfe5ba542cdc48d46a15231995e775 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 15:01:22 +0000 Subject: [PATCH 072/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.34' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 4 ++-- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 6e05007af..2cb4c20ce 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.34 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index cbeacdc38..b09c12165 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.34 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index c3af00e0a..0fd9a2198 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.34 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 24f5c4064..be08ae31d 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.33 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.34 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 57b2b667b..23ad3d294 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1,6 +1,6 @@ #FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 -FROM itsafeaturemythic/mythic_go_base:latest +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.34 WORKDIR /usr/src/app @@ -14,7 +14,7 @@ COPY ["src/", "."] RUN make build_final -FROM alpine +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.34 COPY --from=0 /mythic_server /mythic_server diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 6b479fad0..2f4cceecb 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.34 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index d136512ff..c85db4f60 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.34 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index fdbf96f7f..67fec6b4d 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.34 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 07a8f80ac..28819fb50 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.33 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.34 \ No newline at end of file From 6535887dfe94d6d37be103dde41ae1e092612dfa Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 16:10:05 -0600 Subject: [PATCH 073/117] v0.0.2.35 --- .github/workflows/docker.yml | 100 ++++++++++------- Mythic_CLI/src/cmd/config/env.go | 24 ++-- .../src/cmd/internal/serviceMetadata.go | 106 ++++++++++++------ .../src/cmd/manager/dockerComposeManager.go | 1 + 4 files changed, 149 insertions(+), 82 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 893bb1028..4a7a91793 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -87,48 +87,6 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 - mythic_cli: - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - steps: - # Pull in the repository code - - name: Checkout the repository - uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout - - name: Log in to the container registry - uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - with: - platforms: 'arm64,arm' - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - # the following are unique to this job - - name: Lowercase the cli container image name - run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} - - name: Build and push the cli container image - uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images - with: - context: Mythic_CLI - file: Mythic_CLI/.docker/Dockerfile - tags: | - ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:${{ env.VERSION }} - ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:latest - push: true - # These container metadata labels allow configuring the package in Github - # packages. The source will link the package to this Github repository - labels: | - org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} - org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} - org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} - platforms: linux/amd64,linux/arm64 - mythic_postgres: runs-on: ubuntu-latest permissions: @@ -431,6 +389,64 @@ jobs: org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + # update mythic-cli latest after we're sure all the others build properly + mythic_cli: + runs-on: ubuntu-latest + needs: + - mythic_server + - mythic_postgres + - mythic_rabbitmq + - mythic_documentation + - mythic_jupyter + - mythic_graphql + - mythic_nginx + - mythic_react + permissions: + contents: write + packages: write + steps: + # Pull in the repository code + - name: Checkout the repository + uses: actions/checkout@v4 # ref: https://github.com/marketplace/actions/checkout + - name: Log in to the container registry + uses: docker/login-action@v3 # ref: https://github.com/marketplace/actions/docker-login + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: 'arm64,arm' + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + # the following are unique to this job + - name: Lowercase the cli container image name + run: echo "MYTHIC_CLI_IMAGE_NAME=${MYTHIC_CLI_IMAGE_NAME,,}" >> ${GITHUB_ENV} + + - name: Fix the mythic_docker_latest reference to reference the new release tag + working-directory: Mythic_CLI/src/cmd/config + run: | + sed -i "s|^mythicEnv.Set(\"mythic_docker_latest\", .*$|mythicEnv.Set(\"mythic_docker_latest\", \"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\")|" env.go + + - name: Build and push the cli container image + uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images + with: + context: Mythic_CLI + file: Mythic_CLI/.docker/Dockerfile + tags: | + ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:${{ env.VERSION }} + ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:latest + push: true + # These container metadata labels allow configuring the package in Github + # packages. The source will link the package to this Github repository + labels: | + org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} + org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} + platforms: linux/amd64,linux/arm64 + update_files: runs-on: ubuntu-latest needs: diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index 3a699585b..eb9c60773 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -99,6 +99,7 @@ func GetMythicEnv() *viper.Viper { func setMythicConfigDefaultValues() { // global configuration mythicEnv.SetDefault("debug_level", "warning") + mythicEnv.SetDefault("server_name", "mythic") // nginx configuration mythicEnv.SetDefault("nginx_port", 7443) mythicEnv.SetDefault("nginx_host", "mythic_nginx") @@ -106,17 +107,20 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("nginx_use_ssl", true) mythicEnv.SetDefault("nginx_use_ipv4", true) mythicEnv.SetDefault("nginx_use_ipv6", true) - mythicEnv.SetDefault("nginx_bind_use_volume", false) + mythicEnv.SetDefault("nginx_use_volume", false) + mythicEnv.SetDefault("nginx_use_build_context", true) // mythic react UI configuration mythicEnv.SetDefault("mythic_react_host", "mythic_react") mythicEnv.SetDefault("mythic_react_port", 3000) mythicEnv.SetDefault("mythic_react_bind_localhost_only", true) mythicEnv.SetDefault("mythic_react_use_volume", false) + mythicEnv.SetDefault("mythic_react_use_build_context", true) // documentation configuration mythicEnv.SetDefault("documentation_host", "mythic_documentation") mythicEnv.SetDefault("documentation_port", 8090) mythicEnv.SetDefault("documentation_bind_localhost_only", true) - mythicEnv.SetDefault("documentation_bind_use_volume", false) + mythicEnv.SetDefault("documentation_use_volume", false) + mythicEnv.SetDefault("documentation_use_build_context", true) // mythic server configuration mythicEnv.SetDefault("mythic_debug_agent_message", false) mythicEnv.SetDefault("mythic_server_port", 17443) @@ -127,7 +131,8 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("mythic_server_mem_limit", "") mythicEnv.SetDefault("mythic_server_dynamic_ports", "7000-7010") mythicEnv.SetDefault("mythic_server_dynamic_ports_bind_localhost_only", false) - mythicEnv.SetDefault("mythic_server_bind_use_volume", false) + mythicEnv.SetDefault("mythic_server_use_volume", false) + mythicEnv.SetDefault("mythic_server_use_build_context", true) mythicEnv.SetDefault("mythic_server_command", "") mythicEnv.SetDefault("mythic_sync_cpus", "2") mythicEnv.SetDefault("mythic_sync_mem_limit", "") @@ -140,7 +145,8 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("postgres_password", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("postgres_cpus", "2") mythicEnv.SetDefault("postgres_mem_limit", "") - mythicEnv.SetDefault("postgres_bind_use_volume", false) + mythicEnv.SetDefault("postgres_use_volume", false) + mythicEnv.SetDefault("postgres_use_build_context", true) // rabbitmq configuration mythicEnv.SetDefault("rabbitmq_host", "mythic_rabbitmq") mythicEnv.SetDefault("rabbitmq_port", 5672) @@ -150,7 +156,8 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("rabbitmq_vhost", "mythic_vhost") mythicEnv.SetDefault("rabbitmq_cpus", "2") mythicEnv.SetDefault("rabbitmq_mem_limit", "") - mythicEnv.SetDefault("rabbitmq_bind_use_volume", false) + mythicEnv.SetDefault("rabbitmq_use_volume", false) + mythicEnv.SetDefault("rabbitmq_use_build_context", true) // jwt configuration mythicEnv.SetDefault("jwt_secret", utils.GenerateRandomPassword(30)) // hasura configuration @@ -160,7 +167,8 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("hasura_secret", utils.GenerateRandomPassword(30)) mythicEnv.SetDefault("hasura_cpus", "2") mythicEnv.SetDefault("hasura_mem_limit", "2gb") - mythicEnv.SetDefault("hasura_bind_use_volume", false) + mythicEnv.SetDefault("hasura_use_volume", false) + mythicEnv.SetDefault("hasura_use_build_context", true) // docker-compose configuration mythicEnv.SetDefault("COMPOSE_PROJECT_NAME", "mythic") mythicEnv.SetDefault("REBUILD_ON_START", true) @@ -178,7 +186,8 @@ func setMythicConfigDefaultValues() { mythicEnv.SetDefault("jupyter_cpus", "2") mythicEnv.SetDefault("jupyter_mem_limit", "") mythicEnv.SetDefault("jupyter_bind_localhost_only", true) - mythicEnv.SetDefault("jupyter_bind_use_volume", false) + mythicEnv.SetDefault("jupyter_use_volume", false) + mythicEnv.SetDefault("jupyter_use_build_context", true) // debugging help mythicEnv.SetDefault("postgres_debug", false) mythicEnv.SetDefault("mythic_react_debug", false) @@ -251,6 +260,7 @@ func parseMythicEnvironmentVariables() { mythicEnv.Set(key, val[1]) } } + mythicEnv.Set("mythic_docker_latest", "v0.0.2.34") writeMythicEnvironmentVariables() } func writeMythicEnvironmentVariables() { diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index 814c3ca1e..5e6bb79cf 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -22,10 +22,15 @@ func AddMythicService(service string) { volumes, _ := manager.GetManager().GetVolumes() switch service { case "mythic_postgres": - pStruct["build"] = map[string]interface{}{ - "context": "./postgres-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("postgres_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./postgres-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + pStruct["cpus"] = mythicEnv.GetInt("POSTGRES_CPUS") if mythicEnv.GetString("postgres_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("postgres_mem_limit") @@ -49,7 +54,7 @@ func AddMythicService(service string) { } else { pStruct["environment"] = environment } - if !mythicEnv.GetBool("postgres_bind_use_volume") { + if !mythicEnv.GetBool("postgres_use_volume") { pStruct["volumes"] = []string{ "./postgres-docker/database:/var/lib/postgresql/data", "./postgres-docker/postgres.conf:/etc/postgresql.conf", @@ -66,11 +71,15 @@ func AddMythicService(service string) { } } case "mythic_documentation": - pStruct["build"] = "./documentation-docker" - pStruct["build"] = map[string]interface{}{ - "context": "./documentation-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("documentation_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./documentation-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + if mythicEnv.GetBool("documentation_bind_localhost_only") { pStruct["ports"] = []string{ "127.0.0.1:${DOCUMENTATION_PORT}:${DOCUMENTATION_PORT}", @@ -83,7 +92,7 @@ func AddMythicService(service string) { pStruct["environment"] = []string{ "DOCUMENTATION_PORT=${DOCUMENTATION_PORT}", } - if !mythicEnv.GetBool("documentation_bind_use_volume") { + if !mythicEnv.GetBool("documentation_use_volume") { pStruct["volumes"] = []string{ "./documentation-docker/:/src", } @@ -98,10 +107,15 @@ func AddMythicService(service string) { } } case "mythic_graphql": - pStruct["build"] = map[string]interface{}{ - "context": "./hasura-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("hasura_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./hasura-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + pStruct["cpus"] = mythicEnv.GetInt("HASURA_CPUS") if mythicEnv.GetString("hasura_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("hasura_mem_limit") @@ -135,7 +149,7 @@ func AddMythicService(service string) { "${HASURA_PORT}:${HASURA_PORT}", } } - if !mythicEnv.GetBool("hasura_bind_use_volume") { + if !mythicEnv.GetBool("hasura_use_volume") { pStruct["volumes"] = []string{ "./hasura-docker/metadata:/metadata", } @@ -150,10 +164,15 @@ func AddMythicService(service string) { } } case "mythic_nginx": - pStruct["build"] = map[string]interface{}{ - "context": "./nginx-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("nginx_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./nginx-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + nginxUseSSL := "ssl" if !mythicEnv.GetBool("NGINX_USE_SSL") { nginxUseSSL = "" @@ -202,7 +221,7 @@ func AddMythicService(service string) { "${NGINX_PORT}:${NGINX_PORT}", } } - if !mythicEnv.GetBool("nginx_bind_use_volume") { + if !mythicEnv.GetBool("nginx_use_volume") { pStruct["volumes"] = []string{ "./nginx-docker/ssl:/etc/ssl/private", "./nginx-docker/config:/etc/nginx", @@ -222,10 +241,15 @@ func AddMythicService(service string) { } } case "mythic_rabbitmq": - pStruct["build"] = map[string]interface{}{ - "context": "./rabbitmq-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("rabbitmq_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./rabbitmq-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + pStruct["cpus"] = mythicEnv.GetInt("RABBITMQ_CPUS") if mythicEnv.GetString("rabbitmq_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("rabbitmq_mem_limit") @@ -260,7 +284,7 @@ func AddMythicService(service string) { } } pStruct["environment"] = finalRabbitEnv - if !mythicEnv.GetBool("rabbitmq_bind_use_volume") { + if !mythicEnv.GetBool("rabbitmq_use_volume") { pStruct["volumes"] = []string{ "./rabbitmq-docker/storage:/var/lib/rabbitmq", "./rabbitmq-docker/generate_config.sh:/generate_config.sh", @@ -290,11 +314,16 @@ func AddMythicService(service string) { "./mythic-react-docker/mythic/public:/app/build", } } else { - pStruct["build"] = map[string]interface{}{ - "context": "./mythic-react-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("mythic_react_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./mythic-react-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } - if !mythicEnv.GetBool("mythic_react_bind_use_volume") { + + if !mythicEnv.GetBool("mythic_react_use_volume") { pStruct["volumes"] = []string{ "./mythic-react-docker/config:/etc/nginx", "./mythic-react-docker/mythic/public:/mythic/new", @@ -327,10 +356,15 @@ func AddMythicService(service string) { "MYTHIC_REACT_PORT=${MYTHIC_REACT_PORT}", } case "mythic_jupyter": - pStruct["build"] = map[string]interface{}{ - "context": "./jupyter-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("jupyter_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./jupyter-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + pStruct["cpus"] = mythicEnv.GetInt("JUPYTER_CPUS") if mythicEnv.GetString("jupyter_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("jupyter_mem_limit") @@ -354,7 +388,7 @@ func AddMythicService(service string) { } */ - if !mythicEnv.GetBool("jupyter_bind_use_volume") { + if !mythicEnv.GetBool("jupyter_use_volume") { pStruct["volumes"] = []string{ "./jupyter-docker/jupyter:/projects", } @@ -369,10 +403,15 @@ func AddMythicService(service string) { } } case "mythic_server": - pStruct["build"] = map[string]interface{}{ - "context": "./mythic-docker", - "args": config.GetBuildArguments(), + if mythicEnv.GetBool("mythic_server_use_build_context") { + pStruct["build"] = map[string]interface{}{ + "context": "./mythic-docker", + "args": config.GetBuildArguments(), + } + } else { + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) } + pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SERVER_CPUS") if mythicEnv.GetString("mythic_server_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("mythic_server_mem_limit") @@ -425,7 +464,7 @@ func AddMythicService(service string) { } else { pStruct["environment"] = environment } - if !mythicEnv.GetBool("mythic_server_bind_use_volume") { + if !mythicEnv.GetBool("mythic_server_use_volume") { pStruct["volumes"] = []string{ "./mythic-docker/src:/usr/src/app", } @@ -444,6 +483,7 @@ func AddMythicService(service string) { fmt.Printf("[-] Failed to get abs path for mythic_sync\n") return } else { + pStruct["build"] = map[string]interface{}{ "context": absPath, "args": config.GetBuildArguments(), diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go index 6b5bc03b1..624c783dd 100644 --- a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -275,6 +275,7 @@ func (d *DockerComposeManager) GetServiceConfiguration(service string) (map[stri delete(pStruct, "build") delete(pStruct, "networks") delete(pStruct, "command") + delete(pStruct, "image") delete(pStruct, "healthcheck") } else { pStruct = map[string]interface{}{ From c9919ab9492d2245ee4fc72d688d14a82e67a818 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 22:22:08 +0000 Subject: [PATCH 074/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.35' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-docker/Dockerfile | 4 ++-- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 2cb4c20ce..33de541d7 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.35 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index b09c12165..ed9e5aae4 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.35 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 0fd9a2198..e5b645275 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.35 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index be08ae31d..c15f6bbf9 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.34 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.35 diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index 23ad3d294..d419471d6 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1,6 +1,6 @@ #FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.34 +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.35 WORKDIR /usr/src/app @@ -14,7 +14,7 @@ COPY ["src/", "."] RUN make build_final -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.34 +FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.35 COPY --from=0 /mythic_server /mythic_server diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 2f4cceecb..1a789702f 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.35 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index c85db4f60..794d94a56 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.35 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 67fec6b4d..bebf3950f 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.35 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 28819fb50..92f2ad322 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.34 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.35 \ No newline at end of file From 9226e9563361c7a48b30c603314ea06c76f05d47 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 16:40:14 -0600 Subject: [PATCH 075/117] v0.0.2.36 --- .github/workflows/docker.yml | 20 ++++++++++---------- mythic-docker/Dockerfile | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4a7a91793..7b67de7cf 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|^mythicEnv.Set(\"mythic_docker_latest\", .*$|mythicEnv.Set(\"mythic_docker_latest\", \"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\")|" env.go + sed -i "s|.*mythicEnv\.Set\(\"mythic_docker_latest\".*$|mythicEnv\.Set\(\"mythic_docker_latest\", \"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\"\)|" env.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -492,44 +492,44 @@ jobs: - name: Fix the server Dockerfile reference to reference the new release tag working-directory: mythic-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the cli Dockerfile reference to reference the new release tag working-directory: Mythic_CLI run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the postgres Dockerfile reference to reference the new release tag working-directory: postgres-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_POSTGRES_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_POSTGRES_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the rabbitmq Dockerfile reference to reference the new release tag working-directory: rabbitmq-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_RABBITMQ_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_RABBITMQ_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the documentation Dockerfile reference to reference the new release tag working-directory: documentation-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_DOCUMENTATION_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_DOCUMENTATION_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the jupyter Dockerfile reference to reference the new release tag working-directory: jupyter-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_JUPYTER_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_JUPYTER_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the graphql Dockerfile reference to reference the new release tag working-directory: hasura-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_GRAPHQL_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_GRAPHQL_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the nginx Dockerfile reference to reference the new release tag working-directory: nginx-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_NGINX_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_NGINX_IMAGE_NAME}:${VERSION}|" Dockerfile - name: Fix the react Dockerfile reference to reference the new release tag working-directory: mythic-react-docker run: | - sed -i "s|^FROM .*$|FROM ${REGISTRY}/${MYTHIC_REACT_IMAGE_NAME}:${VERSION}|" Dockerfile + sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_REACT_IMAGE_NAME}:${VERSION}|" Dockerfile # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit diff --git a/mythic-docker/Dockerfile b/mythic-docker/Dockerfile index d419471d6..57b2b667b 100644 --- a/mythic-docker/Dockerfile +++ b/mythic-docker/Dockerfile @@ -1,6 +1,6 @@ #FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.32 -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.35 +FROM itsafeaturemythic/mythic_go_base:latest WORKDIR /usr/src/app @@ -14,7 +14,7 @@ COPY ["src/", "."] RUN make build_final -FROM ghcr.io/its-a-feature/mythic_server:v0.0.2.35 +FROM alpine COPY --from=0 /mythic_server /mythic_server From ab4cc228244d84e08735585d817e6ac3351c5cba Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 19:43:14 -0600 Subject: [PATCH 076/117] v0.0.2.37 --- .github/workflows/docker.yml | 2 +- Mythic_CLI/src/cmd/config/env.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7b67de7cf..c795a09b2 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|.*mythicEnv\.Set\(\"mythic_docker_latest\".*$|mythicEnv\.Set\(\"mythic_docker_latest\", \"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\"\)|" env.go + sed -i "s|.*mythicEnv.Set(\\"mythic_docker_latest\\", .*$|mythicEnv\.Set(\\"mythic_docker_latest\\", \\"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\\")|" env.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index eb9c60773..ab1557efe 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -260,7 +260,7 @@ func parseMythicEnvironmentVariables() { mythicEnv.Set(key, val[1]) } } - mythicEnv.Set("mythic_docker_latest", "v0.0.2.34") + mythicEnv.Set("mythic_docker_latest", "v0.0.2.35") writeMythicEnvironmentVariables() } func writeMythicEnvironmentVariables() { From 9404cbc72c230b7753eac82c397b68ec547166a7 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 01:55:14 +0000 Subject: [PATCH 077/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.37' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 33de541d7..f0e7d85cf 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.37 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index ed9e5aae4..717920dcb 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.37 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index e5b645275..9f57e82e1 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.37 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index c15f6bbf9..4792032c4 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.35 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.37 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 1a789702f..1a8a29389 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.37 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 794d94a56..a6c16aa64 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.37 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index bebf3950f..e2340d550 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.37 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 92f2ad322..a923c31fa 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.35 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.37 \ No newline at end of file From afa4637f22ea71e2cacba0f904f7c98948971457 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 19:56:55 -0600 Subject: [PATCH 078/117] v0.0.2.38 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c795a09b2..c827b6626 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|.*mythicEnv.Set(\\"mythic_docker_latest\\", .*$|mythicEnv\.Set(\\"mythic_docker_latest\\", \\"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\\")|" env.go + sed -i "s|.*mythicEnv\.Set(\\"mythic_docker_latest\\", .*$| mythicEnv\.Set(\\"mythic_docker_latest\\", \\"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\\")|" env.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images From 4fcf296bb582ff817108e166eef565dc4ada8d6b Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 02:08:52 +0000 Subject: [PATCH 079/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.38' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index f0e7d85cf..2611c655f 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.38 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 717920dcb..433c55925 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.38 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 9f57e82e1..5578190f0 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.38 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 4792032c4..aaea706f8 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.37 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.38 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 1a8a29389..223be8942 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.38 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index a6c16aa64..42616c63f 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.38 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index e2340d550..93588ce36 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.38 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index a923c31fa..f56c17f28 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.37 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.38 \ No newline at end of file From bdb783af10f9b647a6b91d1b54f15e4deb7c84f1 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 20:15:30 -0600 Subject: [PATCH 080/117] v0.0.2.39 --- .github/workflows/docker.yml | 2 +- Mythic_CLI/src/cmd/config/constants.go | 3 +++ Mythic_CLI/src/cmd/config/env.go | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 Mythic_CLI/src/cmd/config/constants.go diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c827b6626..9a9a710f4 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|.*mythicEnv\.Set(\\"mythic_docker_latest\\", .*$| mythicEnv\.Set(\\"mythic_docker_latest\\", \\"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\\")|" env.go + sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \\"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\\"|" constants.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go new file mode 100644 index 000000000..d9da2fcae --- /dev/null +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -0,0 +1,3 @@ +package config + +const MythicDockerLatest = "v0.0.2.38" diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index ab1557efe..e898afade 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -260,7 +260,7 @@ func parseMythicEnvironmentVariables() { mythicEnv.Set(key, val[1]) } } - mythicEnv.Set("mythic_docker_latest", "v0.0.2.35") + mythicEnv.Set("mythic_docker_latest", MythicDockerLatest) writeMythicEnvironmentVariables() } func writeMythicEnvironmentVariables() { From 17dbabe1a9713ecea2594885279bd98b5c0c3c00 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 20:23:42 -0600 Subject: [PATCH 081/117] v0.0.2.39 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 9a9a710f4..eb035b7f7 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \\"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\\"|" constants.go + sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\"|" constants.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images From 8184851a13ffcf19fefc3468005d4c317ac4e79a Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 02:35:53 +0000 Subject: [PATCH 082/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.39' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 2611c655f..4af2d5be7 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.39 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 433c55925..c44d4882a 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.39 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 5578190f0..461ce05d3 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.39 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index aaea706f8..3f78535a0 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.38 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.39 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 223be8942..5d9f96498 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.39 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 42616c63f..05508efd2 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.39 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 93588ce36..e0aea2eab 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.39 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index f56c17f28..89f9a2146 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.38 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.39 \ No newline at end of file From 6de347c30da55762eb10f37dd5cb0fa721dcc6ec Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 20:42:09 -0600 Subject: [PATCH 083/117] v0.0.2.40 --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index eb035b7f7..603483569 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${REGISTRY}/${MYTHIC_SERVER_IMAGE_NAME}:${VERSION}\"|" constants.go + sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${VERSION}\"|" constants.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images @@ -535,7 +535,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'Mythic_CLI/src/cmd/config/constants.go', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com From 6d4898ccd00882178c26139da53426abbf4e535f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 02:54:39 +0000 Subject: [PATCH 084/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.40' --- Mythic_CLI/Dockerfile | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 4af2d5be7..440324109 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.40 \ No newline at end of file diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index c44d4882a..91419d91e 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.40 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 461ce05d3..f5c2029bd 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.40 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 3f78535a0..b86a213be 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.39 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.40 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 5d9f96498..59754955a 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.40 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 05508efd2..e001a5b82 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.40 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index e0aea2eab..4edcdb328 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.40 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 89f9a2146..fe78963ab 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.39 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.40 \ No newline at end of file From 3ef05ca8a11cf1f7b9a5e577ffa2c225f3946fb8 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 20:59:14 -0600 Subject: [PATCH 085/117] v0.0.2.41 --- .github/workflows/docker.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 603483569..48c4a934d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -446,6 +446,7 @@ jobs: org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 + outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} update_files: runs-on: ubuntu-latest @@ -499,6 +500,11 @@ jobs: run: | sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the mythic_docker_latest reference to reference the new release tag + working-directory: Mythic_CLI/src/cmd/config + run: | + sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${VERSION}\"|" constants.go + - name: Fix the postgres Dockerfile reference to reference the new release tag working-directory: postgres-docker run: | From d59e30d596ef458ce65628550a878414168dec79 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 21:09:53 -0600 Subject: [PATCH 086/117] v0.0.2.42 --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 48c4a934d..ad712a382 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -443,10 +443,10 @@ jobs: # packages. The source will link the package to this Github repository labels: | org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} - org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + org.opencontainers.image.description="${{ env.IMAGE_DESCRIPTION }}" org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 - outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} + outputs: type=image,name=target,annotation-index.org.opencontainers.image.description="${{ env.IMAGE_DESCRIPTION }}" update_files: runs-on: ubuntu-latest From 5e4470a3f1dc02edb143c2568e0d156a8881a852 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 21:18:44 -0600 Subject: [PATCH 087/117] v0.0.2.43 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index ad712a382..606ca989e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -446,7 +446,7 @@ jobs: org.opencontainers.image.description="${{ env.IMAGE_DESCRIPTION }}" org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 - outputs: type=image,name=target,annotation-index.org.opencontainers.image.description="${{ env.IMAGE_DESCRIPTION }}" + outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=\"${{ env.IMAGE_DESCRIPTION }}\" update_files: runs-on: ubuntu-latest From 6d56cf7f2602a08cf93383da13fba35077dc2dc3 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 21:32:59 -0600 Subject: [PATCH 088/117] v0.0.2.44 --- .github/workflows/docker.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 606ca989e..c6bdfa6ea 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -443,10 +443,9 @@ jobs: # packages. The source will link the package to this Github repository labels: | org.opencontainers.image.source=${{ env.IMAGE_SOURCE }} - org.opencontainers.image.description="${{ env.IMAGE_DESCRIPTION }}" org.opencontainers.image.licenses=${{ env.IMAGE_LICENSE }} platforms: linux/amd64,linux/arm64 - outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=\"${{ env.IMAGE_DESCRIPTION }}\" + outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=${{ env.IMAGE_DESCRIPTION }} update_files: runs-on: ubuntu-latest From d642bf7695a17eb7864a4e253e6173fb3a694e80 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 21:40:19 -0600 Subject: [PATCH 089/117] v0.0.2.45 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c6bdfa6ea..06ff1a98a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -28,7 +28,7 @@ env: MYTHIC_REACT_IMAGE_NAME: ${{ github.repository }}_react # Description label for the package in Github - IMAGE_DESCRIPTION: "test containers for Mythic development, do not use!" + IMAGE_DESCRIPTION: "test containers for Mythic development. Do not use this version!" # Source URL for the package in Github. This links the Github repository packages list # to this container image From d91deb45192e7aeab241f51f5080c5957cd2a3c7 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 03:52:18 +0000 Subject: [PATCH 090/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.45' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 440324109..e1c2fb8db 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.45 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index d9da2fcae..d333ac614 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,3 +1,3 @@ package config -const MythicDockerLatest = "v0.0.2.38" +const MythicDockerLatest = "v0.0.2.45" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 91419d91e..ffee40a11 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.45 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index f5c2029bd..17e6cfc8b 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.45 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index b86a213be..7a9912011 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.40 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.45 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 59754955a..01f0c0e96 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.45 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index e001a5b82..dd0e4eb11 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.45 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 4edcdb328..43b562b9a 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.45 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index fe78963ab..5e6ff83f1 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.40 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.45 \ No newline at end of file From 3b8c636868a1f09ab0255b9ffff4af435c26e557 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 22:07:39 -0600 Subject: [PATCH 091/117] v0.0.2.46 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 06ff1a98a..6b3a3c3fc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${VERSION}\"|" constants.go + sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${env.VERSION}\"|" constants.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images From 6d17fadddd03f62a0df011405eef964a4dacc5fd Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Thu, 18 Jan 2024 22:16:29 -0600 Subject: [PATCH 092/117] v0.0.2.47 --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6b3a3c3fc..06ff1a98a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -428,7 +428,7 @@ jobs: - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | - sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${env.VERSION}\"|" constants.go + sed -i "s|^const MythicDockerLatest =.*$|const MythicDockerLatest = \"${VERSION}\"|" constants.go - name: Build and push the cli container image uses: docker/build-push-action@v5 # ref: https://github.com/marketplace/actions/build-and-push-docker-images From fd3646d0fe5937f28170ef09d17ea6ae550d72ec Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 04:28:17 +0000 Subject: [PATCH 093/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.47' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index e1c2fb8db..84b736e8e 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.47 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index d333ac614..31cbbb007 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,3 +1,3 @@ package config -const MythicDockerLatest = "v0.0.2.45" +const MythicDockerLatest = "v0.0.2.47" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index ffee40a11..e54178e96 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.47 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 17e6cfc8b..3ab62ac14 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.47 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 7a9912011..2c01f4fc4 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.45 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.47 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 01f0c0e96..0b0ee11be 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.47 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index dd0e4eb11..ab60fc366 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.47 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 43b562b9a..a6f7da145 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.47 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 5e6ff83f1..a5791741d 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.45 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.47 \ No newline at end of file From 2e96028896da0704dff6da2e9ec5fe526c1a6931 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 09:32:58 -0600 Subject: [PATCH 094/117] v0.0.2.48 --- Mythic_CLI/src/cmd/config/env.go | 3 ++- .../src/cmd/manager/dockerComposeManager.go | 15 ++++++------- .../src/cmd/manager/managerInterface.go | 21 +++++++++++++------ Mythic_CLI/src/cmd/rootCmd.go | 2 ++ 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index e898afade..5df73e09f 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -99,7 +99,8 @@ func GetMythicEnv() *viper.Viper { func setMythicConfigDefaultValues() { // global configuration mythicEnv.SetDefault("debug_level", "warning") - mythicEnv.SetDefault("server_name", "mythic") + mythicEnv.SetDefault("global_server_name", "mythic") + mythicEnv.SetDefault("global_manager", "docker") // nginx configuration mythicEnv.SetDefault("nginx_port", 7443) mythicEnv.SetDefault("nginx_host", "mythic_nginx") diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go index 624c783dd..715185c15 100644 --- a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -706,19 +706,20 @@ func (d *DockerComposeManager) Status(verbose bool) { } portString = portString + strings.Join(stringPortRanges[:], ", ") } - if utils.StringInSlice(container.Image, config.MythicPossibleServices) { - found := false + if utils.StringInSlice(container.Image, config.MythicPossibleServices) || + strings.HasPrefix(container.Image, "ghcr.io/its-a-feature/mythic_") { + foundMountInfo := false for _, mnt := range container.Mounts { if strings.HasPrefix(mnt.Name, container.Image+"_volume") { - if found { + if foundMountInfo { info += ", " + mnt.Name } else { info += mnt.Name } - found = true + foundMountInfo = true } } - if !found { + if !foundMountInfo { info += "N/A" } info += "\t" @@ -887,12 +888,12 @@ func (d *DockerComposeManager) PrintVolumeInformation() { container := "unused (0)" containerStatus := "offline" for _, c := range containers { - if c.Image == containerName { + if containerName == c.Labels["name"] { containerStatus = c.Status } for _, m := range c.Mounts { if m.Name == currentVolume.Name { - container = c.Image + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" + container = containerName + " (" + strconv.Itoa(int(currentVolume.UsageData.RefCount)) + ")" } } } diff --git a/Mythic_CLI/src/cmd/manager/managerInterface.go b/Mythic_CLI/src/cmd/manager/managerInterface.go index 121a37ebb..7eb60d8e0 100644 --- a/Mythic_CLI/src/cmd/manager/managerInterface.go +++ b/Mythic_CLI/src/cmd/manager/managerInterface.go @@ -1,8 +1,10 @@ package manager import ( + "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/utils" "io" + "log" "path/filepath" ) @@ -61,11 +63,11 @@ type CLIManager interface { PrintConnectionInfo() // Status prints out the current status of all the containers and volumes in use Status(verbose bool) - // ListServices prints out all the 3rd party services on disk and currently installed + // PrintAllServices prints out all the 3rd party services on disk and currently installed PrintAllServices() // ResetDatabase deletes the current database or volume ResetDatabase(useVolume bool) - // ListVolumes prints out all of the volumes in use by Mythic + // PrintVolumeInformation prints out all the volumes in use by Mythic PrintVolumeInformation() // RemoveVolume removes the named volume RemoveVolume(volumeName string) error @@ -77,11 +79,18 @@ type CLIManager interface { var currentManager CLIManager -func init() { - currentManager = &DockerComposeManager{ - InstalledServicesPath: "InstalledServices", - InstalledServicesFolder: filepath.Join(utils.GetCwdFromExe(), "InstalledServices"), +func Initialize() { + envManager := config.GetMythicEnv().GetString("global_manager") + switch envManager { + case "docker": + currentManager = &DockerComposeManager{ + InstalledServicesPath: "InstalledServices", + InstalledServicesFolder: filepath.Join(utils.GetCwdFromExe(), "InstalledServices"), + } + default: + log.Fatalf("[-] Unknown manger specified in .env for global_manager") } + } func GetManager() CLIManager { return currentManager diff --git a/Mythic_CLI/src/cmd/rootCmd.go b/Mythic_CLI/src/cmd/rootCmd.go index bd0db9ec3..1a3b4254a 100644 --- a/Mythic_CLI/src/cmd/rootCmd.go +++ b/Mythic_CLI/src/cmd/rootCmd.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/MythicMeta/Mythic_CLI/cmd/config" "github.com/MythicMeta/Mythic_CLI/cmd/internal" + "github.com/MythicMeta/Mythic_CLI/cmd/manager" "os" ) @@ -31,5 +32,6 @@ func Execute() { func init() { // Create or parse the Docker ``.env`` file config.Initialize() + manager.Initialize() internal.Initialize() } From 1e2cd1a4fe2636b7febe04af9753d27cf34e5b71 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:45:12 +0000 Subject: [PATCH 095/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.48' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 84b736e8e..4ef4c6323 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.48 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 31cbbb007..5fc48479e 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,3 +1,3 @@ package config -const MythicDockerLatest = "v0.0.2.47" +const MythicDockerLatest = "v0.0.2.48" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index e54178e96..96627542d 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.48 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 3ab62ac14..835ff7bf7 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.48 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 2c01f4fc4..cca5fefb6 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.47 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.48 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 0b0ee11be..962d910fa 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.48 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index ab60fc366..d21b2efa1 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.48 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index a6f7da145..ab7c14ec4 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.48 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index a5791741d..9e281a165 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.47 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.48 \ No newline at end of file From 4822fe9f9695eab469d1fb49a1c4aca520aaaeec Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 11:02:33 -0600 Subject: [PATCH 096/117] v0.0.2.49 --- Mythic_CLI/src/cmd/config/constants.go | 1 + Mythic_CLI/src/cmd/config/env.go | 2 +- .../src/cmd/internal/serviceMetadata.go | 26 +++++++++++++------ .../content/C2 Profiles/_index.md | 0 4 files changed, 20 insertions(+), 9 deletions(-) mode change 100644 => 100755 documentation-docker/content/C2 Profiles/_index.md diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 5fc48479e..9b5e01f92 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,3 +1,4 @@ package config +// MythicDockerLatest is the most recent tagged version pushed to GitHub packages const MythicDockerLatest = "v0.0.2.48" diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index 5df73e09f..a6bba89e3 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -261,7 +261,7 @@ func parseMythicEnvironmentVariables() { mythicEnv.Set(key, val[1]) } } - mythicEnv.Set("mythic_docker_latest", MythicDockerLatest) + mythicEnv.Set("global_docker_latest", MythicDockerLatest) writeMythicEnvironmentVariables() } func writeMythicEnvironmentVariables() { diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index 5e6bb79cf..50747ba5d 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -27,8 +27,9 @@ func AddMythicService(service string) { "context": "./postgres-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } pStruct["cpus"] = mythicEnv.GetInt("POSTGRES_CPUS") @@ -76,8 +77,9 @@ func AddMythicService(service string) { "context": "./documentation-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } if mythicEnv.GetBool("documentation_bind_localhost_only") { @@ -112,8 +114,9 @@ func AddMythicService(service string) { "context": "./hasura-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } pStruct["cpus"] = mythicEnv.GetInt("HASURA_CPUS") @@ -169,8 +172,9 @@ func AddMythicService(service string) { "context": "./nginx-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } nginxUseSSL := "ssl" @@ -246,8 +250,9 @@ func AddMythicService(service string) { "context": "./rabbitmq-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } pStruct["cpus"] = mythicEnv.GetInt("RABBITMQ_CPUS") @@ -306,6 +311,7 @@ func AddMythicService(service string) { "context": "./MythicReactUI", "args": config.GetBuildArguments(), } + pStruct["image"] = service pStruct["volumes"] = []string{ "./MythicReactUI/src:/app/src", "./MythicReactUI/public:/app/public", @@ -319,8 +325,9 @@ func AddMythicService(service string) { "context": "./mythic-react-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } if !mythicEnv.GetBool("mythic_react_use_volume") { @@ -361,8 +368,9 @@ func AddMythicService(service string) { "context": "./jupyter-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } pStruct["cpus"] = mythicEnv.GetInt("JUPYTER_CPUS") @@ -408,8 +416,9 @@ func AddMythicService(service string) { "context": "./mythic-docker", "args": config.GetBuildArguments(), } + pStruct["image"] = service } else { - pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("mythic_docker_latest")) + pStruct["image"] = fmt.Sprintf("ghcr.io/its-a-feature/%s:%s", service, mythicEnv.GetString("global_docker_latest")) } pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SERVER_CPUS") @@ -488,6 +497,7 @@ func AddMythicService(service string) { "context": absPath, "args": config.GetBuildArguments(), } + pStruct["image"] = service pStruct["cpus"] = mythicEnv.GetInt("MYTHIC_SYNC_CPUS") if mythicEnv.GetString("mythic_sync_mem_limit") != "" { pStruct["mem_limit"] = mythicEnv.GetString("mythic_sync_mem_limit") diff --git a/documentation-docker/content/C2 Profiles/_index.md b/documentation-docker/content/C2 Profiles/_index.md old mode 100644 new mode 100755 From 0e2f7c5ea3a698d4240c2cfefbba521f7ecf67b0 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:14:29 +0000 Subject: [PATCH 097/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.49' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 4ef4c6323..4fb57d008 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.49 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 9b5e01f92..c575bcda0 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.48" +const MythicDockerLatest = "v0.0.2.49" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 96627542d..0f45358d7 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.49 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 835ff7bf7..720a513d6 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.49 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index cca5fefb6..d5a418ab3 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.48 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.49 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 962d910fa..c42cb1f17 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.49 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index d21b2efa1..66b5e6a19 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.49 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index ab7c14ec4..80c160ee0 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.49 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 9e281a165..9bfa9a3e3 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.48 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.49 \ No newline at end of file From 76c662149ea96045f761e2d6fc7ee9f92188749f Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 14:08:40 -0600 Subject: [PATCH 098/117] v0.0.2.50 --- postgres-docker/.docker/Dockerfile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index a633eff2a..cbce6bf4d 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -4,8 +4,6 @@ COPY ["configuration.sh", "/docker-entrypoint-initdb.d/configuration.sh"] COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ - CMD pg_isready -d mythic_db -p ${POSTGRES_PORT:-5432} -U mythic_user || exit 1 + CMD pg_isready -d mythic_db -U mythic_user || exit 1 -USER postgres - -CMD postgres -c "max_connections=100" -p ${POSTGRES_PORT:-5432} -c config_file=/etc/postgres.conf \ No newline at end of file +CMD ["-c", "config_file=/etc/postgres.conf", "-c", "max_connection=100"] \ No newline at end of file From d1f925eb1d63ff22bbdcfac898b8e32e0a162570 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 20:20:42 +0000 Subject: [PATCH 099/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.50' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 4fb57d008..19c2e7763 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.50 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index c575bcda0..790d761ea 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.49" +const MythicDockerLatest = "v0.0.2.50" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 0f45358d7..27f3a4e1c 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.50 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 720a513d6..1401acb3c 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.50 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index d5a418ab3..79b03b960 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.49 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.50 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index c42cb1f17..5ce81e6a1 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.50 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 66b5e6a19..7861c7ddb 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.50 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 80c160ee0..4a42f00ef 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.50 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 9bfa9a3e3..6fbadf25c 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.49 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.50 \ No newline at end of file From 9c46de7fe293ee54d7d3a940c82982e1492e5eb9 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 14:26:07 -0600 Subject: [PATCH 100/117] v0.0.2.51 --- Mythic_CLI/src/cmd/config/env.go | 37 +++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index a6bba89e3..4f524fc8c 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -8,6 +8,7 @@ import ( "log" "os" "path/filepath" + "regexp" "sort" "strings" ) @@ -305,26 +306,36 @@ func GetConfigAllStrings() map[string]string { } func GetConfigStrings(args []string) map[string]string { resultMap := make(map[string]string) + allSettings := mythicEnv.AllKeys() for i := 0; i < len(args[0:]); i++ { - setting := strings.ToLower(args[i]) - val := mythicEnv.GetString(setting) - if val == "" { - log.Fatalf("Config variable `%s` not found", setting) - } else { - resultMap[setting] = val + searchRegex, err := regexp.Compile(args[i]) + if err != nil { + log.Fatalf("[!] bad regex: %v", err) + } + for _, setting := range allSettings { + if searchRegex.MatchString(setting) { + val := mythicEnv.GetString(setting) + if val == "" { + log.Fatalf("Config variable `%s` not found", setting) + } else { + resultMap[setting] = val + } + } } } return resultMap } func SetConfigStrings(key string, value string) { - if strings.ToLower(value) == "true" { - mythicEnv.Set(key, true) - } else if strings.ToLower(value) == "false" { - mythicEnv.Set(key, false) - } else { - mythicEnv.Set(key, value) + allSettings := mythicEnv.AllKeys() + searchRegex, err := regexp.Compile(key) + if err != nil { + log.Fatalf("[!] bad regex: %v", err) + } + for _, setting := range allSettings { + if searchRegex.MatchString(setting) { + mythicEnv.Set(setting, value) + } } - mythicEnv.Get(key) writeMythicEnvironmentVariables() } func GetBuildArguments() []string { From 25a2ba3c47120dceb5076ac32dace1faf3838500 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 20:38:07 +0000 Subject: [PATCH 101/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.51' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 19c2e7763..6b0d599b0 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.51 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 790d761ea..31c58447e 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.50" +const MythicDockerLatest = "v0.0.2.51" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 27f3a4e1c..81eb33aaf 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.51 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 1401acb3c..ed885404f 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.51 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 79b03b960..1c878b0fb 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.50 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.51 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 5ce81e6a1..78cf66c67 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.51 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 7861c7ddb..d1f659c32 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.51 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 4a42f00ef..82848381a 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.51 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 6fbadf25c..e8af96980 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.50 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.51 \ No newline at end of file From 363aa2b21dd86f03fb679f83ccf5d3b60afa1cc1 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 15:03:50 -0600 Subject: [PATCH 102/117] v0.0.2.52 --- postgres-docker/.docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/postgres-docker/.docker/Dockerfile b/postgres-docker/.docker/Dockerfile index cbce6bf4d..4353364d2 100644 --- a/postgres-docker/.docker/Dockerfile +++ b/postgres-docker/.docker/Dockerfile @@ -6,4 +6,4 @@ COPY ["postgres.conf", "/etc/postgres.conf"] HEALTHCHECK --interval=30s --timeout=30s --retries=5 --start-period=20s \ CMD pg_isready -d mythic_db -U mythic_user || exit 1 -CMD ["-c", "config_file=/etc/postgres.conf", "-c", "max_connection=100"] \ No newline at end of file +CMD ["-c", "config_file=/etc/postgres.conf", "-c", "max_connections=100"] \ No newline at end of file From 5161315036cb188dcb89301075104ce2f7f7f2dc Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 21:15:54 +0000 Subject: [PATCH 103/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.52' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 6b0d599b0..3a86612cf 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.52 \ No newline at end of file diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 31c58447e..b139c952b 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.51" +const MythicDockerLatest = "v0.0.2.52" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 81eb33aaf..6c74900b4 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.52 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index ed885404f..073b44288 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.52 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 1c878b0fb..845de6829 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.51 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.52 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 78cf66c67..d3f9897a2 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.52 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index d1f659c32..efde41314 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.52 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 82848381a..edd6a4e98 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.52 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index e8af96980..cf5fe3a97 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.51 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.52 \ No newline at end of file From c1104449a1ebe4307364936fbe68b7a26471bf97 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 15:36:03 -0600 Subject: [PATCH 104/117] v0.0.2.53 --- .github/workflows/docker.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 06ff1a98a..79247f19a 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -499,6 +499,11 @@ jobs: run: | sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Dockerfile + - name: Fix the cli Makefile reference to reference the new release tag + working-directory: Mythic_CLI + run: | + sed -i "s|^BUILDER_IMAGE=ghcr\.io.*$|BUILDER_IMAGE=${REGISTRY}/${MYTHIC_CLI_IMAGE_NAME}:${VERSION}|" Makefile + - name: Fix the mythic_docker_latest reference to reference the new release tag working-directory: Mythic_CLI/src/cmd/config run: | @@ -540,7 +545,7 @@ jobs: uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified - add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'Mythic_CLI/src/cmd/config/constants.go', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile']" + add: "['mythic-docker/Dockerfile', 'Mythic_CLI/Dockerfile', 'Mythic_CLI/Makefile', 'Mythic_CLI/src/cmd/config/constants.go', 'postgres-docker/Dockerfile', 'rabbitmq-docker/Dockerfile', 'documentation-docker/Dockerfile', 'jupyter-docker/Dockerfile', 'hasura-docker/Dockerfile', 'nginx-docker/Dockerfile', 'mythic-react-docker/Dockerfile']" # Use the Github actions bot for the commit author default_author: github_actions committer_email: github-actions[bot]@users.noreply.github.com From 8c91af3f941a0222e1410688ce803fc568a102fa Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 21:48:11 +0000 Subject: [PATCH 105/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.53' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 3a86612cf..b0f11b482 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.53 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 2a72a36c4..8b44d5408 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:latest +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.53 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index b139c952b..62eb6545a 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.52" +const MythicDockerLatest = "v0.0.2.53" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 6c74900b4..2b3d05999 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.53 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 073b44288..2e40ab257 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.53 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 845de6829..596708242 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.52 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.53 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index d3f9897a2..a61c74d92 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.53 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index efde41314..1fe6dd631 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.53 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index edd6a4e98..83154d9bc 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.53 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index cf5fe3a97..141a57adb 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.52 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.53 \ No newline at end of file From cc08e7e78eaf0bad0d89ceb02be1ebdcc323f844 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Fri, 19 Jan 2024 16:13:39 -0600 Subject: [PATCH 106/117] v0.0.2.54 --- Mythic_CLI/src/cmd/internal/installservice.go | 4 ++-- Mythic_CLI/src/cmd/update.go | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Mythic_CLI/src/cmd/internal/installservice.go b/Mythic_CLI/src/cmd/internal/installservice.go index 50d1490ba..0e8d699f0 100644 --- a/Mythic_CLI/src/cmd/internal/installservice.go +++ b/Mythic_CLI/src/cmd/internal/installservice.go @@ -484,10 +484,10 @@ func InstallMythicSync(url string, branch string) error { } if branch == "" { log.Printf("[*] Cloning %s\n", url) - err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--depth 1", "--recurse-submodules", "--single-branch", url, filepath.Join(workingPath, "tmp")}) + err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--depth", "1", "--recurse-submodules", "--single-branch", url, filepath.Join(workingPath, "tmp")}) } else { log.Printf("[*] Cloning branch \"%s\" from %s\n", branch, url) - err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--depth 1", "--recurse-submodules", "--single-branch", "--branch", branch, url, filepath.Join(workingPath, "tmp")}) + err = runGitClone([]string{"-c", "http.sslVerify=false", "clone", "--depth", "1", "--recurse-submodules", "--single-branch", "--branch", branch, url, filepath.Join(workingPath, "tmp")}) } if err != nil { log.Printf("[-] Failed to clone down repository: %v\n", err) diff --git a/Mythic_CLI/src/cmd/update.go b/Mythic_CLI/src/cmd/update.go index 38a5e9b66..7ee1af3e9 100644 --- a/Mythic_CLI/src/cmd/update.go +++ b/Mythic_CLI/src/cmd/update.go @@ -108,14 +108,10 @@ func checkMythicVersion(client *http.Client, urlBase string) (needsUpdate bool, fmt.Printf("This will require a completely new clone of Mythic\n") } else if semver.MajorMinor(localVersion) != semver.MajorMinor(remoteVersion) { fmt.Printf("[!] Minor version update available. This means there has been some database updates, but not a major change to how Mythic operates.\n") - fmt.Printf("This will require deleting your current database (you will lose ALL data in your database). Please backup your database first.\n") - fmt.Printf("Use the following steps to update:\n") - fmt.Printf("1. ./mythic-cli database reset\n") - fmt.Printf("2. ./mythic-cli rabbitmq reset\n") - fmt.Printf("3. git pull\n") - fmt.Printf("4. ./mythic-cli start\n") + fmt.Printf("This will require doing a 'git pull' and making a new 'mythic-cli' via 'sudo make'. Then restart Mythic\n") } else { fmt.Printf("[+] A patch is available. This means no database schema has changed and only bug fixes applied. This is safe to update now.\n") + fmt.Printf("This will require doing a 'git pull' and making a new 'mythic-cli' via 'sudo make'. Then restart Mythic\n") } return true, nil } else { From f64e45e200f8c8db635685e05b04da794e1759c2 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:25:41 +0000 Subject: [PATCH 107/117] Bump Mythic Dockerfile tag to match release 'v0.0.2.54' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index b0f11b482..f0deab943 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.54 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 8b44d5408..8f184a62d 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.53 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.54 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 62eb6545a..c90d97a6f 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.53" +const MythicDockerLatest = "v0.0.2.54" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 2b3d05999..3231aeb82 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.54 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 2e40ab257..d472071ee 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.54 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 596708242..2f2a108ba 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.53 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.54 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index a61c74d92..742d75b0a 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.54 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 1fe6dd631..b8f774e43 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.54 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 83154d9bc..e737cb48f 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.54 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 141a57adb..a76848ec5 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.53 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.54 \ No newline at end of file From e7b31cdd3c2f4f80bdd381a3770627fc44935706 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 20 Jan 2024 14:55:07 -0600 Subject: [PATCH 108/117] updated mythic-cli for remote agent installs --- Mythic_CLI/src/cmd/config/env.go | 10 + Mythic_CLI/src/cmd/internal/installservice.go | 482 +++++++++--------- .../src/cmd/internal/serviceMetadata.go | 35 +- .../src/cmd/manager/dockerComposeManager.go | 15 +- 4 files changed, 291 insertions(+), 251 deletions(-) diff --git a/Mythic_CLI/src/cmd/config/env.go b/Mythic_CLI/src/cmd/config/env.go index 4f524fc8c..93092b729 100644 --- a/Mythic_CLI/src/cmd/config/env.go +++ b/Mythic_CLI/src/cmd/config/env.go @@ -331,11 +331,21 @@ func SetConfigStrings(key string, value string) { if err != nil { log.Fatalf("[!] bad regex: %v", err) } + found := false for _, setting := range allSettings { if searchRegex.MatchString(setting) { mythicEnv.Set(setting, value) + found = true } } + if !found { + log.Printf("[-] Failed to find any matching keys") + return + } + writeMythicEnvironmentVariables() +} +func SetNewConfigStrings(key string, value string) { + mythicEnv.Set(key, value) writeMythicEnvironmentVariables() } func GetBuildArguments() []string { diff --git a/Mythic_CLI/src/cmd/internal/installservice.go b/Mythic_CLI/src/cmd/internal/installservice.go index 0e8d699f0..394a1d856 100644 --- a/Mythic_CLI/src/cmd/internal/installservice.go +++ b/Mythic_CLI/src/cmd/internal/installservice.go @@ -16,295 +16,301 @@ import ( func InstallFolder(installPath string, overWrite bool) error { workingPath := utils.GetCwdFromExe() - if utils.FileExists(filepath.Join(installPath, "config.json")) { - var installConfig = viper.New() - installConfig.SetConfigName("config") - installConfig.SetConfigType("json") - log.Printf("[*] Parsing installConfig.json\n") - installConfig.AddConfigPath(installPath) - if err := installConfig.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - fmt.Printf("[-] Error while reading in installConfig file: %s", err) - return err - } else { - fmt.Printf("[-] Error while parsing installConfig file: %s", err) - return err - } + if !utils.FileExists(filepath.Join(installPath, "config.json")) { + log.Fatal("[-] Failed to find config.json in cloned down repo\n") + } + var installConfig = viper.New() + installConfig.SetConfigName("config") + installConfig.SetConfigType("json") + log.Printf("[*] Parsing config.json\n") + installConfig.AddConfigPath(installPath) + if err := installConfig.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + fmt.Printf("[-] Error while reading in installConfig file: %s", err) + return err + } else { + fmt.Printf("[-] Error while parsing installConfig file: %s", err) + return err } - if !installConfig.GetBool("exclude_payload_type") { - // handle the payload type copying here - files, err := ioutil.ReadDir(filepath.Join(installPath, "Payload_Type")) - if err != nil { - fmt.Printf("[-] Failed to list contents of new Payload_Type folder: %v\n", err) - return err - } - for _, f := range files { - if f.IsDir() { - fmt.Printf("[*] Processing Payload Type %s\n", f.Name()) + } + latestVersion := installConfig.GetStringMapString("remote_images") + for key, val := range latestVersion { + config.SetNewConfigStrings(fmt.Sprintf("%s_remote_image", key), val) + config.SetNewConfigStrings(fmt.Sprintf("%s_use_volume", key), "true") + config.SetNewConfigStrings(fmt.Sprintf("%s_use_build_context", key), "false") + } + if !installConfig.GetBool("exclude_payload_type") { + // handle the payload type copying here + files, err := ioutil.ReadDir(filepath.Join(installPath, "Payload_Type")) + if err != nil { + fmt.Printf("[-] Failed to list contents of new Payload_Type folder: %v\n", err) + return err + } + for _, f := range files { + if f.IsDir() { + fmt.Printf("[*] Processing Payload Type %s\n", f.Name()) - if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) { - if overWrite || config.AskConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { - log.Printf("[*] Stopping current container\n") - if manager.GetManager().IsServiceRunning(strings.ToLower(f.Name())) { - if err := ServiceStop([]string{f.Name()}); err != nil { - log.Printf("[-] Failed to stop current container: %v\n", err) - return err - } - } - log.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) - if err != nil { - log.Printf("[-] Failed to remove current version: %v\n", err) - log.Printf("[-] Continuing to the next payload\n") - continue - } else { - log.Printf("[+] Successfully removed the current version\n") + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { + log.Printf("[*] Stopping current container\n") + if manager.GetManager().IsServiceRunning(strings.ToLower(f.Name())) { + if err := ServiceStop([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to stop current container: %v\n", err) + return err } - } else { - log.Printf("[!] Skipping Payload Type, %s\n", f.Name()) + } + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) + if err != nil { + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next payload\n") continue + } else { + log.Printf("[+] Successfully removed the current version\n") } + } else { + log.Printf("[!] Skipping Payload Type, %s\n", f.Name()) + continue } - log.Printf("[*] Copying new version of payload into place\n") - err = utils.CopyDir(filepath.Join(installPath, "Payload_Type", f.Name()), - filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) + } + log.Printf("[*] Copying new version of payload into place\n") + err = utils.CopyDir(filepath.Join(installPath, "Payload_Type", f.Name()), + filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) + if err != nil { + log.Printf("[-] Failed to copy directory over: %v\n", err) + continue + } + log.Printf("[*] Adding service into docker-compose\n") + if installConfig.IsSet("docker-compose") { + err := Add3rdPartyService(f.Name(), installConfig.GetStringMap("docker-compose")) if err != nil { - log.Printf("[-] Failed to copy directory over: %v\n", err) - continue + log.Printf("[-] Failed to add service to docker-compose: %v\n", err) + } else if err := ServiceBuild([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to start service: %v\n", err) } - log.Printf("[*] Adding service into docker-compose\n") - if installConfig.IsSet("docker-compose") { - err := Add3rdPartyService(f.Name(), installConfig.GetStringMap("docker-compose")) - if err != nil { - log.Printf("[-] Failed to add service to docker-compose: %v\n", err) - } else if err := ServiceBuild([]string{f.Name()}); err != nil { - log.Printf("[-] Failed to start service: %v\n", err) - } - } else { - if err := Add3rdPartyService(f.Name(), make(map[string]interface{})); err != nil { - log.Printf("[-] Failed to add service to docker-compose: %v\n", err) - } else if err := ServiceBuild([]string{f.Name()}); err != nil { - log.Printf("[-] Failed to start service: %v\n", err) - } + } else { + if err := Add3rdPartyService(f.Name(), make(map[string]interface{})); err != nil { + log.Printf("[-] Failed to add service to docker-compose: %v\n", err) + } else if err := ServiceBuild([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to start service: %v\n", err) } - } + } - log.Printf("[+] Successfully installed service\n") - } else { - log.Printf("[*] Skipping over Payload Type\n") } - if !installConfig.GetBool("exclude_c2_profiles") { - // handle the c2 profile copying here - files, err := ioutil.ReadDir(filepath.Join(installPath, "C2_Profiles")) - if err != nil { - log.Printf("[-] Failed to list contents of C2_Profiles folder from clone\n") - return err - } - for _, f := range files { - if f.IsDir() { - log.Printf("[*] Processing C2 Profile %s\n", f.Name()) - if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) { - if overWrite || config.AskConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { - log.Printf("[*] Stopping current container\n") - if manager.GetManager().IsServiceRunning(strings.ToLower(f.Name())) { - if err := ServiceStop([]string{f.Name()}); err != nil { - log.Printf("[-] Failed to stop container: %v\n", err) - return err - } - } - log.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) - if err != nil { - log.Printf("[-] Failed to remove current version: %v\n", err) - log.Printf("[-] Continuing to the next c2 profile\n") - continue - } else { - log.Printf("[+] Successfully removed the current version\n") + log.Printf("[+] Successfully installed service\n") + } else { + log.Printf("[*] Skipping over Payload Type\n") + } + if !installConfig.GetBool("exclude_c2_profiles") { + // handle the c2 profile copying here + files, err := ioutil.ReadDir(filepath.Join(installPath, "C2_Profiles")) + if err != nil { + log.Printf("[-] Failed to list contents of C2_Profiles folder from clone\n") + return err + } + for _, f := range files { + if f.IsDir() { + log.Printf("[*] Processing C2 Profile %s\n", f.Name()) + if utils.DirExists(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" already exists. Replace current version? ") { + log.Printf("[*] Stopping current container\n") + if manager.GetManager().IsServiceRunning(strings.ToLower(f.Name())) { + if err := ServiceStop([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to stop container: %v\n", err) + return err } - } else { - log.Printf("[!] Skipping C2 Profile, %s\n", f.Name()) + } + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) + if err != nil { + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next c2 profile\n") continue + } else { + log.Printf("[+] Successfully removed the current version\n") } - } - log.Printf("[*] Copying new version into place\n") - err = utils.CopyDir(filepath.Join(installPath, "C2_Profiles", f.Name()), - filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) - if err != nil { - log.Printf("[-] Failed to copy directory over\n") + } else { + log.Printf("[!] Skipping C2 Profile, %s\n", f.Name()) continue } - // now add payload type to yaml installConfig - log.Printf("[*] Adding c2, %s, into docker-compose\n", f.Name()) - if err = Add3rdPartyService(f.Name(), make(map[string]interface{})); err != nil { - log.Printf("[-] Failed to add %s to docker-compose: %v\n", f.Name(), err) - } else if err := ServiceBuild([]string{f.Name()}); err != nil { - log.Printf("[-] Failed to start service: %v\n", err) - } + } + log.Printf("[*] Copying new version into place\n") + err = utils.CopyDir(filepath.Join(installPath, "C2_Profiles", f.Name()), + filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), f.Name())) + if err != nil { + log.Printf("[-] Failed to copy directory over\n") + continue + } + // now add payload type to yaml installConfig + log.Printf("[*] Adding c2, %s, into docker-compose\n", f.Name()) + if err = Add3rdPartyService(f.Name(), make(map[string]interface{})); err != nil { + log.Printf("[-] Failed to add %s to docker-compose: %v\n", f.Name(), err) + } else if err := ServiceBuild([]string{f.Name()}); err != nil { + log.Printf("[-] Failed to start service: %v\n", err) } } - log.Printf("[+] Successfully installed c2\n") - } else { - log.Printf("[*] Skipping over C2 Profile\n") } - if !installConfig.GetBool("exclude_documentation_payload") { - // handle payload documentation copying here - files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-payload")) - if err != nil { - log.Printf("[-] Failed to list contents of documentation_payload folder from clone: %v\n", err) - } else { - for _, f := range files { - if f.IsDir() { - log.Printf("[*] Processing Documentation for %s\n", f.Name()) - if !config.GetMythicEnv().GetBool("documentation_bind_use_volume") { - if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { - if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - log.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) - if err != nil { - log.Printf("[-] Failed to remove current version: %v\n", err) - log.Printf("[-] Continuing to the next payload documentation\n") - continue - } else { - log.Printf("[+] Successfully removed the current version\n") - } - } else { - log.Printf("[!] Skipping documentation for , %s\n", f.Name()) + log.Printf("[+] Successfully installed c2\n") + } else { + log.Printf("[*] Skipping over C2 Profile\n") + } + if !installConfig.GetBool("exclude_documentation_payload") { + // handle payload documentation copying here + files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-payload")) + if err != nil { + log.Printf("[-] Failed to list contents of documentation_payload folder from clone: %v\n", err) + } else { + for _, f := range files { + if f.IsDir() { + log.Printf("[*] Processing Documentation for %s\n", f.Name()) + if !config.GetMythicEnv().GetBool("documentation_bind_use_volume") { + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) + if err != nil { + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next payload documentation\n") continue + } else { + log.Printf("[+] Successfully removed the current version\n") } - } - log.Printf("[*] Copying new documentation into place\n") - err = utils.CopyDir(filepath.Join(installPath, "documentation-payload", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) - if err != nil { - log.Printf("[-] Failed to copy directory over\n") - continue - } - } else { - err = moveFileToVolume("mythic_documentation_volume", - filepath.Join("content", "Agents"), - filepath.Join(installPath, "documentation-payload", f.Name())) - if err != nil { - log.Printf("[-] Failed to install documentation for payload: %v\n", err) + } else { + log.Printf("[!] Skipping documentation for , %s\n", f.Name()) continue } } - + log.Printf("[*] Copying new documentation into place\n") + err = utils.CopyDir(filepath.Join(installPath, "documentation-payload", f.Name()), filepath.Join(workingPath, "documentation-docker", "content", "Agents", f.Name())) + if err != nil { + log.Printf("[-] Failed to copy directory over\n") + continue + } + } else { + err = moveFileToVolume("mythic_documentation_volume", + filepath.Join("content", "Agents"), + filepath.Join(installPath, "documentation-payload", f.Name())) + if err != nil { + log.Printf("[-] Failed to install documentation for payload: %v\n", err) + continue + } } + } - log.Printf("[+] Successfully installed Payload documentation\n") } + log.Printf("[+] Successfully installed Payload documentation\n") + } + } else { + log.Printf("[*] Skipping over Payload Documentation\n") + } + if !installConfig.GetBool("exclude_documentation_c2") { + // handle the c2 documentation copying here + files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-c2")) + if err != nil { + log.Printf("[-] Failed to list contents of documentation_payload folder from clone") } else { - log.Printf("[*] Skipping over Payload Documentation\n") - } - if !installConfig.GetBool("exclude_documentation_c2") { - // handle the c2 documentation copying here - files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-c2")) - if err != nil { - log.Printf("[-] Failed to list contents of documentation_payload folder from clone") - } else { - for _, f := range files { - if f.IsDir() { - log.Printf("[*] Processing Documentation for %s\n", f.Name()) - if !config.GetMythicEnv().GetBool("document_bind_use_volume") { - if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { - if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - log.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) - if err != nil { - log.Printf("[-] Failed to remove current version: %v\n", err) - log.Printf("[-] Continuing to the next c2 documentation\n") - continue - } else { - log.Printf("[+] Successfully removed the current version\n") - } - } else { - log.Printf("[!] Skipping documentation for %s\n", f.Name()) + for _, f := range files { + if f.IsDir() { + log.Printf("[*] Processing Documentation for %s\n", f.Name()) + if !config.GetMythicEnv().GetBool("document_bind_use_volume") { + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) + if err != nil { + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next c2 documentation\n") continue + } else { + log.Printf("[+] Successfully removed the current version\n") } - } - log.Printf("[*] Copying new documentation version into place\n") - err = utils.CopyDir(filepath.Join(installPath, "documentation-c2", f.Name()), - filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) - if err != nil { - log.Printf("[-] Failed to copy directory over\n") - continue - } - } else { - err = moveFileToVolume("mythic_documentation_volume", - filepath.Join("content", "C2 Profiles"), - filepath.Join(installPath, "documentation-c2", f.Name())) - if err != nil { - log.Printf("[-] Failed to install documentation for c2: %v\n", err) + } else { + log.Printf("[!] Skipping documentation for %s\n", f.Name()) continue } - + } + log.Printf("[*] Copying new documentation version into place\n") + err = utils.CopyDir(filepath.Join(installPath, "documentation-c2", f.Name()), + filepath.Join(workingPath, "documentation-docker", "content", "C2 Profiles", f.Name())) + if err != nil { + log.Printf("[-] Failed to copy directory over\n") + continue + } + } else { + err = moveFileToVolume("mythic_documentation_volume", + filepath.Join("content", "C2 Profiles"), + filepath.Join(installPath, "documentation-c2", f.Name())) + if err != nil { + log.Printf("[-] Failed to install documentation for c2: %v\n", err) + continue } } + } - log.Printf("[+] Successfully installed c2 documentation\n") } + log.Printf("[+] Successfully installed c2 documentation\n") + } + } else { + log.Printf("[*] Skipping over C2 Documentation\n") + } + if !installConfig.GetBool("exclude_documentation_wrapper") { + // handle payload documentation copying here + files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-wrapper")) + if err != nil { + log.Printf("[-] Failed to list contents of documentation-wrapper folder from clone: %v\n", err) } else { - log.Printf("[*] Skipping over C2 Documentation\n") - } - if !installConfig.GetBool("exclude_documentation_wrapper") { - // handle payload documentation copying here - files, err := ioutil.ReadDir(filepath.Join(installPath, "documentation-wrapper")) - if err != nil { - log.Printf("[-] Failed to list contents of documentation-wrapper folder from clone: %v\n", err) - } else { - for _, f := range files { - if f.IsDir() { - log.Printf("[*] Processing Documentation for %s\n", f.Name()) - if config.GetMythicEnv().GetBool("document_local_bind_mount") { - if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) { - if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { - log.Printf("[*] Removing current version\n") - err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) - if err != nil { - log.Printf("[-] Failed to remove current version: %v\n", err) - log.Printf("[-] Continuing to the next wrapper documentation\n") - continue - } else { - log.Printf("[+] Successfully removed the current version\n") - } - } else { - log.Printf("[!] Skipping documentation for , %s\n", f.Name()) + for _, f := range files { + if f.IsDir() { + log.Printf("[*] Processing Documentation for %s\n", f.Name()) + if config.GetMythicEnv().GetBool("document_local_bind_mount") { + if utils.DirExists(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) { + if overWrite || config.AskConfirm("[*] "+f.Name()+" documentation already exists. Replace current version? ") { + log.Printf("[*] Removing current version\n") + err = os.RemoveAll(filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) + if err != nil { + log.Printf("[-] Failed to remove current version: %v\n", err) + log.Printf("[-] Continuing to the next wrapper documentation\n") continue + } else { + log.Printf("[+] Successfully removed the current version\n") } - } - log.Printf("[*] Copying new documentation into place\n") - err = utils.CopyDir(filepath.Join(installPath, "documentation-wrapper", f.Name()), - filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) - if err != nil { - log.Printf("[-] Failed to copy directory over\n") - continue - } - } else { - err = moveFileToVolume("mythic_documentation_volume", - filepath.Join("content", "Wrappers"), - filepath.Join(installPath, "documentation-wrapper", f.Name())) - if err != nil { - log.Printf("[-] Failed to install documentation for wrapper: %v\n", err) + } else { + log.Printf("[!] Skipping documentation for , %s\n", f.Name()) continue } } + log.Printf("[*] Copying new documentation into place\n") + err = utils.CopyDir(filepath.Join(installPath, "documentation-wrapper", f.Name()), + filepath.Join(workingPath, "documentation-docker", "content", "Wrappers", f.Name())) + if err != nil { + log.Printf("[-] Failed to copy directory over\n") + continue + } + } else { + err = moveFileToVolume("mythic_documentation_volume", + filepath.Join("content", "Wrappers"), + filepath.Join(installPath, "documentation-wrapper", f.Name())) + if err != nil { + log.Printf("[-] Failed to install documentation for wrapper: %v\n", err) + continue + } } } - log.Printf("[+] Successfully installed Wrapper documentation\n") } - } else { - log.Printf("[*] Skipping over Wrapper Documentation\n") - } - if manager.GetManager().IsServiceRunning("mythic_documentation") { - fmt.Printf("[*] Restarting mythic_documentation container to pull in changes\n") - ServiceStop([]string{"mythic_documentation"}) - ServiceStart([]string{"mythic_documentation"}) + log.Printf("[+] Successfully installed Wrapper documentation\n") } } else { - log.Fatal("[-] Failed to find config.json in cloned down repo\n") + log.Printf("[*] Skipping over Wrapper Documentation\n") + } + + if manager.GetManager().IsServiceRunning("mythic_documentation") { + fmt.Printf("[*] Restarting mythic_documentation container to pull in changes\n") + ServiceStop([]string{"mythic_documentation"}) + ServiceStart([]string{"mythic_documentation"}) } return nil } diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index 50747ba5d..f1cb54fee 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -551,16 +551,43 @@ func Add3rdPartyService(service string, additionalConfigs map[string]interface{} "container_name": strings.ToLower(service), "cpus": config.GetMythicEnv().GetInt("INSTALLED_SERVICE_CPUS"), } + pStruct["build"] = map[string]interface{}{ + "context": filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service), + "args": config.GetBuildArguments(), + } + agentConfigs := config.GetConfigStrings([]string{fmt.Sprintf("%s_.*", service)}) + agentUseBuildContextKey := fmt.Sprintf("%s_use_build_context", service) + agentRemoteImageKey := fmt.Sprintf("%s_remote_image", service) + agentUseVolumeKey := fmt.Sprintf("%s_use_volume", service) + if useBuildContext, ok := agentConfigs[agentUseBuildContextKey]; ok { + if useBuildContext == "false" { + delete(pStruct, "build") + } + pStruct["image"] = agentConfigs[agentRemoteImageKey] + } + if useVolume, ok := agentConfigs[agentUseVolumeKey]; ok { + if useVolume == "true" { + volumeName := fmt.Sprintf("%s_volume", service) + pStruct["volumes"] = []string{ + volumeName + ":/Mythic/", + } + // add our new volume to the list of volumes if needed + volumes, _ := manager.GetManager().GetVolumes() + volumes[volumeName] = map[string]string{ + "name": volumeName, + } + manager.GetManager().SetVolumes(volumes) + } else { + delete(pStruct, "volumes") + } + } if config.GetMythicEnv().GetString("installed_service_mem_limit") != "" { pStruct["mem_limit"] = config.GetMythicEnv().GetString("installed_service_mem_limit") } for key, element := range additionalConfigs { pStruct[key] = element } - pStruct["build"] = map[string]interface{}{ - "context": filepath.Join(manager.GetManager().GetPathTo3rdPartyServicesOnDisk(), service), - "args": config.GetBuildArguments(), - } + pStruct["network_mode"] = "host" pStruct["extra_hosts"] = []string{ "mythic_server:127.0.0.1", diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go index 715185c15..2f336c89b 100644 --- a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -706,8 +706,7 @@ func (d *DockerComposeManager) Status(verbose bool) { } portString = portString + strings.Join(stringPortRanges[:], ", ") } - if utils.StringInSlice(container.Image, config.MythicPossibleServices) || - strings.HasPrefix(container.Image, "ghcr.io/its-a-feature/mythic_") { + if utils.StringInSlice(container.Labels["name"], config.MythicPossibleServices) { foundMountInfo := false for _, mnt := range container.Mounts { if strings.HasPrefix(mnt.Name, container.Image+"_volume") { @@ -726,15 +725,13 @@ func (d *DockerComposeManager) Status(verbose bool) { info = info + portString mythicLocalServices = append(mythicLocalServices, info) } else { - for _, mnt := range container.Mounts { - if strings.Contains(mnt.Source, d.InstalledServicesPath) { - installedServices = append(installedServices, info) - elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container.Labels["name"]) - elementsInCompose = utils.RemoveStringFromSliceNoOrder(elementsInCompose, container.Labels["name"]) - } + if utils.StringInSlice(container.Labels["name"], elementsOnDisk) || + utils.StringInSlice(container.Labels["name"], elementsInCompose) { + installedServices = append(installedServices, info) + elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container.Labels["name"]) + elementsInCompose = utils.RemoveStringFromSliceNoOrder(elementsInCompose, container.Labels["name"]) } } - } fmt.Fprintln(w, "Mythic Main Services") fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tMOUNT\tPORTS") From 37cd9d8cbdf3994e802f8266fa6670f6e62f7c08 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 20 Jan 2024 15:01:52 -0600 Subject: [PATCH 109/117] updated workflow to build on tags --- .github/workflows/docker.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 79247f19a..afaa4c456 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -10,6 +10,8 @@ on: push: branches: - 'docker_updates' + tags: + - "v*.*.*" # Variables holding configuration settings env: @@ -38,8 +40,7 @@ env: IMAGE_LICENSE: BSD-3-Clause # Set the container image version to the Github release tag - #VERSION: ${{ github.event.release.tag_name }} - VERSION: ${{ github.event.head_commit.message }} + VERSION: ${{ github.ref_name }} # Branch for pushing release changes (TODO: Change this to the main branch when the rewrite is finished) RELEASE_BRANCH: docker_updates @@ -78,7 +79,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_SERVER_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_SERVER_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -120,7 +121,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_POSTGRES_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_POSTGRES_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -162,7 +163,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_RABBITMQ_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_RABBITMQ_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -204,7 +205,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_DOCUMENTATION_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_DOCUMENTATION_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -248,7 +249,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_JUPYTER_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_JUPYTER_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -292,7 +293,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_GRAPHQL_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_GRAPHQL_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -336,7 +337,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_NGINX_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_NGINX_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -380,7 +381,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_REACT_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_REACT_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -438,7 +439,7 @@ jobs: tags: | ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:${{ env.VERSION }} ${{ env.REGISTRY }}/${{ env.MYTHIC_CLI_IMAGE_NAME }}:latest - push: true + push: ${{ github.ref_type == 'tag' }} # These container metadata labels allow configuring the package in Github # packages. The source will link the package to this Github repository labels: | @@ -542,6 +543,7 @@ jobs: sed -i "s|^FROM ghcr\.io.*$|FROM ${REGISTRY}/${MYTHIC_REACT_IMAGE_NAME}:${VERSION}|" Dockerfile # Push the changes to the Dockerfile - name: Push the updated base Dockerfile image reference changes + if: ${{ github.ref_type == 'tag' }} uses: EndBug/add-and-commit@v9 # ref: https://github.com/marketplace/actions/add-commit with: # Only add the Dockerfile changes. Nothing else should have been modified @@ -554,10 +556,10 @@ jobs: message: "Bump Mythic Dockerfile tag to match release '${{ env.VERSION }}'" # Overwrite the current git tag with the new changes - #tag: '${{ env.VERSION }} --force' + tag: '${{ env.VERSION }} --force' # Push the new changes with the tag overwriting the current one - #tag_push: '--force' + tag_push: '--force' # Push the commits to the branch marked as the release branch push: origin HEAD:${{ env.RELEASE_BRANCH }} --set-upstream From 60cff48f34538cb3b69f66b436aeb91880258c44 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 20 Jan 2024 23:55:32 +0000 Subject: [PATCH 110/117] Bump Mythic Dockerfile tag to match release 'v0.0.1-rc1' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index f0deab943..e4b188ecf 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.1-rc1 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 8f184a62d..676c4ad23 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.2.54 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.1-rc1 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index c90d97a6f..7deb778a6 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.2.54" +const MythicDockerLatest = "v0.0.1-rc1" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 3231aeb82..57ea76a83 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.1-rc1 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index d472071ee..f6e813d0c 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.1-rc1 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 2f2a108ba..444d6ea14 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.2.54 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.1-rc1 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 742d75b0a..75713293f 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.1-rc1 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index b8f774e43..2860ef72b 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.1-rc1 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index e737cb48f..8fe9ced79 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.1-rc1 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index a76848ec5..dcaaeddd9 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.2.54 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.1-rc1 \ No newline at end of file From 28cf528d2195f2ae713278f1f1fa17c297f140e0 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 00:14:33 +0000 Subject: [PATCH 111/117] Bump Mythic Dockerfile tag to match release 'v0.0.3-rc1' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index e4b188ecf..184eed07c 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc1 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 676c4ad23..701d2d857 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.1-rc1 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc1 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 7deb778a6..3924ce694 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.1-rc1" +const MythicDockerLatest = "v0.0.3-rc1" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 57ea76a83..18838fe22 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc1 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index f6e813d0c..0a9199f90 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc1 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 444d6ea14..0048a6e33 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.1-rc1 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc1 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 75713293f..9d4081ca5 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc1 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 2860ef72b..11f002522 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc1 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 8fe9ced79..0bae05f58 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc1 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index dcaaeddd9..cdb157154 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.1-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc1 \ No newline at end of file From da435f22b18629e62deadbe9f9666a248edffdcf Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 20 Jan 2024 19:08:21 -0600 Subject: [PATCH 112/117] updating volume listing --- .../src/cmd/manager/dockerComposeManager.go | 42 ++++++++++--------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go index 2f336c89b..88b234419 100644 --- a/Mythic_CLI/src/cmd/manager/dockerComposeManager.go +++ b/Mythic_CLI/src/cmd/manager/dockerComposeManager.go @@ -706,22 +706,22 @@ func (d *DockerComposeManager) Status(verbose bool) { } portString = portString + strings.Join(stringPortRanges[:], ", ") } - if utils.StringInSlice(container.Labels["name"], config.MythicPossibleServices) { - foundMountInfo := false - for _, mnt := range container.Mounts { - if strings.HasPrefix(mnt.Name, container.Image+"_volume") { - if foundMountInfo { - info += ", " + mnt.Name - } else { - info += mnt.Name - } - foundMountInfo = true + foundMountInfo := false + for _, mnt := range container.Mounts { + if strings.HasPrefix(mnt.Name, container.Labels["name"]+"_volume") { + if foundMountInfo { + info += ", " + mnt.Name + } else { + info += mnt.Name } + foundMountInfo = true } - if !foundMountInfo { - info += "N/A" - } - info += "\t" + } + if !foundMountInfo { + info += "local" + } + info += "\t" + if utils.StringInSlice(container.Labels["name"], config.MythicPossibleServices) { info = info + portString mythicLocalServices = append(mythicLocalServices, info) } else { @@ -741,11 +741,11 @@ func (d *DockerComposeManager) Status(verbose bool) { fmt.Fprintln(w, "\t\t\t\t\t") w.Flush() fmt.Fprintln(w, "Installed Services") - fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS") + fmt.Fprintln(w, "CONTAINER NAME\tSTATE\tSTATUS\tMOUNT") for _, line := range installedServices { fmt.Fprintln(w, line) } - fmt.Fprintln(w, "\t\t\t") + fmt.Fprintln(w, "\t\t\t\t") // remove all elementsInCompose from elementsOnDisk for _, container := range elementsInCompose { elementsOnDisk = utils.RemoveStringFromSliceNoOrder(elementsOnDisk, container) @@ -871,17 +871,21 @@ func (d *DockerComposeManager) PrintVolumeInformation() { return } var entries []string + volumeList, err := d.GetVolumes() + if err != nil { + log.Fatalf("[-] Failed to get volumes: %v", err) + } for _, currentVolume := range du.Volumes { name := currentVolume.Name size := "unknown" if currentVolume.UsageData != nil { size = utils.ByteCountSI(currentVolume.UsageData.Size) } - if !strings.HasPrefix(currentVolume.Name, "mythic_") { + if _, ok := volumeList[currentVolume.Name]; !ok { continue } - containerPieces := strings.Split(currentVolume.Name, "_") - containerName := strings.Join(containerPieces[0:2], "_") + containerPieces := strings.Split(currentVolume.Name, "_volume") + containerName := containerPieces[0] container := "unused (0)" containerStatus := "offline" for _, c := range containers { From 2bd9eceed53cd9b4ecc499403bed18f08b595494 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 01:20:40 +0000 Subject: [PATCH 113/117] Bump Mythic Dockerfile tag to match release 'v0.0.3-rc2' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 184eed07c..0204b4ecd 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc2 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 701d2d857..761b1cc1e 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc1 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc2 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 3924ce694..6773b7e6c 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.3-rc1" +const MythicDockerLatest = "v0.0.3-rc2" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index 18838fe22..a0fda4f7f 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc2 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 0a9199f90..6abc18ebc 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc2 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 0048a6e33..220ceb788 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc1 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc2 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 9d4081ca5..0ab5ead0b 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc2 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 11f002522..1369ff6a9 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc2 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 0bae05f58..0438aeb62 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc2 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index cdb157154..775ffcf60 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc1 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc2 \ No newline at end of file From ab3e0581c443eeceefeefd1facd73b4da7169b53 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Sat, 20 Jan 2024 21:17:32 -0600 Subject: [PATCH 114/117] updating mythic-cli to reflect .env changes for 3rd party services --- Mythic_CLI/src/cmd/internal/serviceExecution.go | 11 ++++++++++- Mythic_CLI/src/cmd/internal/serviceMetadata.go | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Mythic_CLI/src/cmd/internal/serviceExecution.go b/Mythic_CLI/src/cmd/internal/serviceExecution.go index 42a0bc97f..29098c2d6 100644 --- a/Mythic_CLI/src/cmd/internal/serviceExecution.go +++ b/Mythic_CLI/src/cmd/internal/serviceExecution.go @@ -67,9 +67,12 @@ func ServiceStart(containers []string) error { finalContainers = append(finalContainers, val) } } + // make sure we always update the config when starting in case .env variables changed for _, service := range finalContainers { if utils.StringInSlice(service, config.MythicPossibleServices) { AddMythicService(service) + } else { + Add3rdPartyService(service, map[string]interface{}{}) } } manager.GetManager().TestPorts(finalContainers) @@ -90,13 +93,19 @@ func ServiceStop(containers []string) error { return manager.GetManager().StopServices(containers, config.GetMythicEnv().GetBool("REBUILD_ON_START")) } func ServiceBuild(containers []string) error { + composeServices, err := manager.GetManager().GetAllInstalled3rdPartyServiceNames() + if err != nil { + log.Fatalf("[-] Failed to get installed service list: %v", err) + } for _, container := range containers { if utils.StringInSlice(container, config.MythicPossibleServices) { // update the necessary docker compose entries for mythic services AddMythicService(container) + } else if utils.StringInSlice(container, composeServices) { + Add3rdPartyService(container, map[string]interface{}{}) } } - err := manager.GetManager().BuildServices(containers) + err = manager.GetManager().BuildServices(containers) if err != nil { return err } diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index f1cb54fee..3b7ca0fd4 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -562,8 +562,8 @@ func Add3rdPartyService(service string, additionalConfigs map[string]interface{} if useBuildContext, ok := agentConfigs[agentUseBuildContextKey]; ok { if useBuildContext == "false" { delete(pStruct, "build") + pStruct["image"] = agentConfigs[agentRemoteImageKey] } - pStruct["image"] = agentConfigs[agentRemoteImageKey] } if useVolume, ok := agentConfigs[agentUseVolumeKey]; ok { if useVolume == "true" { From e4c3d767e0a5215968669ff8dbf3d9462dd79816 Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 03:29:48 +0000 Subject: [PATCH 115/117] Bump Mythic Dockerfile tag to match release 'v0.0.3-rc3' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index 0204b4ecd..d3a6005eb 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc3 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 761b1cc1e..205881f39 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc2 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc3 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 6773b7e6c..0b690add7 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.3-rc2" +const MythicDockerLatest = "v0.0.3-rc3" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index a0fda4f7f..c9ddba629 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc3 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 6abc18ebc..25c82c6af 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc3 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 220ceb788..3d4d275f5 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc2 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc3 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 0ab5ead0b..9ddbf9acf 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc3 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index 1369ff6a9..a1aef56f8 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc3 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 0438aeb62..8ac619df3 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc3 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 775ffcf60..7143cafa6 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc2 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc3 \ No newline at end of file From d5c866410f8c7d1604fe51c05d37a5c4b16c7bf7 Mon Sep 17 00:00:00 2001 From: its-a-feature Date: Mon, 22 Jan 2024 09:34:00 -0600 Subject: [PATCH 116/117] updating volume mapping for the mythic_server container --- Mythic_CLI/src/cmd/internal/serviceMetadata.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mythic_CLI/src/cmd/internal/serviceMetadata.go b/Mythic_CLI/src/cmd/internal/serviceMetadata.go index 3b7ca0fd4..5c1635425 100644 --- a/Mythic_CLI/src/cmd/internal/serviceMetadata.go +++ b/Mythic_CLI/src/cmd/internal/serviceMetadata.go @@ -474,12 +474,14 @@ func AddMythicService(service string) { pStruct["environment"] = environment } if !mythicEnv.GetBool("mythic_server_use_volume") { + // mount the entire directory in so that you can see changes to code too pStruct["volumes"] = []string{ "./mythic-docker/src:/usr/src/app", } } else { + // when using a volume for Mythic server, just have it save off the files pStruct["volumes"] = []string{ - "mythic_server_volume:/usr/src/app", + "mythic_server_volume:/usr/src/app/files", } } if _, ok := volumes["mythic_server"]; !ok { From 92aaef58c65dd4d6915d67a31f0bdae0475b3ecf Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 17:44:17 +0000 Subject: [PATCH 117/117] Bump Mythic Dockerfile tag to match release 'v0.0.3-rc4' --- Mythic_CLI/Dockerfile | 2 +- Mythic_CLI/Makefile | 2 +- Mythic_CLI/src/cmd/config/constants.go | 2 +- documentation-docker/Dockerfile | 2 +- hasura-docker/Dockerfile | 2 +- jupyter-docker/Dockerfile | 2 +- mythic-react-docker/Dockerfile | 2 +- nginx-docker/Dockerfile | 2 +- postgres-docker/Dockerfile | 2 +- rabbitmq-docker/Dockerfile | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mythic_CLI/Dockerfile b/Mythic_CLI/Dockerfile index d3a6005eb..251a5ab05 100644 --- a/Mythic_CLI/Dockerfile +++ b/Mythic_CLI/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc4 \ No newline at end of file diff --git a/Mythic_CLI/Makefile b/Mythic_CLI/Makefile index 205881f39..4be95ff60 100644 --- a/Mythic_CLI/Makefile +++ b/Mythic_CLI/Makefile @@ -1,6 +1,6 @@ BINARY_NAME=mythic-cli LOCAL_PATH=$(shell pwd) -BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc3 +BUILDER_IMAGE=ghcr.io/its-a-feature/mythic_cli:v0.0.3-rc4 .PHONY: default default: build_linux ; diff --git a/Mythic_CLI/src/cmd/config/constants.go b/Mythic_CLI/src/cmd/config/constants.go index 0b690add7..ac259966f 100644 --- a/Mythic_CLI/src/cmd/config/constants.go +++ b/Mythic_CLI/src/cmd/config/constants.go @@ -1,4 +1,4 @@ package config // MythicDockerLatest is the most recent tagged version pushed to GitHub packages -const MythicDockerLatest = "v0.0.3-rc3" +const MythicDockerLatest = "v0.0.3-rc4" diff --git a/documentation-docker/Dockerfile b/documentation-docker/Dockerfile index c9ddba629..c723edd0a 100644 --- a/documentation-docker/Dockerfile +++ b/documentation-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_documentation:v0.0.3-rc4 \ No newline at end of file diff --git a/hasura-docker/Dockerfile b/hasura-docker/Dockerfile index 25c82c6af..340539287 100644 --- a/hasura-docker/Dockerfile +++ b/hasura-docker/Dockerfile @@ -5,4 +5,4 @@ #FROM hasura/graphql-engine:v2.9.0-beta.1.cli-migrations-v2 #FROM hasura/graphql-engine:v2.19.0.cli-migrations-v2 #FROM hasura/graphql-engine:latest.cli-migrations-v2 -FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_graphql:v0.0.3-rc4 \ No newline at end of file diff --git a/jupyter-docker/Dockerfile b/jupyter-docker/Dockerfile index 3d4d275f5..97a1bef6b 100644 --- a/jupyter-docker/Dockerfile +++ b/jupyter-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc3 +FROM ghcr.io/its-a-feature/mythic_jupyter:v0.0.3-rc4 diff --git a/mythic-react-docker/Dockerfile b/mythic-react-docker/Dockerfile index 9ddbf9acf..f3eef2fe1 100644 --- a/mythic-react-docker/Dockerfile +++ b/mythic-react-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_react:v0.0.3-rc4 \ No newline at end of file diff --git a/nginx-docker/Dockerfile b/nginx-docker/Dockerfile index a1aef56f8..949f615dd 100644 --- a/nginx-docker/Dockerfile +++ b/nginx-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_nginx:v0.0.3-rc4 \ No newline at end of file diff --git a/postgres-docker/Dockerfile b/postgres-docker/Dockerfile index 8ac619df3..8a4fa488e 100755 --- a/postgres-docker/Dockerfile +++ b/postgres-docker/Dockerfile @@ -1 +1 @@ -FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_postgres:v0.0.3-rc4 \ No newline at end of file diff --git a/rabbitmq-docker/Dockerfile b/rabbitmq-docker/Dockerfile index 7143cafa6..3e5d94433 100755 --- a/rabbitmq-docker/Dockerfile +++ b/rabbitmq-docker/Dockerfile @@ -1,4 +1,4 @@ #FROM rabbitmq:3-alpine #FROM rabbitmq:3-management-alpine #ADD rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc3 \ No newline at end of file +FROM ghcr.io/its-a-feature/mythic_rabbitmq:v0.0.3-rc4 \ No newline at end of file