From 4a8559fa73829b79f4e65cf3c178a526e6e9e963 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Mon, 22 Jun 2026 08:21:04 -0700 Subject: [PATCH] sync: auto-sync from HOWARD-HOME at 2026-06-22 08:20:28 Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-22 08:20:28 --- .claude/scripts/guruscan-agent-test.sh | 11 +- errorlog.md | 1 + .../2026-06-22-howard-guruscan-hardening.md | 156 ++++++++++++++++++ 3 files changed, 166 insertions(+), 2 deletions(-) create mode 100644 session-logs/2026-06/2026-06-22-howard-guruscan-hardening.md diff --git a/.claude/scripts/guruscan-agent-test.sh b/.claude/scripts/guruscan-agent-test.sh index 66183c3a..a6d2f998 100644 --- a/.claude/scripts/guruscan-agent-test.sh +++ b/.claude/scripts/guruscan-agent-test.sh @@ -552,13 +552,20 @@ foreach($n in @('a2cmd','HitmanPro_x64','rkill','EmsisoftCommandlineScanner64')) Start-Sleep 3 Get-ScheduledTask -TaskName 'GuruRMM-ScannerCleanup' -EA SilentlyContinue | Unregister-ScheduledTask -Confirm:$false -EA SilentlyContinue Remove-Item 'C:\GuruScan\cleanup-state.json' -Force -EA SilentlyContinue +# Re-ensure scanners exist (a prior reboot-cleanup may have wiped C:\GuruScan\downloads). +if(-not (Test-Path 'C:\GuruScan\downloads\EmsisoftCommandlineScanner64.exe') -or -not (Test-Path 'C:\GuruScan\downloads\rkill.exe')){ + & C:\GuruScan\Download-Scanners.ps1 *> $null +} +if(-not (Test-Path 'C:\GuruScan\downloads\HitmanPro_x64.exe')){ + try{ [Net.ServicePointManager]::SecurityProtocol=[Net.ServicePointManager]::SecurityProtocol -bor 3072; (New-Object Net.WebClient).DownloadFile('https://dl.surfright.nl/HitmanPro_x64.exe','C:\GuruScan\downloads\HitmanPro_x64.exe') }catch{} +} $zip = Get-ChildItem 'C:\Users\Owner\Downloads' -Filter '*.zip' -EA SilentlyContinue | Where-Object { $_.Name -match 'malware' } | Select-Object -First 1 if($zip){ Expand-Archive -Path $zip.FullName -DestinationPath 'C:\Users\Owner\Desktop' -Force -EA SilentlyContinue } $n=(Get-ChildItem 'C:\Users\Owner\Desktop\malware-samples-master' -Recurse -File -EA SilentlyContinue).Count Set-Content 'C:\GuruScan\_one_before.txt' $n -Write-Output ("setup done - malware samples present: $n") +Write-Output ("setup done - scanners ensured; malware samples present: $n") PS - run_ps "$sf" 240 70 "setup" || { echo "[ERROR] setup failed"; return 1; } + run_ps "$sf" 600 130 "setup" || { echo "[ERROR] setup failed"; return 1; } # Run the scanner the production way: detached scheduled task, unlimited time. gs_launch_detached "-Scanners $scanner -Headless" "one" || { echo "[ERROR] launch failed"; return 1; } diff --git a/errorlog.md b/errorlog.md index a661be28..38528954 100644 --- a/errorlog.md +++ b/errorlog.md @@ -28,6 +28,7 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure · 2026-06-22 | GURU-5070 | packetdial | HTTP 400 POST https://pbx.packetdial.com/ns-api/v2/domains/arizonacomputerguru/timeframes: {"code":400,"message":"All Days of Week timeframes should have at most 1 days of week entry."} [ctx: cmd=create-timeframe] 2026-06-22 | GURU-5070 | packetdial | HTTP 404 GET https://pbx.packetdial.com/ns-api/v2/domains/arizonacomputerguru/devices: {"code":404,"message":"No Route Found [92]"} [ctx: cmd=raw] +2026-06-22 | Howard-Home | guruscan-test | upload failed [ctx: file=GuruScan.psm1 host=DESKTOP-MS42HNC] 2026-06-22 | Howard-Home | guruscan/GuruScan.psm1 | reboot-cleanup task registration fails: -DeleteExpiredTaskAfter on an AtLogOn trigger (no EndBoundary) => task XML invalid HRESULT 0x80041319; also non-terminating CIM error fell through to a false '[OK] task registered'. Fixed: removed DeleteExpiredTaskAfter, added -ErrorAction Stop + post-register verification [ctx: host=DESKTOP-MS42HNC fn=Register-ScannerCleanupTask] diff --git a/session-logs/2026-06/2026-06-22-howard-guruscan-hardening.md b/session-logs/2026-06/2026-06-22-howard-guruscan-hardening.md new file mode 100644 index 00000000..2872df1c --- /dev/null +++ b/session-logs/2026-06/2026-06-22-howard-guruscan-hardening.md @@ -0,0 +1,156 @@ +# GuruScan Hardening + Live Malware Testing — 2026-06-22 + +## User +- **User:** UNKNOWN to harness — `.claude/identity.json` is missing on this machine. +- **Git author (authoritative for commits this session):** Howard Enos +- **Action:** this machine should run the first-machine onboarding flow to create `identity.json`. + +## Session Summary + +Tested and hardened the GuruScan multi-engine malware scanner (`projects/msp-tools/guru-scan`, +a submodule) end-to-end by dispatching it to the Windows GuruRMM agent on DESKTOP-MS42HNC +(AZ Computer Guru / Howard-VM, a laptop test VM). The session started as "verify it works" and +became a bug hunt: running the scanner against a planted EICAR file, then against a real malware +sample set, surfaced six genuine defects, each fixed and (mostly) verified live. + +The first finding was that the scanner detected nothing: Emsisoft's `scanners.json` args contained +flags that do not exist in the current Emsisoft Commandline Scanner (2025.1.x) — `/deep /rk /c /ac`. +The invalid flags made `a2cmd` fall back to its shallow "Malware Scan" preset and ignore the +`/f=C:\` full-disk directive, so on-disk threats were missed. Removing the bad flags restored a +real full-disk scan (verified: EICAR detected + removed). A controlled benchmark proved the +~80-minute scan time is inherent file-count cost (≈20 ms/file × ~250k files), not cloud lookups +(61.5s vs 58.9s on 3000 files with cloud on/off) and not archive scanning; `/a` was made opt-in via +`-Deep`. Per the user's decision, the default stays a full `/f=C:\` scan. + +Concurrency, no-cap, and protective-whitelist work followed: a single-instance global mutex plus +kill-stray-scanners prevents two engines running at once (an orphaned `a2cmd` from a reaped command +had overlapped with a launched HitmanPro); per-scanner timeout now supports 0 = unlimited so a +large-drive scan is never killed; and the hardcoded `@('C:\GuruScan')` whitelist was replaced with a +static list of ACG tool install folders (GuruRMM, ScreenConnect, Bitdefender, MSP360/CloudBerry, +Syncro, Splashtop) so the engines never quarantine our own management agents. PUP handling became +report-only by default with a `-RemovePups` opt-in. + +The highest-value findings came from a real malware test. HitmanPro ignores EICAR by design (proven: +scanned 133k files with EICAR present, flagged 0; Defender flagged the same files). The user placed +a real sample set (`malware-samples-master`) on the Desktop. HitmanPro detected + quarantined 36 +compiled trojans (Agent Tesla, KPOT, Trickbot, PsiXBot, Shade, ArtraDownloader) but returned exit +code **5** — GuruScan's exit-code map only matched `{1,2}`, so it reported `total_threats=0, +reboot_required=False` on a real 36-threat removal. HitmanPro's exit code is a bitmask (bit0=threats, +bit2=reboot). Fixed. Also fixed: threat count now parsed from each scanner log (was a 0/1 flag), and +the reboot-cleanup scheduled task (`-DeleteExpiredTaskAfter` on an AtLogOn trigger threw "missing +EndBoundary" 0x80041319 and the module falsely printed `[OK]`). A full automated `scan-one HitmanPro` +run then verified the whole lifecycle: 36 detected+removed, `total_threats=36 reboot_required=True`, +cleanup task registered and later fired (it wiped the scanner downloads as designed). + +Work was paused when the laptop lid closed and the agent went offline before the Emsisoft-vs-HitmanPro +comparison could run. guru-scan was committed and pushed (fb09102). guru-rmm was left untouched (its +working tree is dirty/detached with changes that are not ours). + +## Key Decisions + +- **Default scan stays full `/f=C:\` (~80 min, uncapped)** — user chose thoroughness over speed + after the benchmark proved speed is bounded by file count, not a tunable flag. `-Deep` adds archive + scanning on top. +- **No cap on scans** — both the RMM-command reaper and the module's internal per-scanner timeout were + removing long scans; fixed with detached scheduled-task execution (harness) + `timeout_min=0` + = unlimited (module). A 50TB drive must be allowed to finish. +- **Did not source/plant malware myself** — only ran the remediation tool against samples the user + placed in their own lab. Vendor AV signature databases are proprietary/encrypted/engine-locked and + legally off-limits; the legitimate path is licensed engines + open community DBs (ClamAV/YARA/abuse.ch). +- **Held guru-rmm entirely** — its submodule was dirty + detached with server/dashboard/agent changes + that are not from this session; merging BUG-018 (a production deploy) or editing BUG-021 docs from + that state was unsafe. Deferred per user. +- **`scan-one ` harness phase** — built a single automated command (setup → detached no-cap + run → collect → report) so HitmanPro could be tested the same hands-off way as Emsisoft, instead of + hand-stitched commands. + +## Problems Encountered + +- **Pre-install date/time blocker (start of session)** — built `Set-CorrectDate.ps1` (later folded + into the guru-rmm preflight idea) and a standalone installer pre-flight concept; NTP is the + clock-independent source when a wrong date breaks TLS. +- **Emsisoft 0-detections** — invalid flags → preset fallback. Fixed by using only valid 2025.1.x flags. +- **Two scanners ran concurrently** — orphaned `a2cmd` from a server-reaped command + a launched + HitmanPro. Fixed with single-instance mutex + kill-stray. +- **HitmanPro exit 5 misparsed** — bitmask, not 1/2. Fixed. +- **Reboot-cleanup task never registered + false [OK]** — `-DeleteExpiredTaskAfter` needs an + expiring trigger; AtLogOn has none. Removed it; added `-ErrorAction Stop` + post-register verify. +- **Defender kept re-enabling / blocked commands** — Tamper Protection auto-reverted RTP; AMSI blocked + scripts containing EICAR fragments or `Set-MpPreference -DisableRealtimeMonitoring`. User disabled + Tamper Protection at the console to proceed. +- **Emsisoft re-run did nothing** — the (now-working) cleanup task had wiped `C:\GuruScan\downloads`; + hardened `scan-one` setup to re-download scanners. The re-download (313MB) then overran a single RMM + command (server reaper) — downloads belong in `prep`, not crammed in one command. +- **Box went offline** — laptop lid closed; agent stopped checking in. Paused. + +## Configuration Changes + +Modified (guru-scan submodule, committed fb09102 + pushed): +- `GuruScan.psm1` — single-instance mutex + kill-stray; static protective whitelist; `-RemovePups` + and `-Deep` switches threaded through `Invoke-ScanPass`; HitmanPro exit-code bitmask (threats + `-band 1`, reboot `-band 4`); `Get-ThreatCountFromLog` (parse real counts); `Wait-ProcessWithTimeout` + 0=unlimited; `Register-ScannerCleanupTask` fixed (no `-DeleteExpiredTaskAfter`, `-ErrorAction Stop` + + verify). +- `scanners.json` — Emsisoft valid flags only, `/a` removed from default (clean/scan), `/pup` out of + clean default; timeout_min 0 for Emsisoft+HitmanPro; chain reordered RKill → HitmanPro → Emsisoft. +- `Invoke-GuruScan.ps1` — added `-RemovePups`, `-Deep` params. +- `Download-Scanners.ps1` — `.Count` StrictMode crash on single-row summary fixed (`@(...).Count`). +- `test-results/DESKTOP-MS42HNC-20260621T174844/` — FINDINGS.md + pulled scan logs (first buggy run). + +Created (main repo, to sync this save): +- `.claude/scripts/guruscan-agent-test.sh` — RMM test harness: chunked module upload, Defender + exclusions, EICAR seed, detached no-cap launch/wait (`gs_launch_detached`/`gs_wait_detached`), + phases `prep`/`scan`/`scan-one `/`collect`/`verify-each`. +- `projects/msp-tools/guru-rmm/script-library/installer-preflight/` + `.../time-date/` — standalone + preflight + clock-fix scripts (UNCOMMITTED — in the on-hold guru-rmm submodule; do not commit yet). +- `errorlog.md` — 3 GuruScan bug entries + corrections/friction. + +## Credentials & Secrets + +- None created or discovered this session. **DESKTOP-MS42HNC has Windows Defender (RTP + Tamper + Protection) DISABLED** by the user at the console for malware testing — must be re-enabled during + cleanup. + +## Infrastructure & Servers + +- **DESKTOP-MS42HNC** — agent id `0de89b88-b21d-4647-ab64-96157ba87cc5`; client AZ Computer Guru, + site Howard-VM; Windows laptop test VM. Currently OFFLINE (lid closed). Has ~480 live malware + sample files on `C:\Users\Owner\Desktop\malware-samples-master` + zip in Downloads + HitmanPro + quarantine; Defender disabled. +- **GuruRMM API** — `http://172.16.3.30:3001`; creds vault `infrastructure/gururmm-server.sops.yaml`. +- GuruScan deploy paths on endpoint: `C:\GuruScan\` (module), `C:\GuruScan\downloads\` (scanner EXEs), + `C:\EmsisoftCmd\` (Emsisoft), `C:\ScanLogs\\` (logs). + +## Commands & Outputs + +- Run the automated single-engine test (the clean way, hands-off): + `bash .claude/scripts/guruscan-agent-test.sh DESKTOP-MS42HNC scan-one HitmanPro` +- HitmanPro verified run: `samples 516->480 REMOVED=36; results.json total_threats=36 + reboot_required=True; HitmanPro exit=5 threats=36; reboot-cleanup task REGISTERED (logon-delay=PT30M)`. +- Cloud benchmark (3000 files): CLOUD=1 61.5s / CLOUD=0 58.9s, EICAR found both → file-count bound. + +## Pending / Incomplete Tasks + +- **Emsisoft vs HitmanPro detection comparison** — re-run `scan-one Emsisoft` when DESKTOP-MS42HNC is + back online (expect Emsisoft to remove far more than 36, incl. the GandCrab `.js` droppers HitmanPro + left). Note: cleanup task may fire ~30 min post-logon and wipe scanner downloads; harness re-downloads. +- **Clean up DESKTOP-MS42HNC** — delete samples + zip + EICAR + test artifacts/tasks, clear HitmanPro + quarantine, **re-enable Defender RTP + Tamper Protection**. +- **Commit the main-repo harness** — this save handles it. The guru-scan gitlink in the main repo is + intentionally NOT bumped (left for when guru-rmm is unblocked, to do all gitlinks together). +- **guru-rmm (HELD)** — dirty/detached submodule; BUG-018 merge (=deploy, Mike cleared Howard) + mark + BUG-021 fixed in FEATURE_ROADMAP + close bug-021 doc, all deferred until the submodule state is sorted. +- **GuruScan feature ideas (not built)** — reboot alert+RMM-issued reboot (consume `reboot_required`); + more scanners (KVRT, MSERT, TDSSKiller, Sophos, Malwarebytes) gated on commercial licensing; a + ClamAV+YARA layer fed by open community DBs (abuse.ch MalwareBazaar/URLhaus, signature-base, Loki). + Vendor AV DBs are NOT reusable. +- **identity.json** missing on this machine — onboard it. + +## Reference Information + +- guru-scan commit: `fb09102` (pushed to `https://git.azcomputerguru.com/azcomputerguru/guru-scan.git` main). +- HitmanPro direct download (manual scanner): `https://dl.surfright.nl/HitmanPro_x64.exe`. +- HitmanPro exit-code bitmask: bit0(1)=threats, bit2(4)=reboot → 5 = threats+reboot. +- Coord (informational this session): ScreenConnect admin granted (computerguru.screenconnect.com, + user acg-sc-api); PacketDial/NetSapiens key vaulted at `msp-tools/oitvoip.sops.yaml`; `screenconnect` + skill added; BUG-018 (`fix/bug-018-fast-delete` cea87d4) + BUG-021 fixed on gururmm main.