Six new endpoint commands: container inventory, file search, content grep, bulk collection, git repo discovery, full USB enumeration

Sensor 5.3.9 adds six commands to the tasking interface. Four of them come out of work on cloud workload and appsec visibility, and two are the general form of commands that were previously narrower than people wanted.

All of them are documented at Endpoint Commands.

dir_find

Search a directory tree on metadata: size, modification time, hash, glob include and exclude. dir_findhash still exists and still does what it did, but it only ever answered one question. dir_find can filter on all of them at once, and optionally return MD5, SHA-1 and SHA-256 for every hit.

dir_find "C:\Users" -x "*.exe" -X "AppData" --depth 4 --newer-than 1756684800 --with-hashes

Windows, macOS, Linux.

file_grep

Search file contents for literal byte patterns.

file_grep /home -x "*.env" -p "AWS_SECRET_ACCESS_KEY" --depth 5 --no-content

--no-content is the flag to know about. It returns the path, pattern index, offset and length of each match, and never a byte of the file. You can confirm an AWS key or an indicator is sitting on a host without pulling the surrounding data off it. That distinction matters when the thing you are hunting for is itself the sensitive part.

Patterns are literal, not regex. Windows, macOS, Linux.

container_list

Inventory containers on a Linux host across Docker, containerd, Podman and CRI-O.

container_list --runtime docker --include-images

Discovery runs off cgroups, so containers get reported even when no daemon answers. When a Docker or Podman daemon is reachable, records get enriched with the image reference, digest, state and creation time. Anything that could not be enriched is flagged CONTAINER_IS_PARTIAL rather than being handed back with empty fields that look like real answers.

Linux only.

artifact_get --root-dir

artifact_get gained a bulk mode. Point it at a directory and it walks the tree and uploads everything matching your include expressions, in one task, to Artifact Collection.

artifact_get --root-dir /etc -x "*.conf" --max-files 10 --max-total-bytes 8388608

Each file gets its own payload ID and its own per-file status in the reply, so a run where three files upload and one fails tells you exactly which one failed and why. Partial runs still return what they collected. Defaults are 25 files, 8 MB per file, 64 MB total.

repo_list

Report the git working copies on a host: checked-out revision, remotes, and optionally the submodules declared in .gitmodules.

repo_list --with-submodules --depth 4

Two uses we had in mind. Find source checkouts on machines that have no business holding code, and inventory what an engineering fleet has actually cloned. With no --root the sensor searches its own per-platform user and code roots (Users on Windows, /home, /root, /opt, /srv on Linux) and never the whole volume.

Windows, macOS, Linux.

usb_list_devices

Every USB device attached to the host, not only the mass-storage keys usb_list_keys reports. No arguments.

One entry per physical device, carrying the device descriptor’s class triple, the manufacturer, product and serial strings alongside the usb.ids names, and the interfaces it exposes nested underneath. The nesting is the useful part. A composite device declares class 0 at the device level and describes itself through its interfaces, so a “flash drive” that also exposes a keyboard interface shows up as exactly that.

usb_list_keys is unchanged, and so is everything DLP-side that depends on it.

On the budgets

Every one of the searching commands carries explicit budgets: max results, max filesystem entries examined, a wall-clock limit, a byte cap. They have defaults, so you can ignore them, and they are always on the wire, so the sensor never guesses.

Two decisions worth calling out. The reply tells you whether it stopped early and why (SCAN_IS_TRUNCATED, SCAN_STOPPED_REASON), which is only meaningful because the budget was explicit in the request. And an out-of-range budget gets rejected when you issue the command rather than quietly clamped. If you type --max-seconds 5000, you find out at the prompt instead of getting a different search back than the one you asked for.

These run on production endpoints. A search that runs away on a 4 TB fileserver is a worse outcome than a search that stops short and says so.

Questions and bug reports here or in the Slack community.