Skip to content

Commit

Permalink
Added more client actions and VQL plugins.
Browse files Browse the repository at this point in the history
  • Loading branch information
scudette committed May 6, 2018
1 parent bc4044a commit 2be5b59
Show file tree
Hide file tree
Showing 35 changed files with 669 additions and 269 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
vendor/
*~
*~
emacs.desktop
3 changes: 3 additions & 0 deletions actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ func GetClientActionsMap() map[string]ClientAction {
result["HashBuffer"] = &HashBuffer{}
result["TransferBuffer"] = &TransferBuffer{}
result["VQLClientAction"] = &VQLClientAction{}
result["GetHostname"] = &GetHostname{}
result["GetPlatformInfo"] = &GetPlatformInfo{}

return result
}
54 changes: 54 additions & 0 deletions actions/admin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package actions

import (
"github.com/Showmax/go-fqdn"
"github.com/golang/protobuf/proto"
"github.com/shirou/gopsutil/host"
"runtime"
"strings"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
"www.velocidex.com/golang/velociraptor/context"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
)

type GetHostname struct{}

func (self *GetHostname) Run(
ctx *context.Context,
msg *crypto_proto.GrrMessage) []*crypto_proto.GrrMessage {
responder := NewResponder(msg)

info, err := host.Info()
if err != nil {
return responder.RaiseError(err.Error())
}
responder.AddResponse(&actions_proto.DataBlob{
String_: proto.String(info.Hostname),
})
return responder.Return()
}

type GetPlatformInfo struct{}

func (self *GetPlatformInfo) Run(
ctx *context.Context,
msg *crypto_proto.GrrMessage) []*crypto_proto.GrrMessage {
responder := NewResponder(msg)

info, err := host.Info()
if err != nil {
return responder.RaiseError(err.Error())
}
responder.AddResponse(&actions_proto.Uname{
System: proto.String(strings.Title(info.OS)),
Fqdn: proto.String(fqdn.Get()),
Architecture: proto.String(runtime.GOARCH),
Release: proto.String(info.Platform),
Version: proto.String(info.PlatformVersion),
Kernel: proto.String(info.KernelVersion),
Pep425Tag: proto.String("Golang_" + info.OS + "_" +
info.Platform + "_" + info.PlatformVersion),
})

return responder.Return()
}
41 changes: 41 additions & 0 deletions actions/admin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package actions

import (
"github.com/shirou/gopsutil/host"
assert "github.com/stretchr/testify/assert"
"strings"
"testing"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
"www.velocidex.com/golang/velociraptor/context"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
)

func TestGetHostname(t *testing.T) {
ctx := context.Background()
get_hostname := GetHostname{}
arg, err := NewRequest(&crypto_proto.GrrMessage{})
if err != nil {
t.Fatal(err)
}

responses := get_hostname.Run(&ctx, arg)
assert.Equal(t, len(responses), 2)
response := ExtractGrrMessagePayload(responses[0]).(*actions_proto.DataBlob)
info, _ := host.Info()
assert.Equal(t, info.Hostname, *response.String_)
}

func TestGetPlatformInfo(t *testing.T) {
ctx := context.Background()
get_platform_info := GetPlatformInfo{}
arg, err := NewRequest(&crypto_proto.GrrMessage{})
if err != nil {
t.Fatal(err)
}

responses := get_platform_info.Run(&ctx, arg)
assert.Equal(t, len(responses), 2)
response := ExtractGrrMessagePayload(responses[0]).(*actions_proto.Uname)
info, _ := host.Info()
assert.Equal(t, strings.Title(info.OS), *response.System)
}
6 changes: 3 additions & 3 deletions actions/common.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package actions

import (
"www.velocidex.com/golang/velociraptor/context"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
"www.velocidex.com/golang/velociraptor/context"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
)

