Switch to new test harness
This commit is contained in:
@@ -2,17 +2,37 @@ 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-"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register(Both, "", detectSSH)
|
||||
}
|
||||
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.
|
||||
@@ -20,34 +40,52 @@ func detectSSH(dir Direction, data []byte, srcPort, dstPort int) (proto *Protoco
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
if dstPort == 22 || dstPort == 2200 || dstPort == 2222 {
|
||||
confidence = .1
|
||||
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: string(line[len(ssh20Prefix):]),
|
||||
Extra: implementation,
|
||||
},
|
||||
}, confidence + 0.75
|
||||
}, 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: string(line[len(ssh20Prefix):]),
|
||||
Extra: implementation,
|
||||
},
|
||||
}, confidence + 0.75
|
||||
}, confidence + 0.65
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user