Velociraptor DFIR: Endpoint Forensics and Incident Response at Scale
When an incident happens, the first question is always the same: what actually occurred on that endpoint? Traditional SIEMs show you log events, but they cannot tell you which processes were injecting into lsass.exe at 02:14 or which files were touched in the 60 seconds before a ransomware payload detonated. Velociraptor can.
Velociraptor is a fast, open-source DFIR platform built around VQL (Velociraptor Query Language) — a SQL-like language purpose-built for endpoint forensics. A single VQL hunt can query every Windows registry hive, every prefetch file, every running process across thousands of endpoints in minutes, with results streamed back to a central server.
By the end of this project you will have a production-grade Velociraptor server running in Docker, clients enrolled on Windows and Linux endpoints, and a library of VQL hunts ready to deploy the moment an alert fires.
Project Overview
What We're Building
┌──────────────────────────────────────────────────────────────────┐
│ Velociraptor DFIR Architecture │
├──────────────────────────────────────────────────────────────────┤
│ │
│ Analyst Browser ──► Velociraptor Server (Web UI / API) │
│ │ │
│ mTLS gRPC (port 8000) │
│ │ │
│ ┌──────────────────────┼──────────────────────┐ │
│ ▼ ▼ ▼ │
│ Windows Client Linux Client macOS Client │
│ (velociraptor.exe) (velociraptor) (velociraptor) │
│ │ │ │ │
│ Collect artifacts Collect artifacts Collect artifacts │
│ Run VQL queries Run VQL queries Run VQL queries │
│ │
│ Results ──► Server Datastore (SQLite / filesystem) │
│ Hunts ──► All clients simultaneously │
│ Notebooks ──► Collaborative investigation workspace │
│ │
└──────────────────────────────────────────────────────────────────┘What You'll Be Able to Do
- Live response: Query any endpoint in real time — running processes, open network connections, logged-in users, recently modified files
- Forensic collection: Pull MFT, registry hives, event logs, prefetch, shimcache, amcache, browser history, and 200+ other artifact types
- Fleet-wide hunting: Deploy a VQL hunt to every enrolled endpoint simultaneously and see results in under 60 seconds
- Timeline reconstruction: Correlate filesystem timestamps, event log entries, and process execution history
- Offline triage: Package the client as a standalone collector for air-gapped systems
Prerequisites
- Docker 24+ and Docker Compose v2 on the server host
- At least one Windows or Linux endpoint you can install an agent on
- DNS or static IP for the Velociraptor server
- Ports 8000 (client comms), 8889 (web UI) reachable
Part 1: Deploy the Velociraptor Server
Step 1: Create the Project Directory
mkdir -p ~/velociraptor/{config,filestore}
cd ~/velociraptorStep 2: Generate the Server Configuration
Velociraptor's configuration is self-bootstrapping. The config generate command creates a full PKI and writes both a server config and a client config.
# Pull the Velociraptor image
docker pull wlambert/velociraptor:latest
# Generate an interactive config (answers below)
docker run --rm -it \
-v "$(pwd)/config:/config" \
wlambert/velociraptor:latest \
config generate -iInteractive prompts and recommended answers:
? What OS will the server be running? linux
? Path to the datastore directory? /velociraptor
? The public DNS name or IP of the server: velociraptor.homelab.local
? Enter the frontend port to listen on: 8000
? Enter the port for the admin GUI: 8889
? Use self-signed SSL certificates? yes
? Name of the output file for the server config: /config/server.config.yaml
? Name of the output file for the client config: /config/client.config.yaml
Inspect what was generated:
ls ~/velociraptor/config/
# server.config.yaml client.config.yamlStep 3: Docker Compose Stack
# ~/velociraptor/docker-compose.yml
version: "3.9"
services:
velociraptor:
image: wlambert/velociraptor:latest
container_name: velociraptor
restart: unless-stopped
command: frontend -v
ports:
- "8000:8000" # client frontend (mTLS gRPC)
- "8889:8889" # web UI (HTTPS)
- "8001:8001" # monitoring / health (optional)
volumes:
- ./config/server.config.yaml:/etc/velociraptor/server.config.yaml:ro
- ./filestore:/velociraptor
environment:
- VELOCIRAPTOR_CONFIG=/etc/velociraptor/server.config.yaml
healthcheck:
test: ["CMD", "curl", "-sk", "https://localhost:8889/app/index.html"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20sdocker compose up -d
docker compose logs -f velociraptorLook for: Listening on ... :8000 and Listening on ... :8889.
Step 4: Create the First Admin User
docker exec -it velociraptor \
velociraptor --config /etc/velociraptor/server.config.yaml \
user add admin --role administrator
# Enter a strong password when promptedOpen https://velociraptor.homelab.local:8889 in your browser. Accept the self-signed cert warning and log in with admin.
Part 2: Enroll Endpoints
Step 5: Build the Windows Client MSI
From the server host, generate a repackaged client that embeds your server config:
docker exec -it velociraptor \
velociraptor --config /etc/velociraptor/server.config.yaml \
config repack \
--exe /usr/local/bin/velociraptor_windows_amd64.exe \
/config/velociraptor_client_windows.exeThis produces a single .exe that contains the embedded client config and connects directly to your server — no separate config file needed on the endpoint.
Copy the binary to your Windows machine and install it as a service:
# On Windows — run as Administrator
.\velociraptor_client_windows.exe service install
# Verify the service is running
Get-Service velociraptor
# Status should be "Running"
# Check connection in Windows Event Log or:
.\velociraptor_client_windows.exe query "SELECT * FROM info()"Step 6: Install the Linux Client
# On a Linux endpoint — copy the binary
scp ~/velociraptor/config/client.config.yaml user@linux-endpoint:~/
scp $(docker exec velociraptor which velociraptor) user@linux-endpoint:~/velociraptor
# On the Linux endpoint
chmod +x ~/velociraptor
sudo mv ~/velociraptor /usr/local/bin/velociraptor
sudo mv ~/client.config.yaml /etc/velociraptor/client.config.yaml
# Install as a systemd service
sudo velociraptor --config /etc/velociraptor/client.config.yaml \
service install
sudo systemctl enable --now velociraptor_clientStep 7: Verify Enrollment
Back in the Velociraptor web UI, go to View Clients. Your enrolled endpoints appear within 30 seconds of the client service starting. Each client shows:
- Hostname and OS version
- Last seen timestamp
- Client ID (e.g.
C.1a2b3c4d5e6f7890) - Assigned labels
You can search clients by hostname, IP, OS, or custom label.
Part 3: VQL Fundamentals
Velociraptor Query Language is the core of everything. It looks like SQL but targets endpoint forensics artifacts.
Basic VQL Syntax
-- List all running processes
SELECT Pid, Name, Exe, CommandLine, Username
FROM pslist()
ORDER BY Name
-- Find processes with no parent
SELECT Pid, Name, Ppid, Exe
FROM pslist()
WHERE Ppid = 0 OR Ppid = 4
-- Recent files in Temp directories
SELECT FullPath, Mtime, Atime, Size
FROM glob(globs="C:/Users/*/AppData/Local/Temp/**")
WHERE Mtime > now() - 3600 -- last hour
-- Network connections
SELECT Pid, Laddr, Raddr, Status, Name
FROM netstat()
WHERE Status = "ESTABLISHED"Running a Query on a Single Client
In the web UI:
- Go to View Clients → select an endpoint
- Click Shell → select VQL
- Paste a query and press Run
Results stream back in real time from the endpoint.
Part 4: Forensic Artifact Collection
Velociraptor ships with 200+ built-in Artifacts — pre-written VQL queries packaged with descriptions, parameter schemas, and result definitions. The Artifact Exchange community repository adds hundreds more.
Step 8: Collect Windows Event Logs
-- Via the GUI: Collect Artifact → Windows.EventLogs.Evtx
-- Or via VQL directly on the client:
SELECT System.TimeCreated.SystemTime AS Time,
System.EventID.Value AS EventID,
System.Channel AS Channel,
EventData
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Security.evtx")
WHERE System.EventID.Value IN (4624, 4625, 4648, 4672, 4688)
ORDER BY Time DESC
LIMIT 500Key Security Event IDs to hunt:
| Event ID | Meaning |
|---|---|
| 4624 | Successful logon |
| 4625 | Failed logon |
| 4648 | Logon with explicit credentials (runas / pass-the-hash) |
| 4672 | Special privileges assigned (admin logon) |
| 4688 | Process creation (requires audit policy) |
| 4698 | Scheduled task created |
| 4720 | User account created |
| 7045 | New service installed |
Step 9: Collect Prefetch and Execution Evidence
-- Windows Prefetch — what executed and when
SELECT Name,
RunCount,
LastRunTime,
PrefetchHash,
Filenames
FROM Artifact.Windows.Forensics.Prefetch()
ORDER BY LastRunTime DESCPrefetch files prove a binary executed even after it has been deleted — critical for malware investigations.
Step 10: Collect Shimcache / AppCompatCache
-- AppCompatCache — every executable that ever ran on this system
SELECT Name, Path, Modified, Executed
FROM Artifact.Windows.Registry.AppCompatCache()
ORDER BY Modified DESCShimcache entries persist reboots and survive log clearing — often the only evidence of attacker tooling.
Step 11: Scheduled Tasks and Services
-- All scheduled tasks (including hidden ones)
SELECT Name, Path, Command, Arguments, Enabled, NextRunTime
FROM Artifact.Windows.System.ScheduledTasks()
WHERE Enabled = true
ORDER BY NextRunTime
-- Installed services (persistence check)
SELECT Name, DisplayName, StartMode, PathName, State
FROM Artifact.Windows.System.Services()
WHERE StartMode IN ("Auto", "Boot", "System")
AND State = "Running"Part 5: Fleet-Wide Hunting
A Hunt deploys a VQL artifact to every enrolled client simultaneously. Results from all endpoints flow back to the server and are aggregated into a single downloadable dataset.
Step 12: Create a Hunt for Suspicious Processes
In the web UI, go to Hunt Manager → New Hunt:
Name: Suspicious LOLBin Execution
Artifact: Windows.Detection.Amcache
Condition: All Windows clients
Labels: (leave blank for all)
Or build a custom artifact in View Artifacts → Add Artifact:
name: Custom.Hunting.LOLBins
description: |
Hunt for common Living-off-the-Land Binary execution evidence
across the entire fleet using Amcache and Prefetch.
parameters:
- name: TargetBinaries
default: "certutil.exe,mshta.exe,wscript.exe,cscript.exe,regsvr32.exe,rundll32.exe,msiexec.exe,wmic.exe,bitsadmin.exe,powershell.exe"
sources:
- name: Prefetch
query: |
LET targets <= split(sep=",", string=TargetBinaries)
SELECT Name, RunCount, LastRunTime, Filenames
FROM Artifact.Windows.Forensics.Prefetch()
WHERE Name =~ join(sep="|", array=targets)
ORDER BY LastRunTime DESC
- name: AmcacheExecution
query: |
LET targets <= split(sep=",", string=TargetBinaries)
SELECT Name, FullPath, SHA1, LastModified
FROM Artifact.Windows.Registry.Amcache()
WHERE Name =~ join(sep="|", array=targets)Launch the hunt → Run Hunt. Results from all enrolled Windows clients appear within minutes.
Step 13: Hunt for Lateral Movement Indicators
name: Custom.Hunting.LateralMovement
description: Identify common lateral movement evidence across the fleet
sources:
- name: RemoteLogons
query: |
SELECT System.TimeCreated.SystemTime AS Time,
EventData.SubjectUserName AS User,
EventData.IpAddress AS SourceIP,
EventData.LogonType AS LogonType
FROM parse_evtx(
filename="C:/Windows/System32/winevt/Logs/Security.evtx"
)
WHERE System.EventID.Value = 4624
AND EventData.LogonType IN ("3", "10")
AND EventData.IpAddress != "-"
AND EventData.IpAddress != "127.0.0.1"
ORDER BY Time DESC
LIMIT 1000
- name: PsExecArtifacts
query: |
SELECT FullPath, Mtime, Size, SHA256
FROM glob(globs=[
"C:/Windows/PSEXESVC.exe",
"C:/Windows/Temp/PSEXESVC*",
"C:/Windows/System32/PSEXESVC.exe"
])Part 6: Notebooks for Investigation
Velociraptor Notebooks are collaborative investigation workspaces — markdown cells mixed with live VQL cells that run against collected data.
Step 14: Create an Investigation Notebook
In the web UI: Notebooks → New Notebook
## Incident Investigation — 2026-04-08
### Scope
Suspected initial access via phishing on WORKSTATION-01.
Investigate process execution chain starting 02:00-03:00 UTC.
### Timeline of Suspicious ProcessesAdd a VQL cell:
-- Processes spawned between 02:00-03:00 UTC on April 8
SELECT Pid, Ppid, Name, CommandLine, CreateTime, Username
FROM Artifact.Windows.System.Pslist()
WHERE CreateTime > "2026-04-08T02:00:00Z"
AND CreateTime < "2026-04-08T03:00:00Z"
ORDER BY CreateTimeNotebooks save to the server and can be shared with team members — all analysts see the same live data.
Part 7: Standalone Collector for Offline Systems
For air-gapped endpoints or quick on-site triage, Velociraptor can generate a self-contained collector binary that runs without a live server connection and zips up all collected artifacts.
Step 15: Build an Offline Collector
docker exec -it velociraptor \
velociraptor --config /etc/velociraptor/server.config.yaml \
artifacts collect \
--output /velociraptor/collectors/triage_collector.zip \
--output_format json \
Windows.KapeFiles.Targets \
Windows.Forensics.Prefetch \
Windows.Registry.AppCompatCache \
Windows.EventLogs.Evtx \
Windows.System.ScheduledTasks \
Windows.System.ServicesCopy triage_collector.zip to the target machine and run:
# On the offline endpoint
Expand-Archive triage_collector.zip -DestinationPath C:\Triage
cd C:\Triage
.\velociraptor_windows_amd64.exe --config collector_config.yaml artifacts collect -v
# Results land in: C:\Triage\results\The output ZIP can be uploaded to any Velociraptor server later for analysis in the GUI.
Testing
Verify Server Health
# Check the container is up and passing health checks
docker inspect velociraptor --format '{{.State.Health.Status}}'
# Expected: healthy
# Check the frontend is listening
curl -sk https://localhost:8889/app/index.html | grep -o "<title>.*</title>"
# Check client comms port
ss -tlnp | grep 8000Simulate a Hunt End-to-End
- In the web UI, create a new hunt: Hunt Manager → New Hunt
- Select artifact:
Generic.Client.Info(safe, no side effects) - Set condition: All clients
- Click Run Hunt
- Wait 30–60 seconds
- Click the hunt → Results tab
- You should see one row per enrolled client with hostname, OS, and memory stats
Run a VQL Test on the Server
docker exec -it velociraptor \
velociraptor --config /etc/velociraptor/server.config.yaml \
query "SELECT client_id, os_info.hostname, last_seen_at FROM clients()" \
--format json | python3 -m json.toolDeployment Considerations
TLS Certificate Replacement
The default self-signed cert causes browser warnings. Replace it with a valid cert:
# In server.config.yaml — update the GUI section
GUI:
bind_address: 0.0.0.0
bind_port: 8889
tls_certificate_filename: /certs/fullchain.pem
tls_private_key_filename: /certs/privkey.pemMount your cert files into the container:
# docker-compose.yml
volumes:
- ./config/server.config.yaml:/etc/velociraptor/server.config.yaml:ro
- ./filestore:/velociraptor
- /etc/letsencrypt/live/velociraptor.homelab.local:/certs:roScaling the Datastore
The default file-based datastore works well up to ~500 clients. For larger fleets, switch to MySQL:
# server.config.yaml
Datastore:
implementation: MySQL
mysql_connection_string: "velociraptor:password@tcp(mysql:3306)/velociraptor"Hardening Checklist
- Replace self-signed TLS cert with a valid certificate
- Create role-based users (analyst, investigator, reader) — avoid sharing the admin account
- Enable audit logging: Server Artifacts → Server.Audit.Logs
- Restrict web UI to admin VPN/network via firewall rules
- Back up the
filestore/directory daily (contains all collected evidence) - Set a data retention policy — hunts can accumulate gigabytes quickly
Extensions and Next Steps
- SIEM integration — configure Velociraptor to forward events to your Elasticsearch SIEM via the
Server.Flows.Webhookartifact or a Syslog forwarder - Sigma rule translation — use
hayabusaor the Velociraptor Sigma artifact to translate Sigma detection rules into VQL hunts and run them fleet-wide - Automated triage on alert — trigger a targeted VQL collection via the Velociraptor API when your EDR or SIEM fires an alert, piping evidence collection into your IR ticketing workflow
- macOS artifacts — deploy the macOS client and collect
unified_logs, launch daemons, FSEvents, and quarantine DB entries - YARA scanning — use
Artifact.Generic.Detection.Yarato push YARA rule sets across your fleet and detect in-memory malware signatures - Custom artifact exchange — host a private artifact repository synced to your team's GitHub so all analysts always have the latest VQL hunts
Resources
- Velociraptor Documentation
- Velociraptor Artifact Exchange
- VQL Reference
- Velociraptor GitHub
- Rapid Triage with Velociraptor (SANS paper)
Questions? Join the CosmicBytez community Discord.