Skip to content

Commit 34c0f16

Browse files
authored
Merge pull request #783 from BC-SECURITY/release/6.1.2
v6.1.2 into main
2 parents dab6bca + 4314e7f commit 34c0f16

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1262
-1027
lines changed

.github/install_tests/docker-compose-install-tests.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ services:
1919
BASE_IMAGE: ubuntu:22.04
2020
image: bcsecurity/empire-test-ubuntu2204
2121
<<: *common-platform
22+
ubuntu2404:
23+
build:
24+
<<: *common-build
25+
args:
26+
BASE_IMAGE: ubuntu:24.04
27+
image: bcsecurity/empire-test-ubuntu2404
28+
<<: *common-platform
2229
debian11:
2330
build:
2431
<<: *common-build

.github/install_tests/run-all-cst.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set -e
55
# or `./run-all-cst.sh debian12` to test a single image
66
# or `./run-all-cst.sh` to test all images
77

8-
all_images=(debian12 debian11 debian10 ubuntu2004 ubuntu2204 kalirolling parrotrolling)
8+
all_images=(debian12 debian11 debian10 ubuntu2004 ubuntu2204 ubuntu2404 kalirolling parrotrolling)
99

1010
for image in "${@:-${all_images[@]}}"
1111
do

.github/workflows/lint-and-test.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
DATABASE_USE=sqlite poetry run pytest . -v --runslow
8686
- name: Pytest coverage comment
8787
if: ${{ matrix.python-version == '3.13' }}
88-
uses: MishaKav/pytest-coverage-comment@v1.1.53
88+
uses: MishaKav/pytest-coverage-comment@v1.1.54
8989
with:
9090
pytest-coverage-path: ./pytest-coverage.txt
9191
junitxml-path: ./pytest.xml
@@ -128,7 +128,7 @@ jobs:
128128
# Because the box runs out of disk space, we can't run all tests on a single docker compose build.
129129
images:
130130
- ['debian11', 'debian12']
131-
- ['ubuntu2004', 'ubuntu2204']
131+
- ['ubuntu2004', 'ubuntu2204', 'ubuntu2404']
132132
- ['kalirolling'] # 'parrotrolling'
133133
# Parrot disabled for now because the apt repo is having some slowness issues.
134134
# Install is running up way too many minutes.
@@ -140,15 +140,19 @@ jobs:
140140
# To save CI time, only run these tests when the install script or deps changed
141141
- name: Get changed files using defaults
142142
id: changed-files
143-
uses: tj-actions/changed-files@v46.0.3
143+
uses: tj-actions/changed-files@v46.0.5
144144
- name: Build images
145-
if: contains(steps.changed-files.outputs.modified_files, 'setup/install.sh')
145+
if: ${{ contains(steps.changed-files.outputs.modified_files, 'setup/install.sh')
146146
|| contains(steps.changed-files.outputs.modified_files, 'poetry.lock')
147+
|| contains(steps.changed-files.outputs.modified_files, '.github/install_tests')
148+
|| startsWith(github.head_ref, 'release/') }}
147149
run: docker compose -f .github/install_tests/docker-compose-install-tests.yml
148150
build --parallel ${{ join(matrix.images, ' ') }}
149151
- name: run install tests
150-
if: contains(steps.changed-files.outputs.modified_files, 'setup/install.sh')
152+
if: ${{ contains(steps.changed-files.outputs.modified_files, 'setup/install.sh')
151153
|| contains(steps.changed-files.outputs.modified_files, 'poetry.lock')
154+
|| contains(steps.changed-files.outputs.modified_files, '.github/install_tests')
155+
|| startsWith(github.head_ref, 'release/') }}
152156
# Using a script instead of prepackaged action because composite actions can't uses
153157
# a matrix and this is way simpler to read.
154158
run: |

CHANGELOG.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
## [Unreleased]
1616

