Compare commits

...
Author SHA1 Message Date
rkervella afe6c88f83 Make vim mode configurable via client settings 2022-07-15 12:18:07 -07:00
Joe 361a4e5112 Merge pull request #743 from BishopFox/go/v1.18.4
Update to Go v1.18.4 and bump grumble
2022-07-15 12:24:30 -05:00
moloch-- 4e7093671c Update to Go v1.18.4 and bump grumble 2022-07-15 09:44:52 -07:00
16 changed files with 172 additions and 56 deletions

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
FROM golang:1.18.3
FROM golang:1.18.4
#
# IMPORTANT: This Dockerfile is used for testing, I do not recommend deploying
+2
View File
@@ -35,6 +35,7 @@ type ClientSettings struct {
BeaconAutoResults bool `json:"beacon_autoresults"`
SmallTermWidth int `json:"small_term_width"`
AlwaysOverflow bool `json:"always_overflow"`
VimMode bool `json:"vim_mode"`
}
// LoadSettings - Load the client settings from disk
@@ -59,6 +60,7 @@ func defaultSettings() *ClientSettings {
BeaconAutoResults: true,
SmallTermWidth: 170,
AlwaysOverflow: false,
VimMode: false,
}
}
+1
View File
@@ -47,6 +47,7 @@ func SettingsCmd(ctx *grumble.Context, con *console.SliverConsoleClient) {
tw.AppendRow(table.Row{"Beacon Auto Results", con.Settings.BeaconAutoResults, "Automatically display beacon results when tasks complete"})
tw.AppendRow(table.Row{"Small Term Width", con.Settings.SmallTermWidth, "Omit some table columns when terminal width is less than this value"})
tw.AppendRow(table.Row{"Always Overflow", con.Settings.AlwaysOverflow, "Disable table pagination"})
tw.AppendRow(table.Row{"Vim mode", con.Settings.VimMode, "Navigation mode, vim style"})
con.Printf("%s\n", tw.Render())
}
+1
View File
@@ -113,6 +113,7 @@ func Start(rpc rpcpb.SliverRPCClient, bindCmds BindCmds, extraCmds BindCmds, isS
HelpHeadlineColor: color.New(),
HelpHeadlineUnderline: true,
HelpSubCommands: true,
VimMode: settings.VimMode,
}),
Rpc: rpc,
ActiveTarget: &ActiveTarget{
+1 -1
View File
@@ -20,7 +20,7 @@ set -e
# Creates the static go asset archives
GO_VER="1.18.3"
GO_VER="1.18.4"
GARBLE_VER="1.18.0"
GO_ARCH_1="amd64"
+1 -1
View File
@@ -2,7 +2,7 @@ module github.com/bishopfox/sliver
go 1.17
replace github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.4
replace github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.6
require (
github.com/AlecAivazis/survey/v2 v2.2.2
+2 -2
View File
@@ -648,8 +648,8 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170308212314-bb9b5e7adda9/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/moloch--/grumble v1.1.4 h1:/utJ405bbS2/Kx73XE03zqP1a3ZE9p3vqD3ePvsrG8o=
github.com/moloch--/grumble v1.1.4/go.mod h1:r7j3ShNy5EmOsegRD2DzTutIaGiLiA3M5yBTXXeLwcs=
github.com/moloch--/grumble v1.1.6 h1:FjPkuGOIwGL8nGkEH0EegnQgsl6Rn0R0fhBW/kcA0s8=
github.com/moloch--/grumble v1.1.6/go.mod h1:r7j3ShNy5EmOsegRD2DzTutIaGiLiA3M5yBTXXeLwcs=
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945 h1:m3yCfV8Vqp4MF1B+gPPjbjINdufl0UXqyYplE0aGhx8=
github.com/moloch--/memmod v0.0.0-20211120144554-8b37cc654945/go.mod h1:1grVt4HaTofvhFUZYtofeRbGXfczNwCie9MYoM4lP/o=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
+1 -1
View File
@@ -109,7 +109,7 @@ func (e *ECCKeyPair) PrivateBase64() string {
return base64.RawStdEncoding.EncodeToString(e.Private[:])
}
// RandomeECCKeyPair - Generate a random Curve 25519 key pair
// RandomECCKeyPair - Generate a random Curve 25519 key pair
func RandomECCKeyPair() (*ECCKeyPair, error) {
public, private, err := box.GenerateKey(rand.Reader)
if err != nil {
-1
View File
@@ -894,7 +894,6 @@ const (
// GoPrivate - The default Go private arg to garble when obfuscation is enabled.
// Wireguard dependencies prevent the use of wildcard github.com/* and golang.org/*.
// The current packages below aren't definitive and need to be tidied up.
// GoPrivate = "github.com/bishopfox/*,github.com/Microsoft/*,github.com/burntsushi/*,github.com/kbinani/*,github.com/lxn/*,github.com/golang/*,github.com/shm/*,github.com/lesnuages/*"
wgGoPrivate = "github.com/*,golang.org/*,golang.zx2c4.com/*,google.golang.org/*"
allGoPrivate = "*"
)
+45 -1
View File
@@ -81,11 +81,55 @@ Builtin support for multiple lines.
... command
```
## Separate flags and args specifically
If you need to pass a flag-like value as positional argument, you can do so by using a double dash:
`>>> command --flag1=something -- --myPositionalArg`
## Remote shell access with readline
By calling RunWithReadline() rather than Run() you can pass instance of readline.Instance.
One of interesting usages is having a possibility of remote access to your shell:
```go
handleFunc := func(rl *readline.Instance) {
var app = grumble.New(&grumble.Config{
// override default interrupt handler to avoid remote shutdown
InterruptHandler: func(a *grumble.App, count int) {
// do nothing
},
// your usual grumble configuration
})
// add commands
app.RunWithReadline(rl)
}
cfg := &readline.Config{}
readline.ListenRemote("tcp", ":5555", cfg, handleFunc)
```
In the client code just use readline built in DialRemote function:
```go
if err := readline.DialRemote("tcp", ":5555"); err != nil {
fmt.Errorf("An error occurred: %s \n", err.Error())
}
```
## Samples
Check out the [sample directory](/sample) for some detailed examples.
The [grml project](https://github.com/desertbit/grml) uses grumble.
## Projects using Grumble
- grml - A simple build automation tool written in Go: https://github.com/desertbit/grml
- orbit - A RPC-like networking backend written in Go: https://github.com/desertbit/orbit
## Known issues
- Windows unicode not fully supported ([issue](https://github.com/desertbit/grumble/issues/48))
## Additional Useful Packages
+61 -31
View File
@@ -80,6 +80,9 @@ func New(c *Config) (a *App) {
printCommandHelp: defaultPrintCommandHelp,
interruptHandler: defaultInterruptHandler,
}
if c.InterruptHandler != nil {
a.interruptHandler = c.InterruptHandler
}
// Register the builtin flags.
a.flags.Bool("h", "help", false, "display help")
@@ -118,6 +121,7 @@ func (a *App) Config() *Config {
}
// Commands returns the app's commands.
// Access is not thread-safe. Only access during command execution.
func (a *App) Commands() *Commands {
return &a.commands
}
@@ -277,8 +281,21 @@ func (a *App) RunCommand(args []string) error {
// Run the application and parse the command line arguments.
// This method blocks.
func (a *App) Run() (err error) {
// Create the readline instance.
config := &readline.Config{}
a.setReadlineDefaults(config)
rl, err := readline.NewEx(config)
if err != nil {
return err
}
return a.RunWithReadline(rl)
}
func (a *App) RunWithReadline(rl *readline.Instance) (err error) {
defer a.Close()
a.setReadlineDefaults(rl.Config)
// Sort all commands by their name.
a.commands.SortRecursive()
@@ -323,6 +340,7 @@ func (a *App) Run() (err error) {
a.printCommandHelp(a, cmd, a.isShell)
return nil
},
isBuiltin: true,
}, false)
// Check if help should be displayed.
@@ -331,6 +349,30 @@ func (a *App) Run() (err error) {
return nil
}
// Add shell builtin commands.
// Ensure to add all commands before running the init hook.
// If the init hook does something with the app commands, then these should also be included.
if a.isShell {
a.AddCommand(&Command{
Name: "exit",
Help: "exit the shell",
Run: func(c *Context) error {
c.Stop()
return nil
},
isBuiltin: true,
})
a.AddCommand(&Command{
Name: "clear",
Help: "clear the screen",
Run: func(c *Context) error {
readline.ClearScreen(a.rl)
return nil
},
isBuiltin: true,
})
}
// Run the init hook.
if a.initHook != nil {
err = a.initHook(a, a.flagMap)
@@ -344,36 +386,8 @@ func (a *App) Run() (err error) {
return a.RunCommand(args)
}
// Add shell builtin commands.
a.AddCommand(&Command{
Name: "exit",
Help: "exit the shell",
Run: func(c *Context) error {
c.Stop()
return nil
},
})
a.AddCommand(&Command{
Name: "clear",
Help: "clear the screen",
Run: func(c *Context) error {
readline.ClearScreen(a.rl)
return nil
},
})
// Create the readline instance.
a.rl, err = readline.NewEx(&readline.Config{
Prompt: a.currentPrompt,
HistorySearchFold: true, // enable case-insensitive history searching
DisableAutoSaveHistory: true,
HistoryFile: a.config.HistoryFile,
HistoryLimit: a.config.HistoryLimit,
AutoComplete: newCompleter(&a.commands),
})
if err != nil {
return err
}
// Assign readline instance
a.rl = rl
a.OnClose(a.rl.Close)
// Run the shell hook.
@@ -393,6 +407,16 @@ func (a *App) Run() (err error) {
return a.runShell()
}
func (a *App) setReadlineDefaults(config *readline.Config) {
config.Prompt = a.currentPrompt
config.HistorySearchFold = true
config.DisableAutoSaveHistory = true
config.HistoryFile = a.config.HistoryFile
config.HistoryLimit = a.config.HistoryLimit
config.AutoComplete = newCompleter(&a.commands)
config.VimMode = a.config.VimMode
}
func (a *App) runShell() error {
var interruptCount int
var lines []string
@@ -461,7 +485,13 @@ Loop:
err = a.RunCommand(args)
if err != nil {
a.PrintError(err)
continue Loop
// Do not continue the Loop here. We want to handle command changes below.
}
// Sort the commands again if they have changed (Add or remove action).
if a.commands.hasChanged() {
a.commands.SortRecursive()
a.commands.unsetChanged()
}
}
+5 -4
View File
@@ -67,10 +67,11 @@ type Command struct {
// A non-nil Completer overrides the default behaviour.
Completer func(prefix string, args []string) []string
parent *Command
flags Flags
args Args
commands Commands
parent *Command
flags Flags
args Args
commands Commands
isBuiltin bool // Whenever this is a build-in command not added by the user.
}
func (c *Command) validate() error {
+42 -9
View File
@@ -30,29 +30,43 @@ import (
// Commands collection.
type Commands struct {
list []*Command
list []*Command
changed bool // Used to resort if something changes.
}
// Add the command to the slice.
// Duplicates are ignored.
func (c *Commands) Add(cmd *Command) {
c.list = append(c.list, cmd)
c.changed = true
}
// Remove a command from the slice.
func (c *Commands) Remove(name string) {
var index int
var cmd *Command
found := false
for index, cmd = range c.list {
func (c *Commands) Remove(name string) (found bool) {
for index, cmd := range c.list {
if cmd.Name == name {
found = true
break
c.changed = true
c.list = append(c.list[:index], c.list[index+1:]...)
return
}
}
if found {
c.list = append(c.list[:index], c.list[index+1:]...)
return
}
func (c *Commands) RemoveAll() {
var builtins []*Command
// Hint: There are no built-in sub commands. Ignore them.
for _, cmd := range c.list {
if cmd.isBuiltin {
builtins = append(builtins, cmd)
}
}
// Only keep the builtins.
c.list = builtins
c.changed = true
}
// All returns a slice of all commands.
@@ -108,6 +122,25 @@ func (c *Commands) SortRecursive() {
}
}
func (c *Commands) hasChanged() bool {
if c.changed {
return true
}
for _, sc := range c.list {
if sc.commands.hasChanged() {
return true
}
}
return false
}
func (c *Commands) unsetChanged() {
c.changed = false
for _, sc := range c.list {
sc.commands.unsetChanged()
}
}
// parse the args and return a command path to the root.
// cmds slice is empty, if no command was found.
func (c *Commands) parse(
+6
View File
@@ -54,6 +54,9 @@ type Config struct {
// NoColor defines if color output should be disabled.
NoColor bool
// VimMode defines if Readline is to use VimMode for line navigation.
VimMode bool
// Prompt defines the shell prompt.
Prompt string
PromptColor *color.Color
@@ -70,6 +73,9 @@ type Config struct {
HelpHeadlineUnderline bool
HelpSubCommands bool
HelpHeadlineColor *color.Color
// Override default iterrupt handler
InterruptHandler func(a *App, count int)
}
// SetDefaults sets the default values if not set.
+2 -3
View File
@@ -26,7 +26,6 @@ package grumble
import (
"fmt"
"runtime"
"sort"
"strconv"
"strings"
@@ -130,9 +129,9 @@ Loop:
}
args = args[1:]
// A double dash (--) is used in most Bash commands to signify the end of command options,
// A double dash (--) is used to signify the end of command options,
// after which only positional arguments are accepted.
if a == "--" && runtime.GOOS == "linux" {
if a == "--" {
break Loop
}
+1 -1
View File
@@ -107,7 +107,7 @@ github.com/desertbit/columnize
# github.com/desertbit/go-shlex v0.1.1
## explicit; go 1.14
github.com/desertbit/go-shlex
# github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.4
# github.com/desertbit/grumble v1.1.1 => github.com/moloch--/grumble v1.1.6
## explicit; go 1.12
github.com/desertbit/grumble
# github.com/desertbit/readline v1.5.1