Skip to content

Commit

Permalink
Updated to startup and install (EmpireProject#790)
Browse files Browse the repository at this point in the history
* Added install and pull for submodules

* fixed pytest

* updated submodules code to run as non-root

* removed comments

* Update empire/server/api/app.py

Co-authored-by: Vincent Rose <[email protected]>

* Update ps-empire

Co-authored-by: Vincent Rose <[email protected]>

* Update ps-empire

Co-authored-by: Vincent Rose <[email protected]>

* Update ps-empire

Co-authored-by: Vincent Rose <[email protected]>

* Update ps-empire

Co-authored-by: Vincent Rose <[email protected]>

* Update ps-empire

Co-authored-by: Vincent Rose <[email protected]>

* updated starkiller pull to use non root

* updated submodule fetch to occur before check

* updated changelog

* updated docs

---------

Co-authored-by: Vincent Rose <[email protected]>
  • Loading branch information
Cx01N and vinnybod authored Mar 11, 2024
1 parent 174b692 commit 6e8eb58
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 21 deletions.
11 changes: 7 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Fixed issue loading `openapi.json` (@Vinnybod)

### Added

- Added dependabot for github actions dependencies (@Vinnybod)
- Added install option to ./ps-empire file (@Cx01N)
- Added auto pull options for submodules on startup (@Cx01N)
- Added hook and socket message to receive callback messages for individual agents (@AaronVigal)

### Changed

- Updated all dependencies (@Vinnybod)
- Updated Dockerfile and install script to Python 3.12.2 (@Vinnybod)
- Updated starkiller snyc to no longer require root (@Cx01N)

### Fixed

- Fixed issue loading `openapi.json` (@Vinnybod)

## [5.9.5] - 2024-02-22

Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,15 @@ Empire is a post-exploitation and adversary emulation framework that is used to
- [ProcessInjection](https://github.com/3xpl01tc0d3r/ProcessInjection)
- And Many More

<!---
## Sponsors
<div align="center">
[<img src="https://github.com/BC-SECURITY/Empire/assets/9831420/f273f4b0-400c-49ce-b62f-521239a86754" width="100"/>](https://www.cybrary.it/)
[<img src="https://github.com/BC-SECURITY/Empire/assets/9831420/d14af000-80d2-4f67-b70c-b62ac42b6a52" width="100"/>](https://twitter.com/joehelle)

</div>
--->

## Release Notes

Expand All @@ -80,7 +81,7 @@ After cloning the repo, you can checkout the latest stable release by running th
git clone --recursive https://github.com/BC-SECURITY/Empire.git
cd Empire
./setup/checkout-latest-tag.sh
./setup/install.sh
./ps-empire install -y
```

If you are using the sponsors version of Empire, it will pull the sponsors version of Starkiller.
Expand Down
7 changes: 7 additions & 0 deletions docs/quickstart/configuration/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,10 @@ directories:
```
* **logging** - See [Logging](../../logging/logging.md) for more information on logging configuration.
* **submodules** - Control if submodules wil be auto updated on startup.
```
submodules:
auto_update: true
```
4 changes: 2 additions & 2 deletions docs/quickstart/installation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Note: The `main` branch is a reflection of the latest changes and may not always
git clone --recursive https://github.com/BC-SECURITY/Empire.git
cd Empire
./setup/checkout-latest-tag.sh
./setup/install.sh
./ps-empire install -y
```

**Sponsors:**
Expand All @@ -28,7 +28,7 @@ cd Empire
git clone --recursive https://github.com/BC-SECURITY/Empire-Sponsors.git
cd Empire-Sponsors
./setup/checkout-latest-tag.sh sponsors
./setup/install.sh
./ps-empire install -y
```

If you are using the sponsors version of Empire, it will pull the sponsors version of Starkiller.
Expand Down
6 changes: 6 additions & 0 deletions empire/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
sync_starkiller_parser = subparsers.add_parser(
"sync-starkiller", help="Sync Starkiller submodule with the config"
)
install_parser = subparsers.add_parser("install", help="Install the Empire framework")
install_parser.add_argument(
"-y",
action="store_true",
help="Automatically say yes to all prompts during installation",
)

# Client Args
client_parser.add_argument(
Expand Down
18 changes: 7 additions & 11 deletions empire/scripts/sync_starkiller.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import logging
import subprocess
from pathlib import Path

from empire.server.utils.file_util import run_as_user

log = logging.getLogger(__name__)


Expand All @@ -26,23 +27,18 @@ def sync_starkiller(empire_config):


def _clone_starkiller(starkiller_config: dict, starkiller_dir: str):
subprocess.run(
["git", "clone", starkiller_config["repo"], starkiller_dir],
check=True,
)
run_as_user(["git", "clone", starkiller_config["repo"], starkiller_dir])


def _fetch_checkout_pull(remote_repo, ref, cwd):
subprocess.run(
run_as_user(
["git", "remote", "set-url", "origin", remote_repo],
cwd=cwd,
check=True,
)

subprocess.run(["git", "fetch"], cwd=cwd, check=True)
subprocess.run(
run_as_user(["git", "fetch"], cwd=cwd)
run_as_user(
["git", "checkout", ref],
cwd=cwd,
check=True,
)
subprocess.run(["git", "pull", "origin", ref], cwd=cwd)
run_as_user(["git", "pull", "origin", ref], cwd=cwd)
2 changes: 2 additions & 0 deletions empire/server/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ starkiller:
# Can be a branch, tag, or commit hash
ref: sponsors-main
auto_update: true
submodules:
auto_update: true
plugins:
# Auto-load plugin with defined settings
csharpserver:
Expand Down
5 changes: 5 additions & 0 deletions empire/server/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class ApiConfig(EmpireBaseModel):
cert_path: Path = "empire/server/data"


class SubmodulesConfig(EmpireBaseModel):
auto_update: bool = True


class StarkillerConfig(EmpireBaseModel):
repo: str = "bc-security/starkiller"
directory: Path = "empire/server/api/v2/starkiller"
Expand Down Expand Up @@ -96,6 +100,7 @@ class EmpireConfig(EmpireBaseModel):
)
api: ApiConfig | None = ApiConfig()
starkiller: StarkillerConfig
submodules: SubmodulesConfig
database: DatabaseConfig
plugins: dict[str, dict[str, str]] = {}
directories: DirectoriesConfig
Expand Down
13 changes: 13 additions & 0 deletions empire/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from empire.server.core.config import empire_config
from empire.server.core.db import base
from empire.server.utils import file_util
from empire.server.utils.file_util import run_as_user
from empire.server.utils.log_util import LOG_FORMAT, SIMPLE_LOG_FORMAT, ColorFormatter

log = logging.getLogger(__name__)
Expand Down Expand Up @@ -124,6 +125,11 @@ def check_submodules():
exit(1)


def fetch_submodules():
command = ["git", "submodule", "update", "--init", "--recursive"]
run_as_user(command)


def check_recommended_configuration():
log.info(f"Using {empire_config.database.use} database.")
if empire_config.database.use == "sqlite":
Expand All @@ -135,6 +141,13 @@ def check_recommended_configuration():

def run(args):
setup_logging(args)

if empire_config.submodules.auto_update:
log.info("Submodules auto update enabled. Loading.")
fetch_submodules()
else:
log.info("Submodules auto update disabled. Not fetching.")

check_submodules()
check_recommended_configuration()

Expand Down
29 changes: 29 additions & 0 deletions empire/server/utils/file_util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import logging
import os
import shutil
import subprocess

log = logging.getLogger(__name__)


def remove_dir_contents(path: str) -> None:
Expand All @@ -22,3 +26,28 @@ def remove_file(path: str) -> None:
"""
if os.path.exists(path):
os.remove(path)


def run_as_user(command, user=None, cwd=None):
"""
Runs a command as a specified user or the user who invoked sudo.
If no user is specified and the script is not run with sudo, it runs as the current user.
Args:
command (list): The command to run, specified as a list of strings.
user (str, optional): The username to run the command as. Defaults to None.
"""
try:
if user is None:
user = os.getenv("SUDO_USER")

command_with_user = ["sudo", "-u", user, *command] if user else command

subprocess.run(command_with_user, check=True, cwd=cwd)

log.debug("Command executed successfully: %s", " ".join(command))

except subprocess.CalledProcessError as e:
# Log the error details
log.error("Failed to execute command: %s", e, exc_info=True)
log.error("Try running the command manually: %s", " ".join(command))
2 changes: 2 additions & 0 deletions empire/test/test_server_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ starkiller:
# for the downstream main branches.
use_temp_dir: false
auto_update: true
submodules:
auto_update: true
directories:
downloads: empire/test/downloads/
module_source: empire/server/data/module_source/
Expand Down
29 changes: 27 additions & 2 deletions ps-empire
Original file line number Diff line number Diff line change
@@ -1,2 +1,27 @@
#! /bin/bash
sudo -E poetry run python empire.py ${@}
#!/bin/bash

INSTALL=0
YES_OPTION=""
EMPIRE_ARGS=()

# Parse command-line options manually, without using getopts, to allow non-standard options
for arg in "$@"; do
case $arg in
install)
INSTALL=1
;;
-y)
YES_OPTION="-y"
;;
*)
EMPIRE_ARGS+=("$arg")
;;
esac
done

# Check if install option was given
if [ $INSTALL -eq 1 ]; then
./setup/install.sh $YES_OPTION
fi

sudo -E poetry run python empire.py "${EMPIRE_ARGS[@]}"

0 comments on commit 6e8eb58

Please sign in to comment.