Velociraptor supports three modes for encrypting Offline Collectors: Password, X.509 Secured, and PGP-secured (as described here ). While X.509 is the standard for automatic server imports, using PGP is a great alternative when you need to decrypt collections independently of the Velociraptor Server.
The PGP Encryption Workflow: When using PGP, Velociraptor follows a “hybrid” encryption approach:
First, generate an RSA key-pair. We will use a batch file for automation, but you can also do this interactively.
gpg --batch --generate-key <<EOF
Key-Type: RSA
Key-Length: 3072
Subkey-Type: RSA
Subkey-Length: 3072
Name-Real: Ilo
Name-Email: ilo@test.com
Expire-Date: 1y
%no-protection
%commit
EOF
# Export the public key for use in the collector
gpg --armor --export ilo@test.com > key.pub
The easiest way to build the Offline Collector is in the GUI. This approach will generate a Velociraptor Offline Collector and a spec.yaml.
The following will show how to build the offline collector using CLI:
Prepare the CLI environment
mkdir datastore artifacts
# Download reference artifacts and the Velociraptor binary
wget https://triage.velocidex.com/artifacts/Velociraptor_Triage_v0.1.zip -P artifacts
7z x artifacts/Velociraptor_Triage_v0.1.zip -oartifacts
wget https://github.com/Velocidex/velociraptor/releases/download/v0.75/velociraptor-v0.75.6-linux-amd64
chmod +x velociraptor-v0.75.6-linux-amd64
# Generate a base template
./velociraptor-v0.75.6-linux-amd64 collector > template-spec.yaml
Update template-spec.yaml
Edit your YAML file to include your public key in the field public_key. Ensure the EncryptionScheme is set to PGP.
OS: Windows
Artifacts:
Windows.Triage.Targets:
HighLevelTargets: '["_SANS_Triage", "_KapeTriage"]'
Devices: '["C:","D:","E:"]'
Target: ZIP
EncryptionScheme: PGP
EncryptionArgs:
public_key: |-
-----BEGIN PGP PUBLIC KEY BLOCK-----
REDACTED...
-----END PGP PUBLIC KEY BLOCK-----
password: ""
OptVerbose: Y
OptBanner: Y
OptPrompt: N
OptAdmin: Y
OptTempdir: ""
OptLevel: 9
OptConcurrency: 2
OptFilenameTemplate: "Collection-%Hostname%-%TIMESTAMP%"
OptCollectorTemplate: ""
OptFormat: jsonl
OptOutputDirectory: ""
OptCpuLimit: 0
OptProgressTimeout: 1800
OptTimeout: 0
OptVersion: ""
OptDeleteAtExit: N
Step 3: Build the Offline Collector
Run the following command to “repack” the Velociraptor binary into a standalone collector based on your spec.
./velociraptor-v0.75.6-linux-amd64 collector --datastore datastore --definitions artifacts template-spec.yaml
[
{
"Repacked": {
"Path": "/REDACTED/datastore/Collector_velociraptor-v0.75.6-windows-amd64.exe",
"Size": 87421951,
"UploadId": 0,
"sha256": "f1487b5686c9616def5c55cd32266b4726162758456d7f5149ebfde51bc3a582",
"md5": "d46f704b4014dd7a76fa2847b21f813e",
"Components": [
"Collector_velociraptor-v0.75.6-windows-amd64.exe"
]
},
"_Source": "Server.Utils.CreateCollector"
}
]
The Velociraptor Offline Collector will generate a Collector.zip file. The file structure within the container is documented as described here :
Within the metadata.json file you fill find the encrypted password in the EncryptedPass entry:
[
{
"EncryptedPass": "REDACTED",
"Scheme": "PGP",
"PublicKey": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nREDACTED\n-----END PGP PUBLIC KEY BLOCK-----"
}
]
You can decrypt the password and the data using the following commands:
# 1. Extract the encrypted pass from metadata
# 2. Base64 decode it
# 3. Decrypt with GPG
# 4. Use the result as the password for the data zip
PASS=$(7z e -so Collection.zip metadata.json | jq -r '.[].EncryptedPass' | base64 -d | gpg --decrypt)
7z x Collection.zip "-p$PASS" -y
This assumes that the private key is in your gpg vault.
Working with the Offline Collection data is described here