Projects STRLCPY reverse_ssh Commits ccb68380
🤬
  • Add bones of listen command being able to open ports on clients that are effectively the server port

  • Loading...
  • NHAS committed 11 months ago
    ccb68380
    1 parent 96ba7cf5
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    internal/client/client.go
    skipped 155 lines
    156 156   continue
    157 157   }
    158 158   
     159 + // Make initial timeout quite long so folks who type their ssh public key can actually do it
     160 + // After this the timeout gets updated by the server
    159 161   realConn := &internal.TimeoutConn{conn, 4 * time.Minute}
    160 162   
    161 163   sshConn, chans, reqs, err := ssh.NewClientConn(realConn, addr, config)
    skipped 24 lines
    186 188   }
    187 189   
    188 190   realConn.Timeout = time.Duration(timeout*2) * time.Second
     191 + 
     192 + case "tcpip-forward":
     193 + go handlers.StartRemoteForward(nil, req, sshConn)
     194 + 
     195 + case "cancel-tcpip-forward":
     196 + var rf internal.RemoteForwardRequest
     197 + 
     198 + err := ssh.Unmarshal(req.Payload, &rf)
     199 + if err != nil {
     200 + req.Reply(false, []byte(fmt.Sprintf("Unable to unmarshal remote forward request in order to stop it: %s", err.Error())))
     201 + return
     202 + }
     203 + 
     204 + go func(r *ssh.Request) {
     205 + err := handlers.StopRemoteForward(rf)
     206 + if err != nil {
     207 + r.Reply(false, []byte(err.Error()))
     208 + return
     209 + }
     210 + 
     211 + r.Reply(true, nil)
     212 + }(req)
    189 213   
    190 214   default:
    191 215   if req.WantReply {
    skipped 29 lines
  • ■ ■ ■ ■ ■ ■
    internal/client/handlers/jumphost.go
    skipped 70 lines
    71 71   return
    72 72   }
    73 73   
    74  - go func() {
     74 + go func(r *ssh.Request) {
    75 75   err := StopRemoteForward(rf)
    76 76   if err != nil {
    77 77   r.Reply(false, []byte(err.Error()))
    skipped 1 lines
    79 79   }
    80 80   
    81 81   r.Reply(true, nil)
    82  - }()
     82 + }(r)
    83 83   default:
    84 84   //Ignore any unspecified global requests
    85 85   r.Reply(false, nil)
    skipped 10 lines
    96 96   log.Error("Channel call back error: %s", err)
    97 97   }
    98 98   
     99 + user.Lock()
    99 100   for rf := range user.SupportedRemoteForwards {
    100 101   go StopRemoteForward(rf)
    101 102   }
     103 + user.Unlock()
    102 104   
    103 105   }
    104 106  }
    skipped 1 lines
  • ■ ■ ■ ■ ■
    internal/client/handlers/remoteforward.go
    skipped 47 lines
    48 48   }
    49 49   defer l.Close()
    50 50   
    51  - user.SupportedRemoteForwards[rf] = true
     51 + defer StopRemoteForward(rf)
     52 + 
     53 + if user != nil {
     54 + user.Lock()
     55 + user.SupportedRemoteForwards[rf] = true
     56 + user.Unlock()
     57 + }
    52 58   
    53 59   //https://datatracker.ietf.org/doc/html/rfc4254
    54 60   responseData := []byte{}
    skipped 7 lines
    62 68   log.Println("Started listening on: ", l.Addr())
    63 69   
    64 70   currentRemoteForwardsLck.Lock()
    65  - 
    66 71   currentRemoteForwards[rf] = l
    67 72   currentRemoteForwardsLck.Unlock()
     73 + 
    68 74   for {
    69 75   
    70 76   proxyCon, err := l.Accept()
    skipped 64 lines
  • ■ ■ ■ ■ ■
    internal/global.go
    skipped 27 lines
    28 28   BindPort uint32
    29 29  }
    30 30   
     31 +// https://tools.ietf.org/html/rfc4254
    31 32  type ChannelOpenDirectMsg struct {
    32 33   Raddr string
    33 34   Rport uint32
    skipped 128 lines
  • ■ ■ ■ ■ ■ ■
    internal/server/commands/listen.go
    skipped 14 lines
    15 15   log logger.Logger
    16 16  }
    17 17   
     18 +func client() {
     19 + 
     20 +}
     21 + 
     22 +func server() {
     23 + 
     24 +}
     25 + 
    18 26  func (w *listen) Run(tty io.ReadWriter, line terminal.ParsedLine) error {
    19 27   if line.IsSet("h") || len(line.Flags) < 1 {
    20 28   fmt.Fprintf(tty, "%s", w.Help(false))
    skipped 70 lines
    91 99   return terminal.MakeHelpText(
    92 100   "listen [OPTION] [PORT]",
    93 101   "listen starts or stops listening ports",
     102 + "\t--client (-c)\tSpecify client/s to act on, e.g -c *, --client your.hostname.here",
     103 + "\t--server (-s)\tSpecify to change the server listeners",
    94 104   "\t--on\tTurn on port, e.g --on :8080 127.0.0.1:4444",
    95 105   "\t--off\tTurn off port, e.g --off :8080 127.0.0.1:4444",
    96 106   "\t-l\tList all enabled addresses",
    skipped 10 lines
  • ■ ■ ■ ■ ■ ■
    internal/server/handlers/forwardserverport.go
     1 +package handlers
     2 + 
     3 +import (
     4 + "errors"
     5 + "fmt"
     6 + "net"
     7 + "sync"
     8 + "time"
     9 + 
     10 + "github.com/NHAS/reverse_ssh/internal"
     11 + "github.com/NHAS/reverse_ssh/internal/server/multiplexer"
     12 + "github.com/NHAS/reverse_ssh/pkg/logger"
     13 + "golang.org/x/crypto/ssh"
     14 +)
     15 + 
     16 +var (
     17 + currentRemoteForwardsLck sync.RWMutex
     18 + currentRemoteForwards = map[string]string{}
     19 + remoteForward = map[string]ssh.Channel{}
     20 +)
     21 + 
     22 +type chanConn struct {
     23 + channel ssh.Channel
     24 + drtMsg internal.ChannelOpenDirectMsg
     25 +}
     26 + 
     27 +func (c *chanConn) Read(b []byte) (n int, err error) {
     28 + return c.channel.Read(b)
     29 +}
     30 + 
     31 +func (c *chanConn) Write(b []byte) (n int, err error) {
     32 + return c.channel.Write(b)
     33 +}
     34 + 
     35 +func (c *chanConn) Close() error {
     36 + return c.channel.Close()
     37 +}
     38 + 
     39 +func (c *chanConn) LocalAddr() net.Addr {
     40 + return &net.TCPAddr{
     41 + IP: net.ParseIP(c.drtMsg.Laddr),
     42 + Port: int(c.drtMsg.Lport),
     43 + }
     44 +}
     45 + 
     46 +func (c *chanConn) RemoteAddr() net.Addr {
     47 + return &net.TCPAddr{
     48 + IP: net.ParseIP(c.drtMsg.Raddr),
     49 + Port: int(c.drtMsg.Rport),
     50 + }
     51 +}
     52 + 
     53 +func (c *chanConn) SetDeadline(t time.Time) error {
     54 + return errors.New("not implemented on a channel")
     55 +}
     56 + 
     57 +func (c *chanConn) SetReadDeadline(t time.Time) error {
     58 + return errors.New("not implemented on a channel")
     59 + 
     60 +}
     61 + 
     62 +func (c *chanConn) SetWriteDeadline(t time.Time) error {
     63 + return errors.New("not implemented on a channel")
     64 + 
     65 +}
     66 + 
     67 +func channelToConn(channel ssh.Channel, drtMsg internal.ChannelOpenDirectMsg) net.Conn {
     68 + return &chanConn{channel, drtMsg}
     69 +}
     70 + 
     71 +func ServerPortForward(clientId string) func(_ *internal.User, newChannel ssh.NewChannel, log logger.Logger) {
     72 + return func(_ *internal.User, newChannel ssh.NewChannel, log logger.Logger) {
     73 + a := newChannel.ExtraData()
     74 + 
     75 + var drtMsg internal.ChannelOpenDirectMsg
     76 + err := ssh.Unmarshal(a, &drtMsg)
     77 + if err != nil {
     78 + log.Warning("Unable to unmarshal proxy %s", err)
     79 + newChannel.Reject(ssh.ResourceShortage, "Unable to unmarshal proxy")
     80 + return
     81 + }
     82 + 
     83 + connection, requests, err := newChannel.Accept()
     84 + if err != nil {
     85 + newChannel.Reject(ssh.ResourceShortage, "nope")
     86 + log.Warning("Unable to accept new channel %s", err)
     87 + return
     88 + }
     89 + defer connection.Close()
     90 + 
     91 + go func() {
     92 + for req := range requests {
     93 + if req.WantReply {
     94 + req.Reply(false, nil)
     95 + }
     96 + }
     97 + 
     98 + StopRemoteForward(clientId)
     99 + }()
     100 + 
     101 + currentRemoteForwardsLck.Lock()
     102 + remoteForward[clientId] = connection
     103 + currentRemoteForwards[clientId] = fmt.Sprintf("%s:%d", drtMsg.Raddr, drtMsg.Rport)
     104 + currentRemoteForwardsLck.Unlock()
     105 + 
     106 + multiplexer.ServerMultiplexer.QueueConn(channelToConn(connection, drtMsg))
     107 + 
     108 + }
     109 +}
     110 + 
     111 +func GetRemoteForwards(clientId string) string {
     112 + currentRemoteForwardsLck.RLock()
     113 + defer currentRemoteForwardsLck.RUnlock()
     114 + 
     115 + return currentRemoteForwards[clientId]
     116 +}
     117 + 
     118 +func StopRemoteForward(clientId string) {
     119 + currentRemoteForwardsLck.Lock()
     120 + defer currentRemoteForwardsLck.Unlock()
     121 + 
     122 + if remoteForward[clientId] != nil {
     123 + remoteForward[clientId].Close()
     124 + }
     125 + 
     126 + delete(remoteForward, clientId)
     127 + delete(currentRemoteForwards, clientId)
     128 +}
     129 + 
  • ■ ■ ■ ■ ■ ■
    internal/server/sshd.go
    skipped 174 lines
    175 175   // net.Conn and a ssh.ServerConfig to ssh.NewServerConn, in effect, upgrading the net.Conn
    176 176   // into an ssh.ServerConn
    177 177   config := &ssh.ServerConfig{
    178  - ServerVersion: "SSH-2.0-OpenSSH_7.4",
     178 + ServerVersion: "SSH-2.0-OpenSSH_8.0",
    179 179   PublicKeyCallback: func(conn ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) {
    180 180   
    181 181   authorizedKeysMap, err := readPubKeys(authorizedKeysPath)
    skipped 65 lines
    247 247   config.AddHostKey(privateKey)
    248 248   
    249 249   // Accept all connections
    250  - 
    251 250   for {
    252 251   tcpConn, err := sshListener.Accept()
    253 252   if err != nil {
    skipped 87 lines
    341 340   go ssh.DiscardRequests(reqs)
    342 341   
    343 342   err = internal.RegisterChannelCallbacks(nil, chans, clientLog, map[string]internal.ChannelHandler{
    344  - "rssh-download": handlers.Download(dataDir),
     343 + "rssh-download": handlers.Download(dataDir),
     344 + "forwarded-tcpip": handlers.ServerPortForward(id),
    345 345   })
    346 346   
    347 347   clientLog.Info("SSH client disconnected")
    skipped 29 lines
  • ■ ■ ■ ■ ■
    internal/users.go
    skipped 14 lines
    15 15  var users map[string]bool = make(map[string]bool)
    16 16   
    17 17  type User struct {
     18 + sync.RWMutex
    18 19   // This is the users connection to the server itself, creates new channels and whatnot. NOT to get io.Copy'd
    19 20   ServerConnection ssh.Conn
    20 21   
    skipped 1 lines
    22 23   
    23 24   ShellRequests <-chan *ssh.Request
    24 25   
    25  - // Remote forwards sent by user
     26 + // Remote forwards sent by user, used to just close user specific remote forwards
    26 27   SupportedRemoteForwards map[RemoteForwardRequest]bool //(set)
    27 28   
    28 29   // So we can capture details about who is currently using the rssh server
    skipped 48 lines
  • ■ ■ ■ ■ ■
    pkg/mux/multiplexer.go
    skipped 67 lines
    68 68   continue
    69 69   
    70 70   }
    71  - 
    72 71   go func() {
    73 72   select {
    74 73   case m.newConnections <- conn:
    skipped 33 lines
    108 107   sort.Strings(listeners)
    109 108   
    110 109   return listeners
     110 +}
     111 + 
     112 +func (m *Multiplexer) QueueConn(c net.Conn) error {
     113 + select {
     114 + case m.newConnections <- c:
     115 + return nil
     116 + case <-time.After(250 * time.Millisecond):
     117 + return errors.New("too busy to queue connection")
     118 + }
    111 119  }
    112 120   
    113 121  func ListenWithConfig(network, address string, _c MultiplexerConfig) (*Multiplexer, error) {
    skipped 144 lines
Please wait...
Page is in error, reload to recover