Projects STRLCPY reverse_ssh Commits c133af05
🤬
  • Add subsystems for sftp, and setuid and setgid

  • Loading...
  • NHAS committed 2 years ago
    c133af05
    1 parent c29e4e02
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■
    internal/client/handlers/session.go
    skipped 7 lines
    8 8   "strings"
    9 9   
    10 10   "github.com/NHAS/reverse_ssh/internal"
     11 + "github.com/NHAS/reverse_ssh/internal/client/handlers/subsystems"
    11 12   "github.com/NHAS/reverse_ssh/pkg/logger"
    12  - "github.com/pkg/sftp"
    13 13   "golang.org/x/crypto/ssh"
    14 14  )
    15 15   
    skipped 19 lines
    35 35   
    36 36   case "subsystem":
    37 37   
    38  - if !(len(req.Payload) > 4 && string(req.Payload[4:]) == "sftp") {
    39  - req.Reply(false, []byte("Unknown subsystem"))
    40  - log.Warning("unknown subsystem '%s' ", req.Payload)
    41  - }
    42  - 
    43  - server, err := sftp.NewServer(connection)
     38 + err := subsystems.RunSubsystems(connection, req)
    44 39   if err != nil {
    45  - log.Warning("Unable to make server from channel '%s'", err.Error())
    46  - req.Reply(false, []byte(err.Error()))
    47  - return
     40 + log.Error("subsystem encountered an error: %s", err.Error())
     41 + fmt.Fprintf(connection, "subsystem error: '%s'", err.Error())
    48 42   }
    49 43   
    50  - req.Reply(true, nil)
    51  - 
    52  - err = server.Serve()
    53  - if err != io.EOF && err != nil {
    54  - log.Error("sftp server had an error: %s", err.Error())
    55  - }
    56 44   return
    57 45   
    58 46   case "exec":
    skipped 87 lines
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/init.go
     1 +package subsystems
     2 + 
     3 +import (
     4 + "fmt"
     5 + 
     6 + "github.com/NHAS/reverse_ssh/internal/terminal"
     7 + "golang.org/x/crypto/ssh"
     8 +)
     9 + 
     10 +// Enable sftp for both windows and linux
     11 +var subsystems = map[string]subsystem{
     12 + "sftp": new(subSftp),
     13 + "list": new(list),
     14 +}
     15 + 
     16 +type subsystem interface {
     17 + Execute(arguments terminal.ParsedLine, connection ssh.Channel, subsystemReq *ssh.Request) error
     18 +}
     19 + 
     20 +func RunSubsystems(connection ssh.Channel, req *ssh.Request) error {
     21 + if len(req.Payload) < 4 {
     22 + return fmt.Errorf("Payload size is too small <4, not enough space for token")
     23 + 
     24 + }
     25 + 
     26 + line := terminal.ParseLine(string(req.Payload[4:]), 0)
     27 + if subsys, ok := subsystems[line.Command.Value()]; ok {
     28 + 
     29 + return subsys.Execute(line, connection, req)
     30 + }
     31 + 
     32 + req.Reply(false, []byte("Unknown subsystem"))
     33 + return fmt.Errorf("Unknown subsystem '%s'", req.Payload)
     34 +}
     35 + 
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/init_linux.go
     1 +package subsystems
     2 + 
     3 +//Enable setuid and setgid for linux only
     4 +func init() {
     5 + subsystems["setuid"] = new(setuid)
     6 + subsystems["setgid"] = new(setgid)
     7 +}
     8 + 
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/init_windows.go
     1 +package subsystems
     2 + 
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/list.go
     1 +package subsystems
     2 + 
     3 +import (
     4 + "fmt"
     5 + 
     6 + "github.com/NHAS/reverse_ssh/internal/terminal"
     7 + "golang.org/x/crypto/ssh"
     8 +)
     9 + 
     10 +type list bool
     11 + 
     12 +func (l *list) Execute(line terminal.ParsedLine, connection ssh.Channel, subsystemReq *ssh.Request) error {
     13 + subsystemReq.Reply(true, nil)
     14 + 
     15 + for k := range subsystems {
     16 + fmt.Fprintf(connection, "%s\n", k)
     17 + }
     18 + 
     19 + return nil
     20 +}
     21 + 
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/setgid.go
     1 +//go:build linux
     2 + 
     3 +package subsystems
     4 + 
     5 +import (
     6 + "fmt"
     7 + "strconv"
     8 + "syscall"
     9 + 
     10 + "github.com/NHAS/reverse_ssh/internal/terminal"
     11 + "golang.org/x/crypto/ssh"
     12 +)
     13 + 
     14 +type setgid bool
     15 + 
     16 +func (su *setgid) Execute(line terminal.ParsedLine, connection ssh.Channel, subsystemReq *ssh.Request) error {
     17 + 
     18 + subsystemReq.Reply(true, nil)
     19 + 
     20 + if len(line.Arguments) != 1 {
     21 + fmt.Fprintf(connection, "setgid only takes one argument, the uid to set rssh to.")
     22 + return nil
     23 + }
     24 + 
     25 + gid, err := strconv.Atoi(line.Arguments[0].Value())
     26 + 
     27 + if err != nil {
     28 + fmt.Fprintf(connection, "%s", err.Error())
     29 + return nil
     30 + }
     31 + 
     32 + return syscall.Setgid(gid)
     33 +}
     34 + 
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/setuid.go
     1 +//go:build linux
     2 + 
     3 +package subsystems
     4 + 
     5 +import (
     6 + "fmt"
     7 + "strconv"
     8 + "syscall"
     9 + 
     10 + "github.com/NHAS/reverse_ssh/internal/terminal"
     11 + "golang.org/x/crypto/ssh"
     12 +)
     13 + 
     14 +type setuid bool
     15 + 
     16 +func (su *setuid) Execute(line terminal.ParsedLine, connection ssh.Channel, subsystemReq *ssh.Request) error {
     17 + subsystemReq.Reply(true, nil)
     18 + 
     19 + if len(line.Arguments) != 1 {
     20 + fmt.Fprintf(connection, "setuid only takes one argument, the uid to set rssh to.")
     21 + return nil
     22 + }
     23 + 
     24 + uid, err := strconv.Atoi(line.Arguments[0].Value())
     25 + 
     26 + if err != nil {
     27 + fmt.Fprintf(connection, "%s", err.Error())
     28 + return nil
     29 + }
     30 + 
     31 + return syscall.Setuid(uid)
     32 +}
     33 + 
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/subsystems/sftp.go
     1 +package subsystems
     2 + 
     3 +import (
     4 + "fmt"
     5 + "io"
     6 + 
     7 + "github.com/NHAS/reverse_ssh/internal/terminal"
     8 + "github.com/pkg/sftp"
     9 + "golang.org/x/crypto/ssh"
     10 +)
     11 + 
     12 +type subSftp bool
     13 + 
     14 +func (s *subSftp) Execute(_ terminal.ParsedLine, connection ssh.Channel, subsystemReq *ssh.Request) error {
     15 + server, err := sftp.NewServer(connection)
     16 + if err != nil {
     17 + subsystemReq.Reply(false, []byte(err.Error()))
     18 + return err
     19 + }
     20 + 
     21 + subsystemReq.Reply(true, nil)
     22 + 
     23 + err = server.Serve()
     24 + if err != io.EOF && err != nil {
     25 + return fmt.Errorf("sftp server had an error: %s", err.Error())
     26 + }
     27 + 
     28 + return nil
     29 +}
     30 + 
  • ■ ■ ■ ■ ■
    internal/server/handlers/session.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "fmt"
     5 + "io"
    5 6   
    6 7   "github.com/NHAS/reverse_ssh/internal"
     8 + "github.com/NHAS/reverse_ssh/internal/server/clients"
    7 9   "github.com/NHAS/reverse_ssh/internal/server/commands"
     10 + "github.com/NHAS/reverse_ssh/internal/server/webserver"
    8 11   "github.com/NHAS/reverse_ssh/internal/terminal"
     12 + "github.com/NHAS/reverse_ssh/internal/terminal/autocomplete"
    9 13   "github.com/NHAS/reverse_ssh/pkg/logger"
    10 14   "golang.org/x/crypto/ssh"
    11 15  )
    skipped 52 lines
    64 68   // (i.e. no command in the Payload)
    65 69   req.Reply(len(req.Payload) == 0, nil)
    66 70   
    67  - //This blocks so will keep the channel from defer closing
    68  - shell(user, connection, log)
     71 + term := terminal.NewAdvancedTerminal(connection, user, "catcher$ ")
     72 + 
     73 + term.SetSize(int(user.Pty.Columns), int(user.Pty.Rows))
     74 + 
     75 + term.AddValueAutoComplete(autocomplete.RemoteId, clients.Autocomplete)
     76 + term.AddValueAutoComplete(autocomplete.WebServerFileIds, webserver.Autocomplete)
     77 + 
     78 + term.AddCommands(commands.CreateCommands(user, log))
     79 + 
     80 + err := term.Run()
     81 + if err != nil && err != io.EOF {
     82 + log.Error("Error: %s", err)
     83 + }
    69 84   
    70 85   return
    71 86   //Yes, this is here for a reason future me. Despite the RFC saying "Only one of shell,subsystem, exec can occur per channel" pty-req actuall proceeds all of them
    skipped 21 lines
  • ■ ■ ■ ■ ■ ■
    internal/server/handlers/shell.go
    1  -package handlers
    2  - 
    3  -import (
    4  - "fmt"
    5  - "io"
    6  - 
    7  - "github.com/NHAS/reverse_ssh/internal"
    8  - "github.com/NHAS/reverse_ssh/internal/server/clients"
    9  - "github.com/NHAS/reverse_ssh/internal/server/commands"
    10  - "github.com/NHAS/reverse_ssh/internal/server/webserver"
    11  - "github.com/NHAS/reverse_ssh/internal/terminal"
    12  - "github.com/NHAS/reverse_ssh/internal/terminal/autocomplete"
    13  - "github.com/NHAS/reverse_ssh/pkg/logger"
    14  - "golang.org/x/crypto/ssh"
    15  -)
    16  - 
    17  -func shell(user *internal.User, connection ssh.Channel, log logger.Logger) error {
    18  - term := terminal.NewAdvancedTerminal(connection, user, "catcher$ ")
    19  - 
    20  - term.SetSize(int(user.Pty.Columns), int(user.Pty.Rows))
    21  - 
    22  - term.AddValueAutoComplete(autocomplete.RemoteId, clients.Autocomplete)
    23  - term.AddValueAutoComplete(autocomplete.WebServerFileIds, webserver.Autocomplete)
    24  - 
    25  - term.AddCommands(commands.CreateCommands(user, log))
    26  - 
    27  - err := term.Run()
    28  - if err != nil && err != io.EOF {
    29  - fmt.Fprintf(term, "Error: %s\n", err)
    30  - }
    31  - 
    32  - return err
    33  -}
    34  - 
Please wait...
Page is in error, reload to recover