ir-velociraptor
Endpoint visibility, digital forensics, and incident response using Velociraptor Query Language (VQL) for evidence collection and threat hunting at scale. Use when: (1) Conducting forensic investigations across multiple endpoints, (2) Hunting for indicators of compromise or suspicious activities, (3) Collecting endpoint telemetry and artifacts for incident analysis, (4) Performing live response and evidence preservation, (5) Monitoring endpoints for security events, (6) Creating custom forensic artifacts for specific threat scenarios.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Install command
npx @skill-hub/cli install agentsecops-secopsagentkit-ir-velociraptor
Repository
Skill path: skills/incident-response/ir-velociraptor
Endpoint visibility, digital forensics, and incident response using Velociraptor Query Language (VQL) for evidence collection and threat hunting at scale. Use when: (1) Conducting forensic investigations across multiple endpoints, (2) Hunting for indicators of compromise or suspicious activities, (3) Collecting endpoint telemetry and artifacts for incident analysis, (4) Performing live response and evidence preservation, (5) Monitoring endpoints for security events, (6) Creating custom forensic artifacts for specific threat scenarios.
Open repositoryBest for
Primary workflow: Run DevOps.
Technical facets: Security.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: AgentSecOps.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install ir-velociraptor into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/AgentSecOps/SecOpsAgentKit before adding ir-velociraptor to shared team environments
- Use ir-velociraptor for incident response workflows
Works across
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: ir-velociraptor
description: >
Endpoint visibility, digital forensics, and incident response using Velociraptor
Query Language (VQL) for evidence collection and threat hunting at scale. Use when:
(1) Conducting forensic investigations across multiple endpoints, (2) Hunting for
indicators of compromise or suspicious activities, (3) Collecting endpoint telemetry
and artifacts for incident analysis, (4) Performing live response and evidence
preservation, (5) Monitoring endpoints for security events, (6) Creating custom
forensic artifacts for specific threat scenarios.
version: 0.1.0
maintainer: SirAppSec
category: incident-response
tags: [forensics, incident-response, endpoint-detection, threat-hunting, vql, dfir, live-response, evidence-collection]
frameworks: [MITRE-ATT&CK, NIST]
dependencies:
tools: [velociraptor]
references:
- https://docs.velociraptor.app/
- https://github.com/Velocidex/velociraptor
- https://docs.velociraptor.app/artifact_references/
---
# Velociraptor Incident Response
## Overview
Velociraptor is an endpoint visibility and forensics platform for collecting host-based state information using Velociraptor Query Language (VQL). It operates in three core modes: **Collect** (targeted evidence gathering), **Monitor** (continuous event capture), and **Hunt** (proactive threat hunting).
**When to use this skill**:
- Active incident response requiring endpoint evidence collection
- Threat hunting across enterprise infrastructure
- Digital forensics investigations and timeline analysis
- Endpoint monitoring and anomaly detection
- Custom forensic artifact development for specific threats
## Quick Start
### Local Forensic Triage (Standalone Mode)
```bash
# Download Velociraptor binary for your platform
# https://github.com/Velocidex/velociraptor/releases
# Run GUI mode for interactive investigation
velociraptor gui
# Access web interface at https://127.0.0.1:8889/
# Default admin credentials shown in console output
```
### Enterprise Server Deployment
```bash
# Generate server configuration
velociraptor config generate > server.config.yaml
# Start server
velociraptor --config server.config.yaml frontend
# Generate client configuration
velociraptor --config server.config.yaml config client > client.config.yaml
# Deploy clients across endpoints
velociraptor --config client.config.yaml client
```
## Core Incident Response Workflows
### Workflow 1: Initial Compromise Investigation
Progress:
[ ] 1. Identify affected endpoints and timeframe
[ ] 2. Collect authentication logs and suspicious logins
[ ] 3. Gather process execution history and command lines
[ ] 4. Extract network connection artifacts
[ ] 5. Collect persistence mechanisms (scheduled tasks, autoruns, services)
[ ] 6. Analyze file system modifications and suspicious files
[ ] 7. Extract memory artifacts if needed
[ ] 8. Build timeline and document IOCs
Work through each step systematically. Check off completed items.
**Key VQL Artifacts**:
- `Windows.EventLogs.RDP` - Remote desktop authentication events
- `Windows.System.Pslist` - Running processes with details
- `Windows.Network.NetstatEnriched` - Network connections with process context
- `Windows.Persistence.PermanentWMIEvents` - WMI-based persistence
- `Windows.Timeline.Prefetch` - Program execution timeline
- `Windows.Forensics.Timeline` - Comprehensive filesystem timeline
### Workflow 2: Threat Hunting Campaign
Progress:
[ ] 1. Define threat hypothesis and IOCs
[ ] 2. Select or create custom VQL artifacts for detection
[ ] 3. Create hunt targeting relevant endpoint groups
[ ] 4. Execute hunt across infrastructure
[ ] 5. Monitor collection progress and errors
[ ] 6. Analyze results and identify positive matches
[ ] 7. Triage findings and escalate confirmed threats
[ ] 8. Document TTPs and update detections
Work through each step systematically. Check off completed items.
**Common Hunt Scenarios**:
- Lateral movement detection (PsExec, WMI, remote services)
- Webshell identification on web servers
- Suspicious scheduled task discovery
- Credential dumping tool artifacts
- Malicious PowerShell execution patterns
### Workflow 3: Evidence Collection for Forensics
Progress:
[ ] 1. Document collection requirements and scope
[ ] 2. Create offline collector with required artifacts
[ ] 3. Deploy collector to target endpoint(s)
[ ] 4. Execute collection and verify completion
[ ] 5. Retrieve collection archive
[ ] 6. Validate evidence integrity (hashes)
[ ] 7. Import into forensic platform for analysis
[ ] 8. Document chain of custody
Work through each step systematically. Check off completed items.
```bash
# Create offline collector (no server required)
velociraptor --config server.config.yaml artifacts collect \
Windows.KapeFiles.Targets \
Windows.EventLogs.Evtx \
Windows.Registry.Sysinternals.Eulacheck \
--output /path/to/collection.zip
# For custom artifact collection
velociraptor artifacts collect Custom.Artifact.Name --args param=value
```
## VQL Query Patterns
### Pattern 1: Process Investigation
Search for suspicious process execution patterns:
```sql
-- Find processes with unusual parent-child relationships
SELECT Pid, Ppid, Name, CommandLine, Username, Exe
FROM pslist()
WHERE Name =~ "(?i)(powershell|cmd|wscript|cscript)"
AND CommandLine =~ "(?i)(invoke|download|iex|bypass|hidden)"
```
### Pattern 2: Network Connection Analysis
Identify suspicious network connections:
```sql
-- Active connections with process context
SELECT Laddr.IP AS LocalIP,
Laddr.Port AS LocalPort,
Raddr.IP AS RemoteIP,
Raddr.Port AS RemotePort,
Status, Pid,
process_tracker_get(id=Pid).Name AS ProcessName,
process_tracker_get(id=Pid).CommandLine AS CommandLine
FROM netstat()
WHERE Status = "ESTABLISHED"
AND Raddr.IP =~ "^(?!10\\.)" -- External IPs only
```
### Pattern 3: File System Forensics
Timeline suspicious file modifications:
```sql
-- Recent file modifications in suspicious locations
SELECT FullPath, Size, Mtime, Atime, Ctime, Btime
FROM glob(globs="C:/Users/*/AppData/**/*.exe")
WHERE Mtime > timestamp(epoch=now() - 86400) -- Last 24 hours
ORDER BY Mtime DESC
```
### Pattern 4: Registry Persistence
Hunt for registry-based persistence:
```sql
-- Common autorun registry keys
SELECT Key.Name AS RegistryKey,
ValueName,
ValueData
FROM read_reg_key(globs="HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run/*")
WHERE ValueData =~ "(?i)(powershell|cmd|wscript|rundll32)"
```
For comprehensive VQL patterns and advanced queries, see [references/vql-patterns.md](references/vql-patterns.md)
## Custom Artifact Development
Create custom VQL artifacts for specific investigation needs:
```yaml
name: Custom.Windows.SuspiciousProcess
description: |
Detect processes with suspicious characteristics for incident response.
parameters:
- name: ProcessNameRegex
default: "(?i)(powershell|cmd|wscript)"
type: regex
- name: CommandLineRegex
default: "(?i)(invoke|download|bypass)"
type: regex
sources:
- query: |
SELECT Pid, Ppid, Name, CommandLine, Username, Exe, CreateTime
FROM pslist()
WHERE Name =~ ProcessNameRegex
AND CommandLine =~ CommandLineRegex
```
Save artifacts in YAML format and import via Velociraptor UI or command line.
**For artifact development guidance**, see [references/artifact-development.md](references/artifact-development.md)
## Security Considerations
- **Sensitive Data Handling**: VQL queries can collect credentials, PII, and sensitive files. Implement data minimization - only collect necessary evidence. Use encryption for evidence transport and storage.
- **Access Control**: Velociraptor server access provides significant endpoint control. Implement RBAC, audit all queries, and restrict administrative access. Use client certificates for authentication.
- **Audit Logging**: All VQL queries, hunts, and collections are logged. Enable audit trail for compliance. Document investigation scope and approvals.
- **Compliance**: Ensure evidence collection follows organizational policies and legal requirements. Document chain of custody for forensic investigations. Consider data sovereignty for multi-region deployments.
- **Operational Security**: Velociraptor generates significant endpoint activity. Plan for network bandwidth, endpoint performance impact, and detection by adversaries during covert investigations.
## Common Investigation Patterns
### Pattern: Ransomware Investigation
1. Identify patient zero endpoint
2. Collect: `Windows.Forensics.Timeline` for file modification patterns
3. Collect: `Windows.EventLogs.Evtx` for authentication events
4. Hunt for: Lateral movement artifacts across network
5. Hunt for: Scheduled tasks or services for persistence
6. Extract: Ransomware binary samples for malware analysis
7. Build: Timeline of infection spread and data encryption
### Pattern: Data Exfiltration Detection
1. Collect network connection history: `Windows.Network.NetstatEnriched`
2. Identify large outbound transfers to unusual destinations
3. Correlate with process execution and file access
4. Hunt for: Compression tools or staging directories
5. Examine: Browser downloads and cloud sync activities
6. Review: DNS queries for tunneling or C2 domains
7. Document: Data classification and breach scope
### Pattern: Insider Threat Investigation
1. Collect: User authentication and logon events
2. Track: USB device connections and file transfers
3. Monitor: Sensitive file access patterns
4. Review: Email and browser history (with authorization)
5. Analyze: Print spooler activity for document printing
6. Examine: Cloud storage access and uploads
7. Build: User activity timeline with behavioral anomalies
## Integration Points
- **SIEM Integration**: Export VQL results to Splunk, Elastic, or other SIEM platforms for correlation
- **Threat Intel Platforms**: Enrich IOCs with TIP integrations via VQL plugins
- **SOAR Platforms**: Trigger automated Velociraptor hunts from SOAR playbooks
- **Forensic Suites**: Import Velociraptor collections into X-Ways, Autopsy, or EnCase
- **EDR Interoperability**: Complement EDR with custom VQL detections and forensic depth
## Troubleshooting
### Issue: High CPU Usage During Collection
**Solution**:
- Limit concurrent VQL queries using `rate()` function
- Reduce glob scope to specific directories
- Use `--ops_per_second` limit when creating offline collectors
- Schedule resource-intensive hunts during maintenance windows
### Issue: Client Not Reporting to Server
**Solution**:
- Verify network connectivity and firewall rules (default: TCP 8000)
- Check client logs: `velociraptor --config client.config.yaml logs`
- Validate client certificate and enrollment status
- Ensure server frontend is running and accessible
### Issue: VQL Query Returns No Results
**Solution**:
- Test query in local notebook mode first
- Verify filesystem paths use correct syntax (forward slashes)
- Check plugin availability on target OS
- Use `log()` function to debug query execution
- Review client event logs for permission errors
## Bundled Resources
### Scripts (`scripts/`)
- `vql_query_builder.py` - Generate common VQL queries from templates
- `artifact_validator.py` - Validate custom artifact YAML syntax
- `evidence_collector.sh` - Automate offline collector deployment
### References (`references/`)
- `vql-patterns.md` - Comprehensive VQL query patterns for common IR scenarios
- `artifact-development.md` - Guide to creating custom forensic artifacts
- `mitre-attack-mapping.md` - MITRE ATT&CK technique detection artifacts
- `deployment-guide.md` - Enterprise server deployment and architecture
### Assets (`assets/`)
- `artifact-template.yaml` - Template for custom artifact development
- `hunt-template.yaml` - Hunt configuration template with best practices
- `offline-collector-config.yaml` - Offline collector configuration example
## References
- [Velociraptor Documentation](https://docs.velociraptor.app/)
- [VQL Reference](https://docs.velociraptor.app/vql_reference/)
- [Artifact Exchange](https://docs.velociraptor.app/exchange/)
- [GitHub Repository](https://github.com/Velocidex/velociraptor)
- [MITRE ATT&CK Framework](https://attack.mitre.org/)
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/vql-patterns.md
```markdown
# VQL Query Patterns for Incident Response
Comprehensive VQL query patterns for common incident response and threat hunting scenarios.
## Table of Contents
- [Process Analysis](#process-analysis)
- [Network Forensics](#network-forensics)
- [File System Analysis](#file-system-analysis)
- [Registry Forensics](#registry-forensics)
- [Memory Analysis](#memory-analysis)
- [Event Log Analysis](#event-log-analysis)
- [Persistence Mechanisms](#persistence-mechanisms)
- [Lateral Movement Detection](#lateral-movement-detection)
- [Data Exfiltration](#data-exfiltration)
- [Malware Analysis](#malware-analysis)
## Process Analysis
### Suspicious Process Detection
```sql
-- Processes with suspicious characteristics
SELECT Pid, Ppid, Name, CommandLine, Username, Exe, CreateTime
FROM pslist()
WHERE (
-- Suspicious parent-child relationships
(Ppid IN (SELECT Pid FROM pslist() WHERE Name =~ "(?i)(winword|excel|powerpnt|acrobat)")
AND Name =~ "(?i)(powershell|cmd|wscript|cscript)")
-- Processes running from temp directories
OR Exe =~ "(?i)(temp|tmp|appdata)"
-- Processes with obfuscated command lines
OR CommandLine =~ "(?i)(iex|invoke-expression|downloadstring|webclient|hidden|bypass)"
)
```
### Living-off-the-Land Binaries (LOLBins)
```sql
-- Detect abuse of legitimate Windows binaries
SELECT Pid, Name, CommandLine, Username, Exe
FROM pslist()
WHERE (
-- certutil for downloading
(Name =~ "(?i)certutil" AND CommandLine =~ "(?i)(urlcache|url)")
-- bitsadmin for downloading
OR (Name =~ "(?i)bitsadmin" AND CommandLine =~ "(?i)(transfer|download)")
-- mshta for code execution
OR (Name =~ "(?i)mshta" AND CommandLine =~ "(?i)(http|javascript|vbscript)")
-- rundll32 suspicious usage
OR (Name =~ "(?i)rundll32" AND CommandLine =~ "(?i)(javascript|url)")
)
```
### Process Injection Detection
```sql
-- Identify potential process injection
SELECT Pid, Name,
AllocatedMemory,
ProtectionFlags,
Handles
FROM handles()
WHERE Type = "Section"
AND ProtectionFlags =~ "EXECUTE"
AND Name != ""
```
## Network Forensics
### External Connections
```sql
-- All external network connections with process context
SELECT Laddr.IP AS LocalIP,
Laddr.Port AS LocalPort,
Raddr.IP AS RemoteIP,
Raddr.Port AS RemotePort,
Status, Pid,
process_tracker_get(id=Pid).Name AS ProcessName,
process_tracker_get(id=Pid).Exe AS ProcessPath,
process_tracker_get(id=Pid).CommandLine AS CommandLine
FROM netstat()
WHERE Status = "ESTABLISHED"
AND Raddr.IP != ""
AND Raddr.IP !~ "^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)" -- Exclude RFC1918
AND Raddr.IP !~ "^(127\\.|169\\.254\\.)" -- Exclude localhost and link-local
```
### Unusual Port Activity
```sql
-- Connections on unusual ports
SELECT Raddr.IP AS RemoteIP,
Raddr.Port AS RemotePort,
COUNT(*) AS ConnectionCount,
GROUP_CONCAT(DISTINCT process_tracker_get(id=Pid).Name) AS Processes
FROM netstat()
WHERE Status = "ESTABLISHED"
AND Raddr.Port NOT IN (80, 443, 22, 3389, 445, 139, 53)
GROUP BY Raddr.IP, Raddr.Port
HAVING ConnectionCount > 5
```
### DNS Query Analysis
```sql
-- Suspicious DNS queries
SELECT query AS Domain,
response AS IPAddress,
timestamp(epoch=Time) AS QueryTime
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Microsoft-Windows-DNS-Client%4Operational.evtx")
WHERE System.EventID.Value = 3008
AND (
-- Long domain names (possible DGA)
length(query) > 50
-- High entropy domains
OR query =~ "[a-z0-9]{20,}"
-- Suspicious TLDs
OR query =~ "\\.(tk|ml|ga|cf|gq)$"
)
```
## File System Analysis
### Recently Modified Executables
```sql
-- Executables modified in last 7 days
SELECT FullPath, Size,
timestamp(epoch=Mtime) AS ModifiedTime,
timestamp(epoch=Ctime) AS CreatedTime,
hash(path=FullPath, accessor="file") AS SHA256
FROM glob(globs=[
"C:/Windows/System32/**/*.exe",
"C:/Windows/SysWOW64/**/*.exe",
"C:/Users/*/AppData/**/*.exe",
"C:/ProgramData/**/*.exe"
])
WHERE Mtime > timestamp(epoch=now() - 604800) -- 7 days
ORDER BY Mtime DESC
```
### Webshell Detection
```sql
-- Potential webshells in web directories
SELECT FullPath, Size,
timestamp(epoch=Mtime) AS ModifiedTime,
read_file(filename=FullPath, length=1000) AS Content
FROM glob(globs=[
"C:/inetpub/wwwroot/**/*.asp",
"C:/inetpub/wwwroot/**/*.aspx",
"C:/inetpub/wwwroot/**/*.php",
"C:/xampp/htdocs/**/*.php"
])
WHERE Content =~ "(?i)(eval|base64_decode|exec|shell_exec|system|passthru|WScript\\.Shell)"
OR FullPath =~ "(?i)(cmd|shell|upload|backdoor|c99)"
```
### Suspicious File Timestamps
```sql
-- Files with timestamp anomalies (timestomping detection)
SELECT FullPath,
timestamp(epoch=Mtime) AS ModifiedTime,
timestamp(epoch=Ctime) AS ChangeTime,
timestamp(epoch=Btime) AS BornTime
FROM glob(globs="C:/Users/**/*.exe")
WHERE Mtime < Btime -- Modified time before birth time (anomaly)
OR Ctime < Btime -- Change time before birth time
```
## Registry Forensics
### Autorun Locations
```sql
-- Comprehensive autorun registry key enumeration
SELECT Key.FullPath AS RegistryPath,
ValueName,
ValueData.value AS Value,
timestamp(epoch=Key.Mtime) AS LastModified
FROM read_reg_key(globs=[
"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run/*",
"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/RunOnce/*",
"HKEY_CURRENT_USER/SOFTWARE/Microsoft/Windows/CurrentVersion/Run/*",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Microsoft/Windows/CurrentVersion/Run/*",
"HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/*"
])
WHERE ValueData.value != ""
```
### Recent Registry Modifications
```sql
-- Recently modified registry keys in security-sensitive locations
SELECT FullPath,
timestamp(epoch=Mtime) AS ModifiedTime
FROM glob(globs=[
"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/**",
"HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/**",
"HKEY_CURRENT_USER/SOFTWARE/Microsoft/Windows/CurrentVersion/**"
], accessor="registry")
WHERE Mtime > timestamp(epoch=now() - 86400) -- Last 24 hours
ORDER BY Mtime DESC
```
### AppInit DLL Injection
```sql
-- Detect AppInit DLL injection mechanism
SELECT ValueName,
ValueData.value AS DLLPath,
timestamp(epoch=Key.Mtime) AS LastModified
FROM read_reg_key(globs=[
"HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs"
])
WHERE ValueData.value != ""
```
## Memory Analysis
### Suspicious Memory Regions
```sql
-- Memory regions with unusual protections
SELECT Pid,
process_tracker_get(id=Pid).Name AS ProcessName,
Address,
Size,
Protection
FROM vad()
WHERE Protection =~ "EXECUTE.*WRITE" -- RWX memory (suspicious)
AND Type = "Private"
```
### Injected Code Detection
```sql
-- Detect potentially injected code
SELECT Pid,
Name AS ProcessName,
Vad.Address AS MemoryAddress,
Vad.Protection AS Protection,
Vad.Type AS MemoryType
FROM pslist()
LET Vad <= SELECT * FROM vad(pid=Pid)
WHERE Vad.Protection =~ "EXECUTE"
AND Vad.Type = "Private"
AND Vad.Name = ""
```
## Event Log Analysis
### Failed Logon Attempts
```sql
-- Failed authentication attempts
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS EventTime,
EventData.TargetUserName AS Username,
EventData.IpAddress AS SourceIP,
EventData.WorkstationName AS Workstation,
EventData.FailureReason AS Reason
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Security.evtx")
WHERE System.EventID.Value = 4625 -- Failed logon
ORDER BY EventTime DESC
LIMIT 1000
```
### Privilege Escalation Events
```sql
-- Privilege elevation and sensitive privilege use
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS EventTime,
System.EventID.Value AS EventID,
EventData.SubjectUserName AS User,
EventData.PrivilegeList AS Privileges
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Security.evtx")
WHERE System.EventID.Value IN (4672, 4673, 4674) -- Special privilege events
AND EventData.PrivilegeList =~ "(SeDebugPrivilege|SeTcbPrivilege|SeLoadDriverPrivilege)"
```
### Scheduled Task Creation
```sql
-- Detect scheduled task creation for persistence
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS EventTime,
EventData.TaskName AS TaskName,
EventData.UserContext AS RunAsUser,
EventData.TaskContent AS TaskXML
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Microsoft-Windows-TaskScheduler%4Operational.evtx")
WHERE System.EventID.Value = 106 -- Task registered
ORDER BY EventTime DESC
```
## Persistence Mechanisms
### Comprehensive Persistence Hunt
```sql
-- Multi-vector persistence detection
LET RegistryAutoRuns = SELECT "Registry" AS Method, Key.FullPath AS Location, ValueData.value AS Value
FROM read_reg_key(globs="HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run/*")
LET ScheduledTasks = SELECT "Scheduled Task" AS Method, FullPath AS Location, "" AS Value
FROM glob(globs="C:/Windows/System32/Tasks/**")
WHERE NOT IsDir
LET Services = SELECT "Service" AS Method, Key.Name AS Location, ImagePath.value AS Value
FROM read_reg_key(globs="HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/**/ImagePath")
LET StartupFolders = SELECT "Startup Folder" AS Method, FullPath AS Location, "" AS Value
FROM glob(globs=[
"C:/Users/*/AppData/Roaming/Microsoft/Windows/Start Menu/Programs/Startup/*",
"C:/ProgramData/Microsoft/Windows/Start Menu/Programs/Startup/*"
])
SELECT * FROM chain(
a=RegistryAutoRuns,
b=ScheduledTasks,
c=Services,
d=StartupFolders
)
```
### WMI Event Subscription Persistence
```sql
-- Detect malicious WMI event subscriptions
SELECT Name,
EventFilter,
Consumer,
timestamp(epoch=CreationDate) AS Created
FROM wmi_persist()
WHERE EventFilter != "" OR Consumer != ""
```
## Lateral Movement Detection
### PsExec Activity
```sql
-- PsExec service creation and execution
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS EventTime,
EventData.ServiceName AS ServiceName,
EventData.ImagePath AS ExecutablePath,
EventData.AccountName AS Account
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/System.evtx")
WHERE System.EventID.Value = 7045 -- Service installed
AND (
EventData.ServiceName =~ "(?i)PSEXESVC"
OR EventData.ImagePath =~ "(?i)(\\\\\\\\.*\\\\.*\\\\|admin\\$|c\\$)"
)
```
### Remote Desktop Activity
```sql
-- RDP logon activity
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS LogonTime,
EventData.TargetUserName AS Username,
EventData.IpAddress AS SourceIP,
EventData.LogonType AS LogonType
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Security.evtx")
WHERE System.EventID.Value = 4624 -- Successful logon
AND EventData.LogonType = 10 -- RemoteInteractive (RDP)
ORDER BY LogonTime DESC
```
### SMB/Admin Share Access
```sql
-- Network share access from remote systems
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS AccessTime,
EventData.SubjectUserName AS Username,
EventData.IpAddress AS SourceIP,
EventData.ShareName AS ShareAccessed,
EventData.ObjectName AS FileAccessed
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Security.evtx")
WHERE System.EventID.Value = 5140 -- Network share accessed
AND EventData.ShareName =~ "(?i)(ADMIN\\$|C\\$|IPC\\$)"
```
## Data Exfiltration
### Large File Transfers
```sql
-- Files copied to removable media or network shares
SELECT FullPath,
Size,
timestamp(epoch=Mtime) AS LastModified,
hash(path=FullPath, accessor="file").SHA256 AS SHA256
FROM glob(globs=[
"D:/**", -- Removable drive
"E:/**",
"\\\\*/**" -- Network paths
])
WHERE Size > 10485760 -- Files larger than 10MB
AND Mtime > timestamp(epoch=now() - 86400)
ORDER BY Size DESC
```
### USB Device History
```sql
-- USB device connection history
SELECT Key.Name AS DeviceID,
FriendlyName.value AS DeviceName,
timestamp(epoch=Key.Mtime) AS LastConnected
FROM read_reg_key(globs="HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Enum/USBSTOR/**/FriendlyName")
ORDER BY LastConnected DESC
```
### Cloud Storage Activity
```sql
-- Files in cloud sync directories
SELECT FullPath, Size,
timestamp(epoch=Mtime) AS LastModified
FROM glob(globs=[
"C:/Users/*/OneDrive/**",
"C:/Users/*/Dropbox/**",
"C:/Users/*/Google Drive/**"
])
WHERE Mtime > timestamp(epoch=now() - 86400)
ORDER BY Mtime DESC
```
## Malware Analysis
### Suspicious File Indicators
```sql
-- Files with malware-associated characteristics
SELECT FullPath,
Size,
timestamp(epoch=Mtime) AS ModifiedTime,
hash(path=FullPath, accessor="file") AS Hashes
FROM glob(globs=[
"C:/Windows/Temp/**/*.exe",
"C:/Users/*/AppData/Local/Temp/**/*.exe",
"C:/ProgramData/**/*.exe"
])
WHERE (
-- Small executables (potential droppers)
Size < 102400
-- Or recently created
OR Mtime > timestamp(epoch=now() - 3600)
)
```
### Packed Executable Detection
```sql
-- Detect potentially packed executables (high entropy)
SELECT FullPath,
parse_pe(file=FullPath).Entropy AS Entropy,
parse_pe(file=FullPath).Sections AS Sections
FROM glob(globs="C:/Users/**/*.exe")
WHERE parse_pe(file=FullPath).Entropy > 7.0 -- High entropy suggests packing
```
### Malicious Scripts
```sql
-- Suspicious PowerShell/VBS scripts
SELECT FullPath,
Size,
timestamp(epoch=Mtime) AS ModifiedTime,
read_file(filename=FullPath, length=5000) AS Content
FROM glob(globs=[
"C:/Users/**/*.ps1",
"C:/Users/**/*.vbs",
"C:/Users/**/*.js",
"C:/Windows/Temp/**/*.ps1"
])
WHERE Content =~ "(?i)(invoke-expression|iex|downloadstring|webclient|bypass|hidden|encodedcommand)"
```
## Advanced Hunting Patterns
### Threat Hunting with Multiple Indicators
```sql
-- Correlate multiple suspicious indicators
LET SuspiciousProcesses = SELECT Pid, Name, CommandLine
FROM pslist()
WHERE CommandLine =~ "(?i)(bypass|hidden|encodedcommand)"
LET SuspiciousConnections = SELECT Pid, Raddr.IP AS RemoteIP
FROM netstat()
WHERE Status = "ESTABLISHED"
AND Raddr.IP !~ "^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)"
SELECT sp.Pid,
sp.Name,
sp.CommandLine,
GROUP_CONCAT(sc.RemoteIP) AS ConnectedIPs
FROM SuspiciousProcesses sp
JOIN SuspiciousConnections sc ON sp.Pid = sc.Pid
GROUP BY sp.Pid
```
### Timeline Analysis
```sql
-- Comprehensive timeline of system activity
SELECT timestamp(epoch=Timestamp) AS EventTime,
Source,
EventType,
Details
FROM chain(
a={SELECT Mtime AS Timestamp, "FileSystem" AS Source, "FileCreated" AS EventType, FullPath AS Details
FROM glob(globs="C:/Users/**") WHERE Mtime > timestamp(epoch=now() - 86400)},
b={SELECT System.TimeCreated.SystemTime AS Timestamp, "EventLog" AS Source,
format(format="EventID:%v", args=System.EventID.Value) AS EventType,
EventData AS Details
FROM parse_evtx(filename="C:/Windows/System32/winevt/Logs/Security.evtx")
WHERE System.TimeCreated.SystemTime > timestamp(epoch=now() - 86400)},
c={SELECT Key.Mtime AS Timestamp, "Registry" AS Source, "KeyModified" AS EventType, Key.FullPath AS Details
FROM glob(globs="HKEY_LOCAL_MACHINE/SOFTWARE/**", accessor="registry")
WHERE Key.Mtime > timestamp(epoch=now() - 86400)}
)
ORDER BY EventTime DESC
```
```
### references/artifact-development.md
```markdown
# Velociraptor Artifact Development Guide
Guide to creating custom VQL artifacts for specific investigation and threat hunting scenarios.
## Table of Contents
- [Artifact Structure](#artifact-structure)
- [Parameter Types](#parameter-types)
- [Source Types](#source-types)
- [Best Practices](#best-practices)
- [Common Patterns](#common-patterns)
- [Testing Artifacts](#testing-artifacts)
## Artifact Structure
Velociraptor artifacts are YAML files with a defined structure:
```yaml
name: Category.Subcategory.ArtifactName
description: |
Detailed description of what this artifact collects and why.
Include use cases and expected output.
author: Your Name <[email protected]>
type: CLIENT # CLIENT, SERVER, or CLIENT_EVENT
parameters:
- name: ParameterName
default: "default_value"
type: string
description: Parameter description
precondition: |
SELECT OS FROM info() WHERE OS = 'windows'
sources:
- name: SourceName
query: |
SELECT * FROM plugin()
WHERE condition
reports:
- type: CLIENT
template: |
# Report Title
{{ .Description }}
{{ range .Rows }}
- {{ .Column }}
{{ end }}
```
### Required Fields
- **name**: Unique artifact identifier in dot notation
- **description**: What the artifact does and when to use it
- **sources**: At least one VQL query source
### Optional Fields
- **author**: Creator information
- **type**: Artifact type (CLIENT, SERVER, CLIENT_EVENT)
- **parameters**: User-configurable inputs
- **precondition**: Check before running (OS, software presence)
- **reports**: Output formatting templates
- **references**: External documentation links
## Parameter Types
### String Parameters
```yaml
parameters:
- name: SearchPath
default: "C:/Windows/System32/"
type: string
description: Directory path to search
```
### Integer Parameters
```yaml
parameters:
- name: DaysBack
default: 7
type: int
description: Number of days to look back
```
### Boolean Parameters
```yaml
parameters:
- name: IncludeSystem
default: Y
type: bool
description: Include system files
```
### Regex Parameters
```yaml
parameters:
- name: ProcessPattern
default: "(?i)(powershell|cmd)"
type: regex
description: Process name pattern to match
```
### Choice Parameters
```yaml
parameters:
- name: LogLevel
default: "INFO"
type: choices
choices:
- DEBUG
- INFO
- WARNING
- ERROR
description: Logging verbosity
```
### CSV Parameters
```yaml
parameters:
- name: IOCList
default: |
evil.com
malicious.net
type: csv
description: List of IOC domains
```
## Source Types
### Query Sources
Standard VQL query that collects data:
```yaml
sources:
- name: ProcessCollection
query: |
SELECT Pid, Name, CommandLine, Username
FROM pslist()
WHERE Name =~ ProcessPattern
```
### Event Sources
Continuous monitoring queries for CLIENT_EVENT artifacts:
```yaml
sources:
- name: ProcessCreation
query: |
SELECT * FROM watch_evtx(
filename="C:/Windows/System32/winevt/Logs/Security.evtx"
)
WHERE System.EventID.Value = 4688
```
### Multiple Sources
Artifacts can have multiple sources for different data collection:
```yaml
sources:
- name: Processes
query: |
SELECT * FROM pslist()
- name: NetworkConnections
query: |
SELECT * FROM netstat()
- name: LoadedDLLs
query: |
SELECT * FROM modules()
```
## Best Practices
### 1. Use Preconditions
Prevent artifact execution on incompatible systems:
```yaml
# Windows-only artifact
precondition: |
SELECT OS FROM info() WHERE OS = 'windows'
# Requires specific tool
precondition: |
SELECT * FROM stat(filename="C:/Tools/sysinternals/psexec.exe")
# Version check
precondition: |
SELECT * FROM info() WHERE OS = 'windows' AND OSVersion =~ '10'
```
### 2. Parameterize Paths and Patterns
Make artifacts flexible and reusable:
```yaml
parameters:
- name: TargetPath
default: "C:/Users/**/AppData/**"
type: string
- name: FilePattern
default: "*.exe"
type: string
sources:
- query: |
SELECT * FROM glob(globs=TargetPath + "/" + FilePattern)
```
### 3. Use LET for Query Composition
Break complex queries into manageable parts:
```yaml
sources:
- query: |
-- Define reusable subqueries
LET SuspiciousProcesses = SELECT Pid, Name, CommandLine
FROM pslist()
WHERE CommandLine =~ "(?i)(bypass|hidden)"
LET NetworkConnections = SELECT Pid, Raddr.IP AS RemoteIP
FROM netstat()
WHERE Status = "ESTABLISHED"
-- Join and correlate
SELECT sp.Name,
sp.CommandLine,
nc.RemoteIP
FROM SuspiciousProcesses sp
JOIN NetworkConnections nc ON sp.Pid = nc.Pid
```
### 4. Add Error Handling
Handle missing data gracefully:
```yaml
sources:
- query: |
SELECT * FROM foreach(
row={
SELECT FullPath FROM glob(globs=SearchPath)
},
query={
SELECT FullPath,
hash(path=FullPath, accessor="file").SHA256 AS SHA256
FROM scope()
WHERE log(message="Processing: " + FullPath)
},
workers=5
)
WHERE SHA256 -- Filter out hash failures
```
### 5. Include Documentation
Add inline comments and comprehensive descriptions:
```yaml
description: |
## Overview
This artifact hunts for suspicious scheduled tasks.
## Use Cases
- Persistence mechanism detection
- Lateral movement artifact collection
- Threat hunting campaigns
## Output
Returns task name, actions, triggers, and creation time.
## References
- MITRE ATT&CK T1053.005 (Scheduled Task/Job)
```
## Common Patterns
### Pattern: File Collection with Hashing
```yaml
name: Custom.Windows.FileCollection
description: Collect files matching patterns with hashes
parameters:
- name: GlobPatterns
default: |
C:/Users/**/AppData/**/*.exe
C:/Windows/Temp/**/*.dll
type: csv
sources:
- query: |
SELECT FullPath,
Size,
timestamp(epoch=Mtime) AS Modified,
timestamp(epoch=Btime) AS Created,
hash(path=FullPath, accessor="file") AS Hashes
FROM foreach(
row={
SELECT * FROM parse_csv(filename=GlobPatterns, accessor="data")
},
query={
SELECT * FROM glob(globs=_value)
}
)
WHERE NOT IsDir
```
### Pattern: Event Log Analysis
```yaml
name: Custom.Windows.EventLogHunt
description: Hunt for specific event IDs with context
parameters:
- name: LogFile
default: "C:/Windows/System32/winevt/Logs/Security.evtx"
type: string
- name: EventIDs
default: "4624,4625,4672"
type: csv
sources:
- query: |
LET EventIDList = SELECT parse_string_with_regex(
string=EventIDs,
regex="(\\d+)"
).g1 AS EventID FROM scope()
SELECT timestamp(epoch=System.TimeCreated.SystemTime) AS EventTime,
System.EventID.Value AS EventID,
System.Computer AS Computer,
EventData
FROM parse_evtx(filename=LogFile)
WHERE str(str=System.EventID.Value) IN EventIDList.EventID
ORDER BY EventTime DESC
```
### Pattern: Process Tree Analysis
```yaml
name: Custom.Windows.ProcessTree
description: Build process tree from a starting PID
parameters:
- name: RootPID
default: 0
type: int
description: Starting process PID (0 for all)
sources:
- query: |
LET ProcessList = SELECT Pid, Ppid, Name, CommandLine, Username, CreateTime
FROM pslist()
LET RECURSIVE GetChildren(ParentPID) = SELECT *
FROM ProcessList
WHERE Ppid = ParentPID
LET RECURSIVE BuildTree(Level, ParentPID) = SELECT
Level,
Pid,
Ppid,
Name,
CommandLine,
Username,
CreateTime
FROM GetChildren(ParentPID=ParentPID)
UNION ALL
SELECT * FROM BuildTree(Level=Level+1, ParentPID=Pid)
SELECT * FROM if(
condition=RootPID > 0,
then={
SELECT * FROM BuildTree(Level=0, ParentPID=RootPID)
},
else={
SELECT 0 AS Level, * FROM ProcessList
}
)
ORDER BY CreateTime
```
### Pattern: Network IOC Matching
```yaml
name: Custom.Windows.NetworkIOCMatch
description: Match network connections against IOC list
parameters:
- name: IOCList
default: |
IP,Description
192.0.2.1,C2 Server
198.51.100.50,Malicious Host
type: csv
sources:
- query: |
LET IOCs = SELECT IP, Description
FROM parse_csv(filename=IOCList, accessor="data")
LET Connections = SELECT
Raddr.IP AS RemoteIP,
Raddr.Port AS RemotePort,
Pid,
process_tracker_get(id=Pid).Name AS ProcessName,
process_tracker_get(id=Pid).CommandLine AS CommandLine
FROM netstat()
WHERE Status = "ESTABLISHED"
SELECT c.RemoteIP,
c.RemotePort,
c.ProcessName,
c.CommandLine,
i.Description AS IOCMatch
FROM Connections c
JOIN IOCs i ON c.RemoteIP = i.IP
```
### Pattern: Registry Timeline
```yaml
name: Custom.Windows.RegistryTimeline
description: Timeline registry modifications in specific keys
parameters:
- name: RegistryPaths
default: |
HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows/CurrentVersion/Run/**
HKEY_CURRENT_USER/SOFTWARE/Microsoft/Windows/CurrentVersion/Run/**
type: csv
- name: DaysBack
default: 7
type: int
sources:
- query: |
LET StartTime = timestamp(epoch=now() - DaysBack * 86400)
SELECT timestamp(epoch=Key.Mtime) AS Modified,
Key.FullPath AS RegistryPath,
ValueName,
ValueData.value AS Value
FROM foreach(
row={
SELECT * FROM parse_csv(filename=RegistryPaths, accessor="data")
},
query={
SELECT * FROM read_reg_key(globs=_value)
}
)
WHERE Key.Mtime > StartTime
ORDER BY Modified DESC
```
## Testing Artifacts
### 1. Local Testing with GUI
```bash
# Start Velociraptor in GUI mode
velociraptor gui
# Navigate to: View Artifacts → Add Artifact
# Paste your artifact YAML and click Save
# Run artifact via Collected Artifacts → New Collection
```
### 2. Command Line Testing
```bash
# Test artifact syntax
velociraptor artifacts show Custom.Artifact.Name
# Run artifact locally
velociraptor artifacts collect Custom.Artifact.Name \
--args ParameterName=value \
--format json
# Run with output file
velociraptor artifacts collect Custom.Artifact.Name \
--output results.json
```
### 3. Notebook Testing
Use VQL notebooks for interactive development:
```sql
-- Test query components in isolation
SELECT * FROM pslist() WHERE Name =~ "powershell" LIMIT 10
-- Test parameter substitution
LET ProcessPattern = "(?i)(powershell|cmd)"
SELECT * FROM pslist() WHERE Name =~ ProcessPattern
-- Test full artifact query
/* Paste your artifact query here */
```
### 4. Validation Checklist
Before deploying artifacts:
- [ ] Artifact name follows convention: Category.Subcategory.Name
- [ ] Description includes use cases and expected output
- [ ] Parameters have sensible defaults
- [ ] Precondition prevents incompatible execution
- [ ] Query tested in notebook mode
- [ ] Error handling for missing data
- [ ] Performance acceptable on test system
- [ ] Output format is useful and parseable
- [ ] Documentation includes MITRE ATT&CK mapping if applicable
## Performance Considerations
### Limit Scope
```yaml
# BAD: Scans entire filesystem
SELECT * FROM glob(globs="C:/**/*.exe")
# GOOD: Targeted scope
SELECT * FROM glob(globs=[
"C:/Users/**/AppData/**/*.exe",
"C:/Windows/Temp/**/*.exe"
])
```
### Use Workers for Parallel Processing
```yaml
sources:
- query: |
SELECT * FROM foreach(
row={SELECT * FROM glob(globs=SearchPath)},
query={
SELECT FullPath,
hash(path=FullPath, accessor="file").SHA256 AS SHA256
FROM scope()
},
workers=10 -- Process 10 files concurrently
)
```
### Rate Limiting
```yaml
sources:
- query: |
SELECT * FROM foreach(
row={SELECT * FROM glob(globs="C:/**")},
query={
SELECT * FROM scope()
WHERE rate(query_name="my_query", ops_per_sec=100)
}
)
```
## MITRE ATT&CK Mapping
Map artifacts to MITRE ATT&CK techniques:
```yaml
name: Custom.Windows.PersistenceHunt
description: |
Hunt for persistence mechanisms.
MITRE ATT&CK Techniques:
- T1547.001: Registry Run Keys / Startup Folder
- T1053.005: Scheduled Task/Job
- T1543.003: Windows Service
- T1546.003: Windows Management Instrumentation Event Subscription
references:
- https://attack.mitre.org/techniques/T1547/001/
- https://attack.mitre.org/techniques/T1053/005/
```
## Artifact Distribution
### Export Artifacts
```bash
# Export single artifact
velociraptor artifacts show Custom.Artifact.Name > artifact.yaml
# Export all custom artifacts
velociraptor artifacts list --filter Custom > all_artifacts.yaml
```
### Import Artifacts
```bash
# Via command line
velociraptor --config server.config.yaml artifacts import artifact.yaml
# Via GUI
# Navigate to: View Artifacts → Upload Artifact Pack
```
### Share via Artifact Exchange
Contribute artifacts to the community:
1. Test thoroughly across different systems
2. Document clearly with examples
3. Add MITRE ATT&CK mappings
4. Submit to: https://docs.velociraptor.app/exchange/
```