diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ff3116df..4af0e245b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - The process list collection system info collector to now be a post-breach action. #1697 - The "/api/monkey/download" endpoint to accept an OS and return a file. #1675 - Log messages to contain human-readable thread names. #1766 +- The log file name to `infection-monkey-agent--.log`. #1761 ### Removed - VSFTPD exploiter. #1533 @@ -51,6 +52,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - ElasticGroovy exploiter. #1732 - T1082 attack technique report. #1754 - 32-bit agents. #1675 +- Log path config options. #1761 ### Fixed - A bug in network map page that caused delay of telemetry log loading. #1545 diff --git a/docs/content/FAQ/_index.md b/docs/content/FAQ/_index.md index 76fedf3a4..1c5760549 100644 --- a/docs/content/FAQ/_index.md +++ b/docs/content/FAQ/_index.md @@ -179,10 +179,20 @@ It's also possible to change the default log level by editing `log_level` value ### Infection Monkey agent logs -The Infection Monkey agent log file can be found in the following paths on machines where it was executed: +The Infection Monkey agent log file can be found in directories specified for +temporary files on the machines where it was executed. In most cases, this will +be `/tmp` on Linux and `%temp%` on Windows. The agent searches a standard list +of directories to find an appropriate place to store the log: -- Path on Linux: `/tmp/user-1563` -- Path on Windows: `%temp%\\~df1563.tmp` +1. The directory named by the `TMPDIR` environment variable. +2. The directory named by the `TEMP` environment variable. +3. The directory named by the `TMP` environment variable. +4. A platform-specific location: + - On Windows, the directories `C:\TEMP`, `C:\TMP`, `\TEMP`, and `\TMP`, in that order. + - On all other platforms, the directories `/tmp`, `/var/tmp`, and `/usr/tmp`, in that order. +5. As a last resort, the current working directory. + +Infection Monkey log file name is constructed to the following pattern: `infection-monkey-agent--.log` The logs contain information about the internals of the Infection Monkey agent's execution. The log will contain entries like these: @@ -206,9 +216,9 @@ The logs contain information about the internals of the Infection Monkey agent's The Infection Monkey leaves hardly any trace on the target system. It will leave: -- Log files in the following locations: - - Path on Linux: `/tmp/user-1563` - - Path on Windows: `%temp%\\~df1563.tmp` +- Log files in [temporary directories]({{< ref "/faq/#infection-monkey-agent-logs">}}): + - Path on Linux: `/tmp/infection-monky-agent--.log` + - Path on Windows: `%temp%\\infection-monky-agent--.log` ### What's the Infection Monkey Agent's impact on system resources usage? diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 63c8c5c3b..8feb3f3f7 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -67,15 +67,6 @@ class Configuration(object): return result - ########################### - # logging config - ########################### - - dropper_log_path_windows = "%temp%\\~df1562.tmp" - dropper_log_path_linux = "/tmp/user-1562" - monkey_log_path_windows = "%temp%\\~df1563.tmp" - monkey_log_path_linux = "/tmp/user-1563" - ########################### # dropper config ########################### diff --git a/monkey/infection_monkey/example.conf b/monkey/infection_monkey/example.conf index f370e5fdd..ebadf1429 100644 --- a/monkey/infection_monkey/example.conf +++ b/monkey/infection_monkey/example.conf @@ -16,8 +16,6 @@ "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", "dropper_date_reference_path_linux": "/bin/sh", - "dropper_log_path_windows": "%temp%\\~df1562.tmp", - "dropper_log_path_linux": "/tmp/user-1562", "dropper_set_date": true, "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", "dropper_target_path_linux": "/tmp/monkey", @@ -38,8 +36,6 @@ "MSSQLFingerprint", "ElasticFinger" ], - "monkey_log_path_windows": "%temp%\\~df1563.tmp", - "monkey_log_path_linux": "/tmp/user-1563", "ping_scan_timeout": 10000, "smb_download_timeout": 300, "smb_service_name": "InfectionMonkey", diff --git a/monkey/infection_monkey/main.py b/monkey/infection_monkey/main.py index 9388d5431..74961e0ad 100644 --- a/monkey/infection_monkey/main.py +++ b/monkey/infection_monkey/main.py @@ -16,7 +16,7 @@ from infection_monkey.config import EXTERNAL_CONFIG_FILE, WormConfiguration from infection_monkey.dropper import MonkeyDrops from infection_monkey.model import DROPPER_ARG, MONKEY_ARG from infection_monkey.monkey import InfectionMonkey -from infection_monkey.utils.monkey_log_path import get_dropper_log_path, get_monkey_log_path +from infection_monkey.utils.monkey_log_path import get_agent_log_path, get_dropper_log_path logger = None @@ -80,7 +80,7 @@ def main(): try: if MONKEY_ARG == monkey_mode: - log_path = get_monkey_log_path() + log_path = get_agent_log_path() monkey_cls = InfectionMonkey elif DROPPER_ARG == monkey_mode: log_path = get_dropper_log_path() @@ -116,6 +116,7 @@ def main(): ) logger.info(f"version: {get_version()}") + logger.info(f"writing log file to {log_path}") monkey = monkey_cls(monkey_args) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 218b0e92a..983e2dd2b 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -52,7 +52,7 @@ from infection_monkey.utils.monkey_dir import ( get_monkey_dir_path, remove_monkey_dir, ) -from infection_monkey.utils.monkey_log_path import get_monkey_log_path +from infection_monkey.utils.monkey_log_path import get_agent_log_path from infection_monkey.utils.signal_handler import register_signal_handlers, reset_signal_handlers logger = logging.getLogger(__name__) @@ -288,8 +288,8 @@ class InfectionMonkey: @staticmethod def _send_log(): - monkey_log_path = get_monkey_log_path() - if os.path.exists(monkey_log_path): + monkey_log_path = get_agent_log_path() + if monkey_log_path.is_file(): with open(monkey_log_path, "r") as f: log = f.read() else: diff --git a/monkey/infection_monkey/utils/monkey_log_path.py b/monkey/infection_monkey/utils/monkey_log_path.py index 0b97f83b9..4fd418f50 100644 --- a/monkey/infection_monkey/utils/monkey_log_path.py +++ b/monkey/infection_monkey/utils/monkey_log_path.py @@ -1,20 +1,19 @@ -import os -import sys - -from infection_monkey.config import WormConfiguration +import tempfile +import time +from functools import lru_cache, partial +from pathlib import Path -def get_monkey_log_path(): - return ( - os.path.expandvars(WormConfiguration.monkey_log_path_windows) - if sys.platform == "win32" - else WormConfiguration.monkey_log_path_linux - ) +# Cache the result of the call so that subsequent calls always return the same result +@lru_cache(maxsize=None) +def _get_log_path(monkey_arg: str) -> Path: + prefix = f"infection-monkey-{monkey_arg}-" + suffix = f"-{time.strftime('%Y-%m-%d-%H-%M-%S', time.gmtime())}.log" + + _, monkey_log_path = tempfile.mkstemp(suffix=suffix, prefix=prefix) + + return Path(monkey_log_path) -def get_dropper_log_path(): - return ( - os.path.expandvars(WormConfiguration.dropper_log_path_windows) - if sys.platform == "win32" - else WormConfiguration.dropper_log_path_linux - ) +get_agent_log_path = partial(_get_log_path, "monkey") +get_dropper_log_path = partial(_get_log_path, "dropper") diff --git a/monkey/monkey_island/cc/services/config_schema/internal.py b/monkey/monkey_island/cc/services/config_schema/internal.py index 45b76dd23..98ab8b95e 100644 --- a/monkey/monkey_island/cc/services/config_schema/internal.py +++ b/monkey/monkey_island/cc/services/config_schema/internal.py @@ -184,36 +184,6 @@ INTERNAL = { }, }, }, - "logging": { - "title": "Logging", - "type": "object", - "properties": { - "dropper_log_path_linux": { - "title": "Dropper log file path on Linux", - "type": "string", - "default": "/tmp/user-1562", - "description": "The fullpath of the dropper log file on Linux", - }, - "dropper_log_path_windows": { - "title": "Dropper log file path on Windows", - "type": "string", - "default": "%temp%\\~df1562.tmp", - "description": "The fullpath of the dropper log file on Windows", - }, - "monkey_log_path_linux": { - "title": "Monkey log file path on Linux", - "type": "string", - "default": "/tmp/user-1563", - "description": "The fullpath of the monkey log file on Linux", - }, - "monkey_log_path_windows": { - "title": "Monkey log file path on Windows", - "type": "string", - "default": "%temp%\\~df1563.tmp", - "description": "The fullpath of the monkey log file on Windows", - }, - }, - }, "exploits": { "title": "Exploits", "type": "object", diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js index d7d13db54..42a86dbff 100644 --- a/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/InternalConfig.js @@ -5,7 +5,6 @@ import {Nav} from 'react-bootstrap'; const sectionOrder = [ 'network', 'island_server', - 'logging', 'exploits', 'dropper', 'classes', diff --git a/monkey/tests/data_for_tests/monkey_configs/flat_config.json b/monkey/tests/data_for_tests/monkey_configs/flat_config.json index fdac570f5..1f82c5499 100644 --- a/monkey/tests/data_for_tests/monkey_configs/flat_config.json +++ b/monkey/tests/data_for_tests/monkey_configs/flat_config.json @@ -23,8 +23,6 @@ "depth": 2, "dropper_date_reference_path_linux": "/bin/sh", "dropper_date_reference_path_windows": "%windir%\\system32\\kernel32.dll", - "dropper_log_path_linux": "/tmp/user-1562", - "dropper_log_path_windows": "%temp%\\~df1562.tmp", "dropper_set_date": true, "dropper_target_path_linux": "/tmp/monkey", "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe", @@ -71,8 +69,6 @@ "keep_tunnel_open_time": 60, "local_network_scan": true, "max_depth": null, - "monkey_log_path_linux": "/tmp/user-1563", - "monkey_log_path_windows": "%temp%\\~df1563.tmp", "ping_scan_timeout": 1000, "post_breach_actions": [ "CommunicateAsBackdoorUser", diff --git a/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json b/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json index 9891fef0c..f0c95e5b3 100644 --- a/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json +++ b/monkey/tests/data_for_tests/monkey_configs/monkey_config_standard.json @@ -106,12 +106,6 @@ "dropper_target_path_linux": "/tmp/monkey", "dropper_target_path_win_64": "C:\\Windows\\temp\\monkey64.exe" }, - "logging": { - "dropper_log_path_linux": "/tmp/user-1562", - "dropper_log_path_windows": "%temp%\\~df1562.tmp", - "monkey_log_path_linux": "/tmp/user-1563", - "monkey_log_path_windows": "%temp%\\~df1563.tmp" - }, "exploits": { "exploit_lm_hash_list": [], "exploit_ntlm_hash_list": [], diff --git a/monkey/tests/unit_tests/infection_monkey/utils/test_monkey_log_path.py b/monkey/tests/unit_tests/infection_monkey/utils/test_monkey_log_path.py new file mode 100644 index 000000000..339b0f37a --- /dev/null +++ b/monkey/tests/unit_tests/infection_monkey/utils/test_monkey_log_path.py @@ -0,0 +1,28 @@ +import pytest + +from infection_monkey.utils.monkey_log_path import get_agent_log_path, get_dropper_log_path + +def delete_log_file(log_path): + if log_path.is_file(): + log_path.unlink() + + +@pytest.mark.parametrize("get_log_path", [get_agent_log_path, get_dropper_log_path]) +def test_subsequent_calls_return_same_path(get_log_path): + log_path_1 = get_log_path() + assert log_path_1.is_file() + + log_path_2 = get_log_path() + assert log_path_1 == log_path_2 + + delete_log_file(log_path_1) + + +def test_agent_dropper_paths_differ(): + agent_log_path = get_agent_log_path() + dropper_log_path = get_dropper_log_path() + + assert agent_log_path != dropper_log_path + + for log_path in [agent_log_path, dropper_log_path]: + delete_log_file(log_path)