{ Josh Rendek }

<3 Go & Kubernetes

I was working on the agent for SSH Pot and ran into something interesting last night. A lot of the brute force attempts attempt to run a command like this:

1ssh user@host 'uname'

This is different than:

1ssh user@host
2$ uname

The first command is executing a command then exiting, the second is actually logging in and giving the user a shell. The first requests a exec subsystem and the second requests a shell subsystem - so there are two ways to handle it.

 1func HandleShellRequest(channel ssh.Channel, in <-chan *ssh.Request) {
 2	for req := range in {
 3		ok := true
 4		logfile.Println("[request " + req.Type + "]: " + string(req.Payload))
 5		switch req.Type {
 6		case "shell":
 7			req.Reply(ok, nil)
 8		case "exec":
 9			if string(req.Payload) == string("uname") {
10				channel.Write([]byte("\n\rLinux\n\r"))
11			}
12
13			channel.Close()
14		}
15	}
16}

When logging in my logfile it would show something like:

1[request exec]: uname

And even when comparing the two side by side with something like this:

1logfile.Println("["+string(req.Payload)+"]:["+"uname"+"]")

I would get this output:

1[uname]:[uname]

Yet the comparison on line 9 would not get hit. After sitting and thinking about it for a while I decided to print the bytes out:

1INFO: 2014/07/07 23:15:18 sshd.go:157: [0 0 0 5 117 110 97 109 101]
2INFO: 2014/07/07 23:15:18 sshd.go:158: [117 110 97 109 101]

Aha! So for some reason req.Payload is padded with 3 null bytes and a ENQ byte (hex 5).

Here is the corrected version removing the correct bytes - now the string comparison works:

 1func HandleShellRequest(channel ssh.Channel, in <-chan *ssh.Request) {
 2	for req := range in {
 3		ok := true
 4		logfile.Println("[request " + req.Type + "]: " + string(req.Payload))
 5		switch req.Type {
 6		case "shell":
 7			req.Reply(ok, nil)
 8		case "exec":
 9			if string(req.Payload[4:]) == string("uname") {
10				channel.Write([]byte("\n\rLinux\n\r"))
11			}
12
13			channel.Close()
14		}
15	}
16}
comments powered by Disqus