17+
## [6.1.2] - 2025-05-21
18+
19+
### Added
20+
21+
- Added support for Ubuntu 24.04 in the install script
22+
23+
### Fixed
24+
25+
- Fixed issue launching powershell on some distros by installing libicu
26+
27+
## [6.1.1] - 2025-05-21
28+
29+
### Fixed
30+
31+
- Fix issue caused by ordering of API routers
32+
33+
## [6.1.0] - 2025-05-20
34+
35+
### Changed
36+
37+
- Use pyyaml's C extension for loading/dumping module yamls to make startup and tests faster
38+
- Simplified Dockerfile by using TARGETARCH variable
39+
- Cleanup API code
40+
- Use a new version of donut that supports arm64
41+
- Update all deps
42+
43+
### Removed
44+
45+
- Remove unused files
46+
1747
## [6.0.3] - 2025-04-24
1848

1949
- Fixed SMB listener not sending start task
@@ -1102,7 +1132,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
11021132
- Updated shellcoderdi to newest version (@Cx01N)
11031133
- Added a Nim launcher (@Hubbl3)
11041134

1105-
[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v6.0.3...HEAD
1135+
[Unreleased]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v6.1.2...HEAD
1136+
1137+
[6.1.2]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v6.1.1...v6.1.2
1138+
1139+
[6.1.1]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v6.1.0...v6.1.1
1140+
1141+
[6.1.0]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v6.0.3...v6.1.0
11061142

11071143
[6.0.3]: https://github.com/BC-SECURITY/Empire-Sponsors/compare/v6.0.2...v6.0.3
11081144

Dockerfile

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77
# 2) create volume storage: `docker create -v /empire --name data bcsecurity/empire`
88
# 3) run out container: `docker run -it --volumes-from data bcsecurity/empire /bin/bash`
99

10-
FROM python:3.13.2-bullseye
10+
FROM python:3.13.3-bullseye
1111

1212
LABEL maintainer="bc-security"
13-
LABEL description="Dockerfile for Empire server and client. https://bc-security.gitbook.io/empire-wiki/quickstart/installation#docker"
13+
LABEL description="Dockerfile for Empire. https://bc-security.gitbook.io/empire-wiki/quickstart/installation#docker"
1414

1515
ENV DEBIAN_FRONTEND=noninteractive DOTNET_CLI_TELEMETRY_OPTOUT=1
1616

17+
ARG TARGETARCH
18+
1719
SHELL ["/bin/bash", "-c"]
1820

1921
RUN apt-get update && \
@@ -27,13 +29,12 @@ RUN apt-get update && \
2729
default-jdk \
2830
&& rm -rf /var/lib/apt/lists/*
2931

30-
RUN unameOut="$(uname -m)" && \
31-
case "$unameOut" in \
32-
x86_64) export arch=x64 ;; \
33-
aarch64) export arch=arm64 ;; \
34-
*) exit 1;; \
35-
esac && \
36-
curl -L -o /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.3.9/powershell-7.3.9-linux-$arch.tar.gz && \
32+
RUN if [ "$TARGETARCH" = "amd64" ]; then \
33+
PS_ARCH="x64"; \
34+
elif [ "$TARGETARCH" = "arm64" ]; then \
35+
PS_ARCH="arm64"; \
36+
fi && \
37+
curl -L -o /tmp/powershell.tar.gz https://github.com/PowerShell/PowerShell/releases/download/v7.3.9/powershell-7.3.9-linux-${PS_ARCH}.tar.gz && \
3738
mkdir -p /opt/microsoft/powershell/7 && \
3839
tar zxf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && \
3940
chmod +x /opt/microsoft/powershell/7/pwsh && \
@@ -45,15 +46,7 @@ RUN curl -sSL https://install.python-poetry.org | python3 - && \
4546

4647
ENV PARENT_PATH="/empire"
4748

48-
RUN ARCH=$(uname -m) && \
49-
if [ "$ARCH" = "x86_64" ]; then \
50-
ARCH="linux-amd64"; \
51-
elif [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then \
52-
ARCH="linux-arm64"; \
53-
else \
54-
echo -e "[!] Unsupported architecture: $ARCH. Exiting." && exit 1; \
55-
fi && \
56-
curl -L -o /tmp/go.tar.gz https://go.dev/dl/go1.23.2.$ARCH.tar.gz && \
49+
RUN curl -L -o /tmp/go.tar.gz https://go.dev/dl/go1.23.2.linux-${TARGETARCH}.tar.gz && \
5750
tar zxf /tmp/go.tar.gz -C /opt && \
5851
ln -s /opt/go/bin/go /usr/bin/go && \
5952
rm /tmp/go.tar.gz

empire/server/api/app.py

Lines changed: 30 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,22 @@
1111
from starlette.staticfiles import StaticFiles
1212

1313
from empire.server.api.middleware import EmpireCORSMiddleware
14+
from empire.server.api.v2.admin import admin_api
15+
from empire.server.api.v2.agent import agent_api, agent_file_api, agent_task_api
16+
from empire.server.api.v2.bypass import bypass_api
17+
from empire.server.api.v2.credential import credential_api
18+
from empire.server.api.v2.download import download_api
19+
from empire.server.api.v2.host import host_api, process_api
20+
from empire.server.api.v2.ip import ip_api
21+
from empire.server.api.v2.listener import listener_api, listener_template_api
22+
from empire.server.api.v2.meta import meta_api
23+
from empire.server.api.v2.module import module_api
24+
from empire.server.api.v2.obfuscation import obfuscation_api
25+
from empire.server.api.v2.plugin import plugin_api, plugin_registry_api, plugin_task_api
26+
from empire.server.api.v2.profile import profile_api
27+
from empire.server.api.v2.stager import stager_api, stager_template_api
28+
from empire.server.api.v2.tag import tag_api
29+
from empire.server.api.v2.user import user_api
1430
from empire.server.api.v2.websocket.socketio import setup_socket_events
1531
from empire.server.core.config.config_manager import empire_config
1632
from empire.server.core.config.data_manager import sync_starkiller
@@ -71,27 +87,6 @@ def initialize(run: bool = True, cert_path=None): # noqa: PLR0915
7187
port = empire_config.api.port
7288
secure = empire_config.api.secure
7389

74-
# Not pretty but allows us to use main_menu by delaying the import
75-
from empire.server.api.v2.admin import admin_api
76-
from empire.server.api.v2.agent import agent_api, agent_file_api, agent_task_api
77-
from empire.server.api.v2.bypass import bypass_api
78-
from empire.server.api.v2.credential import credential_api
79-
from empire.server.api.v2.download import download_api
80-
from empire.server.api.v2.host import host_api, process_api
81-
from empire.server.api.v2.ip import ip_api
82-
from empire.server.api.v2.listener import listener_api, listener_template_api
83-
from empire.server.api.v2.meta import meta_api
84-
from empire.server.api.v2.module import module_api
85-
from empire.server.api.v2.obfuscation import obfuscation_api
86-
from empire.server.api.v2.plugin import (
87-
plugin_api,
88-
plugin_registry_api,
89-
plugin_task_api,
90-
)
91-
from empire.server.api.v2.profile import profile_api
92-
from empire.server.api.v2.stager import stager_api, stager_template_api
93-
from empire.server.api.v2.tag import tag_api
94-
from empire.server.api.v2.user import user_api
9590
from empire.server.server import main
9691

9792
@asynccontextmanager
@@ -106,29 +101,29 @@ async def lifespan(app: FastAPI):
106101

107102
app = FastAPI(lifespan=lifespan)
108103

109-
app.include_router(listener_template_api.router)
110-
app.include_router(listener_api.router)
111-
app.include_router(stager_template_api.router)
112-
app.include_router(stager_api.router)
104+
app.include_router(admin_api.router)
105+
app.include_router(agent_file_api.router)
113106
app.include_router(agent_task_api.router)
114107
app.include_router(agent_api.router)
115-
app.include_router(agent_file_api.router)
116-
app.include_router(user_api.router)
117-
app.include_router(module_api.router)
118108
app.include_router(bypass_api.router)
119-
app.include_router(obfuscation_api.router)
120-
app.include_router(process_api.router)
121-
app.include_router(profile_api.router)
122109
app.include_router(credential_api.router)
123-
app.include_router(host_api.router)
124110
app.include_router(download_api.router)
111+
app.include_router(host_api.router)
112+
app.include_router(ip_api.router)
113+
app.include_router(listener_api.router)
114+
app.include_router(listener_template_api.router)
125115
app.include_router(meta_api.router)
116+
app.include_router(module_api.router)
117+
app.include_router(obfuscation_api.router)
118+
app.include_router(plugin_registry_api.router)
126119
app.include_router(plugin_task_api.router)
127120
app.include_router(plugin_api.router)
128-
app.include_router(plugin_registry_api.router)
121+
app.include_router(process_api.router)
122+
app.include_router(profile_api.router)
123+
app.include_router(stager_api.router)
124+
app.include_router(stager_template_api.router)
129125
app.include_router(tag_api.router)
130-
app.include_router(ip_api.router)
131-
app.include_router(admin_api.router)
126+
app.include_router(user_api.router)
132127

133128
app.add_middleware(
134129
EmpireCORSMiddleware,
@@ -149,9 +144,6 @@ async def lifespan(app: FastAPI):
149144
sio = socketio.AsyncServer(
150145
async_mode="asgi",
151146
cors_allowed_origins="*",
152-
# logger=True,
153-
# engineio_logger=True,
154-
# https://github.com/miguelgrinberg/flask-socketio/issues/274#issuecomment-231206374
155147
json=MyJsonWrapper,
156148
)
157149
sio_app = socketio.ASGIApp(
@@ -179,7 +171,6 @@ async def lifespan(app: FastAPI):
179171
lifespan="on",
180172
ssl_keyfile=f"{cert_path}/empire-priv.key",
181173
ssl_certfile=f"{cert_path}/empire-chain.pem",
182-
# log_level="info",
183174
)
184175
else:
185176
uvicorn.run(
@@ -188,7 +179,6 @@ async def lifespan(app: FastAPI):
188179
port=port,
189180
log_config=None,
190181
lifespan="on",
191-
# log_level="info",
192182
)
193183

194184
return app

empire/server/api/v2/admin/admin_api.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
get_current_active_admin_user,
66
get_current_active_user,
77
)
8-
from empire.server.api.v2.shared_dependencies import CurrentSession
8+
from empire.server.api.v2.shared_dependencies import AppCtx, CurrentSession
99
from empire.server.api.v2.shared_dto import BadRequestResponse, NotFoundResponse
10-
from empire.server.server import main
10+
from empire.server.core.ip_service import IpService
11+
12+
13+
def get_ip_service(main: AppCtx) -> IpService:
14+
return main.ipsv2
1115

12-
ip_service = main.ipsv2
1316

1417
router = APIRouter(
1518
prefix="/api/v2/admin",
@@ -23,10 +26,12 @@
2326

2427

2528
@router.put("/ip_filtering", dependencies=[Depends(get_current_active_admin_user)])
26-
def toggle_ip_filtering(db: CurrentSession, enabled: bool):
29+
def toggle_ip_filtering(
30+
db: CurrentSession, enabled: bool, ip_service: IpService = Depends(get_ip_service)
31+
):
2732
ip_service.toggle_ip_filtering(db, enabled)
2833

2934

3035
@router.get("/ip_filtering", dependencies=[Depends(get_current_active_user)])
31-
def get_ip_filtering():
36+
def get_ip_filtering(ip_service: IpService = Depends(get_ip_service)):
3237
return {"enabled": ip_service.ip_filtering}

0 commit comments

Comments
 (0)