# src/ctf/cli_steg.py # {{{ imports import click from pathlib import Path from rich.console import Console from rich.panel import Panel from ctf.steg import crack_steghide # }}} # {{{ steg_group @click.group(name="steg") def steg_group(): """ Steganography tools and solvers """ pass # }}} # {{{ crack_steghide_cmd @steg_group.command(name="crack-steghide") @click.argument('path', type=click.Path(exists=True)) @click.option('-w', '--wordlist', type=click.Path(exists=True), required=True, help="Path to password wordlist.") @click.option('-o', '--output', type=click.Path(), help="Path to write the extracted payload (if cracked).") def crack_steghide_cmd(path, wordlist, output): """Attempt to crack steghide passphrases using a wordlist""" console = Console() # Read the wordlist try: with open(wordlist, "r", errors="ignore") as f: words = [line.strip() for line in f if line.strip()] except Exception as e: console.print(f"[bold red]Failed to read wordlist: {e}[/bold red]") return console.print(f"[*] Cracking {path} using {len(words)} passwords...") result = crack_steghide(Path(path), words) if result.success: console.print(Panel( f"[bold green]✓ Successfully cracked![/bold green]\n" f"[bold cyan]Password:[/bold cyan] {result.password}\n" f"[bold cyan]Payload Size:[/bold cyan] {len(result.payload)} bytes", title="Crack Result", border_style="green" )) # If output destination is supplied, write payload; otherwise print preview if output: try: out_path = Path(output).resolve() out_path.write_bytes(result.payload) console.print(f"[green]✓ Extracted payload written to {out_path}[/green]") except Exception as e: console.print(f"[bold red]Failed to write output file: {e}[/bold red]") else: # Show a safe, printable preview of the payload try: preview = result.payload.decode("utf-8") # Truncate if long if len(preview) > 300: preview = preview[:300] + "\n..." console.print(Panel(preview, title="Payload Preview", border_style="blue")) except UnicodeDecodeError: # Binary payload hex_preview = result.payload.hex()[:100] + "..." console.print(f"[yellow]Binary payload (hex preview): {hex_preview}[/yellow]") else: console.print(f"[bold red]✗ Cracking failed: {result.error_message}[/bold red]") # }}}