From 1d2b171c2154769e9242bf160d24e131d5069866 Mon Sep 17 00:00:00 2001 From: Mike Cohen Date: Tue, 10 Sep 2024 12:14:57 +1000 Subject: [PATCH] Various bugfixes * Bug: Notebook env doesn't seem to work * Quarantine artifact is broken when using wss for comms * Artifact parameters should be unset when string is set to empty --- .../Windows/Remediation/Quarantine.yaml | 67 +++++++++++++------ config/validate.go | 4 ++ .../src/components/flows/new-collection.jsx | 7 +- vql/server/notebooks/create.go | 10 +++ 4 files changed, 66 insertions(+), 22 deletions(-) diff --git a/artifacts/definitions/Windows/Remediation/Quarantine.yaml b/artifacts/definitions/Windows/Remediation/Quarantine.yaml index 0bed55e428a..bdee2746390 100644 --- a/artifacts/definitions/Windows/Remediation/Quarantine.yaml +++ b/artifacts/definitions/Windows/Remediation/Quarantine.yaml @@ -2,25 +2,40 @@ name: Windows.Remediation.Quarantine description: | **Apply quarantine via Windows local IPSec policy** - - By default the current client configuration is applied as an exclusion - using resolved IP address at time of application. - - A configurable lookup table is also used to generate additional entries - using the same syntax as netsh ipsec configuration. - - DNS and DHCP are - entires here allowed by default. - - An optional MessageBox may also be configured to alert all logged in users. + - By default the current client configuration is applied as an + exclusion using resolved IP address at time of application. + + - A configurable lookup table is also used to generate + additional entries using the same syntax as netsh ipsec + configuration. + + - DNS and DHCP are entires here allowed by default. + + - An optional MessageBox may also be configured to alert all + logged in users. + - The message will be truncated to 256 characters. + - After policy application, connection back to the Velociraptor - frontend is tested and the policy removed if connection unavailable. + frontend is tested and the policy removed if connection + unavailable. + - To remove policy, select the RemovePolicy checkbox. + - To update policy, simply rerun the artifact. NOTE: - - Remember DNS resolution may change. It is highly recommended to plan - policy accordingly and not rely on DNS lookups. + - Remember DNS resolution may change. It is highly recommended + to plan policy accordingly and not rely on DNS lookups. + - Local IPSec policy can not be applied when Domain IPSec policy - is already enforced. Please configure at GPO level in this case. + is already enforced. Please configure at GPO level in this case. + + - This artifact deliberately does not support connecting back on + plain http! We only support the https or wss protocols because + this is the recommended connectivity mechanism between server + and client. author: Matt Green - @mgreen27 @@ -43,16 +58,25 @@ parameters: Permit,me,,0,any,,53,tcp,yes,DNS TCP Permit,me,,68,any,,67,udp,yes,DHCP Block,any,,,any,,,,yes,All other traffic + - name: MessageBox description: | Optional message box notification to send to logged in users. 256 character limit. + - name: RemovePolicy type: bool description: Tickbox to remove policy. + - name: VelociraptorURL + description: | + A URL for allowing connections back to the + Velociraptor server. If not specified we use the first URL in the + client's configuration file. + sources: - query: | + LET AllURLs <= filter(list=config.server_urls + VelociraptorURL, regex='.+') // If a MessageBox configured truncate to 256 character limit LET MessageBox <= parse_string_with_regex( @@ -74,18 +98,15 @@ sources: FROM RuleLookupTable // Parse a URL to get domain name. - LET get_domain(URL) = parse_string_with_regex( - string=URL, regex='^https?://(?P[^:/]+)').Domain + LET get_domain(URL) = split(string=url(parse=URL).Host, sep=":")[0] - // Parse a URL to get the port - LET get_port(URL) = if(condition= URL=~"https://[^:]+/", then="443", - else=if(condition= URL=~"http://[^:]+/", then="80", - else=parse_string_with_regex(string=URL, - regex='^https?://[^:/]+(:(?P[0-9]*))?/').Port)) + // Parse a URL to get the port or use 443. We deliberately do + // not support plain http! + LET get_port(URL) = split(string=url(parse=URL).Host, sep=":")[1] || "443" // extract Velociraptor config for policy LET extracted_config <= SELECT * FROM foreach( - row=config.server_urls, + row= AllURLs, query={ SELECT 'Permit' AS Action, @@ -244,8 +265,12 @@ sources: Url, response FROM - http_client(url='https://' + DstAddr + ':' + DstPort + '/server.pem', - disable_ssl_security='TRUE') + -- Always use https even when configured for wss + http_client(url=url( + scheme='https', + host=DstAddr + ':' + DstPort, + path='/server.pem').String) + WHERE Response = 200 LIMIT 1 }) diff --git a/config/validate.go b/config/validate.go index 588577140a6..298e6f3ca34 100644 --- a/config/validate.go +++ b/config/validate.go @@ -73,6 +73,10 @@ func ValidateClientConfig(config_obj *config_proto.Config) error { config_obj.Version = GetVersion() + // The client's config contains the running version of the client + // itself. + config_obj.Client.Version = GetVersion() + // Ensure the writeback service is configured. writeback_service := writeback.GetWritebackService() writeback, err := writeback_service.GetWriteback(config_obj) diff --git a/gui/velociraptor/src/components/flows/new-collection.jsx b/gui/velociraptor/src/components/flows/new-collection.jsx index 69489d2954b..ce76b52bb8e 100644 --- a/gui/velociraptor/src/components/flows/new-collection.jsx +++ b/gui/velociraptor/src/components/flows/new-collection.jsx @@ -954,7 +954,12 @@ class NewCollectionWizard extends React.Component { return; } - spec.parameters.env.push({key: k, value: v}); + // If the value is cleared just let the artifact use + // its own default value and dont mention it in the + // request at all. + if (v !== "") { + spec.parameters.env.push({key: k, value: v}); + } }); specs.push(spec); artifacts.push(item.name); diff --git a/vql/server/notebooks/create.go b/vql/server/notebooks/create.go index 257056bab64..4a920c498ef 100644 --- a/vql/server/notebooks/create.go +++ b/vql/server/notebooks/create.go @@ -51,6 +51,16 @@ func (self *CreateNotebookFunction) Call(ctx context.Context, Public: arg.Public, } + if arg.Env != nil { + for _, k := range arg.Env.Keys() { + v := vql_subsystem.GetStringFromRow(scope, arg.Env, k) + new_notebook.Env = append(new_notebook.Env, &api_proto.Env{ + Key: k, + Value: v, + }) + } + } + err = services.RequireFrontend() if err != nil { scope.Log("notebook_create: %v", err)