From 8d399081ceb06587a24b36ffec5690b1e64d9ebe Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Wed, 3 Jul 2024 14:42:13 +1000 Subject: [PATCH] Add option to override collector filename to CreateCollector.yaml (#3591) Added a parameter to add a prefix to the filename of the collector being built. This allows the artifact to be run multiple times in a single notebook, with different configurations, and not overwrite the previously created executables. --------- Co-authored-by: menewol --- .../Server/Utils/CreateCollector.yaml | 10 ++++++--- bin/offline.go | 4 ++++ docs/offline_collector/offline_collector.sh | 1 + docs/offline_collector/sample.spec.yaml | 1 + .../components/flows/offline-collector.jsx | 21 +++++++++++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/artifacts/definitions/Server/Utils/CreateCollector.yaml b/artifacts/definitions/Server/Utils/CreateCollector.yaml index ee58a527279..8ba4060bb30 100644 --- a/artifacts/definitions/Server/Utils/CreateCollector.yaml +++ b/artifacts/definitions/Server/Utils/CreateCollector.yaml @@ -103,6 +103,11 @@ parameters: The filename to use. You can expand environment variables as well as the following %FQDN% and %TIMESTAMP%. + - name: opt_collector_filename + type: string + description: | + If used, this option overrides the default filename of the collector being built. + - name: opt_cpu_limit default: "0" type: int @@ -388,9 +393,8 @@ sources: LET Target <= tool_name[0].Type // This is what we will call it. - LET CollectorName <= format( - format='Collector_%v', - args=inventory_get(tool=Target).Definition.filename) + LET CollectorName <= opt_collector_filename || + format(format='Collector_%v', args=inventory_get(tool=Target).Definition.filename) LET CollectionArtifact <= SELECT Value FROM switch( a = { SELECT CommonCollections + StandardCollection AS Value diff --git a/bin/offline.go b/bin/offline.go index f398fe651ee..5a1fab0edfb 100644 --- a/bin/offline.go +++ b/bin/offline.go @@ -62,6 +62,9 @@ OptTempdir: OptLevel: 5 OptFilenameTemplate: "Collection-%FQDN%-%TIMESTAMP%" +# What to call the collection binary. If empty we use an autogenerated name. +OptCollectorTemplate: "" + # Can be jsonl or csv OptFormat: jsonl @@ -207,6 +210,7 @@ SELECT * FROM Artifact.Server.Utils.CreateCollector( opt_tempdir=Spec.OptTempdir, opt_level=Spec.OptLevel, opt_filename_template=Spec.OptFilenameTemplate, + opt_collector_filename=Spec.OptCollectorTemplate, opt_format=Spec.OptFormat, opt_output_directory=Spec.OptOutputDirectory, opt_cpu_limit=Spec.OptCpuLimit, diff --git a/docs/offline_collector/offline_collector.sh b/docs/offline_collector/offline_collector.sh index cc8c8fb7047..381f75850d1 100755 --- a/docs/offline_collector/offline_collector.sh +++ b/docs/offline_collector/offline_collector.sh @@ -61,6 +61,7 @@ SELECT * FROM Artifact.Server.Utils.CreateCollector( opt_tempdir=Spec.OptTempdir, opt_level=Spec.OptLevel, opt_filename_template=Spec.OptFilenameTemplate, + opt_collector_filename=Spec.OptCollectorTemplate, opt_format=Spec.OptFormat, opt_output_directory=Spec.OptOutputDirectory, opt_cpu_limit=Spec.OptCpuLimit, diff --git a/docs/offline_collector/sample.spec.yaml b/docs/offline_collector/sample.spec.yaml index 489c11c7471..b29f91da5cb 100644 --- a/docs/offline_collector/sample.spec.yaml +++ b/docs/offline_collector/sample.spec.yaml @@ -33,6 +33,7 @@ OptTempdir: # Compression level to use OptLevel: 5 OptFilenameTemplate: "Collection-%FQDN%-%TIMESTAMP%" +OptCollectorTemplate: "" # Can be jsonl or csv OptFormat: jsonl diff --git a/gui/velociraptor/src/components/flows/offline-collector.jsx b/gui/velociraptor/src/components/flows/offline-collector.jsx index 9c27967af45..abeb66cfd13 100644 --- a/gui/velociraptor/src/components/flows/offline-collector.jsx +++ b/gui/velociraptor/src/components/flows/offline-collector.jsx @@ -595,6 +595,21 @@ class OfflineCollectorParameters extends React.Component { /> + + {T("Collector Name")} + + { + this.props.parameters.opt_collector_filename = e.target.value; + this.props.setParameters(this.props.parameters); + }} + /> + + @@ -759,6 +774,7 @@ function getDefaultCollectionParameters() { opt_output_directory: "", opt_tempdir: "", opt_filename_template: "Collection-%FQDN%-%TIMESTAMP%", + opt_collector_filename: "", opt_format: "jsonl", opt_prompt: "N", }; @@ -836,6 +852,10 @@ export default class OfflineCollectorWizard extends React.Component { case "opt_filename_template": collector_parameters.opt_filename_template = x.value; break; + case "opt_collector_filename": + collector_parameters.opt_collector_filename = x.value; + break; + case "opt_progress_timeout": resources.progress_timeout = JSONparse(x.value); break; @@ -901,6 +921,7 @@ export default class OfflineCollectorWizard extends React.Component { env.push({key: "opt_level", value: this.state.collector_parameters.opt_level.toString()}); env.push({key: "opt_output_directory", value: this.state.collector_parameters.opt_output_directory}); env.push({key: "opt_filename_template", value: this.state.collector_parameters.opt_filename_template}); + env.push({key: "opt_collector_filename", value: this.state.collector_parameters.opt_collector_filename}); env.push({key: "opt_progress_timeout", value: JSON.stringify( this.state.resources.progress_timeout)}); env.push({key: "opt_timeout", value: JSON.stringify(