Switch to new test harness

This commit is contained in:
2025-10-09 15:37:17 +02:00
parent 170a038612
commit fd55412020
8 changed files with 567 additions and 304 deletions

View File

@@ -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
}
}