From 75ce6b3a1b3f0223342a465940e59c18c4b59fcf Mon Sep 17 00:00:00 2001 From: venus Date: Fri, 17 Jul 2026 01:27:31 -0500 Subject: [PATCH] Implement forensics signatures command and expand supported magic signatures dictionary --- src/ctf/forensics.py | 47 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/src/ctf/forensics.py b/src/ctf/forensics.py index f73412b..a418610 100644 --- a/src/ctf/forensics.py +++ b/src/ctf/forensics.py @@ -16,6 +16,24 @@ except ImportError: pwd = None grp = None +COMMON_SIGNATURES = { + b"\x89PNG\r\n\x1a\n": ("PNG Image", [".png"]), + b"\xff\xd8\xff": ("JPEG Image", [".jpg", ".jpeg"]), + b"%PDF": ("PDF Document", [".pdf"]), + b"PK\x03\x04": ("ZIP Archive", [".zip"]), + b"\x7fELF": ("ELF Executable", [".elf"]), + b"MZ": ("PE Executable", [".exe", ".dll"]), + b"GIF87a": ("GIF Image", [".gif"]), + b"GIF89a": ("GIF Image", [".gif"]), + b"7z\xbc\xaf\x27\x1c": ("7-Zip Archive", [".7z"]), + b"\x1f\x8b": ("GZIP Archive", [".gz"]), + b"Rar!\x1a\x07\x00": ("RAR Archive", [".rar"]), + b"Rar!\x1a\x07\x01\x00": ("RAR Archive", [".rar"]), + b"BZh": ("BZIP2 Archive", [".bz2"]), + b"BM": ("BMP Image", [".bmp"]), + b"ID3": ("MP3 Audio", [".mp3"]), +} + @click.group(name="forensics") def forensics_group(): pass @@ -65,7 +83,7 @@ def inspect(path): # Magic bytes try: with open(p, 'rb') as f: - magic = f.read(4).hex().upper() + magic = f.read(8).hex().upper() except Exception: magic = "" @@ -91,20 +109,20 @@ def inspect(path): except KeyError: pass - # Allocation Metrics + # Allocation Metrics if hasattr(stat_info, "st_blocks"): allocated_size = stat_info.st_blocks * 512 else: allocated_size = size - # Hard Links + # Hard Links hard_links = stat_info.st_nlink - # Task 5: Inode & Device Identifiers + # Inode & Device Identifiers inode = stat_info.st_ino device = stat_info.st_dev - # Task 6: Extended Attributes + # Extended Attributes extended_attributes = {} if hasattr(os, "listxattr") and hasattr(os, "getxattr"): try: @@ -163,3 +181,22 @@ def inspect(path): console.print(table) return meta + +@forensics_group.command(name="signatures") +def list_signatures(): + """List all supported file magic signatures and expected extensions.""" + from rich.console import Console + from rich.table import Table + + console = Console() + table = Table(title="Supported Magic Signatures", show_header=True) + table.add_column("Magic Bytes (Hex)", style="bold cyan") + table.add_column("File Type", style="bold green") + table.add_column("Expected Exts") + + for signature, (type_name, exts) in COMMON_SIGNATURES.items(): + hex_str = signature.hex().upper() + exts_str = ", ".join(exts) if exts else "Any / None" + table.add_row(hex_str, type_name, exts_str) + + console.print(table)