Collectors What digger pulls from the host. Cross-platform first, OS-specific where it matters.

How they work

Each collector is a subclass of digger.core.collector.Collector with:

name
Unique identifier — used in --only, in detector cross-references, and in artifact rows.
category
Coarse grouping (process, persistence, network, logs, identity, inventory, …).
supported_os
Tuple of OSes. Collectors are silently skipped on others.
requires_admin
If true, collector is skipped (with a logged reason) when not running elevated.

The runner catches all exceptions per collector — a single failing collector never aborts the case. Skip reasons and errors land in log.

Cross-platform

NameWhat it collectsNeeds admin
systemHost fingerprint, boot time, uptime, filesystems, CPU/memoryno
processesEvery running process: pid, ppid, exe, exe SHA-256, cmdline, user, network connections per pid, open files, env samplemore detail with admin
networkInterfaces, listening sockets, established connections, routing table, ARP cache, hostname/FQDNsome platforms
usersCurrent sessions, every local account, sudo/wheel/admin group membershipno
browsersChrome / Edge / Brave / Arc / Vivaldi / Opera / Firefox: history, downloads, extensions (perms + host_permissions), cookies (per-domain counts + bytes — values NEVER captured), saved-passwords summary (counts only), IndexedDB origins+bytes, Local Storage origins+bytes, installed PWAs, profile defaults (search engine / homepage / startup URLs), service workers (origins + script count + storage bytes). See browser scanner.no
envProcess environment with special attention to PATH, LD_PRELOAD, DYLD_INSERT_LIBRARIES, BASH_ENV, PROMPT_COMMAND, proxy varsno
dns/etc/hosts, /etc/resolv.conf, DNS cache (ipconfig /displaydns, scutil --dns, resolvectl)no
recent_filesFiles modified in the last 14 days under common drop locations (Downloads, Desktop, /tmp, %TEMP%, AppData/Local/Temp, /Users/Shared, /dev/shm…)no
installed_softwaremacOS .app bundles + brew, Linux dpkg/rpm/snap/flatpak, Windows registry Uninstall keysno
python_packagespip list in the current interpreter and discovered virtualenvsno
npm_packagespackage.json + package-lock.json + yarn.lock + pnpm-lock.yaml across common project dirs (max depth 4)no
github_workflowsEvery .github/workflows/*.yml across local repos — for Shai-Hulud worm detectionno
ssh_keys~/.ssh contents: authorized_keys, known_hosts, config, key fingerprintsno — more users with admin
service_versionsProbes <binary> --version for 30+ services (sshd, nginx, apache, redis, postgres, mysql, mongo, openssl, curl, git, docker, php, ruby, go, node, python, kubelet, samba, bind9, etc.) — only from trusted system paths (/usr/bin, /usr/sbin, /opt/homebrew/, etc.). Used by service_cve detector against the live NVD feed.no
memory_regionsPer-process VM region snapshot. Records only suspect regions: RWX, anonymous-executable, or file-backed by a drop location.some processes only
code_signingCode-signature status for every running binary via codesign (macOS) / dpkg -V + rpm -V (Linux). Feeds the unsigned-binary detector.no

Windows

NameWhat it collectsNeeds admin
windows.registry_persistenceRun/RunOnce, Winlogon, Image File Execution Options, AppInit_DLLs, Active Setup, Office Resiliency, COM CLSID, …some keys
windows.scheduled_tasksschtasks /query /XML + CSV verbose dumpno
windows.servicesEvery service via psutil: name, display name, start type, binpath, account, statusno
windows.event_logsSecurity, System, Application, Sysmon, PowerShell Operational, Defender Operational, Task Scheduler Operational, WMI-Activity, RDP sessionsyes
windows.defenderGet-MpComputerStatus, Get-MpPreference, Get-MpThreat, Get-MpThreatDetectionrecommended
windows.firewallProfiles + enabled rules via Get-NetFirewallProfile / Get-NetFirewallRuleno
windows.wmi_persistenceEventFilter, EventConsumer, FilterToConsumerBinding (MITRE T1546.003)recommended
windows.startup_foldersPer-user + all-users Start Menu Startup foldersno

macOS

NameWhat it collectsNeeds admin
macos.launchdEvery /System/Library/Launch*, /Library/Launch*, ~/Library/LaunchAgents plist (parsed: ProgramArguments, RunAtLoad, KeepAlive, MachServices, watch paths, …)no
macos.login_itemsBackgroundTaskManagementAgent btm.plist + osascript fallback (T1547.015)no
macos.tccTCC.db — apps with camera, mic, screen recording, AppleEvents, full-disk permissionsystem DB needs FDA
macos.quarantineQuarantineEventsV2 — what was downloaded by what app from whereno
macos.unified_logslog show slices for auth, network, XProtect, Gatekeeper, sudoyes
macos.kextkmutil showloaded + systemextensionsctl listno
macos.profilesConfiguration profiles (MDM + manually installed)no
macos.security_postureSIP (csrutil), Gatekeeper (spctl), FileVault (fdesetup), XProtect / MRT versionsno
macos.firewallpf ruleset + info + NAT (pfctl -sr / -s info / -s nat) plus the macOS Application Firewall state (socketfilterfw: global state, stealth mode, block-all, logging). Audited by firewall_audit detector.no
macos.privescWalks /usr/bin, /usr/sbin, /usr/libexec, /opt/homebrew/{bin,sbin}, /tmp, /private/tmp, /Users/Shared, /Users/*, /private/var/root for setuid/setgid binaries. Each artifact records owner_uid, mode, world-writable, in-system-dir.no

Linux

NameWhat it collectsNeeds admin
linux.systemdsystemctl list-units + list-unit-files + per-user units; full unit files from /etc/systemd, /usr/lib/systemd, /lib/systemd, /run/systemdno
linux.cron/etc/crontab, /etc/anacrontab, /etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly}, /var/spool/cron, /var/spool/atsome paths
linux.auth_logs/var/log/auth.log + secure + journalctl _COMM=sshd / sudo + last / lastb / whorecommended
linux.auditauditd.conf, /etc/audit/rules.d, auditctl -l, tail of /var/log/audit/audit.logyes
linux.kmod/proc/modules, lsmod, /etc/modules-load.d, /etc/modprobe.dno
linux.sudoers/etc/sudoers and /etc/sudoers.d/*yes

Selecting and skipping

List which collectors will run on the current host:

python -c "from digger.collectors import all_collectors; \
           [print(f'{c.name:30} admin={c.requires_admin}') for c in all_collectors()]"

Run only a subset:

digger collect --case-dir x --only system,processes,network,macos.launchd

Skip everything needing elevation:

digger collect --case-dir x --no-admin

Adding a new collector

See the Extending page for the full walkthrough. Short version: subclass Collector, yield Artifacts from collect(), register in digger/collectors/__init__.py.

Graceful degradation. Catch PermissionError, OSError, subprocess.SubprocessError, and missing binaries (shutil.which(...) is None). A collector with no artifacts to yield should just return an empty iterator — that's the only way the runner can keep going for the next collector.