Projects STRLCPY reverse_ssh Commits cbe9d8a4
🤬
  • ■ ■ ■ ■ ■
    internal/client/client.go
    skipped 186 lines
    187 187   
    188 188   clientLog := logger.NewLog("client")
    189 189   
    190  - user, err := internal.CreateUser(sshConn)
    191  - if err != nil {
    192  - clientLog.Warning("Unable to create internal user")
    193  - return
    194  - }
    195  - 
    196 190   //Do not register new client callbacks here, they are actually within the JumpHandler
    197 191   //session is handled here as a legacy hangerover from allowing a client who has directly connected to the servers console to run the connect command
    198 192   //Otherwise anything else should be done via jumphost syntax -J
    199  - err = internal.RegisterChannelCallbacks(user, chans, clientLog, map[string]internal.ChannelHandler{
    200  - "session": handlers.Session,
     193 + err = internal.RegisterChannelCallbacks(nil, chans, clientLog, map[string]internal.ChannelHandler{
     194 + "session": handlers.ServerConsoleSession(sshConn),
    201 195   "jump": handlers.JumpHandler(sshPriv),
    202 196   })
    203 197   
    skipped 12 lines
  • ■ ■ ■ ■
    internal/client/handlers/scp.go
    skipped 25 lines
    26 26   //Find what the target file path is, essentially ignore anything that is a flag '-t'
    27 27   loc := -1
    28 28   mode := ""
    29  - for i := 1; i < len(commandParts); i++ {
     29 + for i := 0; i < len(commandParts); i++ {
    30 30   if mode == "" && (commandParts[i] == "-t" || commandParts[i] == "-f") {
    31 31   mode = commandParts[i]
    32 32   continue
    skipped 327 lines
  • ■ ■ ■ ■ ■
    internal/client/handlers/session.go
    skipped 13 lines
    14 14   
    15 15   "github.com/NHAS/reverse_ssh/internal"
    16 16   "github.com/NHAS/reverse_ssh/internal/client/handlers/subsystems"
     17 + "github.com/NHAS/reverse_ssh/internal/terminal"
    17 18   "github.com/NHAS/reverse_ssh/pkg/logger"
    18 19   "github.com/NHAS/reverse_ssh/pkg/storage"
     20 + 
    19 21   "golang.org/x/crypto/ssh"
    20 22  )
     23 + 
     24 +func ServerConsoleSession(ServerConn ssh.Conn) internal.ChannelHandler {
     25 + 
     26 + user, err := internal.CreateUser(ServerConn)
     27 + 
     28 + return func(_ *internal.User, newChannel ssh.NewChannel, log logger.Logger) {
     29 + if err != nil {
     30 + log.Error("Unable to add user %s\n", err)
     31 + newChannel.Reject(ssh.ConnectionFailed, err.Error())
     32 + return
     33 + }
     34 + 
     35 + Session(user, newChannel, log)
     36 + }
     37 + 
     38 +}
    21 39   
    22 40  // Session has a lot of 'function' in ssh. It can be used for shell, exec, subsystem, pty-req and more.
    23 41  // However these calls are done through requests, rather than opening a new channel
    skipped 36 lines
    60 78   
    61 79   req.Reply(true, nil)
    62 80   
    63  - parts := strings.Split(cmd.Cmd, " ")
    64  - if len(parts) == 0 {
     81 + line := terminal.ParseLine(cmd.Cmd, 0)
     82 + 
     83 + if line.Empty() {
     84 + log.Warning("Human client sent an empty exec payload: %s\n", err)
    65 85   return
    66 86   }
    67 87   
    68  - if parts[0] == "scp" {
    69  - scp(parts, connection, log)
     88 + command := line.Command.Value()
     89 + 
     90 + if command == "scp" {
     91 + scp(line.Chunks[1:], connection, log)
    70 92   return
    71 93   }
    72 94   
    73  - command := parts[0]
    74  - if u, ok := isUrl(parts[0]); ok {
     95 + if u, ok := isUrl(command); ok {
    75 96   command, err = download(user.ServerConnection, u)
    76 97   if err != nil {
    77 98   fmt.Fprintf(connection, "%s", err.Error())
    skipped 2 lines
    80 101   }
    81 102   
    82 103   if user.Pty != nil {
    83  - runCommandWithPty(command, parts[1:], user, requests, log, connection)
     104 + runCommandWithPty(command, line.Chunks[1:], user, requests, log, connection)
    84 105   return
    85 106   }
    86  - runCommand(command, parts[1:], connection)
     107 + runCommand(command, line.Chunks[1:], connection)
    87 108   
    88 109   return
    89 110   case "shell":
    skipped 143 lines
  • ■ ■ ■ ■
    internal/client/handlers/shell_windows.go
    skipped 42 lines
    43 43   
    44 44  func runCommandWithPty(command string, args []string, user *internal.User, requests <-chan *ssh.Request, log logger.Logger, connection ssh.Channel) {
    45 45   
    46  - fullCommand := command + strings.Join(args, " ")
     46 + fullCommand := command + " " + strings.Join(args, " ")
    47 47   vsn := windows.RtlGetVersion()
    48 48   if vsn.MajorVersion < 10 || vsn.BuildNumber < 17763 {
    49 49   
    skipped 175 lines
  • ■ ■ ■ ■
    internal/server/commands/exec.go
    skipped 88 lines
    89 89   continue
    90 90   }
    91 91   go ssh.DiscardRequests(r)
    92  - defer newChan.Close()
    93 92   
    94 93   response, err := newChan.SendRequest("exec", true, commandByte)
    95 94   if err != nil && !line.IsSet("q") {
    skipped 12 lines
    108 107   }
    109 108   
    110 109   io.Copy(tty, newChan)
     110 + newChan.Close()
    111 111   }
    112 112   
    113 113   fmt.Fprint(tty, "\n")
    skipped 22 lines
  • ■ ■ ■ ■ ■ ■
    internal/terminal/utils.go
    skipped 66 lines
    67 67  }
    68 68   
    69 69  type ParsedLine struct {
     70 + Chunks []string
     71 + 
    70 72   FlagsOrdered []Flag
    71 73   Flags map[string]Flag
    72 74   
    skipped 5 lines
    78 80   Command *Cmd
    79 81   
    80 82   RawLine string
     83 +}
     84 + 
     85 +func (pl *ParsedLine) Empty() bool {
     86 + return pl.RawLine == ""
    81 87  }
    82 88   
    83 89  func (pl *ParsedLine) ArgumentsAsStrings() (out []string) {
    skipped 88 lines
    172 178  func parseSingleArg(line string, startPos int) (arg Argument, endPos int) {
    173 179   
    174 180   var (
    175  - isInString = false
    176  - literalNext = false
     181 + inString = false
     182 + stringDelimiter = byte(0)
     183 + literalNext = false
    177 184   )
    178  - 
    179  - if line[startPos] == '"' {
    180  - startPos++
    181  - isInString = true
    182  - }
    183 185   
    184 186   arg.start = startPos
    185 187   
    skipped 6 lines
    192 194   for arg.end = startPos; arg.end < len(line); arg.end++ {
    193 195   endPos = arg.end
    194 196   
     197 + if !inString && (line[endPos] == '"' || line[endPos] == '\'' || line[endPos] == '`') {
     198 + 
     199 + inString = true
     200 + stringDelimiter = line[endPos]
     201 + 
     202 + continue
     203 + }
     204 + 
    195 205   if !literalNext {
    196 206   
    197 207   if line[endPos] == '\\' {
    skipped 1 lines
    199 209   continue
    200 210   }
    201 211   
    202  - if line[endPos] == '"' {
    203  - isInString = false
     212 + if inString && line[endPos] == stringDelimiter {
     213 + stringDelimiter = byte(0)
     214 + inString = false
    204 215   continue
    205 216   }
    206  - }
    207 217   
    208  - if line[endPos] == ' ' && !isInString && !literalNext {
    209  - return
     218 + if line[endPos] == ' ' && !inString {
     219 + return
     220 + }
    210 221   }
    211 222   
    212 223   sb.WriteByte(line[endPos])
    skipped 47 lines
    260 271   pl.RawLine = line
    261 272   
    262 273   for i := 0; i < len(line); i++ {
     274 + 
    263 275   if line[i] == '-' {
    264 276   
    265 277   if capture != nil {
    skipped 12 lines
    278 290   pl.Focus = &newFlag
    279 291   pl.Section = &newFlag
    280 292   }
     293 + 
     294 + pl.Chunks = append(pl.Chunks, pl.RawLine[newFlag.start:newFlag.end])
    281 295   
    282 296   //First start parsing long options --blah
    283 297   if newFlag.long {
    skipped 29 lines
    313 327   args, i = parseArgs(line, i)
    314 328   
    315 329   for m, arg := range args {
     330 + pl.Chunks = append(pl.Chunks, arg.value)
     331 + 
    316 332   if cursorPosition >= arg.start && cursorPosition <= arg.end {
    317 333   pl.Focus = &args[m]
    318 334   
    skipped 66 lines
  • ■ ■ ■ ■ ■ ■
    internal/terminal/utils_test.go
    skipped 139 lines
    140 140   
    141 141  }
    142 142   
     143 +func TestStrings(t *testing.T) {
     144 + line := ParseLine("lala --long_arg \"test ''``-t a\" --zero -m", 0)
     145 + 
     146 + _, err := line.GetArgString("long_arg")
     147 + if err != nil {
     148 + t.Fatalf("Getting single string arg on 'long_arg' should work: %s", err)
     149 + }
     150 + 
     151 + _, err = line.GetArgString("zero")
     152 + if err == nil {
     153 + t.Fatalf("Expected error, 'zero' has no arg, yet we are still nil")
     154 + }
     155 + 
     156 + _, err = line.GetArgString("m")
     157 + if err == nil {
     158 + t.Fatalf("Expected error, 'm' has no arg, yet we are still nil")
     159 + }
     160 + 
     161 + e, err := line.ExpectArgs("long_arg", 1)
     162 + if err != nil {
     163 + t.Fatalf("Long arg supplies correct number of expected args, should not error: %s", err)
     164 + }
     165 + 
     166 + if len(e) != 1 || e[0].Value() != "test ''``-t a" {
     167 + t.Fatal("String was not handled correct as the value is incorrect")
     168 + }
     169 + 
     170 + if line.Chunks[0] != "lala" || line.Chunks[0] != line.Command.Value() {
     171 + t.Fatal("First chunk should be command")
     172 + }
     173 + 
     174 + if line.Chunks[1] != "--long_arg" {
     175 + t.Fatal("Next chunk should be flag")
     176 + }
     177 + 
     178 + if line.Chunks[2] != "test ''``-t a" {
     179 + t.Fatal("Next chunk should be argument string")
     180 + }
     181 +}
     182 + 
Please wait...
Page is in error, reload to recover