Skip to content

Commit

Permalink
Added stand alone GUI command. (Velocidex#580)
Browse files Browse the repository at this point in the history
* Added stand alone GUI command.

Now running:

```
velociraptor.exe gui
```

Will do everything automatigally - create a new config, and open the
browser to the welcome page.
  • Loading branch information
scudette authored Aug 22, 2020
1 parent 4fcd30c commit 44ca649
Show file tree
Hide file tree
Showing 37 changed files with 941 additions and 371 deletions.
16 changes: 15 additions & 1 deletion api/reports.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package api

import (
"fmt"
"strings"

errors "github.com/pkg/errors"
Expand Down Expand Up @@ -41,9 +42,22 @@ func getReport(ctx context.Context,

var template_data string

if in.Type == "" {
definition, pres := repository.Get("Custom." + in.Artifact)
if !pres {
definition, pres = repository.Get(in.Artifact)
if pres {
for _, report := range definition.Reports {
in.Type = strings.ToUpper(report.Type)
}
}
}
}

switch in.Type {
default:
return nil, errors.New("Report type not supported")
return nil, errors.New(fmt.Sprintf(
"Report type %v not supported", in.Type))

// A CLIENT artifact report is a specific artifact
// collected from a client.
Expand Down
26 changes: 20 additions & 6 deletions artifacts/definitions/Generic/Utils/FetchBinary.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ sources:
// Try to get info from the ToolInfo parameter.
a={SELECT get(field="Tool_" + ToolName + "_HASH", item=ToolInfo) AS ToolHash,
get(field="Tool_" + ToolName + "_FILENAME", item=ToolInfo) AS ToolFilename,
get(field="Tool_" + ToolName + "_URL", item=ToolInfo) AS ToolURL
get(field="Tool_" + ToolName + "_URL", item=ToolInfo) AS ToolURL,
get(field="Tool_" + ToolName + "_PATH", item=ToolInfo) AS ToolPath
FROM scope() WHERE ToolFilename},
// Failing this - get it from the scope()
b={SELECT get(field="Tool_" + ToolName + "_HASH", item=scope()) AS ToolHash,
get(field="Tool_" + ToolName + "_FILENAME", item=scope()) AS ToolFilename,
get(field="Tool_" + ToolName + "_URL", item=scope()) AS ToolURL
get(field="Tool_" + ToolName + "_URL", item=scope()) AS ToolURL,
get(field="Tool_" + ToolName + "_PATH", item=ToolInfo) AS ToolPath
FROM scope() WHERE ToolFilename},
// Failing this - try to get it from the inventory service directly.
Expand All @@ -64,7 +66,18 @@ sources:
)
// Where we should save the file.
LET ToolPath <= SELECT path_join(components=[(binpath[0]).Path, (args[0]).ToolFilename]) AS Path FROM scope()
LET ToolPath <= SELECT path_join(components=[
(binpath[0]).Path, (args[0]).ToolFilename]) AS Path FROM scope()
// Support tools locally served from disk
LET local_file =
SELECT hash(path=(args[0]).ToolPath) as Hash,
(args[0]).ToolFilename AS Name,
"Downloaded" AS DownloadStatus,
(args[0]).ToolPath AS FullPath
FROM scope()
WHERE (args[0]).ToolPath AND
log(message="File served from " + (args[0]).ToolPath)
// Download the file from the binary URL and store in the local
// binary cache.
Expand Down Expand Up @@ -101,12 +114,13 @@ sources:
// have to download the file we sleep for a random time to
// stagger server bandwidth load.
SELECT * FROM switch(
a=existing,
b={
a=local_file,
b=existing,
c={
SELECT rand(range=atoi(string=SleepDuration)) AS timeout
FROM scope()
WHERE args AND (args[0]).ToolURL AND
log(message=format(format='Sleeping %v Seconds',
args=[timeout])) AND sleep(time=timeout) AND FALSE
},
c=download)
d=download)
17 changes: 17 additions & 0 deletions artifacts/definitions/Server/Internal/Welcome.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Server.Internal.Welcome

reports:
- type: CLIENT
template: |
<div class="row dashboard ">
<div class="card col-10">
<img src="https://www.velocidex.com/images/logos/logo.svg" class="card-img-top">
<div class="card-body">
# Welcome to Velociraptor!
## Common tasks:
* <a href="/app.html#/server_artifacts">Building an Offline Collector</a>
</div></div></div>
290 changes: 150 additions & 140 deletions artifacts/proto/artifact.pb.go

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions artifacts/proto/artifact.proto
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ message Tool {
// the url above.
string serve_url = 8;

// Only valid for local dummy inventory.
string serve_path = 12;

// A filestore path where the file can be downloaded from - if
// served locally.
string filestore_path = 4;
Expand Down
9 changes: 5 additions & 4 deletions artifacts/testdata/server/testcases/binary_blobs.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ SELECT * FROM switch( b={SELECT Complete FROM execve(argv=["rm", "-f", "/tmp/aut
"inventory_add(tool=\"WinPmem\", url=\"https://storage.googleapis.com/go.velocidex.com/winpmem_v3.3.rc3.exe\", filename=\"winpmem_v3.3.rc3.exe\")": {
"name": "WinPmem",
"url": "https://storage.googleapis.com/go.velocidex.com/winpmem_v3.3.rc3.exe",
"filename": "winpmem_v3.3.rc3.exe",
"admin_override": true
"admin_override": true,
"filename": "winpmem_v3.3.rc3.exe"
}
}
]SELECT * FROM inventory() WHERE name =~ "WinPmem"[
{
"name": "WinPmem",
"url": "https://storage.googleapis.com/go.velocidex.com/winpmem_v3.3.rc3.exe",
"serve_url": "",
"github_project": "",
"github_asset_regex": "",
"serve_locally": false,
"admin_override": true,
"serve_url": "",
"serve_path": "",
"filestore_path": "351b4f6d59a4266cc7a2eab9cedf959eb6a4c924746044e6edeabdd1a477643e",
"filename": "winpmem_v3.3.rc3.exe",
"hash": "",
"admin_override": true,
"materialize": false
}
]LET ToolInfo <= dict( Tool_WinPmem_URL="https://github.com/Velocidex/c-aff4/releases/download/v3.3.rc3/winpmem_v3.3.rc3.exe", Tool_WinPmem_FILENAME="winpmem_v3.3.rc3.exe", Tool_WinPmem_HASH="319f6c714d682505157cf72aa928c94ada3c839fb8eb0e503d8770624e897318")[]SELECT DownloadStatus, Hash FROM Artifact.Generic.Utils.FetchBinary( ToolName="WinPmem", SleepDuration=0, ToolInfo=ToolInfo)[
Expand Down
12 changes: 6 additions & 6 deletions artifacts/testdata/server/testcases/tools.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/go.velocidex.com/autorunsc.exe', hash='083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153', filename='autorunsc_x64.exe')": {
"name": "Autorun_amd64",
"url": "https://storage.googleapis.com/go.velocidex.com/autorunsc.exe",
"admin_override": true,
"filename": "autorunsc_x64.exe",
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153",
"admin_override": true
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153"
}
}
]SELECT inventory_get(tool='Autorun_amd64') FROM scope()[
Expand All @@ -22,9 +22,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"name": "Autorun_amd64",
"url": "https://storage.googleapis.com/go.velocidex.com/autorunsc.exe",
"serve_locally": true,
"admin_override": true,
"filename": "autorunsc_x64.exe",
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153",
"admin_override": true
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153"
}
}
]SELECT inventory_get(tool='Autorun_amd64') FROM scope()[
Expand All @@ -40,10 +40,10 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"inventory_add(tool=\"FooBar\", file=srcDir + \"/artifacts/testdata/files/yara_test.txt\")": {
"name": "FooBar",
"serve_locally": true,
"admin_override": true,
"filestore_path": "1c21ee4d8609f81482dc0a78c641e4586488a9fd562ee28eec25e448a9d0b2e1",
"filename": "yara_test.txt",
"hash": "f03278c10a41adcc97f24a612a680e7aa43efb461b337fef3d2a3d47b51e77bb",
"admin_override": true
"hash": "f03278c10a41adcc97f24a612a680e7aa43efb461b337fef3d2a3d47b51e77bb"
}
}
]SELECT inventory_get(tool="FooBar") FROM scope()[
Expand Down
4 changes: 2 additions & 2 deletions artifacts/testdata/windows/autoexec.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ SELECT inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/g
"inventory_add(tool='Autorun_amd64', url='https://storage.googleapis.com/go.velocidex.com/autorunsc.exe', hash='083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153', filename='autorunsc_x64.exe')": {
"name": "Autorun_amd64",
"url": "https://storage.googleapis.com/go.velocidex.com/autorunsc.exe",
"admin_override": true,
"filename": "autorunsc_x64.exe",
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153",
"admin_override": true
"hash": "083d7eee4ed40a3e5a35675503b0b6be0cb627b4cb1009d185a558a805f64153"
}
}
]SELECT * FROM Artifact.Windows.Sysinternals.Autoruns( AutorunArgs='-nobanner -accepteula -a b -c *', ToolInfo=inventory_get(tool='Autorun_amd64')) WHERE Company =~ 'Microsoft'[
Expand Down
1 change: 1 addition & 0 deletions bin/artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ func doArtifactCollect() {
kingpin.FatalIfError(err, "Load Config ")

sm, err := startEssentialServices(config_obj)
kingpin.FatalIfError(err, "Load Config ")
defer sm.Close()

collect_args := ordereddict.NewDict()
Expand Down
68 changes: 68 additions & 0 deletions bin/browser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package browser provides utilities for interacting with users' browsers.
// Comes from https://raw.githubusercontent.com/golang/go/master/src/cmd/internal/browser/browser.go
package main

import (
"os"
"os/exec"
"runtime"
"time"
)

// Commands returns a list of possible commands to use to open a url.
func Commands() [][]string {
var cmds [][]string
if exe := os.Getenv("BROWSER"); exe != "" {
cmds = append(cmds, []string{exe})
}
switch runtime.GOOS {
case "darwin":
cmds = append(cmds, []string{"/usr/bin/open"})
case "windows":
cmds = append(cmds, []string{"cmd", "/c", "start"})
default:
if os.Getenv("DISPLAY") != "" {
// xdg-open is only for use in a desktop environment.
cmds = append(cmds, []string{"xdg-open"})
}
}
cmds = append(cmds,
[]string{"chrome"},
[]string{"google-chrome"},
[]string{"chromium"},
[]string{"firefox"},
)
return cmds
}

// Open tries to open url in a browser and reports whether it succeeded.
func OpenBrowser(url string) bool {
for _, args := range Commands() {
cmd := exec.Command(args[0], append(args[1:], url)...)
if cmd.Start() == nil && appearsSuccessful(cmd, 3*time.Second) {
return true
}
}
return false
}

// appearsSuccessful reports whether the command appears to have run successfully.
// If the command runs longer than the timeout, it's deemed successful.
// If the command runs within the timeout, it's deemed successful if it exited cleanly.
func appearsSuccessful(cmd *exec.Cmd, timeout time.Duration) bool {
errc := make(chan error, 1)
go func() {
errc <- cmd.Wait()
}()

select {
case <-time.After(timeout):
return true
case err := <-errc:
return err == nil
}
}
13 changes: 10 additions & 3 deletions bin/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"www.velocidex.com/golang/velociraptor/executor"
"www.velocidex.com/golang/velociraptor/http_comms"
logging "www.velocidex.com/golang/velociraptor/logging"
"www.velocidex.com/golang/velociraptor/services"
"www.velocidex.com/golang/velociraptor/utils"
)

Expand Down Expand Up @@ -94,7 +95,15 @@ func RunClient(
// Wait for the comms to properly start before we begin the
// services. If services need to communicate with the server
// they will deadlock otherwise.
executor.StartServices(ctx, wg, config_obj, manager.ClientId, exe)
sm := services.NewServiceManager(ctx, config_obj)
defer sm.Close()

err = executor.StartServices(sm, manager.ClientId, exe)
if err != nil {
return
}

wg.Wait()
}

func init() {
Expand All @@ -106,8 +115,6 @@ func init() {

RunClient(ctx, wg, config_path)

wg.Wait()

return true
}
return false
Expand Down
Loading

0 comments on commit 44ca649

Please sign in to comment.