Skip to content

Commit

Permalink
Added a VQL client action.
Browse files Browse the repository at this point in the history
Refactored VQL subsystem to its own module.
  • Loading branch information
scudette committed Apr 28, 2018
1 parent bd731d9 commit 6512b9f
Show file tree
Hide file tree
Showing 16 changed files with 229 additions and 29 deletions.
1 change: 1 addition & 0 deletions actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ func GetClientActionsMap() map[string]ClientAction {
result["HashFile"] = &HashFile{}
result["HashBuffer"] = &HashBuffer{}
result["TransferBuffer"] = &TransferBuffer{}
result["VQLClientAction"] = &VQLClientAction{}
return result
}
3 changes: 3 additions & 0 deletions actions/proto/actions.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 76 additions & 0 deletions actions/proto/vql.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions actions/proto/vql.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// These are the messages used in client actions.
syntax = "proto2";

import "www.velocidex.com/golang/velociraptor/proto/semantic.proto";

package proto;

message VQLCollectorArgs {
optional string Query = 1 [(sem_type) = {
description: "The VQL query to execute on the client.",
}, default = "select * from client_info()"];
}

message VQLResponse {
optional string Response = 1 [(sem_type) = {
description: "JSON encoded response.",
}];
}
49 changes: 49 additions & 0 deletions actions/vql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package actions

import (
"www.velocidex.com/golang/velociraptor/context"
"encoding/json"
"www.velocidex.com/golang/vfilter"
"github.com/golang/protobuf/proto"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
)

type VQLClientAction struct{}
func (self *VQLClientAction) Run(
ctx *context.Context,
msg *crypto_proto.GrrMessage) []*crypto_proto.GrrMessage {
responder := NewResponder(msg)
arg, pres := responder.GetArgs().(*actions_proto.VQLCollectorArgs)
if !pres {
return responder.RaiseError("Request should be of type VQLCollectorArgs")
}

if arg.Query == nil {
return responder.RaiseError("Query should be specified.")
}

vql, err := vfilter.Parse(*arg.Query)
if err != nil {
responder.RaiseError(err.Error())
}

scope := vql_subsystem.MakeScope()
output_chan := vql.Eval(ctx, scope)
result := []vfilter.Row{}
for row := range output_chan {
result = append(result, row)
}

s, err := json.MarshalIndent(result, "", " ")
if err != nil {
return responder.RaiseError(err.Error())
}

responder.AddResponse(&actions_proto.VQLResponse{
Response: proto.String(string(s)),
})

return responder.Return()
}
49 changes: 49 additions & 0 deletions bin/velociraptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package main

import (
"gopkg.in/alecthomas/kingpin.v2"
"www.velocidex.com/golang/velociraptor/config"
"www.velocidex.com/golang/velociraptor/http_comms"
"www.velocidex.com/golang/velociraptor/context"
"www.velocidex.com/golang/velociraptor/crypto"
"www.velocidex.com/golang/velociraptor/executor"
)

var (
config_path = kingpin.Arg("config", "The client's config file.").Required().String()
)


func main() {
kingpin.Parse()

ctx := context.Background()
config, err := config.LoadConfig(*config_path)
if err != nil {
kingpin.FatalIfError(err, "Unable to load config file")
}
ctx.Config = *config
manager, err := crypto.NewClientCryptoManager(
&ctx, []byte(config.Client_private_key))
if err != nil {
kingpin.FatalIfError(err, "Unable to parse config file")
}

exe, err := executor.NewClientExecutor(&ctx)
if err != nil {
kingpin.FatalIfError(err, "Can not create executor.")
}

comm, err := http_comms.NewHTTPCommunicator(
ctx,
manager,
exe,
config.Client_server_urls,
)
if err != nil {
kingpin.FatalIfError(err, "Can not create HTTPCommunicator.")
}

comm.Run()

}
12 changes: 6 additions & 6 deletions cmd/vraptor.go → bin/vraptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/olekukonko/tablewriter"
"gopkg.in/alecthomas/kingpin.v2"
"os"
"www.velocidex.com/golang/velociraptor"
vql_subsystem "www.velocidex.com/golang/velociraptor/vql"
"www.velocidex.com/golang/vfilter"
)

Expand All @@ -16,12 +16,12 @@ var (
queries = query.Arg("query", "The VQL Query to run.").Required().Strings()
format = query.Flag("format", "Output format to use.").Default("json").Enum("text", "json")

explain = kingpin.Command("explain", "Explain the output from a plugun")
explain_plugin = explain.Arg("plugun", "Plugin to explain").Required().String()
explain = kingpin.Command("explain", "Explain the output from a plugin")
explain_plugin = explain.Arg("plugin", "Plugin to explain").Required().String()
)

