Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.
Introduction
Velociraptor is an open-source endpoint monitoring, digital-forensics, and incident-response (DFIR) platform built around VQL (Velociraptor Query Language), a SQL-like language for querying live host state, collecting forensic artifacts, and running response actions. Where a tool like osquery focuses on point-in-time state queried through a fixed table schema, Velociraptor is built specifically for the DFIR workflow: deploy lightweight client agents across thousands of endpoints, then run on-demand or scheduled hunts — a single VQL artifact executed against an arbitrary subset of the fleet — to answer “which of our hosts show this indicator” or to pull specific forensic artifacts (MFT entries, registry hives, prefetch files, event logs) back to the server for offline analysis, all without pre-staging collection scripts on every machine.
This matters because the traditional DFIR bottleneck is triage-at-scale: confirming that an indicator found on one compromised host is or isn’t present on the other 4,000 endpoints in the environment. Velociraptor collapses that from a multi-day, per-host manual exercise into a single hunt definition pushed to the fleet. Its artifact model — a versioned, shareable YAML file combining metadata, parameters, and embedded VQL — is also how the community distributes ready-made collectors for specific persistence mechanisms and forensic artifact types, similar in spirit to how YARA rules are shared for malware detection.
Attack Prerequisites
Framed as deployment/operational prerequisites, since Velociraptor is a defensive DFIR platform rather than an attack tool:
- A deployed Velociraptor server and enrolled clients — the server (
velociraptor frontend) issuing signed client configs, and the lightweightvelociraptor clientagent installed/enrolled on target endpoints (or pushed transiently for a one-off collection viavelociraptor.exe -c client.config.yaml). - Network reachability from client to server — clients poll/connect outbound over HTTPS to the frontend, so egress to the Velociraptor server must be permitted from the endpoints being monitored.
- Sufficient privilege on the endpoint for the artifact being run — reading the MFT, registry hives in use, or memory requires the client process to run as SYSTEM/root; artifacts declare their required OS and, implicitly, the access level they need.
- GUI or API access to the Velociraptor server for the operator building and launching hunts, reviewing results, and downloading collected files.
How It Works
An artifact is a YAML document with a name, description, type (CLIENT, SERVER, CLIENT_EVENT, etc.), optional parameters, and one or more sources, each containing a VQL query. VQL itself looks like SQL (SELECT ... FROM ... WHERE ...) but its FROM clause calls plugins — functions that produce rows from live system state, such as glob() (filesystem enumeration), pslist() (running processes), read_reg_key() (registry), parse_ntfs() (raw MFT parsing bypassing file locks), or execve() (running a subprocess and capturing output). Because VQL queries are composable, an artifact can chain plugins: glob for files matching a pattern, pipe each match into a hash plugin, then filter by hash against a known-bad list, all in one query.
The server-client model is designed for scale and evidence integrity: clients don’t need an always-on connection (useful for laptops), the server queues hunts and collects results as clients check in, and every collection is written to a versioned, timestamped result set on the server rather than mutating anything on the endpoint. A hunt is simply an artifact plus a targeting rule (all clients, a label, an OS filter, or an explicit host list) plus an expiry, submitted once and fanned out as matching clients check in — making “search 5,000 endpoints for this indicator” a single action instead of 5,000 individual ones.
Because VQL can both *read* forensic artifacts and *act* (kill a process, quarantine a host, delete a file, collect a memory image), Velociraptor spans triage and response in the same language — an artifact that detects a persistence mechanism and one that removes it differ only in the plugins used, which is why response-capable hunts need tighter approval controls than read-only collection ones.
Practical Example / Configuration
A minimal but real VQL artifact concept: a persistence hunt that enumerates Windows Run-key entries and scheduled tasks, joins each to a fresh hash of the target binary, and flags anything not signed by Microsoft. This is a valid Velociraptor client artifact structure (trimmed for length, but the VQL itself is syntactically correct):
name: Custom.Windows.Persistence.RunKeysUnsigned
description: |
Enumerate Run/RunOnce registry persistence and scheduled tasks,
hash the referenced binary, and flag entries whose target is
missing, unsigned, or signed by someone other than Microsoft.
type: CLIENT
parameters:
- name: RunKeyGlob
default: HKEY_USERS\\*\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\*
sources:
- query: |
LET run_keys = SELECT Key.FullPath AS RegPath,
Name AS ValueName,
Data.value AS Command
FROM glob(globs=RunKeyGlob, accessor="registry")
LET extracted_paths = SELECT RegPath, ValueName, Command,
regex_replace(source=Command,
re='^"?([A-Za-z]:\\\\[^"]+\\.exe)"?.*$',
replace="$1") AS BinaryPath
FROM run_keys
SELECT RegPath, ValueName, Command, BinaryPath,
hash(path=BinaryPath).SHA256 AS SHA256,
authenticode(filename=BinaryPath).Subject AS Signer
FROM extracted_paths
WHERE NOT Signer =~ "Microsoft"
YAMLThe same hunt concept for Linux, restated with real plugins/tables against cron and systemd persistence, plus an in-line SELECT (rather than a full artifact) — this is what an operator would type directly into the Velociraptor notebook/VQL query box for ad hoc triage:
-- Ad hoc VQL: cron entries whose command references a path outside
-- standard system directories -- a common persistence heuristic
SELECT OSPath, Line
FROM parse_records_with_regex(
file=glob(globs="/var/spool/cron/crontabs/*").OSPath,
regex="(?P<Line>.*)")
WHERE Line =~ "(/tmp/|/dev/shm/|/var/tmp/)"
-- Ad hoc VQL: currently running processes with no backing file on disk
-- (deleted-binary / fileless-persistence tell), using the pslist() plugin
SELECT Pid, Name, Exe, CommandLine
FROM pslist()
WHERE NOT Exe =~ "^/" OR NOT stat(filename=Exe).Name
SQLWalkthrough / Exploitation
A realistic fleet-wide DFIR workflow: confirm the artifact locally on one known-affected host, then launch a hunt to scope the same indicator across the environment, and finally collect the raw evidence from every host that matched.
# 1. Standalone triage: run the artifact against one host without a server,
# to validate the VQL before a fleet-wide hunt
velociraptor.exe artifacts collect Custom.Windows.Persistence.RunKeysUnsigned \
--format csv --output C:\\triage\\runkeys_host01.csv
# 2. Server-side: launch the same artifact as a hunt against a label of
# endpoints (labels assigned at enrollment or via the GUI)
velociraptor --config server.config.yaml \
hunts create Custom.Windows.Persistence.RunKeysUnsigned \
--labels "workstations-emea" --expiry 24h
# 3. Poll hunt progress and pull results once clients have checked in
velociraptor --config server.config.yaml hunts list
velociraptor --config server.config.yaml hunts results \
--hunt_id H.abcd1234 --format csv > hunt_results.csv
# 4. For matched hosts, follow up with a full targeted collection --
# e.g. Windows.KapeFiles.Targets for MFT, hives, prefetch, event logs
velociraptor --config server.config.yaml \
hunts create Windows.KapeFiles.Targets \
--hosts host07,host19,host133 --parameters Device=C: --expiry 6h
BashNote: VQL’s
LETbindings inside asources.queryblock are lazily evaluated subqueries, not materialized temp tables, so aLETthat is never referenced by a laterSELECTsimply never runs — a common authoring mistake is defining aLETfor documentation purposes and forgetting it produces no output on its own.
Opsec: Response-capable artifacts (process kill, host quarantine/isolation, file deletion) execute with the same privilege as the Velociraptor client service, typically SYSTEM/root — gate these behind Velociraptor’s ACL system (
server.config.yamlroles, per-user artifact permissions) so read-only hunters cannot accidentally launch a response action, and log every hunt launch and result export for chain-of-custody.
Detection and Defense
Velociraptor is deployed as part of the detection/response stack, so this section covers operating it soundly rather than defending against it:
- Scope hunts before running them fleet-wide — validate a new artifact against one or two known hosts first so a malformed query or an overly broad
glob()doesn’t generate excessive load across thousands of endpoints. - Use CLIENT_EVENT artifacts for continuous monitoring (new-process creation, new listening socket) rather than only on-demand hunts, so the platform also serves as an always-on detection layer.
- Tier ACLs by capability — separate roles for read-only collection versus response-capable actions (process termination, quarantine), and require the stronger role for anything that mutates endpoint state.
- Retain hunt and audit logs on the server independently of endpoint logs, since a compromised endpoint’s local logs cannot be trusted once an attacker has admin/root there.
- Version and peer-review custom artifacts the same as any other detection content (YARA/Sigma rules), given how directly VQL can read and modify endpoint state.
For fleet health, monitor client check-in rates and hunt completion percentages — a large gap between clients targeted and clients returned is itself a signal worth investigating (segmentation, offline hosts, or a client killed by an attacker).
Real-World Impact
Velociraptor, originally created by Michael Cohen (formerly of GRR/Google) and now maintained under Rapid7, has become a standard tool in commercial and volunteer DFIR response, including large nonprofit-sector incident response efforts that used it to triage thousands of endpoints during active compromises. Its artifact exchange model has produced a large community library covering ransomware families, living-off-the-land techniques, and forensic artifact types (event logs, USN journal, shimcache/amcache), making it a common component alongside osquery and EDR telemetry in mature detection-and-response programs.
Conclusion
Velociraptor’s core contribution is collapsing fleet-wide DFIR triage into a single artifact-plus-hunt operation: write the VQL once, validate it against one host, then scope it to a thousand. The same query language that answers “is this indicator present anywhere” can also collect the full forensic artifact set or take a response action, spanning the triage-to-response workflow rather than just visibility — provided ACLs keep read-only hunting and response-capable actions properly separated.
You Might Also Like
If you found this useful, these related deep-dives cover adjacent techniques and their defenses:



Comments