From 0f7b6c0f3520d5377ae7a834530b254a4076f824 Mon Sep 17 00:00:00 2001 From: rkervella Date: Mon, 20 Jun 2022 19:57:50 -0700 Subject: [PATCH 1/3] Report errors on failure for `shell` and `portfwd` --- .../tunnel_handlers/portfwd_handler.go | 13 +++++++++++++ .../handlers/tunnel_handlers/shell_handler.go | 19 +++++++++++++++++++ .../sliver/handlers/tunnel_handlers/utils.go | 13 +++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 implant/sliver/handlers/tunnel_handlers/utils.go diff --git a/implant/sliver/handlers/tunnel_handlers/portfwd_handler.go b/implant/sliver/handlers/tunnel_handlers/portfwd_handler.go index 89b83d4a58..e72bf92171 100644 --- a/implant/sliver/handlers/tunnel_handlers/portfwd_handler.go +++ b/implant/sliver/handlers/tunnel_handlers/portfwd_handler.go @@ -13,6 +13,7 @@ import ( "time" "github.com/bishopfox/sliver/implant/sliver/transports" + "github.com/bishopfox/sliver/protobuf/commonpb" "github.com/bishopfox/sliver/protobuf/sliverpb" "google.golang.org/protobuf/proto" ) @@ -24,6 +25,12 @@ func PortfwdReqHandler(envelope *sliverpb.Envelope, connection *transports.Conne // {{if .Config.Debug}} log.Printf("[portfwd] Failed to unmarshal protobuf %s", err) // {{end}} + portfwdResp, _ := proto.Marshal(&sliverpb.Portfwd{ + Response: &commonpb.Response{ + Err: err.Error(), + }, + }) + reportError(envelope, connection, portfwdResp) return } @@ -43,6 +50,12 @@ func PortfwdReqHandler(envelope *sliverpb.Envelope, connection *transports.Conne log.Printf("[portfwd] Failed to dial remote address %s", err) // {{end}} cancelContext() + portfwdResp, _ := proto.Marshal(&sliverpb.Portfwd{ + Response: &commonpb.Response{ + Err: err.Error(), + }, + }) + reportError(envelope, connection, portfwdResp) return } if conn, ok := dst.(*net.TCPConn); ok { diff --git a/implant/sliver/handlers/tunnel_handlers/shell_handler.go b/implant/sliver/handlers/tunnel_handlers/shell_handler.go index 2180283124..8e4f382690 100644 --- a/implant/sliver/handlers/tunnel_handlers/shell_handler.go +++ b/implant/sliver/handlers/tunnel_handlers/shell_handler.go @@ -10,6 +10,7 @@ import ( "github.com/bishopfox/sliver/implant/sliver/shell" "github.com/bishopfox/sliver/implant/sliver/transports" + "github.com/bishopfox/sliver/protobuf/commonpb" "github.com/bishopfox/sliver/protobuf/sliverpb" "google.golang.org/protobuf/proto" ) @@ -22,6 +23,12 @@ func ShellReqHandler(envelope *sliverpb.Envelope, connection *transports.Connect // {{if .Config.Debug}} log.Printf("[shell] Failed to unmarshal protobuf %s", err) // {{end}} + shellResp, _ := proto.Marshal(&sliverpb.Shell{ + Response: &commonpb.Response{ + Err: err.Error(), + }, + }) + reportError(envelope, connection, shellResp) return } @@ -31,6 +38,12 @@ func ShellReqHandler(envelope *sliverpb.Envelope, connection *transports.Connect // {{if .Config.Debug}} log.Printf("[shell] Failed to get system shell") // {{end}} + shellResp, _ := proto.Marshal(&sliverpb.Shell{ + Response: &commonpb.Response{ + Err: err.Error(), + }, + }) + reportError(envelope, connection, shellResp) return } @@ -39,6 +52,12 @@ func ShellReqHandler(envelope *sliverpb.Envelope, connection *transports.Connect // {{if .Config.Debug}} log.Printf("[shell] Failed to spawn! err: %v", err) // {{end}} + shellResp, _ := proto.Marshal(&sliverpb.Shell{ + Response: &commonpb.Response{ + Err: err.Error(), + }, + }) + reportError(envelope, connection, shellResp) return } else { // {{if .Config.Debug}} diff --git a/implant/sliver/handlers/tunnel_handlers/utils.go b/implant/sliver/handlers/tunnel_handlers/utils.go new file mode 100644 index 0000000000..f858b55ea7 --- /dev/null +++ b/implant/sliver/handlers/tunnel_handlers/utils.go @@ -0,0 +1,13 @@ +package tunnel_handlers + +import ( + "github.com/bishopfox/sliver/implant/sliver/transports" + "github.com/bishopfox/sliver/protobuf/sliverpb" +) + +func reportError(envelope *sliverpb.Envelope, connection *transports.Connection, data []byte) { + connection.Send <- &sliverpb.Envelope{ + Data: data, + ID: envelope.ID, + } +} From 20520755b29ef8fa56340b813804ca0596faa740 Mon Sep 17 00:00:00 2001 From: rkervella Date: Mon, 20 Jun 2022 20:22:43 -0700 Subject: [PATCH 2/3] Add client side error handling --- client/command/shell/shell.go | 14 +++++++++++++- client/core/portfwd.go | 10 ++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/client/command/shell/shell.go b/client/command/shell/shell.go index 4f157e5dc2..2cc2e1b066 100644 --- a/client/command/shell/shell.go +++ b/client/command/shell/shell.go @@ -82,7 +82,6 @@ func runInteractive(ctx *grumble.Context, shellPath string, noPty bool, con *con // Start() takes an RPC tunnel and creates a local Reader/Writer tunnel object tunnel := core.GetTunnels().Start(rpcTunnel.TunnelID, rpcTunnel.SessionID) - defer tunnel.Close() shell, err := con.Rpc.Shell(context.Background(), &sliverpb.ShellReq{ Request: con.ActiveTarget.Request(ctx), @@ -94,6 +93,19 @@ func runInteractive(ctx *grumble.Context, shellPath string, noPty bool, con *con con.PrintErrorf("%s\n", err) return } + // + if shell.Response != nil && shell.Response.Err != "" { + con.PrintErrorf("Error: %s\n", shell.Response.Err) + _, err = con.Rpc.CloseTunnel(context.Background(), &sliverpb.Tunnel{ + TunnelID: tunnel.ID, + SessionID: session.ID, + }) + if err != nil { + con.PrintErrorf("RPC Error: %s\n", err) + } + return + } + defer tunnel.Close() log.Printf("Bound remote shell pid %d to tunnel %d", shell.Pid, shell.TunnelID) con.PrintInfof("Started remote shell with pid %d\n\n", shell.Pid) diff --git a/client/core/portfwd.go b/client/core/portfwd.go index 6339d89205..92e2141ce6 100644 --- a/client/core/portfwd.go +++ b/client/core/portfwd.go @@ -20,6 +20,7 @@ package core import ( "context" + "errors" "io" "log" "net" @@ -202,6 +203,7 @@ func (p *ChannelProxy) dialImplant(ctx context.Context) (*TunnelIO, error) { log.Printf("[tcpproxy] Failed to dial implant %s", err) return nil, err } + log.Printf("[tcpproxy] Created new tunnel with id %d (session %s)", rpcTunnel.TunnelID, p.Session.ID) tunnel := GetTunnels().Start(rpcTunnel.TunnelID, rpcTunnel.SessionID) @@ -218,6 +220,14 @@ func (p *ChannelProxy) dialImplant(ctx context.Context) (*TunnelIO, error) { if err != nil { return nil, err } + // Close tunnel in case of error on the implant side + if portfwdResp.Response != nil && portfwdResp.Response.Err != "" { + p.Rpc.CloseTunnel(ctx, &sliverpb.Tunnel{ + TunnelID: tunnel.ID, + SessionID: p.Session.ID, + }) + return nil, errors.New(portfwdResp.Response.Err) + } log.Printf("Portfwd response: %v", portfwdResp) return tunnel, nil From be7b723c8a0897a750c497d853aa1ec687490e17 Mon Sep 17 00:00:00 2001 From: moloch-- <875022+moloch--@users.noreply.github.com> Date: Tue, 21 Jun 2022 08:24:22 -0700 Subject: [PATCH 3/3] Spelling fix --- client/command/armory/armory.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/command/armory/armory.go b/client/command/armory/armory.go index a174243234..07ef9fd2cb 100644 --- a/client/command/armory/armory.go +++ b/client/command/armory/armory.go @@ -56,7 +56,7 @@ type ArmoryPackage struct { IsAlias bool `json:"-"` } -// AmoryBundle - A list of packages +// ArmoryBundle - A list of packages type ArmoryBundle struct { Name string `json:"name"` Packages []string `json:"packages"`