func outputJSON(vql *vfilter.VQL) {
scope := velociraptor.MakeScope()
scope := vql_subsystem.MakeScope()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand All @@ -38,7 +38,7 @@ func outputJSON(vql *vfilter.VQL) {
}

func evalQuery(vql *vfilter.VQL) {
scope := velociraptor.MakeScope()
scope := vql_subsystem.MakeScope()
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -74,7 +74,7 @@ func evalQuery(vql *vfilter.VQL) {

func doExplain(plugin string) {
type_map := make(vfilter.TypeMap)
scope := velociraptor.MakeScope()
scope := vql_subsystem.MakeScope()
if pslist_info, pres := scope.Info(&type_map, plugin); pres {
vfilter.Debug(pslist_info)
vfilter.Debug(type_map)
Expand Down
14 changes: 14 additions & 0 deletions context/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package context

import (
"context"
"time"
"www.velocidex.com/golang/velociraptor/config"
)

Expand All @@ -21,6 +22,19 @@ func (self *Context) Done() <- chan struct{} {
return self.ctx.Done()
}

func (self *Context)Deadline() (deadline time.Time, ok bool) {
t, ok := self.ctx.Deadline()
return t,ok
}

func (self *Context) Err() error {
return self.ctx.Err()
}

func (self *Context) Value(key interface{}) interface{} {
return self.ctx.Value(key)
}

func Background() Context {
return Context{
ctx: context.Background(),
Expand Down
3 changes: 2 additions & 1 deletion glob/glob.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"regexp"
"strconv"
"strings"
"www.velocidex.com/golang/velociraptor/utils"
)

// The algorithm in this file is based on the Rekall algorithm here:
Expand Down Expand Up @@ -126,7 +127,7 @@ func (self *Globber) _brace_expansion(pattern string, result *[]string) {
for _, item := range middle {
self._brace_expansion(left+item+right, result)
}
} else if !in_string(result, pattern) {
} else if !utils.InString(result, pattern) {
*result = append(*result, pattern)
}
}
Expand Down
11 changes: 0 additions & 11 deletions utils.go

This file was deleted.

4 changes: 2 additions & 2 deletions glob/utils.go → utils/utils.go
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package glob
package utils

func in_string(hay *[]string, needle string) bool {
func InString(hay *[]string, needle string) bool {
for _, x := range *hay {
if x == needle {
return true
Expand Down
2 changes: 1 addition & 1 deletion filesystem.go → vql/filesystem.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package velociraptor
package vql

import (
"context"
Expand Down
2 changes: 1 addition & 1 deletion info.go → vql/info.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package velociraptor
package vql

import (
"github.com/shirou/gopsutil/host"
Expand Down
7 changes: 4 additions & 3 deletions process.go → vql/process.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package velociraptor
package vql

import (
"github.com/shirou/gopsutil/process"
"www.velocidex.com/golang/vfilter"
"www.velocidex.com/golang/velociraptor/utils"
)

// Block potentially dangerous methods.
Expand All @@ -23,7 +24,7 @@ func (self _ProcessFieldImpl) Associative(
scope *vfilter.Scope, a vfilter.Any, b vfilter.Any) (vfilter.Any, bool) {
field := b.(string)

if in_string(&_BlockedMembers, field) {
if utils.InString(&_BlockedMembers, field) {
return false, true
}

Expand All @@ -35,7 +36,7 @@ func (self _ProcessFieldImpl) GetMembers(scope *vfilter.Scope, a vfilter.Any) []
var result []string

for _, item := range (vfilter.DefaultAssociative{}).GetMembers(scope, a) {
if !in_string(&_BlockedMembers, item) {
if !utils.InString(&_BlockedMembers, item) {
result = append(result, item)
}
}
Expand Down
2 changes: 1 addition & 1 deletion users.go → vql/users.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package velociraptor
package vql

import (
"github.com/shirou/gopsutil/host"
Expand Down
5 changes: 2 additions & 3 deletions velociraptor.go → vql/vql.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
/*
Velociraptor is a tool for collecting host based state information
The VQL subsystem allows for collecting host based state information
using Velocidex Query Language (VQL) queries.
The primary use case for Velociraptor is for incident
response/detection and host based inventory management.
*/

package velociraptor
package vql

import (
"www.velocidex.com/golang/vfilter"
Expand Down

0 comments on commit 6512b9f

Please sign in to comment.