shadow1ng/fscan · warning
service_not_identified
service_not_identified
Error message
service_not_identified: SSH
What it means
The SSH plugin connected and read the banner but could not positively identify the service as SSH, so identifyService returns 'service_not_identified' with the received banner quoted ('SSH'). The banner exchange failed to match the plugin's identification criteria.
Source
Thrown at plugins/services/ssh.go:304
Error: err,
}
}
defer func() { _ = conn.Close() }()
if banner := p.readSSHBanner(conn, session.Config); banner != "" {
session.LogSuccess(i18n.Tr("ssh_service_identified", target, banner)) //nolint:govet
return &ScanResult{
Type: plugins.ResultTypeService,
Success: true,
Service: "ssh",
Banner: banner,
}
}
return &ScanResult{
Success: false,
Service: "ssh",
Error: fmt.Errorf("%s", i18n.Tr("service_not_identified", "SSH")),
}
}
// readSSHBanner 读取SSH服务器Banner
func (p *SSHPlugin) readSSHBanner(conn net.Conn, config *common.Config) string {
_ = conn.SetReadDeadline(time.Now().Add(config.ModuleTimeout()))
// RFC 4253 permits servers to send informational lines before the SSH
// identification string. Read bounded lines until the protocol banner is
// found instead of requiring SSH- at the first byte of the first read.
reader := bufio.NewReaderSize(conn, 256)
for range 50 {
line, err := reader.ReadString('\n')
if len(line) > 255 {
return ""
}
banner := strings.TrimSpace(line)View on GitHub (pinned to 95cc12e753)
Solutions
- Manually connect (nc host 22) and inspect the actual banner to confirm it matches SSH format.
- Increase the module read timeout so slow banners are captured.
- Loosen/extend the banner identification pattern to cover the server's banner variant.
- Verify the target port really hosts SSH and not a different or wrapped service.
Example fix
// before cfg.SetModuleTimeout(2 * time.Second) // banner read times out // after cfg.SetModuleTimeout(10 * time.Second) // allow slow SSH banner exchange
Defensive patterns
Strategy: retry
Validate before calling
conn.SetReadDeadline(time.Now().Add(10*time.Second))
buf := make([]byte, 256); n, _ := conn.Read(buf)
if !strings.Contains(string(buf[:n]), "SSH-") { /* warn: not a standard SSH banner */ } Type guard
func looksLikeSSH(banner string) bool { return strings.HasPrefix(banner, "SSH-") } Prevention
- Increase module timeout for slow banner exchange
- Manually inspect banners of ambiguous hosts
- Keep banner patterns updated for non-standard servers
- Confirm port 22 actually hosts SSH
When it happens
Trigger: Calling Scan when readSSHBanner returns a banner that does not match the SSH identification pattern (or is empty/timeout), causing the final fallback error in identifyService.
Common situations: Server on port 22 is not really SSH (a proxy, tarpit, or honeypot); banner delayed beyond ModuleTimeout; non-standard SSH servers with unusual banners; rate-limiting wrappers that greet differently.
Related errors
- i18n.Tr("service_not_identified", "Memcached")
- service_not_identified
- service_not_identified
- service_not_identified
AI-assisted analysis of shadow1ng/fscan@95cc12e753 (2026-09-06).
Data as JSON: /api/errors/16c81cf1b945bd0e.
Report an issue: GitHub.