#!/usr/bin/env python3 """Generate and apply environment masking configurations to defeat sandbox evasion. Produces configuration scripts and commands to make an analysis VM appear as a realistic end-user workstation, defeating environment fingerprinting checks used by evasive malware. """ from __future__ import annotations import argparse import json import platform import random import string import sys from pathlib import Path from typing import Any # Realistic configuration values for masking REALISTIC_HOSTNAMES: list[str] = [ "DESKTOP-A1B2C3D", "DESKTOP-K7M9N2P", "LAPTOP-Q4R6T8V", "WORKSTATION-01", "PC-JSMITH", "DESKTOP-HOME", ] REALISTIC_USERNAMES: list[str] = [ "jsmith", "john.doe", "mwilson", "agarcia", "rbrown", "klee", "djohnson", ] NON_VM_MAC_PREFIXES: list[str] = [ "D4:3D:7E", "A4:83:E7", "F0:18:98", "3C:52:82", "70:85:C2", "B4:2E:99", ] DECOY_FILE_PATHS: dict[str, list[str]] = { "windows": [ r"C:\Users\{user}\Documents\Budget_2025.xlsx", r"C:\Users\{user}\Documents\Meeting Notes.docx", r"C:\Users\{user}\Documents\Project Plan.pdf", r"C:\Users\{user}\Downloads\photo_vacation.jpg", r"C:\Users\{user}\Downloads\installer_chrome.exe", r"C:\Users\{user}\Desktop\notes.txt", r"C:\Users\{user}\Pictures\family_photo.png", r"C:\Users\{user}\Music\playlist.m3u", ], "linux": [ "/home/{user}/Documents/budget_2025.ods", "/home/{user}/Documents/meeting_notes.odt", "/home/{user}/Downloads/photo_vacation.jpg", "/home/{user}/Desktop/notes.txt", "/home/{user}/Pictures/family_photo.png", ], } COMMON_PROCESSES: list[str] = [ "chrome.exe", "firefox.exe", "outlook.exe", "WINWORD.EXE", "EXCEL.EXE", "slack.exe", "teams.exe", "spotify.exe", "OneDrive.exe", "Acrobat.exe", ] def generate_hostname() -> str: """Generate a realistic-looking Windows hostname.""" return random.choice(REALISTIC_HOSTNAMES) def generate_username() -> str: """Generate a realistic-looking username.""" return random.choice(REALISTIC_USERNAMES) def generate_mac_address() -> str: """Generate a non-VM MAC address.""" prefix = random.choice(NON_VM_MAC_PREFIXES) suffix = ":".join( f"{random.randint(0, 255):02X}" for _ in range(3) ) return f"{prefix}:{suffix}" def generate_decoy_file_list(username: str, os_type: str = "windows") -> list[str]: """Generate a list of decoy file paths for a realistic environment.""" templates = DECOY_FILE_PATHS.get(os_type, DECOY_FILE_PATHS["windows"]) return [t.format(user=username) for t in templates] def generate_masking_config( hostname: str | None = None, username: str | None = None, mac_address: str | None = None, add_decoy_files: bool = False, add_decoy_processes: bool = False, apply_all: bool = False, ) -> dict[str, Any]: """Generate a complete environment masking configuration.""" config: dict[str, Any] = { "platform": platform.system().lower(), "actions": [], } effective_hostname = hostname or generate_hostname() effective_username = username or generate_username() effective_mac = mac_address or generate_mac_address() if apply_all or hostname is not None: config["actions"].append({ "action": "set_hostname", "value": effective_hostname, "commands": _hostname_commands(effective_hostname), }) if apply_all or username is not None: config["actions"].append({ "action": "set_username", "value": effective_username, "commands": _username_commands(effective_username), }) if apply_all or mac_address is not None: config["actions"].append({ "action": "spoof_mac", "value": effective_mac, "commands": _mac_commands(effective_mac), }) if apply_all or add_decoy_files: os_type = "linux" if platform.system().lower() == "linux" else "windows" decoy_files = generate_decoy_file_list(effective_username, os_type) config["actions"].append({ "action": "create_decoy_files", "files": decoy_files, "commands": _decoy_file_commands(decoy_files, os_type), }) if apply_all or add_decoy_processes: config["actions"].append({ "action": "add_decoy_processes", "processes": COMMON_PROCESSES, "note": "Use process simulation tools or renamed dummy executables", }) if apply_all: config["actions"].append({ "action": "install_indicators", "description": "Install common application indicators", "items": [ "Create browser history database", "Add recent documents to registry", "Set realistic screen resolution (1920x1080)", "Configure 2+ CPU cores, 4+ GB RAM", "Set disk size > 100 GB", "Set system uptime to several hours", "Remove VM guest tools indicators", ], }) config["summary"] = { "hostname": effective_hostname, "username": effective_username, "mac_address": effective_mac, "total_actions": len(config["actions"]), } return config def _hostname_commands(hostname: str) -> dict[str, list[str]]: """Generate commands to set hostname on Windows and Linux.""" return { "windows": [ f'Rename-Computer -NewName "{hostname}" -Force', f'reg add "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName" /v ComputerName /t REG_SZ /d "{hostname}" /f', ], "linux": [ f"hostnamectl set-hostname {hostname}", f'echo "{hostname}" > /etc/hostname', ], } def _username_commands(username: str) -> dict[str, list[str]]: """Generate commands to create a realistic user account.""" return { "windows": [ f'net user {username} Password123! /add', f'net localgroup Administrators {username} /add', ], "linux": [ f"useradd -m -s /bin/bash {username}", ], } def _mac_commands(mac: str) -> dict[str, list[str]]: """Generate commands to spoof MAC address.""" return { "windows": [ f'Set-NetAdapter -Name "Ethernet" -MacAddress "{mac.replace(":", "-")}"', ], "linux": [ "ip link set eth0 down", f"ip link set eth0 address {mac.lower()}", "ip link set eth0 up", ], } def _decoy_file_commands(files: list[str], os_type: str) -> list[str]: """Generate commands to create decoy files.""" commands: list[str] = [] for f in files: if os_type == "windows": commands.append(f'New-Item -ItemType File -Path "{f}" -Force') else: commands.append(f'mkdir -p "$(dirname "{f}")" && touch "{f}"') return commands def analyze(input_path: Path, output_format: str = "json") -> dict[str, Any]: """Generate a default masking configuration.""" return generate_masking_config(apply_all=True) def main() -> None: """Entry point for the environment masker CLI.""" parser = argparse.ArgumentParser( description="Generate environment masking configurations to defeat sandbox evasion." ) parser.add_argument( "--input", type=Path, help="Path to existing configuration file to extend" ) parser.add_argument( "--output", type=Path, help="Path to output file (stdout if omitted)" ) parser.add_argument( "--format", default="json", choices=["json", "text"], help="Output format (default: json)", ) parser.add_argument( "--apply-all", action="store_true", help="Generate configuration for all countermeasures", ) parser.add_argument( "--set-hostname", type=str, metavar="HOSTNAME", help="Set a specific hostname", ) parser.add_argument( "--set-username", type=str, metavar="USERNAME", help="Set a specific username", ) parser.add_argument( "--spoof-mac", type=str, metavar="MAC", help="Set a specific MAC address (format: XX:XX:XX:XX:XX:XX)", ) parser.add_argument( "--add-decoy-files", action="store_true", help="Generate decoy user files", ) parser.add_argument( "--add-decoy-processes", action="store_true", help="Generate decoy process configuration", ) parser.add_argument( "--install-indicators", action="store_true", help="Generate common application indicators", ) args = parser.parse_args() config = generate_masking_config( hostname=args.set_hostname, username=args.set_username, mac_address=args.spoof_mac, add_decoy_files=args.add_decoy_files, add_decoy_processes=args.add_decoy_processes, apply_all=args.apply_all or args.install_indicators, ) if args.format == "text": output_text = _format_text(config) else: output_text = json.dumps(config, indent=2) if args.output: args.output.parent.mkdir(parents=True, exist_ok=True) args.output.write_text(output_text, encoding="utf-8") print(f"Configuration written to {args.output}", file=sys.stderr) else: print(output_text) def _format_text(config: dict[str, Any]) -> str: """Format configuration as human-readable text.""" lines: list[str] = [ "=== Environment Masking Configuration ===", f"Platform: {config['platform']}", "", ] summary = config.get("summary", {}) if summary: lines.append(f"Hostname: {summary.get('hostname', 'N/A')}") lines.append(f"Username: {summary.get('username', 'N/A')}") lines.append(f"MAC Address: {summary.get('mac_address', 'N/A')}") lines.append("") for action in config.get("actions", []): lines.append(f"--- {action['action']} ---") if "commands" in action: cmds = action["commands"] if isinstance(cmds, dict): for os_name, cmd_list in cmds.items(): lines.append(f" [{os_name}]") for cmd in cmd_list: lines.append(f" $ {cmd}") elif isinstance(cmds, list): for cmd in cmds: lines.append(f" $ {cmd}") if "items" in action: for item in action["items"]: lines.append(f" - {item}") lines.append("") return "\n".join(lines) if __name__ == "__main__": main()