94 lines
2.0 KiB
Go
94 lines
2.0 KiB
Go
package protocol
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
)
|
|
|
|
func init() {
|
|
// We can't match on SSH-?.? here, because the client or server may send a banner prior
|
|
// to sending the SSH handshake.
|
|
Register(Both, "", detectSSH)
|
|
}
|
|
|
|
// The required prefix for the SSH protocol identification line.
|
|
const (
|
|
ssh199Prefix = "SSH-1.99-"
|
|
ssh20Prefix = "SSH-2.0-"
|
|
)
|
|
|
|
var (
|
|
commonPort = map[int]bool{
|
|
22: true,
|
|
2200: true,
|
|
2222: true,
|
|
}
|
|
commonImplementations = []string{
|
|
"OpenSSH_",
|
|
"PuTTY",
|
|
"libssh",
|
|
"dropbear",
|
|
"Go",
|
|
"paramiko",
|
|
"Cyberduck",
|
|
}
|
|
)
|
|
|
|
func detectSSH(dir Direction, data []byte, srcPort, dstPort int) (proto *Protocol, confidence float64) {
|
|
// The data must be at least as long as the prefix itself.
|
|
if len(data) < len(ssh20Prefix) {
|
|
return nil, 0
|
|
}
|
|
|
|
if commonPort[srcPort] || commonPort[dstPort] {
|
|
confidence += .1
|
|
}
|
|
|
|
// The protocol allows for pre-banner text, so we have to check all lines.
|
|
for _, line := range bytes.Split(data, []byte{'\n'}) {
|
|
line = bytes.TrimSuffix(line, []byte{'\r'})
|
|
|
|
// Match the most common SSH 2.0 protocol.
|
|
if bytes.HasPrefix(line, []byte(ssh20Prefix)) {
|
|
implementation := string(line[len(ssh20Prefix):])
|
|
for _, prefix := range commonImplementations {
|
|
if strings.HasPrefix(implementation, prefix) {
|
|
confidence += .2
|
|
break
|
|
}
|
|
}
|
|
return &Protocol{
|
|
Name: ProtocolSSH,
|
|
Version: Version{
|
|
Major: 2,
|
|
Minor: 0,
|
|
Patch: -1,
|
|
Extra: implementation,
|
|
},
|
|
}, confidence + 0.65
|
|
}
|
|
|
|
// Match the (far) less common SSH 1.99 protocol.
|
|
if bytes.HasPrefix(line, []byte(ssh199Prefix)) {
|
|
implementation := string(line[len(ssh20Prefix):])
|
|
for _, prefix := range commonImplementations {
|
|
if strings.HasPrefix(implementation, prefix) {
|
|
confidence += .2
|
|
break
|
|
}
|
|
}
|
|
return &Protocol{
|
|
Name: ProtocolSSH,
|
|
Version: Version{
|
|
Major: 1,
|
|
Minor: 99,
|
|
Patch: -1,
|
|
Extra: implementation,
|
|
},
|
|
}, confidence + 0.65
|
|
}
|
|
}
|
|
|
|
return nil, 0
|
|
}
|