diff --git a/dissect/target/loaders/log.py b/dissect/target/loaders/log.py index e330c4fde..cf73f1458 100644 --- a/dissect/target/loaders/log.py +++ b/dissect/target/loaders/log.py @@ -11,13 +11,20 @@ @arg("--log-hint", dest="hint", help="hint for file type") +@arg("--path", dest="path", help="Map log file(s) to a specific path in the target filesystem") class LogLoader(Loader): - """Load separate log files without a target. + """Load separate log files without a target. By default attempts to map discovered log files based on their file + extension. The loader can also map log files to a specific path in the target filesystem using the ``--path`` + option. Usage: ``target-query /evtx/* -L log -f evtx`` + or by specifying a manual path, which can be a directory or a single file: + + * ``target-query log://evidence/extracted_wtmp?path=/var/log/wtmp -f wtmp`` + * ``target-query log://evidence/apache?path=/var/log/apache2 -f apache.access`` """ LOGS_DIRS = { @@ -40,9 +47,19 @@ def map(self, target: Target) -> None: vfs = VirtualFilesystem(case_sensitive=False, alt_separator=target.fs.alt_separator) target.filesystems.add(vfs) target.fs.mount("/", vfs) - for entry in self.path.parent.glob(self.path.name): - ext = self.options.get("hint", entry.suffix.lower()).strip(".") - if (mapping := self.LOGS_DIRS.get(ext, None)) is None: - continue - mapping = str(vfs.path(mapping).joinpath(entry.name)) - vfs.map_file(mapping, str(entry)) + if manual_path := self.options.get("path"): + if self.path.is_dir(): + for entry in self.path.glob("*"): + # Map every entry in the directory to the manual path + mapping = str(vfs.path(manual_path).joinpath(entry.name)) + vfs.map_file(mapping, str(entry)) + else: + # Manual path is a single file, map it into the virtual filesystem + vfs.map_file(manual_path, str(self.path)) + else: + for entry in self.path.parent.glob(self.path.name): + ext = self.options.get("hint", entry.suffix.lower()).strip(".") + if (mapping := self.LOGS_DIRS.get(ext, None)) is None: + continue + mapping = str(vfs.path(mapping).joinpath(entry.name)) + vfs.map_file(mapping, str(entry)) diff --git a/tests/loaders/test_log.py b/tests/loaders/test_log.py index 82d31a10f..10fb7ed3e 100644 --- a/tests/loaders/test_log.py +++ b/tests/loaders/test_log.py @@ -15,6 +15,8 @@ ("/dir/*.evt*", None, "/dir/test.evtx", "/sysvol/windows/system32/winevt/logs/test.evtx"), ("/dir/*.evt*", None, "/dir/test.evt", "/sysvol/windows/system32/config/test.evt"), ("/source/iis.log", "log:///dir/with/files/*.log?hint=iis", "/source/iis.log", "/sysvol/files/logs/iis.log"), + ("/source/", "log://?path=/var/log", "/source/test.log", "/var/log/test.log"), + ("/source/test.log", "log://test.log?path=/var/log/test.log", "/source/test.log", "/var/log/test.log"), ], ) def test_log_loader(target_default: Target, path: str, uri: str, input_file: str, expected_mapping: str) -> None: