Skip to content

Commit

Permalink
Allow additional event artifacts to be specified in client config. (V…
Browse files Browse the repository at this point in the history
…elocidex#2664)

By including custom event artifacts in the config it is possible to
implement client initialization actions that can take place even before
the client contacts the server.
  • Loading branch information
scudette authored May 6, 2023
1 parent 5cb5708 commit a6e5aed
Show file tree
Hide file tree
Showing 13 changed files with 3,747 additions and 3,607 deletions.
60 changes: 56 additions & 4 deletions actions/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,11 @@ import (
config "www.velocidex.com/golang/velociraptor/config"
config_proto "www.velocidex.com/golang/velociraptor/config/proto"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
flows_proto "www.velocidex.com/golang/velociraptor/flows/proto"
"www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/responder"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/vql/acl_managers"
)

type EventTable struct {
Expand Down Expand Up @@ -179,19 +182,68 @@ func (self *EventTable) Update(
return nil, true /* changed */
}

func (self *EventTable) StartQueries(
// Make a copy of the event table and appand any config enforced
// additional event queries.
func (self *EventTable) GetEventQueries(
ctx context.Context,
config_obj *config_proto.Config,
output_chan chan *crypto_proto.VeloMessage) {
config_obj *config_proto.Config) ([]*actions_proto.VQLCollectorArgs, error) {

self.mu.Lock()
defer self.mu.Unlock()

result := make([]*actions_proto.VQLCollectorArgs, 0, len(self.Events))
result = append(result, self.Events...)

if config_obj.Client == nil ||
len(config_obj.Client.AdditionalEventArtifacts) == 0 {
return result, nil
}

launcher, err := services.GetLauncher(config_obj)
if err != nil {
return result, err
}

manager, err := services.GetRepositoryManager(config_obj)
if err != nil {
return result, err
}
repository, err := manager.GetGlobalRepository(config_obj)
if err != nil {
return result, err
}

// Compile the built in artifacts
queries, err := launcher.CompileCollectorArgs(ctx, config_obj,
acl_managers.NullACLManager{}, repository,
services.CompilerOptions{}, &flows_proto.ArtifactCollectorArgs{
Artifacts: config_obj.Client.AdditionalEventArtifacts,
})

if err != nil {
return result, err
}

result = append(result, queries...)
return result, nil
}

func (self *EventTable) StartQueries(
ctx context.Context,
config_obj *config_proto.Config,
output_chan chan *crypto_proto.VeloMessage) {

logger := logging.GetLogger(config_obj, &logging.ClientComponent)

events, err := self.GetEventQueries(ctx, config_obj)
if err != nil {
logger := logging.GetLogger(config_obj, &logging.ClientComponent)
logger.Error("While appending initial event artifacts: %v", err)
}

// Start a new query for each event.
action_obj := &VQLClientAction{}
for _, event := range self.Events {
for _, event := range events {

// Name of the query we are running. There must be at least
// one query with a name.
Expand Down
6 changes: 5 additions & 1 deletion artifacts/definitions/Generic/Utils/FetchBinary.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,18 @@ parameters:
If true we use a temporary directory to hold the binary and
remove it afterwards
- name: Version
description: The version of the tool to fetch

sources:
- query: |
-- The following VQL is particularly ancient because it is
-- running on the client and it needs to be compatibile with
-- clients at least back to 0.3.9
LET info_cache <= SELECT * FROM info()
LET inventory_item = SELECT inventory_get(tool=ToolName) AS Item FROM scope()
LET inventory_item = SELECT inventory_get(
tool=ToolName, version=Version) AS Item FROM scope()
LET args <= SELECT * FROM switch(
// Try to get info from the ToolInfo parameter.
Expand Down
2,626 changes: 1,320 additions & 1,306 deletions artifacts/definitions/Linux/KapeFiles/CollectFromDirectory.yaml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion artifacts/definitions/Server/Import/ArtifactExchange.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ required_permissions:

parameters:
- name: ExchangeURL
default: https://github.com/Velocidex/velociraptor-docs/raw/gh-pages/exchange/artifact_exchange.zip
default: https://github.com/Velocidex/velociraptor-docs/raw/gh-pages/exchange/artifact_exchange_v2.zip
- name: Prefix
description: Add artifacts with this prefix
default: Exchange.
Expand Down
2,626 changes: 1,320 additions & 1,306 deletions artifacts/definitions/Windows/KapeFiles/Targets.yaml

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions bin/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,9 @@ func runClientOnce(
}

// Check for crashes
err = executor.CheckForCrashes(ctx, config_obj, sm.Wg, exe)
err = executor.RunStartupTasks(ctx, config_obj, sm.Wg, exe)
if err != nil {
// Not a fatal error, just move on
logger := logging.GetLogger(config_obj, &logging.ClientComponent)
logger.Error("<red>CheckForCrashes Error:</> %v", err)
return err
}

<-ctx.Done()
Expand Down
7 changes: 6 additions & 1 deletion bin/gui.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ func doGUI() error {

datastore_directory := *gui_command_datastore
if datastore_directory == "" {
datastore_directory = os.TempDir()
datastore_directory = filepath.Join(os.TempDir(), "gui_datastore")
// Ensure the directory exists
err := os.MkdirAll(datastore_directory, 0o777)
if err != nil {
return fmt.Errorf("Unable to create datastore directory: %w", err)
}
}

datastore_directory, err := filepath.Abs(datastore_directory)
Expand Down
6 changes: 3 additions & 3 deletions bin/installer_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -551,12 +551,12 @@ func runOnce(ctx context.Context,
return
}

// Check for crashes
err = executor.CheckForCrashes(ctx, config_obj, sm.Wg, exe)
// Check for crashes etc
err = executor.RunStartupTasks(ctx, config_obj, sm.Wg, exe)
if err != nil {
// Not a fatal error, just move on
logger := logging.GetLogger(config_obj, &logging.ClientComponent)
logger.Error("<red>CheckForCrashes Error:</> %v", err)
logger.Error("<red>Start up error:</> %v", err)
}

<-ctx.Done()
Expand Down
Loading

0 comments on commit a6e5aed

Please sign in to comment.