acquire 3.7.dev2__tar.gz → 3.7.dev4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {acquire-3.7.dev2/acquire.egg-info → acquire-3.7.dev4}/PKG-INFO +1 -1
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/acquire.py +1 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/tools/decrypter.py +47 -10
- acquire-3.7.dev4/acquire/version.py +4 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4/acquire.egg-info}/PKG-INFO +1 -1
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire.egg-info/SOURCES.txt +1 -0
- acquire-3.7.dev4/tests/test_decryptor_funcs.py +28 -0
- acquire-3.7.dev2/acquire/version.py +0 -4
- {acquire-3.7.dev2 → acquire-3.7.dev4}/COPYRIGHT +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/LICENSE +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/MANIFEST.in +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/README.md +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/collector.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/crypt.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/collect.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/exceptions.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/handles.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/named_objects.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/ntdll.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/dynamic/windows/types.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/esxi.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/hashes.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/log.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/outputs/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/outputs/base.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/outputs/dir.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/outputs/tar.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/tools/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/uploaders/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/uploaders/minio.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/uploaders/plugin.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/uploaders/plugin_registry.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire/utils.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire.egg-info/dependency_links.txt +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire.egg-info/entry_points.txt +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire.egg-info/requires.txt +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/acquire.egg-info/top_level.txt +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/pyproject.toml +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/setup.cfg +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/__init__.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/conftest.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/docs/Makefile +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/docs/conf.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/docs/index.rst +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_acquire_command.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_collector.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_esxi_memory.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_file_sorting.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_minio_uploader.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_plugin.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tests/test_utils.py +0 -0
- {acquire-3.7.dev2 → acquire-3.7.dev4}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: acquire
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.dev4
|
|
4
4
|
Summary: A tool to quickly gather forensic artifacts from disk images or a live system into a lightweight container
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -946,6 +946,7 @@ class QuarantinedFiles(Module):
|
|
|
946
946
|
# Sophos
|
|
947
947
|
("glob", "sysvol/ProgramData/Sophos/Sophos/*/Quarantine"),
|
|
948
948
|
("glob", "sysvol/ProgramData/Sophos/Sophos */INFECTED"),
|
|
949
|
+
("dir", "sysvol/ProgramData/Sophos/Safestore"),
|
|
949
950
|
# HitmanPRO
|
|
950
951
|
("dir", "sysvol/ProgramData/HitmanPro/Quarantine"),
|
|
951
952
|
]
|
|
@@ -8,7 +8,8 @@ import multiprocessing
|
|
|
8
8
|
import os
|
|
9
9
|
import signal
|
|
10
10
|
import sys
|
|
11
|
-
|
|
11
|
+
import textwrap
|
|
12
|
+
from collections import defaultdict, deque
|
|
12
13
|
from concurrent.futures import ProcessPoolExecutor
|
|
13
14
|
from datetime import datetime, timezone
|
|
14
15
|
from pathlib import Path
|
|
@@ -343,19 +344,20 @@ def main():
|
|
|
343
344
|
if not progress:
|
|
344
345
|
log.info("`rich` is not installed, progress will not be shown")
|
|
345
346
|
|
|
346
|
-
if args.output and len(args.files) > 1:
|
|
347
|
-
parser.exit("--output
|
|
347
|
+
if args.output and args.output.is_file() and len(args.files) > 1:
|
|
348
|
+
parser.exit("--output should be a directory when decrypting multiple files.")
|
|
348
349
|
|
|
349
|
-
|
|
350
|
-
for path in args.files:
|
|
351
|
-
if path.suffix != ".enc":
|
|
352
|
-
parser.exit(f"File doesn't have .enc extension: {path}")
|
|
350
|
+
files = find_enc_files(args.files)
|
|
353
351
|
|
|
354
352
|
if args.output:
|
|
355
|
-
|
|
353
|
+
resolv_path = args.output.resolve()
|
|
354
|
+
outputs = [resolv_path / path.stem for path in files] if args.output.is_dir() else [resolv_path]
|
|
356
355
|
else:
|
|
357
356
|
# Strip .enc extension
|
|
358
|
-
outputs = [path.with_suffix("") for path in
|
|
357
|
+
outputs = [path.with_suffix("") for path in files]
|
|
358
|
+
|
|
359
|
+
if len(set(outputs)) != len(outputs):
|
|
360
|
+
show_duplicates(args.output, files)
|
|
359
361
|
|
|
360
362
|
if not args.key_file and not args.key_server:
|
|
361
363
|
parser.exit("Need either --key-file or --key-server")
|
|
@@ -378,7 +380,7 @@ def main():
|
|
|
378
380
|
status_queue = mp.Queue()
|
|
379
381
|
tasks = []
|
|
380
382
|
|
|
381
|
-
for in_path, out_path in zip(
|
|
383
|
+
for in_path, out_path in zip(files, outputs):
|
|
382
384
|
task_id = (
|
|
383
385
|
progress.add_task("decrypt", start=False, visible=False, filename=in_path.name)
|
|
384
386
|
if progress
|
|
@@ -424,6 +426,41 @@ def main():
|
|
|
424
426
|
break
|
|
425
427
|
|
|
426
428
|
|
|
429
|
+
def show_duplicates(output_directory: Path, files: list[Path]) -> None:
|
|
430
|
+
# Gather all files that could cause duplicates in `args.output`.
|
|
431
|
+
input_files = defaultdict(list)
|
|
432
|
+
for input_file in files:
|
|
433
|
+
input_files[input_file.name].append(input_file)
|
|
434
|
+
|
|
435
|
+
# Find all duplicates
|
|
436
|
+
duplicate_generator = (file_paths for file_paths in input_files.values() if len(file_paths) > 1)
|
|
437
|
+
duplicates = "\n\n".join(
|
|
438
|
+
textwrap.indent(
|
|
439
|
+
"\n".join(str(file) for file in file_paths),
|
|
440
|
+
prefix=" - ",
|
|
441
|
+
)
|
|
442
|
+
for file_paths in duplicate_generator
|
|
443
|
+
)
|
|
444
|
+
log.warning(
|
|
445
|
+
"Two or more encrypted files have the same name. "
|
|
446
|
+
f"This will skip decrypting the file if it already exists in '{output_directory}'\n"
|
|
447
|
+
f"The files with the same names are:\n"
|
|
448
|
+
f"{duplicates}"
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def find_enc_files(files: list[Path]) -> list[Path]:
|
|
453
|
+
encrypted_files = []
|
|
454
|
+
for path in files:
|
|
455
|
+
if path.is_file() and path.suffix == ".enc":
|
|
456
|
+
encrypted_files.append(path)
|
|
457
|
+
elif path.is_dir():
|
|
458
|
+
encrypted_files.extend(path.rglob("*.enc"))
|
|
459
|
+
else:
|
|
460
|
+
log.info(f"File {path!r} does not have the .enc extension. skipping.")
|
|
461
|
+
return encrypted_files
|
|
462
|
+
|
|
463
|
+
|
|
427
464
|
if __name__ == "__main__":
|
|
428
465
|
try:
|
|
429
466
|
sys.exit(main())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: acquire
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.dev4
|
|
4
4
|
Summary: A tool to quickly gather forensic artifacts from disk images or a live system into a lightweight container
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from acquire.tools.decrypter import find_enc_files
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_find_non_encrypted_files(tmp_path: Path):
|
|
7
|
+
input_files = [tmp_path / "test", tmp_path / "help"]
|
|
8
|
+
|
|
9
|
+
for file in input_files:
|
|
10
|
+
file.touch()
|
|
11
|
+
|
|
12
|
+
assert find_enc_files(input_files) == []
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_find_inside_dir(tmp_path: Path):
|
|
16
|
+
output_path = tmp_path.joinpath("output/for/this/test")
|
|
17
|
+
output_path.mkdir(parents=True)
|
|
18
|
+
|
|
19
|
+
rel_path = output_path.relative_to(tmp_path)
|
|
20
|
+
|
|
21
|
+
expected_outputs = []
|
|
22
|
+
|
|
23
|
+
for directory in rel_path.parents:
|
|
24
|
+
searchable_file = tmp_path / directory / "test.enc"
|
|
25
|
+
searchable_file.touch()
|
|
26
|
+
expected_outputs.append(searchable_file)
|
|
27
|
+
|
|
28
|
+
assert sorted(find_enc_files([tmp_path])) == sorted(expected_outputs)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|