Decode parses the stream according to the SSH protocol.
()
| 64 | |
| 65 | // Decode parses the stream according to the SSH protocol. |
| 66 | func (h *sshReader) Decode() { |
| 67 | sshLog.Info("SSH Decode() called", |
| 68 | zap.String("ident", h.conversation.Ident), |
| 69 | zap.Int("dataFragments", len(h.conversation.Data)), |
| 70 | zap.String("clientIP", h.conversation.ClientIP), |
| 71 | zap.String("serverIP", h.conversation.ServerIP), |
| 72 | zap.Int("clientPort", int(h.conversation.ClientPort)), |
| 73 | zap.Int("serverPort", int(h.conversation.ServerPort)), |
| 74 | ) |
| 75 | |
| 76 | // prevent nil pointer access if decoder is not initialized |
| 77 | if Decoder.Writer == nil { |
| 78 | sshLog.Error("SSH Decoder.Writer is nil - cannot write SSH audit records!") |
| 79 | return |
| 80 | } |
| 81 | |
| 82 | var ( |
| 83 | serverBuf bytes.Buffer |
| 84 | clientBuf bytes.Buffer |
| 85 | ) |
| 86 | |
| 87 | for _, d := range h.conversation.Data { |
| 88 | payloadLen := len(d.Raw()) |
| 89 | if d.Direction() == reassembly.TCPDirClientToServer { |
| 90 | // 2255k bytes should be enough to capture ident (max 255 bytes) + kexInit (usually ~1200-1700 bytes) |
| 91 | if clientBuf.Len() < 2255 { |
| 92 | clientBuf.Write(d.Raw()) |
| 93 | } |
| 94 | // Track for JA4SSH |
| 95 | if payloadLen > 0 { |
| 96 | h.ja4sshData.AddClientPacket(payloadLen) |
| 97 | } else { |
| 98 | h.ja4sshData.AddClientACK() |
| 99 | } |
| 100 | } else { |
| 101 | // 2255k bytes should be enough to capture ident (max 255 bytes) + kexInit (usually ~1200-1700 bytes) |
| 102 | if serverBuf.Len() < 2255 { |
| 103 | serverBuf.Write(d.Raw()) |
| 104 | } |
| 105 | // Track for JA4SSH |
| 106 | if payloadLen > 0 { |
| 107 | h.ja4sshData.AddServerPacket(payloadLen) |
| 108 | } else { |
| 109 | h.ja4sshData.AddServerACK() |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | // Compute JA4SSH fingerprint from all collected packet data |
| 115 | h.ja4sshFingerprint = ja4.ComputeJA4SSH(h.ja4sshData) |
| 116 | h.ja4sshSessionType = ja4.DetectSessionType(h.ja4sshFingerprint) |
| 117 | |
| 118 | h.searchKexInit(bufio.NewReader(&clientBuf), reassembly.TCPDirClientToServer) |
| 119 | h.searchKexInit(bufio.NewReader(&serverBuf), reassembly.TCPDirServerToClient) |
| 120 | |
| 121 | sshLog.Info("SSH decode complete", |
| 122 | zap.String("ident", h.conversation.Ident), |
| 123 | zap.Int("softwareRecords", len(h.software)), |
nothing calls this directly
no test coverage detected