# Session Log — TPM-PC Broken Link Handler Fix + Adware Sweep (Ace PUP follow-up)

## User
- **Executed by:** ClaudeTools Discord Bot (GURU-BEAST-ROG)
- **Requested by:** Winter Williams (@winterguru, via Discord) - tech
- **Role:** automation (acting on the requester's behalf)

## Session Summary

Winter reported (Discord #tech-department, thread 1525175952261382354) that Tom Moore at
Mineralogical Record was getting an error when clicking links on TPM-PC saying he needed
to download an app. This is a direct follow-up to the 2026-07-07 session (see
`2026-07-07-discord-bot-tpm-pc-ace-pup-removal.md`): that session removed the Ace PUP
browser's files, run keys, and scheduled task — but the Windows default-handler
registrations survived, leaving http/https/.html/.pdf pointing at the now-deleted
`C:\Users\TPM\AppData\Local\Ace\Ace\Application\ace.exe`. Every link click tried to launch
the ghost exe, producing the Store "you need a new app to open this" prompt.

Located TPM-PC in GuruRMM (agent `03322f46-42b8-432d-a103-bdcae244ab55`, online, Windows 11
24H2 build 26100, user `tpm` at console). Diagnostics confirmed UserChoice ProgId
`AceHTM.Y7MX532PR2LX3GQE3ZGPQFQCF4` on http/https/.html plus a stale phantom
"Chromium.Y7MX532PR2LX3GQE3ZGPQFQCF4" StartMenuInternet registration. Chrome, Edge, and
Firefox all installed and healthy; Chrome is Tom's primary browser (15 MB history, active
same-day).

Remediation (registry exports backed up to C:\Temp on TPM-PC first): deleted the dead
AceHTM and AcePDF class keys from the user-classes hive, the HKLM StartMenuInternet
Chromium entry, and the RegisteredApplications value; cleared the broken .html/.htm
UserChoice keys. The http/https UserChoice keys could NOT be removed or rewritten — Windows
11 24H2's UCPD (User Choice Protection Driver) blocks all script/registry paths, even as
SYSTEM and even via SFTA-style hash writes in the user session (verified: staged
DanysysTeam PS-SFTA to C:\Temp\SFTA.ps1 via chunked base64 upload, Set-PTA threw "Write Reg
Protocol UserChoice FAILED"). With the AceHTM class deleted the Store prompt is gone;
finalizing Chrome as default requires one user click. Opened Settings deep-linked to
`ms-settings:defaultapps?registeredAppUser=Google Chrome` on Tom's screen — he clicks
"Set default".

Winter then requested a full adware sweep. Results: persistence clean (all non-Microsoft
scheduled tasks and Run keys legit — Adobe, Epson, Carbonite, Datto EDR, CentraStage,
Google/Mozilla updaters), no services from AppData/Temp, proxy clean, hosts file clean, no
Chrome policy hijacks, Chrome search engine default (no hijack), Edge extensions all legit
(Google Docs Offline, Adblock Plus, uBlock Origin, Edge internal). Found and removed a
leftover **"Ace AI Assistant" Chrome extension** (`epmgebdnnndkfangenlfacdlkekinpkl`,
removed while Chrome was not running) and an ancient junk folder
`C:\Users\TPM\AppData\Local\Eption` (2016). PDF association verified correct
(Acrobat.Document.DC).

Per Winter: posted the work narrative to Syncro ticket #32529 (customer-visible, emailed),
billed 0.5 hr Labor - Remote Business @ $150 credited to Winter (user_id 1737), created
invoice #68025 ($75.00, no prepaid block), set the block-rate upsell invoice note, marked
the ticket Invoiced. Bot alerts posted to #dev-alerts (RMM dispatches/remediation) and
#bot-alerts (billing).

## Key Decisions

- Root-caused before touching anything: the "download an app" error is the signature of a
  UserChoice ProgId whose class/exe no longer exists — a leftover of the 7/7 file-level
  Ace removal, not a new infection.
- Backed up (reg export to C:\Temp) before deleting any registry keys.
- Chose Chrome as the target default based on usage evidence (15 MB history, same-day use)
  and Winter's explicit instruction.
- Did not fight UCPD: on 24H2 the supported path for default-browser change is a
  Microsoft-signed UI (Settings). Deep-linked Settings to the Chrome entry on the user's
  active session rather than disabling the UCPD driver (which would need a reboot).
- Removed the Ace AI Assistant Chrome extension by folder deletion only after confirming
  Chrome was not running.
- Billing gated on a dollar-figure preview; Winter confirmed 0.5h remote.

## Problems Encountered

- `ps-encoded.sh` refused the combined fix script (>6000 encoded chars) — split into two
  dispatches.
- Heredoc JSON dispatch with `\\` escapes failed server-side JSON parse ("invalid escape")
  — switched to `jq -n --arg` payload construction, which worked.
- Dot-sourcing C:\Temp\SFTA.ps1 in user_session hit ExecutionPolicy restriction — bypassed
  with `Invoke-Expression (Get-Content -Raw)`.
- SFTA Set-PTA failed with "Write Reg Protocol UserChoice FAILED" — UCPD block, expected on
  24H2; fell back to the Settings deep-link + one user click.
- Sweep-A diagnostic exited 1 despite full output (trailing Get-Process on nonexistent
  process names) — cosmetic, output complete.

## Configuration Changes

On TPM-PC (Mineralogical Record):
- Deleted registry: `HKU\<SID>_Classes\AceHTM.Y7MX532PR2LX3GQE3ZGPQFQCF4`,
  `HKU\<SID>_Classes\AcePDF.Y7MX532PR2LX3GQE3ZGPQFQCF4`,
  `HKLM\SOFTWARE\Clients\StartMenuInternet\Chromium.Y7MX532PR2LX3GQE3ZGPQFQCF4`,
  RegisteredApplications value `Chromium.Y7MX532PR2LX3GQE3ZGPQFQCF4`,
  `.html`/`.htm` UserChoice keys (SID `S-1-5-21-2859265824-3766688748-477818468-1001`)
- Backups: `C:\Temp\acehtm-backup.reg`, `C:\Temp\chromium-smi-backup.reg` (on TPM-PC)
- Deleted: `C:\Users\TPM\AppData\Local\Google\Chrome\User Data\Default\Extensions\epmgebdnnndkfangenlfacdlkekinpkl`
  (Ace AI Assistant), `C:\Users\TPM\AppData\Local\Eption` (2016 junk)
- Staged (left in place): `C:\Temp\SFTA.ps1`, `C:\Temp\sfta.b64` on TPM-PC
- Repo: no file changes beyond this session log (scratch scripts cleaned up)

## Credentials & Secrets

- None created or discovered. Vault reads: GuruRMM API admin creds
  (`infrastructure/gururmm-server.sops.yaml`) via rmm-auth.sh.

## Infrastructure & Servers

- TPM-PC: GuruRMM agent `03322f46-42b8-432d-a103-bdcae244ab55`, Mineralogical Record /
  Main, Windows 11 Pro 24H2 build 26100, user `tpm`, SID
  `S-1-5-21-2859265824-3766688748-477818468-1001`
- Browsers on TPM-PC: Chrome (primary), Edge (in use), Firefox (rarely used)
- GuruRMM API: http://172.16.3.30:3001

## Commands & Outputs

- Diagnostics/remediation via `ps-encoded.sh rmm` dispatches: 61fc7d8a (assoc recon),
  33381deb (Ace ProgId deep-dive), 150d8587 (browser usage), d9dcccb8 (registry cleanup),
  76affcce (UserChoice clear — http/https blocked by UCPD, .html/.htm removed),
  55b083b8 (sweep A), efc6a711 (sweep B), 17618dab (sweep C + extension removal),
  780c5801 (SFTA attempt — UCPD blocked), 45c71567 + final deep-link (Settings opened)
- SFTA staging: chunked base64 upload (9 sequential Add-Content dispatches, 5000-char
  chunks) then `[IO.File]::WriteAllBytes` decode — pattern works for >7KB payloads
- Key error: `Write Reg Protocol UserChoice FAILED` = UCPD on 24H2; scripted default-browser
  changes are dead on 24H2, plan for user-click or reboot+driver-disable

## Pending / Incomplete Tasks

- Tom must click "Set default" on Google Chrome in the Settings window opened on his screen
  (or pick Chrome + "Always" at the next link-click picker). Not yet verified done.
- Optional: delete C:\Temp\SFTA.ps1 / sfta.b64 / *.reg backups from TPM-PC after
  confirmation (harmless to leave).
- Winter declined/didn't answer the Defender full-scan offer — machine swept clean manually,
  no indicators remaining.

## Reference Information

- Syncro ticket #32529 (id 113703284): https://computerguru.syncromsp.com/tickets/113703284
  — comment 423181784, line item 43220054 (0.5h @ $150, user_id 1737), invoice #68025
  (id 1651008874, $75.00), status Invoiced
- Customer: Mineralogical Record (207770), no prepay block
- Prior session: clients/mineralogical-record/session-logs/2026-07/2026-07-07-discord-bot-tpm-pc-ace-pup-removal.md
  (ticket #32511, invoice #67997 — original Ace file-level removal)
- Discord thread: 1525175952261382354 (#tech-department)
- SFTA tool: https://github.com/DanysysTeam/PS-SFTA

## Update: 10:05 AZ — Winter's per-user Syncro API key vaulted + wired

Follow-up in the same thread: I had noted the ticket comment/billing on #32529 were
attributed to Mike's API key (only line-item user_id could be set to Winter). Winter
generated and provided her own Syncro API token. Actions taken:

- Verified the token live against GET /me — authenticates as Winter Williams, user_id
  1737, admin, full permissions. (Note: /me response is FLAT — user_id/user_email at top
  level, not under .user.)
- Vaulted it: `msp-tools/syncro-winter.sops.yaml` (kind api-key, owner winter,
  syncro_user_id 1737), SOPS-encrypted, round-trip verified via vault.sh get-field.
  Vault commit 6cb2639, pushed.
- Wired into `.claude/scripts/syncro-env.sh`: refactored the key-select case into
  `_syncro_key_path()` (mike/howard/winter), and added a **requester preference** — when
  `CLAUDETOOLS_REQUESTER_USER` is set (Discord bot threads) and that user has a vaulted
  key, syncro-env.sh uses THEIR key and sets SYNCRO_USER accordingly, so bot-driven
  Syncro actions attribute to the person who asked. Falls back to the identity.json user
  when the requester has no key (e.g. rob) — never hard-fails on the preference.
  Tested: `CLAUDETOOLS_REQUESTER_USER=winter` resolves Winter's key (Td75b771c601...).
- Updated `.claude/commands/syncro.md`: user table now includes winter (1737) + vault
  paths column; removed the stale "keys are baked into the skill" note (Howard's
  2f351638 refactor moved keys to the vault).

Effect: all future Syncro comments/tickets/invoices created through the bot in Winter's
threads are attributed to Winter in Syncro, not Mike.

## Update: 13:20 AZ — Howard: GuruScan deep scan on TPM-PC + reboot + ticket note

Howard (in the same thread) requested a GuruScan on TPM-PC. Also: Winter verified Tom
clicked "Set default" — Chrome default confirmed, closing that pending item.

**Scan execution:**
- Prepped via `guruscan-agent-test.sh TPM-PC prep` (module + RKill/Emsisoft/HitmanPro
  staged; Defender exclusions failed 0x800106ba — Defender dormant, Datto primary —
  harmless). Removed the EICAR test seed before scanning (client production machine).
- **BUG FOUND:** first full-chain detached run died ~1 min in. RKill completed fine as
  an orphan (43s, nothing malicious), but the hidden SYSTEM PowerShell wrapper was
  hard-killed mid-RKill (no marker, no catch output, task -> Ready). No Datto quarantine
  or EDR kill events; binaries intact. Conclusion: RKill's process sweep killed its own
  hidden parent powershell. Logged to errorlog (guruscan). Chain design issue: full
  chain + RKill + detached wrapper combo was never exercised on the Howard-VM tests.
- Relaunched with `-SkipScanners RKill` (rewrote _detached_scan.ps1 wrapper, re-registered
  GuruScan-scan task); reused the still-running poller.

**Results (scan TPM-PC-20260710-123020, 33 min, clean mode, 4 threats remediated):**
- Emsisoft (28.5 min, 1,173,097 objects): 2x Trojan.JS.Agent.SIT REMOVED —
  `C:\Users\TPM\AppData\LocalLow\EmieBrowserModeList\Znkhguh\Wehrqovsczuc\Fsxqxnxpuqgw.js`
  and `...\Znkhguh\Vnmngrhgutba\usummkvt.js` (random-named JS; survived prior manual sweeps)
- HitmanPro (3.6 min, 3.2M objects): quarantined `C:\Users\TPM\Downloads\PDFEditor_56571.exe`
  (Mal/Generic-S, fake PDF editor bundleware, Jan 2026 — likely same family that bundled Ace)
  and `C:\Users\TPM\AppData\Local\Temp\AgentInstall.exe` (Datto RMM installer in
  non-standard location, PUA flag — benign leftover; installed Datto services verified Running)
- Logs pulled to `projects/msp-tools/guru-scan/test-results/TPM-PC-20260710T200344/`

**Cleanup (all verified removed):** GuruScan-scan task, C:\GuruScan, C:\EmsisoftCmd,
C:\ScanLogs, C:\GuruScanTest, HitmanPro ProgramData leftovers, Defender exclusions, plus
Tuesday's C:\Temp\SFTA.ps1 / sfta.b64 / acehtm-backup.reg / chromium-smi-backup.reg.

**Reboot:** machine had not rebooted since scan (LastBoot 07:39). Tom active at console,
so issued `shutdown /r /t 300` with on-screen 5-min warning. Reboot verified: LastBoot
13:13:40, agent reconnected.

**Syncro:** posted customer-visible comment 423219795 ("Follow-up deep scan results",
do_not_email) to ticket #32529 — attributed to **Winter Williams** via the new per-user
key + requester preference (first production use, worked). No additional billing per
Howard. Alerts posted to #dev-alerts + #bot-alerts.

## Update: 14:55 AZ — Winter: origin forensics for today's scan findings

Winter asked whether the origin of today's 4 scan findings could be determined and whether it linked to ticket #32511 (Ace). Ran two recon passes on TPM-PC via RMM (`ps-encoded.sh`, agent 03322f46-42b8-432d-a103-bdcae244ab55): NTFS creation timestamps, Prefetch, Downloads Zone.Identifier ADS, and a raw URL extraction from a copied Chrome History file.

**Findings:**
- **JS trojans (EmieBrowserModeList\Znkhguh) — unrelated to #32511.** Tree created 2014-12-11 (root 2014-11-13), contains a bundled fake Chrome 36.0.1985.143 payload. 11-year-old dormant remnants; only modified today by Emsisoft's removal.
- **Ace — malvertising.** Chrome History: `get.ace.ai/AceSetup.exe?...utm_source=adx` (ad-exchange delivery). Prefetch ACESETUP.EXE run 2026-06-26 10:16. AceSetup.exe no longer on disk.
- **PDFEditor_56571.exe — paid ad campaign.** `cleareditpdfdd.com/PDFEditor.exe?campaign_id=23228291019&adgroup_id=6629007750` (fake PDF-editor site), downloaded 2026-01-29.
- **Browsing habit:** 2026-06-09 12:39-12:42 burst — Fortect.exe (cloud.fortect.com, "Repair & Update PC Sound Drivers" banner) + 4x Driver_Updater_setup.exe (cdn.pchelpsoft.com, Bing search-ad landing pages keyword=speakers / Windows-11 Audio). Tom searches for audio/driver fixes and clicks sponsored results.
- This morning's 07:52 "ADOBE INSTALLER.EXE"/SETUP.EXE prefetch entries = benign Adobe Photoshop 2026 install via Creative Cloud.

**Syncro:** comment 423226885 added to #32529 (id 113703284) — "Root cause - origin of adware findings", items 2+3 only (JS trojans excluded per Winter), hidden:false, do_not_email:false (emails Tom). Tech attribution: Winter Williams (her vaulted key via CLAUDETOOLS_REQUESTER_USER). No billing added. Bot alert posted.

**Recommendation delivered:** avoid sponsored search results for software/fix tools; consider ad-blocking on Tom's browser profile.

Scratch scripts .origin1-3.ps1 created and deleted from repo root.

## Update: 15:35 AZ — Syncro RMM agent install on TPM-PC + ScreenConnect link check

Winter requested Syncro RMM install on TPM-PC; Howard supplied the per-customer MSI link
(https://rmm.syncromsp.com/dl/msi/djEtMjA3NzcwLTEzODg2Mjg2NTgtNDg3NTMtNjA3NTkz, customer 207770).
Dispatched via GuruRMM as SYSTEM: downloaded MSI (7 MB) to C:\Windows\Temp, msiexec /qn exit 0,
Syncro service Running, installed to C:\Program Files\RepairTech\Syncro. Datto AV did not interfere.
Asset registered: TPM-PC, asset_id 12676510, created 2026-07-10 14:15 AZ. Installer removed after install.
Bot alert posted to #dev-alerts.

Winter then flagged the asset was not linked to ScreenConnect. Findings:
- ScreenConnect Client (1912bf3444b41a08) already installed + Running on TPM-PC; service ImagePath
  shows relay instance-kgc7jt-relay.screenconnect.com, session GUID 5cb1ff35-7d2b-4a36-8649-2961cc461c42.
- Verified same instance fingerprint 1912bf3444b41a08 on BEAST -> client belongs to
  computerguru.screenconnect.com (ACG instance).
- SC REST API (msp-tools/screenconnect.sops.yaml) cannot enumerate unattended sessions
  (GetSessionsByName only, per vault notes) — could not verify server-side via API.
- Syncro asset 12676510 lacks the "ScreenConnect GUID" property (compare CHRISTIPC2024 9317759 which
  has it). Restarted Syncro agent service to force inventory sync; property still empty after ~3 min.
- Offered: (1) API PUT of properties["ScreenConnect GUID"]=5cb1ff35-...; (2) manual UI edit;
  (3) wait for the next full inventory sync. Winter chose option 3 (wait for self-link).

Follow-up if it does not self-link within a day: PUT /customer_assets/12676510 with
{"properties": {"ScreenConnect GUID": "5cb1ff35-7d2b-4a36-8649-2961cc461c42"}} (preview first).

Vault paths accessed: msp-tools/syncro-winter.sops.yaml (key via syncro-env.sh), msp-tools/screenconnect.sops.yaml.
Scratch scripts .syncro-install.ps1 / .sc-check.ps1 created and deleted.
