diff --git a/acquire/acquire.py b/acquire/acquire.py index 05b581ef..428448b7 100644 --- a/acquire/acquire.py +++ b/acquire/acquire.py @@ -44,7 +44,9 @@ filter_out_by_path_match, filter_out_by_value_match, filter_out_huge_files, + md5sum, serialize_into_csv, + sha256sum, ) from acquire.log import get_file_handler, reconfigure_log_file, setup_logging from acquire.outputs import OUTPUTS @@ -2127,6 +2129,10 @@ def acquire_target(target: Target, args: argparse.Namespace, output_ts: str | No else: report_file_name = f"{output_path.name}.report.json" + if args.hash_collection: + hashes = {"md5": md5sum(output.path), "sha256": sha256sum(output.path)} + execution_report["hashes"] = hashes + report_file_path = output_path.parent / report_file_name persist_execution_report(report_file_path, execution_report) @@ -2134,6 +2140,10 @@ def acquire_target(target: Target, args: argparse.Namespace, output_ts: str | No log.info("Acquisition report for %s is written to %s", target, report_file_path) log.info("Output: %s", output.path) + + if args.hash_collection: + log.info("Output MD5: %s", hashes["md5"]) + log.info("Output SHA-256: %s", hashes["sha256"]) return files diff --git a/acquire/hashes.py b/acquire/hashes.py index 62535b7a..b51fe6e5 100644 --- a/acquire/hashes.py +++ b/acquire/hashes.py @@ -244,3 +244,17 @@ def serialize_into_csv(rows: Iterator[list], compress: bool = True) -> tuple[int ) return (counter, raw_buffer.getvalue()) + + +def md5sum(path: Path) -> str: + with path.open(mode="rb") as f: + digest = hashlib.file_digest(f, "md5") + + return digest.hexdigest() + + +def sha256sum(path: Path) -> str: + with path.open(mode="rb") as f: + digest = hashlib.file_digest(f, "sha256") + + return digest.hexdigest() diff --git a/acquire/utils.py b/acquire/utils.py index 26c3a01e..9efeca00 100644 --- a/acquire/utils.py +++ b/acquire/utils.py @@ -180,6 +180,11 @@ def create_argument_parser(profiles: dict, volatile: dict, modules: dict) -> arg nargs="+", help="upload specified files (all other acquire actions are ignored)", ) + parser.add_argument( + "--hash-collection", + action=argparse.BooleanOptionalAction, + help="Calculate hashes of the collection", + ) parser.add_argument("--no-proxy", action="store_true", help="don't autodetect proxies") parser.add_argument("-K", "--keychain-file", type=Path, help="keychain file in CSV format")