Skip to content

feat: add TLS ClientHello/ServerHello analyzer with JA3/JA3S fingerprinting (#2)#30

Merged
Zious11 merged 14 commits intodevelopfrom
worktree-tls-analyzer
Apr 7, 2026
Merged

feat: add TLS ClientHello/ServerHello analyzer with JA3/JA3S fingerprinting (#2)#30
Zious11 merged 14 commits intodevelopfrom
worktree-tls-analyzer

Conversation

@Zious11
Copy link
Copy Markdown
Owner

@Zious11 Zious11 commented Apr 7, 2026

Summary

  • Adds TlsAnalyzer implementing StreamAnalyzer — parses ClientHello and ServerHello from reassembled TCP streams, extracts SNI, computes JA3/JA3S fingerprints, detects weak cipher suites (NULL/anonymous/export/RC4) and deprecated SSL 2.0/3.0 versions
  • Adds StreamDispatcher (ADR 0001) — content-first routing of reassembled TCP streams to HTTP or TLS analyzers based on first-byte inspection (0x16 0x03 for TLS, HTTP method keywords for HTTP), with port-based fallback
  • Wires --tls CLI flag to the new analyzer via the dispatcher
  • Two ADRs: content-first stream dispatch (0001) and modular protocol analyzer pattern (0002)

Test plan

  • 10 TLS analyzer tests: ClientHello/ServerHello parsing, JA3 GREASE filtering, weak cipher findings (client + server), normal handshake, parse errors, stop after handshake, summarize output
  • 4 dispatcher tests: TLS routing, HTTP routing, content-over-port detection (TLS on port 80), port fallback
  • Tested against real PCAP tests/fixtures/tls.pcap — detected SSL 3.0, export ciphers, computed correct JA3/JA3S hashes
  • Tested HTTP routing through dispatcher: tests/fixtures/http-full.cap — 2 GET requests parsed, TLS sees 0 packets
  • All 114 existing tests pass
  • cargo clippy --tests clean
  • PR review applied: extension parse errors tracked in parse_errors counter; deprecated SSL detection added; 2 enhancements deferred to TLS: surface non-UTF-8 SNI hostnames instead of silently dropping #28, StreamDispatcher: add unclassified_flows counter for visibility #29

Zious11 added 11 commits April 7, 2026 08:30
Establishes the routing pattern for multiple stream analyzers
(HTTP, TLS, future SSH/SMB). Content-based detection is primary
(TLS record header, HTTP method keywords), port hints as fallback.
Validated against Zeek DPD, Suricata, and Wireshark approaches.
Covers: StreamDispatcher (ADR 0001), TlsAnalyzer with JA3/JA3S
fingerprinting, weak cipher detection, SNI extraction, TLS record
buffering. Validated via Perplexity: tls-parser API, JA3 format,
GREASE filtering, TLS 1.3 version handling, detection scope.
Codifies the two-trait model (ProtocolAnalyzer for packet-level,
StreamAnalyzer for stream-level), internal structure pattern
(per-flow state, aggregate counters, findings, error tracking),
and the steps to add a new analyzer. Documents existing DNS/HTTP
analyzers and planned TLS analyzer.
6 tasks: scaffolding, dispatcher tests, TLS record parsing + JA3,
ServerHello + JA3S + weak cipher tests, summarize(), CLI integration.
14 total tests across 2 test files.
Extension parsing failures were silently producing empty extension
lists via .ok().unwrap_or_default(), computing JA3 with missing
data without any indication to the user. Now increments parse_errors
so users know fingerprints may be incomplete. Also counts unexpected
Incomplete errors from record parsing. Partial JA3 with empty
extension fields is still computed (matches Zeek behavior).
SSLv3 is prohibited by RFC 7568 (POODLE vulnerability). SSLv2 is
even worse (DROWN attack). Generate Anomaly/Likely/High findings
for both ClientHello and ServerHello using these versions.
Verified against tests/fixtures/tls.pcap (SSL 3.0 traffic).
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds TLS stream analysis (ClientHello/ServerHello parsing) to wirerust, including JA3/JA3S fingerprinting and weak/deprecated TLS signal detection, and introduces a stream dispatcher to route reassembled TCP flows to the appropriate analyzer.

Changes:

  • Added TlsAnalyzer (StreamAnalyzer) to parse TLS handshakes, extract SNI, compute JA3/JA3S, and emit findings for weak ciphers / deprecated SSL versions.
  • Added StreamDispatcher to classify reassembled TCP streams via content-first detection with port fallback and forward data to HTTP/TLS analyzers.
  • Wired --tls into the CLI analyze path and added unit tests + ADR/spec documentation.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/analyzer/tls.rs New TLS stream analyzer with per-flow buffering, handshake parsing, JA3/JA3S, counters, and findings.
src/dispatcher.rs New dispatcher to route reassembled flow bytes to HTTP vs TLS analyzers.
src/main.rs Integrates dispatcher and --tls flag into analyze workflow; updates reassembly requirements and reporting.
src/lib.rs Exposes the new dispatcher module.
src/analyzer/mod.rs Exposes the new tls analyzer module.
tests/tls_analyzer_tests.rs Adds TLS analyzer unit tests (ClientHello/ServerHello parsing, JA3/JA3S, findings, summarize).
tests/dispatcher_tests.rs Adds dispatcher routing unit tests.
docs/adr/0001-content-first-stream-dispatch.md ADR documenting dispatcher approach and rationale.
docs/adr/0002-modular-protocol-analyzers.md ADR documenting analyzer modularity/traits pattern.
docs/superpowers/specs/2026-04-07-tls-clienthello-design.md Design spec for TLS analyzer + dispatcher.
docs/superpowers/plans/2026-04-07-tls-analyzer.md Implementation plan for TLS analyzer + dispatcher.
Cargo.toml Adds tls-parser and md-5 dependencies.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/dispatcher.rs Outdated
Comment thread src/analyzer/tls.rs
Comment thread tests/dispatcher_tests.rs
Comment on lines +49 to +56
// TLS record header on port 80 — content detection should override port
let tls_data = [0x16, 0x03, 0x03, 0x00, 0x05, 0x01, 0x00, 0x00, 0x01, 0x00];
dispatcher.on_data(&fk, Direction::ClientToServer, &tls_data, 0);

// HTTP analyzer should NOT have received this data
let http = dispatcher.http.as_ref().unwrap();
assert_eq!(http.method_counts().len(), 0);
}
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dispatcher routing assertions here don’t actually detect misrouting: if TLS bytes are incorrectly forwarded to HttpAnalyzer, method_counts() can still remain empty while parse_errors increments. To make these tests validate routing, also assert that dispatcher.http.as_ref().unwrap().parse_error_count() remains 0 for TLS payloads (and/or assert TLS analyzer state changed, e.g., handshake_count()/parse_error_count()), so a wrong route would fail the test.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 343a101. Added parse_error_count() == 0 assertions to the content detection and port fallback tests to verify HTTP analyzer didn't attempt to parse misrouted TLS bytes.

Comment thread src/main.rs
Zious11 added 3 commits April 7, 2026 09:57
Add TLS 1.2 (aes256gcm, with SNI) and TLS 1.3 (rfc8446) pcap
fixtures from the Wireshark test suite. 4 integration tests verify:
- TLS 1.2: SNI extraction, JA3/JA3S computation, version tracking
- TLS 1.3: legacy_version (771) in JA3, 2 handshakes parsed
- SSL 3.0: deprecated protocol + weak cipher findings generated
- summarize() output has all required fields
…gth check

1. Don't cache DispatchTarget::None — allow reclassification on
   subsequent on_data when more bytes arrive (Copilot #1)
2. Add MAX_RECORD_PAYLOAD (18,432) sanity check to reject impossibly
   large TLS records that would pin buffer memory (Copilot #2)
3. Stronger dispatcher test assertions — verify HTTP parse_error_count
   stays 0 when TLS is routed correctly (Copilot #3)
4. Early return in dispatcher when no analyzers enabled (Copilot #4)
@Zious11 Zious11 merged commit 3200bf3 into develop Apr 7, 2026
4 checks passed
@Zious11 Zious11 deleted the worktree-tls-analyzer branch April 7, 2026 15:14
@Zious11 Zious11 mentioned this pull request Apr 7, 2026
3 tasks
Zious11 added a commit that referenced this pull request Apr 7, 2026
Adds TLS to protocol analysis, features, architecture diagram, and
component table. Updates --tls flag description (no longer "coming
soon"). Removes TLS from roadmap (implemented in #30). Adds
max_receive_window to reassembly feature description.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants