Skip to content

Commit

Permalink
Change file permissions for empire and listener logs to be non-root (E…
Browse files Browse the repository at this point in the history
…mpireProject#796)

* change file premissions for empire and listener logs to be non-root

* updated changelog

* fixed test when no sudo found

* updated changelog
  • Loading branch information
Cx01N authored Mar 29, 2024
1 parent a6b7827 commit 3034816
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added auto pull options for submodules on startup (@Cx01N)
- Added hook and socket message to receive callback messages for individual agents (@AaronVigal)
- Added sacrificial Spawn Process bof (@Cx01N)
- Added suggested values to most modules (@Cx01N)

### 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)
- Change file permissions for empire and listener logs to be non-root (@Cx01N)

### Fixed

Expand Down
14 changes: 14 additions & 0 deletions empire/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import os
import pathlib
import pwd
import shutil
import signal
import subprocess
Expand Down Expand Up @@ -51,6 +52,19 @@ def setup_logging(args):
root_logger_stream_handler.setLevel(log_level)
root_logger.addHandler(root_logger_stream_handler)

try:
user = os.getenv("SUDO_USER")
if user:
user_info = pwd.getpwnam(user)
os.chown(root_log_file, user_info.pw_uid, user_info.pw_gid)
log.debug(f"Log file owner changed to {user}.")
else:
log.warning("Log file owner not changed. SUDO_USER not found.")
except KeyError:
log.error("User not found. Log file owner not changed.")
except PermissionError:
log.error("Permission denied. You need root privileges to change file owner.")


CSHARP_DIR_BASE = os.path.join(os.path.dirname(__file__), "csharp/Covenant")
INVOKE_OBFS_SRC_DIR_BASE = os.path.join(
Expand Down
15 changes: 15 additions & 0 deletions empire/server/utils/log_util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import logging
import os
import pwd
from pathlib import Path

from empire.server.core.config import empire_config
Expand Down Expand Up @@ -33,6 +35,19 @@ def get_listener_logger(log_name_prefix: str, listener_name: str):
listener_stream_handler.setFormatter(ColorFormatter(stream_format))
log.addHandler(listener_stream_handler)

try:
user = os.getenv("SUDO_USER")
if user:
user_info = pwd.getpwnam(user)
os.chown(log_file, user_info.pw_uid, user_info.pw_gid)
log.debug(f"Log file owner changed to {user}.")
else:
log.warning("SUDO_USER not set. Log file owner not changed.")
except KeyError:
log.error("User not found. Log file owner not changed.")
except PermissionError:
log.error("Permission denied. You need root privileges to change file owner.")

return log


Expand Down
37 changes: 37 additions & 0 deletions empire/test/test_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,40 @@ def test_log_level_by_debug_arg():
setup_logging(args)

assert logging.getLogger().level == logging.DEBUG


def test_log_file_not_owned_by_root(monkeypatch):
logging.getLogger().handlers.clear()
os.chdir(Path(os.path.dirname(os.path.abspath(__file__))).parent.parent)
sys.argv = ["", "server", "--config", SERVER_CONFIG_LOC]

monkeypatch.setattr("empire.server.server.empire", MagicMock())

from empire import arguments
from empire.server.core.config import EmpireConfig
from empire.server.server import setup_logging

test_config = load_test_config()
config = EmpireConfig(test_config)
monkeypatch.setattr("empire.server.server.empire_config", config)

args = arguments.parent_parser.parse_args()
setup_logging(args)

log_dir = Path(config.logging.directory)
log_file_path = log_dir / "empire_server.log"

assert log_file_path.exists(), "Empire log file does not exist."

stat_info = os.stat(log_file_path)

assert stat_info.st_uid != 0, "Empire log file is owned by root."

listener_log_dir = Path(config.logging.directory)
listener_log_file_path = listener_log_dir / "listener_new-listener-1.log"

assert listener_log_file_path.exists(), "Listener log file does not exist."

listener_stat_info = os.stat(listener_log_file_path)

assert listener_stat_info.st_uid != 0, "Listener log file is owned by root."

0 comments on commit 3034816

Please sign in to comment.