# 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 <howard@azcomputerguru.com>
- **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 <Scanner>` 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 <Scanner>`/`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\<scanid>\` (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.
