56 lines
1.2 KiB
Go
56 lines
1.2 KiB
Go
package protocol
|
|
|
|
import (
|
|
"bytes"
|
|
)
|
|
|
|
// The required prefix for the SSH protocol identification line.
|
|
const (
|
|
ssh199Prefix = "SSH-1.99-"
|
|
ssh20Prefix = "SSH-2.0-"
|
|
)
|
|
|
|
func init() {
|
|
Register(Both, "", detectSSH)
|
|
}
|
|
|
|
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 dstPort == 22 || dstPort == 2200 || dstPort == 2222 {
|
|
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'})
|
|
if bytes.HasPrefix(line, []byte(ssh20Prefix)) {
|
|
return &Protocol{
|
|
Name: ProtocolSSH,
|
|
Version: Version{
|
|
Major: 2,
|
|
Minor: 0,
|
|
Patch: -1,
|
|
Extra: string(line[len(ssh20Prefix):]),
|
|
},
|
|
}, confidence + 0.75
|
|
}
|
|
if bytes.HasPrefix(line, []byte(ssh199Prefix)) {
|
|
return &Protocol{
|
|
Name: ProtocolSSH,
|
|
Version: Version{
|
|
Major: 1,
|
|
Minor: 99,
|
|
Patch: -1,
|
|
Extra: string(line[len(ssh20Prefix):]),
|
|
},
|
|
}, confidence + 0.75
|
|
}
|
|
}
|
|
|
|
return nil, 0
|
|
}
|