From cce4ad78d3420c9f842f77424b529bb2d1f1f69b Mon Sep 17 00:00:00 2001 From: chahinebrini Date: Thu, 25 Jun 2026 22:43:24 +0200 Subject: [PATCH] chore(pilots): add self-contained TSK-0003 Windows protection pilot script One-command Windows validation: claims TSK-0003, runs the magic-reviewed DNS-only protection flow (self-elevating), verifies, and reports back via agenthub memory add + task done. Delivered via git since Mac<->Win clipboard is unavailable. Co-Authored-By: Claude Opus 4.8 --- pilots/tsk-0003-windows.ps1 | 184 ++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 pilots/tsk-0003-windows.ps1 diff --git a/pilots/tsk-0003-windows.ps1 b/pilots/tsk-0003-windows.ps1 new file mode 100644 index 0000000..2402c1e --- /dev/null +++ b/pilots/tsk-0003-windows.ps1 @@ -0,0 +1,184 @@ +#Requires -Version 5.1 +<# +.SYNOPSIS + TSK-0003 pilot: activate ReBreak DNS-only protection on Windows via CLI and + report the result back through AgentHub — in one run, one UAC prompt. + +.DESCRIPTION + Self-contained validation script for a fresh Windows machine. It: + 1. claims TSK-0003 in AgentHub (best-effort) + 2. pairs + registers this device with the ReBreak staging backend + 3. resolves the DoH server and self-elevates to apply DNS/DoH/firewall/ + browser-policy protection (the magic-reviewed HOF-0001 flow) + 4. verifies, then reports back via `agenthub memory add` + `task done` + + Run from a normal PowerShell. You get exactly one UAC prompt. + Protection is the critical part; all AgentHub calls are best-effort and never + block the protection itself. + + Scope: DNS-only. NOT fail-closed (no tamper-service) — that is TSK-0005. +#> + +$ErrorActionPreference = "Stop" + +# --- Config ----------------------------------------------------------------- +$BASE_URL = "https://staging.rebreak.org" +$DEBUG_CODE = "000000" # test-only debug bypass (staging) +$DOH_HOST = "dns.rebreak.org" +$DOH_FALLBACK_IP = "178.105.101.137" +# Mac AgentHub hub — adjust if the Mac's LAN IP changes: +$AGENTHUB_SERVER = "http://192.168.178.30:3377" +$AGENT_NAME = "windows-ps" + +$env:AGENTHUB_SERVER = $AGENTHUB_SERVER + +function Test-Admin { + $id = [Security.Principal.WindowsIdentity]::GetCurrent() + return (New-Object Security.Principal.WindowsPrincipal($id)).IsInRole( + [Security.Principal.WindowsBuiltInRole]::Administrator) +} + +function Invoke-AgentHub { + param([string[]]$Args) + # Best-effort: never let an AgentHub hiccup abort the protection test. + try { + if (-not (Get-Command agenthub -ErrorAction SilentlyContinue)) { + Write-Host " (agenthub CLI not found on PATH — skipping coordination)" + return + } + & agenthub @Args 2>&1 | ForEach-Object { Write-Host " $_" } + } catch { + Write-Host " (agenthub call failed: $($_.Exception.Message))" + } +} + +# --- 0. Claim the task ------------------------------------------------------ +Write-Host "[0/6] Claiming TSK-0003 in AgentHub ($AGENTHUB_SERVER)..." +Invoke-AgentHub @("task", "claim", "TSK-0003", "--agent", $AGENT_NAME) + +# --- 1. Pairing ------------------------------------------------------------- +Write-Host "[1/6] Pairing with debug code $DEBUG_CODE ..." +$pair = Invoke-RestMethod -Uri "$BASE_URL/api/magic/pair/redeem" ` + -Method POST -ContentType "application/json" ` + -Body (@{ code = $DEBUG_CODE; label = "win-pilot" } | ConvertTo-Json -Compress) +if ($pair -is [string]) { $pair = $pair | ConvertFrom-Json } +$token = $pair.data.token +if (-not $token) { throw "Pairing failed: no session token returned." } +Write-Host " Session token acquired." + +# --- 2. Device registration ------------------------------------------------- +Write-Host "[2/6] Registering this device ..." +$machineGuid = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Cryptography').MachineGuid +$deviceId = "win-$machineGuid" +$headers = @{ Authorization = "Bearer $token" } +$regBody = @{ + deviceId = $deviceId + hostname = $env:COMPUTERNAME + model = "Windows CLI" + osVersion = (Get-CimInstance Win32_OperatingSystem).Version + platform = "windows" +} | ConvertTo-Json +$reg = Invoke-RestMethod -Uri "$BASE_URL/api/magic/register" ` + -Method POST -Headers $headers -ContentType "application/json" -Body $regBody +if ($reg -is [string]) { $reg = $reg | ConvertFrom-Json } +$dnsToken = $reg.data.dnsToken +if (-not $dnsToken) { throw "Registration failed: no dnsToken returned." } +Write-Host " DNS token acquired ($deviceId)." + +# --- 3. Resolve DoH IP ------------------------------------------------------ +Write-Host "[3/6] Resolving $DOH_HOST ..." +try { + $dohIp = (Resolve-DnsName -Name $DOH_HOST -Type A -ErrorAction Stop | Select-Object -First 1).IPAddress +} catch { + $dohIp = $DOH_FALLBACK_IP +} +$template = "https://$DOH_HOST/dns-query/$dnsToken" +Write-Host " DoH IP: $dohIp" + +# --- 4. Build + run elevated apply script ----------------------------------- +Write-Host "[4/6] Applying protection (one UAC prompt) ..." +$applyScript = @" +`$ErrorActionPreference = "Stop" +`$ip = "$dohIp" +`$template = "$template" + +Remove-DnsClientDohServerAddress -ServerAddress `$ip -ErrorAction Ignore +Add-DnsClientDohServerAddress -ServerAddress `$ip -DohTemplate `$template -AllowFallbackToUdp `$False -AutoUpgrade `$True + +`$adapters = Get-NetAdapter -IncludeHidden | Where-Object { `$_.Status -eq "Up" -and `$_.InterfaceDescription -notmatch "Loopback" } +if (-not `$adapters) { throw "Kein aktiver Netzwerkadapter gefunden." } +foreach (`$adapter in `$adapters) { + Set-DnsClientServerAddress -InterfaceIndex `$adapter.ifIndex -ServerAddresses `$ip + `$guid = `$adapter.InterfaceGuid + `$dohPath = "HKLM:\System\CurrentControlSet\Services\Dnscache\InterfaceSpecificParameters`$guid\DohInterfaceSettings\Doh`$ip" + New-Item -Path `$dohPath -Force | Out-Null + New-ItemProperty -Path `$dohPath -Name "DohFlags" -Value 1 -PropertyType QWORD -Force | Out-Null +} + +Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters" -Name "EnableAutoDoh" -Value 2 -Type DWord + +function Set-ChromiumDnsPolicy(`$base) { + if (-not (Test-Path `$base)) { New-Item -Path `$base -Force | Out-Null } + Set-ItemProperty -Path `$base -Name "DnsOverHttpsMode" -Value "off" -Type String + Set-ItemProperty -Path `$base -Name "BuiltInDnsClientEnabled" -Value 0 -Type DWord +} +Set-ChromiumDnsPolicy "HKLM:\SOFTWARE\Policies\Microsoft\Edge" +Set-ChromiumDnsPolicy "HKLM:\SOFTWARE\Policies\Google\Chrome" +Set-ChromiumDnsPolicy "HKLM:\SOFTWARE\Policies\BraveSoftware\Brave" + +`$ff = "HKLM:\SOFTWARE\Policies\Mozilla\Firefox\DNSOverHTTPS" +if (-not (Test-Path `$ff)) { New-Item -Path `$ff -Force | Out-Null } +Set-ItemProperty -Path `$ff -Name "Enabled" -Value 0 -Type DWord +Set-ItemProperty -Path `$ff -Name "Locked" -Value 1 -Type DWord + +Remove-NetFirewallRule -DisplayName "ReBreak Protection - Block DNS UDP" -ErrorAction Ignore +Remove-NetFirewallRule -DisplayName "ReBreak Protection - Block DNS TCP" -ErrorAction Ignore +Remove-NetFirewallRule -DisplayName "ReBreak Protection - Block DNS over TLS" -ErrorAction Ignore +New-NetFirewallRule -DisplayName "ReBreak Protection - Block DNS UDP" -Direction Outbound -Action Block -Protocol UDP -RemotePort 53 -Profile Any | Out-Null +New-NetFirewallRule -DisplayName "ReBreak Protection - Block DNS TCP" -Direction Outbound -Action Block -Protocol TCP -RemotePort 53 -Profile Any | Out-Null +New-NetFirewallRule -DisplayName "ReBreak Protection - Block DNS over TLS" -Direction Outbound -Action Block -Protocol TCP -RemotePort 853 -Profile Any | Out-Null + +Clear-DnsClientCache +Write-Host "Protection applied successfully." +"@ + +$tmp = Join-Path $env:TEMP "rebreak-apply-protection-elevated.ps1" +Set-Content -Path $tmp -Value $applyScript -Encoding UTF8 + +$applyOk = $false +if (Test-Admin) { + & $tmp + $applyOk = $true +} else { + $proc = Start-Process powershell.exe -Verb RunAs -Wait -PassThru ` + -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $tmp) + $applyOk = ($proc.ExitCode -eq 0) +} +Remove-Item $tmp -ErrorAction Ignore + +# --- 5. Verify -------------------------------------------------------------- +Write-Host "[5/6] Verifying ..." +$dohList = "" +try { $dohList = (Get-DnsClientDohServerAddress | Where-Object { $_.ServerAddress -eq $dohIp } | Out-String).Trim() } catch {} +$lottoResult = "" +try { + Clear-DnsClientCache + $lottoResult = (Resolve-DnsName -Name "lotto.de" -ErrorAction Stop | Out-String).Trim() +} catch { + $lottoResult = "BLOCKED / not resolved: $($_.Exception.Message)" +} +Write-Host " DoH endpoint present: $([bool]$dohList)" +Write-Host " lotto.de -> $lottoResult" + +# --- 6. Report back via AgentHub -------------------------------------------- +Write-Host "[6/6] Reporting result to AgentHub ..." +$status = if ($applyOk) { "SUCCESS" } else { "FAILED (elevated apply exit non-zero)" } +$report = "TSK-0003 Windows-Pilot: $status. device=$deviceId, dohIp=$dohIp, dohPresent=$([bool]$dohList), lotto.de=$lottoResult" +Invoke-AgentHub @("memory", "add", "--title", "TSK-0003 Windows-Schutz Test", "--category", "implementation", "--content", $report) +if ($applyOk) { + Invoke-AgentHub @("task", "done", "TSK-0003") +} + +Write-Host "" +Write-Host "==================== DONE: $status ====================" +Write-Host $report