Expand All @@ -13,9 +13,9 @@ func (self *GetClientInfo) Run(
args *crypto_proto.GrrMessage) []*crypto_proto.GrrMessage {
responder := NewResponder(args)
info := &actions_proto.ClientInformation{
ClientName: &ctx.Config.Client_name,
ClientName: &ctx.Config.Client_name,
ClientVersion: &ctx.Config.Client_version,
Labels: ctx.Config.Client_labels,
Labels: ctx.Config.Client_labels,
}
responder.AddResponse(info)
return responder.Return()
Expand Down
10 changes: 3 additions & 7 deletions actions/common_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package actions

import (
"testing"
"github.com/stretchr/testify/assert"
"www.velocidex.com/golang/velociraptor/context"
"testing"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
"www.velocidex.com/golang/velociraptor/context"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
utils "www.velocidex.com/golang/velociraptor/testing"
)


func TestClientInfo(t *testing.T) {
args := crypto_proto.GrrMessage{}
plugin := GetClientInfo{}
Expand All @@ -18,9 +16,7 @@ func TestClientInfo(t *testing.T) {
assert.Equal(t, len(responses), 2)
assert.Equal(t, *responses[1].ArgsRdfName, "GrrStatus")

result := ExtractGrrMessagePayload(responses[0]).(
*actions_proto.ClientInformation)
result := ExtractGrrMessagePayload(responses[0]).(*actions_proto.ClientInformation)

assert.Equal(t, *result.ClientName, "velociraptor")
utils.Debug(result)
}
34 changes: 4 additions & 30 deletions actions/files.go
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
package actions

import (
"syscall"
"os"
"io/ioutil"
"github.com/golang/protobuf/proto"
"www.velocidex.com/golang/velociraptor/context"
"io/ioutil"
"os"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
"www.velocidex.com/golang/velociraptor/context"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
)

func buildStatEntryFromFileInfo(stat os.FileInfo) *actions_proto.StatEntry {
sys_stat, ok := stat.Sys().(*syscall.Stat_t)
if ok {
stat_reply := &actions_proto.StatEntry{
StMode: proto.Uint64(uint64(sys_stat.Mode)),
StIno: proto.Uint32(uint32(sys_stat.Ino)),
StDev: proto.Uint32(uint32(sys_stat.Dev)),
StNlink: proto.Uint32(uint32(sys_stat.Nlink)),
StUid: &sys_stat.Uid,
StGid: &sys_stat.Gid,
StSize: proto.Uint64(uint64(sys_stat.Size)),
StAtime: proto.Uint64(uint64(sys_stat.Atim.Sec)),
StMtime: proto.Uint64(uint64(sys_stat.Mtim.Sec)),
StCtime: proto.Uint64(uint64(sys_stat.Ctim.Sec)),
StBlocks: proto.Uint32(uint32(sys_stat.Blocks)),
StBlksize: proto.Uint32(uint32(sys_stat.Blksize)),
}
return stat_reply
}

return nil
}


type StatFile struct{}

func (self *StatFile) Run(
Expand Down Expand Up @@ -62,7 +37,6 @@ func (self *StatFile) Run(
return responder.Return()
}


type ListDirectory struct{}

func (self *ListDirectory) Run(
Expand Down Expand Up @@ -92,7 +66,7 @@ func (self *ListDirectory) Run(
last := LastPathspec(new_pathspec)
last.NestedPath = &actions_proto.PathSpec{
Pathtype: actions_proto.PathSpec_OS.Enum(),
Path: proto.String(stat.Name()),
Path: proto.String(stat.Name()),
}
stat_reply.Pathspec = new_pathspec
responder.AddResponse(stat_reply)
Expand Down
31 changes: 31 additions & 0 deletions actions/files_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package actions

import (
"github.com/golang/protobuf/proto"
"os"
"syscall"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
)

func buildStatEntryFromFileInfo(stat os.FileInfo) *actions_proto.StatEntry {
sys_stat, ok := stat.Sys().(*syscall.Stat_t)
if ok {
stat_reply := &actions_proto.StatEntry{
StMode: proto.Uint64(uint64(sys_stat.Mode)),
StIno: proto.Uint32(uint32(sys_stat.Ino)),
StDev: proto.Uint32(uint32(sys_stat.Dev)),
StNlink: proto.Uint32(uint32(sys_stat.Nlink)),
StUid: &sys_stat.Uid,
StGid: &sys_stat.Gid,
StSize: proto.Uint64(uint64(sys_stat.Size)),
StAtime: proto.Uint64(uint64(sys_stat.Atim.Sec)),
StMtime: proto.Uint64(uint64(sys_stat.Mtim.Sec)),
StCtime: proto.Uint64(uint64(sys_stat.Ctim.Sec)),
StBlocks: proto.Uint32(uint32(sys_stat.Blocks)),
StBlksize: proto.Uint32(uint32(sys_stat.Blksize)),
}
return stat_reply
}

return nil
}
10 changes: 10 additions & 0 deletions actions/files_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package actions

import (
"os"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
)

func buildStatEntryFromFileInfo(stat os.FileInfo) *actions_proto.StatEntry {
return nil
}
13 changes: 6 additions & 7 deletions actions/fingerprint.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package actions

import (
"os"
"crypto/sha1"
"crypto/sha256"
"github.com/golang/protobuf/proto"
"www.velocidex.com/golang/velociraptor/context"
"os"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
"www.velocidex.com/golang/velociraptor/context"
crypto_proto "www.velocidex.com/golang/velociraptor/crypto/proto"
)

type HashBuffer struct{}

func (self *HashBuffer) Run(
ctx *context.Context,
msg *crypto_proto.GrrMessage) []*crypto_proto.GrrMessage {
Expand Down Expand Up @@ -46,17 +47,15 @@ func (self *HashBuffer) Run(
hash := sha256.Sum256(buffer)

responder.AddResponse(&actions_proto.BufferReference{
Offset: arg.Offset,
Length: proto.Uint64(uint64(bytes_read)),
Data: hash[:],
Offset: arg.Offset,
Length: proto.Uint64(uint64(bytes_read)),
Data: hash[:],
Pathspec: arg.Pathspec,
})

return responder.Return()
}



type HashFile struct{}

func (self *HashFile) Run(
Expand Down
23 changes: 14 additions & 9 deletions actions/fingerprint_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
package actions

import (
"github.com/golang/protobuf/proto"
assert "github.com/stretchr/testify/assert"
"os"
"testing"
_ "github.com/stretchr/testify/assert"
"github.com/golang/protobuf/proto"
"www.velocidex.com/golang/velociraptor/context"
actions_proto "www.velocidex.com/golang/velociraptor/actions/proto"
utils "www.velocidex.com/golang/velociraptor/testing"
"www.velocidex.com/golang/velociraptor/context"
)


func TestHashFile(t *testing.T) {
cwd, _ := os.Getwd()
pathspec := &actions_proto.PathSpec{
Path: proto.String(cwd),
Path: proto.String(cwd),
Pathtype: actions_proto.PathSpec_OS.Enum(),
NestedPath: &actions_proto.PathSpec{
Path: proto.String("test_data"),
Path: proto.String("test_data"),
Pathtype: actions_proto.PathSpec_OS.Enum(),
NestedPath: &actions_proto.PathSpec{
Path: proto.String("hello.txt"),
Path: proto.String("hello.txt"),
Pathtype: actions_proto.PathSpec_OS.Enum(),
},
},
Expand All @@ -46,5 +44,12 @@ func TestHashFile(t *testing.T) {
t.Fatal(err)
}
responses := hash_file.Run(&ctx, arg)
utils.Debug(responses)
assert.Equal(t, len(responses), 2)
response := ExtractGrrMessagePayload(responses[0]).(*actions_proto.FingerprintResponse)

assert.Equal(t, response.Hash.Sha256,
[]uint8([]byte{0xf5, 0x44, 0xea, 0x51, 0xaa, 0x45, 0x9, 0x89,
0x7, 0x1e, 0xc7, 0x95, 0xc1, 0xad, 0x45, 0x36, 0xdb,
0xb3, 0x7b, 0x9c, 0xcd, 0x22, 0xec, 0xaa, 0x39, 0x92,
0x33, 0xdb, 0xc1, 0x9d, 0xdb, 0xc0}))
}
Loading

0 comments on commit 2be5b59

Please sign in to comment.